Autor Tema: ReinierTL - Problemas con RTOS CCS  (Leído 5118 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado leobianco

  • PIC10
  • *
  • Mensajes: 7
ReinierTL - Problemas con RTOS CCS
« en: 11 de Junio de 2015, 16:39:44 »
Estimados,

me contacto con ustedes debido a que he estado siguiendo el hilo del post sobre RTOS CCS que realizo hace ya unos cuantos años el amigo reiniertl.

He comenzado a realizar algunos códigos, para poner en practico los conocimientos y técnicas.

Resulta que me he encontrado con dos problemas bastantes insistentes. Paso a mencionarlos para ver si ustedes pueden ayudarme a lidiar con ellos:

# El primero de los problemas, viene relacionado con la función rtos_yield(). Resulta que en el código "Prueba01A.c", que se encuentra a continuacion, en la linea 112, cuando la función es llamada, comienza a tomar forma el primer problema.
La función entrega el procesador y al volver a ejecutarse la tarea, vuelve a este punto y todo parece andar muy bien, pero cuando la ejecución del código analiza la condición que impone el while, a pesar de que los valores de la condición son correctos, ésta no se cumple y sale del while.

A estas comprobaciones las he estado haciendo con el simulador Proteus con la ayuda de la función "Dissassemby" al hacer click derecho sobre el código, el cual desde mi punto de vista es bastante confiable, no se Uds que me dicen!!

Lo extraño es que gracias al código "Prueba01B.c" el codigo "Prueba01A.c" recibe por la UART un mensaje muy simple, el cual se lo procesa y envía a la consola como una cadena y el problema desaparece.

Lo cual me esta haciendo romper la cabeza un muy buen poco  :-).


# El segundo problema esta asociado a las estadísticas. Siguiendo con el tema, a medida que voy habilitando por partes la utilización de las estadísticas como puede verse en las lineas 40 y 41. El problema va desapareciendo gradualmente, ya que simplemente activando las estadísticas, al imprimir la trama "CH08:" se imprime "CH8:". Finalmente activando la utilización de las estadísticas, aparentemente desaparece por completo el problema.

El segundo problema relacionado con las estadísticas no tiene que ver con el problema anterior. Este problema me surge al momento de recopilar los datos y almacenarlos en la estructura que contendrá los tick's.
Puntualmente el valor hns_per_tick me lo entrega = 0. Por lo que, no puedo realizar los cálculos como lo explica la documentación de CCS.

Este problema se me ha dado en las plataformas Windows 10 y Windows 7, y no he encontrado diferencias.

La versión de CCS que utilizo es la 5.010 y la de Proteus es 7.10 SP0. También he probado con algunas versiones 4.xxx de CCS y Proteus 8.1 SP1 pero así aun el problema persiste.

Espero puedan dedicarle un tiempito a revisar mi código y aydarme a entender el problema.



Código: C
  1. Prueba01A.c
  2. #include <18F46K20.h>
  3. #device adc=10
  4.  
  5. #zero_ram
  6.  
  7. #FUSES noWDT                       //Usare el WDT
  8. #FUSES WDT2048                   //Watch Dog Timer uses 1:2048 Postscale 2.048s
  9. #FUSES INTRC_IO                  //Resistor/Capacitor Osc with CLKOUT
  10. #FUSES PUT                       //Power Up Timer
  11. #FUSES NOBROWNOUT                //No brownout reset
  12. #FUSES NOMCLR                    //Master Clear pin used for I/O
  13. #FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  14. #FUSES NOXINST                   //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
  15. #FUSES PROTECT                   //Code protected from reads
  16. #FUSES CPB                       //Boot Block Code Protected
  17. #FUSES WRTC                      //configuration registers write protected
  18. #FUSES EBTR                      //Memory protected from table reads
  19.  
  20. #use delay(clock=64000000, restart_wdt)
  21.  
  22. #use rs232(uart1,baud=9600)//,timeout=10)
  23. //#use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3, stream=uart_2)
  24.  
  25. #include <string.h>
  26.  
  27. //Constantes.
  28. #define TAM_RDA   4           //Tamaño del Buffer del puerto serie.
  29. #define TAM_CADENA 24
  30. //Variables.
  31. int8 hs, min, seg, iBuffer_RDA[TAM_RDA], iCont_Buffer_RDA, iSem_Port_ADC, iSem_Cadena_Put;
  32.  
  33. int16 Canal8, Canal9, Canal10, Canal11;
  34.  
  35. char cadena_mensaje_disponible[TAM_CADENA];
  36.  
  37. //-----------------------------------------------------------------------------
  38. //---------------------->Rutinas de RTOS<--------------------------------------
  39. //-----------------------------------------------------------------------------
  40. #define RTOS_USAR_ESTADISTICAS
  41. #define RTOS_TOMAR_ESTADISTICAS
  42. #define RTOS_MINOR_CYCLE 100ms
  43.  
  44. /* Para el RTOS se utiliza el timer 0 y las tareas tienen un minimo timepo de ejecucion de ...*/
  45. #IFDEF RTOS_USAR_ESTADISTICAS
  46. #use RTOS(timer = 0, minor_cycle = RTOS_MINOR_CYCLE, statistics)
  47. #ELSE
  48. #use RTOS(timer = 0, minor_cycle = RTOS_MINOR_CYCLE)
  49. #ENDIF
  50.  
  51. #IFDEF RTOS_TOMAR_ESTADISTICAS
  52. //Definicion de estructura para la adquisicion de estadisticas.
  53. struct rtos_estadisticas{
  54.    int32 total_ticks;    //Numero de tics que la tarea ha tenido.
  55.    int16 min_ticks;      //Minimo numero de ticks que demanda la tarea al ejecutarse
  56.    int16 max_ticks;      //Maximo numero de ticks que demanda la tarea al ejecutarse.
  57.    int16 hns_per_tick;   //???.
  58. } estadisticas_envia_cadena, estadisticas_reloj;
  59.  
  60. int32 us_max_envia_cadena, us_min_envia_cadena, us_total_envia_cadena, us_max_reloj, us_min_reloj, us_total_reloj;
  61. #ENDIF
  62.  
  63. //Prototipo de tareas.
  64. #task (rate = 100ms, max = 80ms)
  65. void envia_cadena();
  66.  
  67. #task (rate = 1s, max = 1ms)
  68. void reloj();
  69.  
  70. #task (rate = 100ms, max = 1ms)
  71. void lectura_ADC_CH8();
  72.  
  73. #task (rate = 100ms, max = 1ms)
  74. void lectura_ADC_CH9();
  75.  
  76. #task (rate = 100ms, max = 1ms)
  77. void lectura_ADC_CH10();
  78.  
  79. #task (rate = 100ms, max = 1ms)
  80. void lectura_ADC_CH11();
  81.  
  82. #task (rate = 100ms, max = 1ms, queue = 1)
  83. void mensaje_disponible();
  84.  
  85. #task (rate = 500ms, max = 1ms)
  86. void tiempo_max_espera_mensaje_RDA();
  87.  
  88. //Definicion de tareas.
  89. void envia_cadena()
  90. {  /* Esta es habilitada por la tarea reloj, una ves la misma termina de enviar la cadena, se autodeshabilita. */
  91.    static char cadena_put[150];
  92.    static int longi_char_put, cont_char_put, div_longi_char_put;
  93.    rtos_wait(iSem_Cadena_Put);
  94.    longi_char_put = 0;
  95.    cont_char_put = 0;
  96.    div_longi_char_put = 2;
  97.    /*Se Genera la cadena que sera enviada por el puerto serie*/
  98.    sprintf(cadena_put,"\rLa hora del sistemas es:\r%02u:%02u:%02u\rLas mediciones ADC son:\rCH08: %4Lu\rCH09: %4Lu\rCH10: %4Lu\rCH11: %4Lu %s", hs, min, seg, Canal8, Canal9, Canal10, Canal11, cadena_mensaje_disponible);
  99.    //Una vez cargados se borran para ver la frecuencia de lectura.
  100.    Canal8  = 0;
  101.    Canal9  = 0;
  102.    Canal10 = 0;
  103.    Canal11 = 0;
  104.    sprintf(cadena_mensaje_disponible,"\r\rNo hay Mensajes");
  105.    /*Seccion que envia la mitad de los caracteres y devuelve el prosesador al administrador de tares, para regresar al punto de devolusion, llegado su proximo turno de ejecicion*/
  106.    longi_char_put = strlen(cadena_put);
  107.    while(cont_char_put < longi_char_put)
  108.    {  putc(cadena_put[cont_char_put]);
  109.       cont_char_put ++;
  110.       if(cont_char_put > (int)(longi_char_put / div_longi_char_put))
  111.       {  -- div_longi_char_put;
  112.          rtos_yield();
  113.       }
  114.    }
  115.    rtos_signal(iSem_Cadena_Put);
  116.    rtos_disable(envia_cadena);
  117. }
  118.  
  119. void reloj()
  120. {  if(++seg >= 60)
  121.    {  seg = 0;
  122.       if(++min >= 60)
  123.       {  min = 0;
  124.          if(++hs >= 24)
  125.             hs = 0;
  126.       }
  127.    }
  128.  
  129.    if(iSem_Cadena_Put)
  130.       rtos_enable(envia_cadena);
  131.  
  132. #IFDEF RTOS_USAR_ESTADISTICAS
  133.    if(rtos_overrun(envia_cadena))
  134.       output_toggle(PIN_B7);
  135.    if(rtos_overrun(reloj))
  136.       output_toggle(PIN_B7);
  137. #ENDIF
  138.      
  139. #IFDEF RTOS_TOMAR_ESTADISTICAS
  140.    rtos_stats(envia_cadena, &estadisticas_envia_cadena);
  141.    us_total_envia_cadena   = (int32)(estadisticas_envia_cadena.total_ticks * estadisticas_envia_cadena.hns_per_tick)/10;
  142.    us_min_envia_cadena     = (int32)(estadisticas_envia_cadena.min_ticks * estadisticas_envia_cadena.hns_per_tick)/10;
  143.    us_max_envia_cadena     = (int32)(estadisticas_envia_cadena.max_ticks * estadisticas_envia_cadena.hns_per_tick)/10;
  144.    
  145.    rtos_stats(reloj, &estadisticas_reloj);
  146.    us_total_reloj          = (int32)(estadisticas_reloj.total_ticks * estadisticas_reloj.hns_per_tick)/10;
  147.    us_min_reloj            = (int32)(estadisticas_reloj.min_ticks * estadisticas_reloj.hns_per_tick)/10;
  148.    us_max_reloj            = (int32)(estadisticas_reloj.max_ticks * estadisticas_reloj.hns_per_tick)/10;
  149. #ENDIF
  150. }
  151.  
  152. void lectura_ADC_CH8()
  153. {  rtos_wait(iSem_Port_ADC);    //Comiensa la seccion critica.
  154.    set_adc_channel(8);
  155.    delay_us(20);
  156.    //rtos_yield();      No se justifica entregar el procesador por 20us.
  157.    read_adc(ADC_START_ONLY);
  158.    rtos_await(adc_done());       //devuelve el procesador hasta cuando se termine de realizar la convesion.
  159.    Canal8 = read_adc(ADC_READ_ONLY);
  160.    rtos_signal(iSem_Port_ADC);
  161. }
  162.  
  163. void lectura_ADC_CH9()
  164. {  rtos_wait(iSem_Port_ADC);    //Comiensa la seccion critica.
  165.    set_adc_channel(9);
  166.    delay_us(20);
  167.    //rtos_yield();      No se justifica entregar el procesador por 20us.
  168.    read_adc(ADC_START_ONLY);
  169.    rtos_await(adc_done());       //devuelve el procesador hasta cuando se termine de realizar la convesion.
  170.    Canal9 = read_adc(ADC_READ_ONLY);
  171.    rtos_signal(iSem_Port_ADC);
  172. }
  173.  
  174. void lectura_ADC_CH10()
  175. {  rtos_wait(iSem_Port_ADC);    //Comiensa la seccion critica.
  176.    set_adc_channel(10);
  177.    delay_us(20);
  178.    //rtos_yield();      No se justifica entregar el procesador por 20us.
  179.    read_adc(ADC_START_ONLY);
  180.    rtos_await(adc_done());       //devuelve el procesador hasta cuando se termine de realizar la convesion.
  181.    Canal10 = read_adc(ADC_READ_ONLY);
  182.    rtos_signal(iSem_Port_ADC);
  183. }
  184.  
  185. void lectura_ADC_CH11()
  186. {  rtos_wait(iSem_Port_ADC);    //Comiensa la seccion critica.
  187.    set_adc_channel(11);
  188.    delay_us(20);
  189.    //rtos_yield();      No se justifica entregar el procesador por 20us.
  190.    read_adc(ADC_START_ONLY);
  191.    rtos_await(adc_done());       //devuelve el procesador hasta cuando se termine de realizar la convesion.
  192.    Canal11 = read_adc(ADC_READ_ONLY);
  193.    rtos_signal(iSem_Port_ADC);
  194. }
  195.  
  196. void mensaje_disponible()
  197. {  rtos_await(rtos_msg_poll());   //Espera a la llegada de un mensaje.
  198.    //Control de checksum, complemento a 2, debe dar cero.
  199.    //Si no da cero, hubo error de trama y se desecha el Mensaje.
  200.    int g = 0, caracter = iBuffer_RDA[0], complementoA2 = 0;
  201.    while(caracter != '\n')
  202.    {  complementoA2 += caracter;
  203.       caracter = iBuffer_RDA[++g];
  204.    }
  205.    if(complementoA2 == 0)
  206.    {  //Carga el mensaje en la cadena, para ser impresa desde la tarea reloj.
  207. //      sprintf(cadena_mensaje_disponible,"\r\rMensaje: %u para %u\r\r", iBuffer_RDA[1], rtos_msg_read());
  208.       sprintf(cadena_mensaje_disponible,"\r\rMensaje: %c para %u", iBuffer_RDA[1], rtos_msg_read());
  209.       //int i=0;
  210.    }
  211. }
  212.  
  213. void tiempo_max_espera_mensaje_RDA()
  214. {  //Al cumplirse su tiempo, se supone que el mensaje por la UART llego incompleto y no se le pudo dar fin.
  215.    iCont_Buffer_RDA = 0;   //Se reinicia su contador para un nuevo mensaje.
  216.    rtos_disable(tiempo_max_espera_mensaje_RDA);
  217. }
  218.  
  219. //---------------------->Fin Rutinas de RTOS<----------------------------------
  220. //-----------------------------------------------------------------------------
  221.  
  222. //-----------------------------------------------------------------------------
  223. //--------------------------->Interrupciones<----------------------------------
  224. //-----------------------------------------------------------------------------
  225. #int_RDA
  226. void RDA_isr(void)
  227. {  //Toma el dato y lo almacena en la Buffer.
  228.    int caracter = getc();
  229.   //Control de Rango del Buffer antes de almacenar.
  230.    if(iCont_Buffer_RDA < TAM_RDA)
  231.    {  iBuffer_RDA[iCont_Buffer_RDA] = caracter;
  232.       //Si es el primer caracter recivido, activa la tarea de tiempo maximo de espera por un mensaje.
  233.       if(iCont_Buffer_RDA == 0)
  234.          rtos_enable(tiempo_max_espera_mensaje_RDA);
  235.       //Se incrementa para un proximo caracter.
  236.       iCont_Buffer_RDA++;
  237.    }
  238.    else
  239.       iCont_Buffer_RDA = 255;
  240.    //Verifica si entro un caracter nueva linea '\n', con una longitud de mensaje valida.
  241.    //Asegurando por lo menos el mensaje mas corto. De lo contrario se sigen esperando mas caracteres.
  242.    if(caracter == '\n' && iCont_Buffer_RDA >= 3)
  243.    {  //Al completarse el mensaje, desactiva la tarea de tiempo maximo de espera por un mensaje.
  244.       rtos_disable(tiempo_max_espera_mensaje_RDA);
  245.       iCont_Buffer_RDA = 0;
  246.       //Envia el nobre del dispocitivo al que se llama indicando que hay un mensaje disponible.
  247.       rtos_msg_send(mensaje_disponible, iBuffer_RDA[0]);
  248.    }
  249. }
  250. //--------------------------->Fin Interrupciones<------------------------------
  251. //-----------------------------------------------------------------------------
  252.  
  253. void main()
  254. {  clear_interrupt(INT_RDA);
  255.    enable_interrupts(INT_RDA);
  256.    //enable_interrupts(INT_AD);
  257.    enable_interrupts(GLOBAL);
  258.    setup_adc_ports(sAN8|sAN9|sAN10|sAN11|VSS_VDD);
  259.    setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0);
  260.    setup_oscillator(OSC_64MHZ);
  261.    iSem_Port_ADC = 1;         //El recurso ADC, solo puede ser accedido por una tarea.
  262.    iSem_Cadena_Put = 1;       //Indica que se esta transmitiendo una cadena.
  263.    rtos_run();  
  264. }
  265.  

Código: C
  1. Prueba01B.c
  2. #include <18F46K20.h>
  3. #device adc=10
  4.  
  5. #zero_ram
  6.  
  7. #FUSES noWDT                       //Usare el WDT
  8. #FUSES WDT2048                   //Watch Dog Timer uses 1:2048 Postscale 2.048s
  9. #FUSES INTRC_IO                  //Resistor/Capacitor Osc with CLKOUT
  10. #FUSES PUT                       //Power Up Timer
  11. #FUSES NOBROWNOUT                //No brownout reset
  12. #FUSES NOMCLR                    //Master Clear pin used for I/O
  13. #FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  14. #FUSES NOXINST                   //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
  15. #FUSES PROTECT                   //Code protected from reads
  16. #FUSES CPB                       //Boot Block Code Protected
  17. #FUSES WRTC                      //configuration registers write protected
  18. #FUSES EBTR                      //Memory protected from table reads
  19.  
  20. #use delay(clock=16000000, restart_wdt)
  21.  
  22. #use rs232(uart1,baud=9600)//,timeout=10)
  23. //#use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3, stream=uart_2)
  24.  
  25. //Constantes.
  26. #define TAM_RDA   4           //Tamaño del Buffer del puerto serie.
  27. //Variables.
  28. int8 i=32;
  29.  
  30. //---------------------->Rutinas de RTOS<--------------------------------------
  31. /* Para el RTOS se utiliza el timer 0 y las tareas tienen un minimo timepo de ejecucion de 1us*/
  32. #use RTOS(timer = 0, minor_cycle = 3ms)
  33.  
  34. #task (rate = 2001ms, max = 3ms)
  35. void envia()
  36. {  //1 es un identificador de dispositivo, i es un mensaje o codigo y el resto es el complemento a dos para utilizarlo como checksum.
  37.    printf("%c%c%c\n",1,++i,~(int)(1+i)+1);
  38. }
  39.  
  40. //---------------------->Fin Rutinas de RTOS<----------------------------------
  41.  
  42. //--------------------------->Interrupciones<----------------------------------
  43. //--------------------------->Fin Interrupciones<------------------------------
  44.  
  45. void main()
  46. {  setup_oscillator(OSC_16MHZ);
  47.    rtos_run();
  48. }

Adjunto códigos fuente y esquema en Proteus.

Cordial Saludo desde Argentina

Desconectado JackPic

  • PIC10
  • *
  • Mensajes: 2
Re: ReinierTL - Problemas con RTOS CCS
« Respuesta #1 en: 28 de Agosto de 2015, 16:05:26 »
Buen día Leo,  yo tambien he tenido el mismo problema al trabajar con el RTOS de CCS. De igual forma he notado que cuando se implementa el rtos_yield() para ceder el procesador al regresar a la tarea es como si el contenido de las variables en RAM o ROM se pierden. Creo que se debe a que el RTOS de CCS destina ciertos bytes para almacenar variables importantes durante la ejecución de tareas y quizás al devolver el controla preprocesador éstas por algun motivo se pierden, teniendo en cuenta eso quite el rtos_yield() (cosa que podria ocasionar muchos errores, depende de la logica de tu programa y la asignacion de tiempo a las tareas) y con eso solucione parcialmente el problema. Agradeceria compartieras cualquier experiencia nueva que hayas tenido. Saludos

Desconectado leobianco

  • PIC10
  • *
  • Mensajes: 7
Re: ReinierTL - Problemas con RTOS CCS
« Respuesta #2 en: 02 de Septiembre de 2015, 11:16:26 »
Estimado JackPic,

Gracias por ser el unico en contestar a mi consulta. Realmente pense que podria interesarle a ésta comunidad discutir este dilema que a mi parecer no es poca cosa, ya que este compilador si bien no es lo mejor que hay, es muy eficiente a la hora de realizar proyectos relativamente simples. Tambien te cuento, para que el resto de la comunidad no se sienta intimidado por este comentario, que les envié a los de CCS esta misma consulta, redactada en ingles, y ni ellos me respondieron. Ja Ja Ja.

Te comparto una sección del codigo que he modificado, del codigo que ya he publicado en este tema:
Código: C
  1. 'Apartir de la linea 63 del primer codigo poblicado arriba'
  2. //Prototipo de tareas.
  3. #task (rate = 4ms, max = 2ms)
  4. void envia_cadena();
  5.  
  6. #task (rate = 4ms, max = 1ms)
  7. void reloj();
  8.  
  9. #task (rate = 100ms, max = 1ms)
  10. void lectura_ADC_CH8();
  11.  
  12. #task (rate = 100ms, max = 1ms)
  13. void lectura_ADC_CH9();
  14.  
  15. #task (rate = 100ms, max = 1ms)
  16. void lectura_ADC_CH10();
  17.  
  18. #task (rate = 100ms, max = 1ms)
  19. void lectura_ADC_CH11();
  20.  
  21. #task (rate = 100ms, max = 1ms, queue = 1)
  22. void mensaje_disponible();
  23.  
  24. #task (rate = 500ms, max = 1ms)
  25. void tiempo_max_espera_mensaje_RDA();
  26.  
  27. //Definicion de tareas.
  28. void envia_cadena()
  29. {  //static char cadena_put[150], cadena_put_now[4];
  30.    //static int longi_char_put, cont_char_put;
  31.    //char cadena_put[150], cadena_put_now[4];
  32.    //int longi_char_put, cont_char_put;
  33.    volatile char cadena_put[150], cadena_put_now[4];
  34.    volatile int longi_char_put, cont_char_put;
  35.    rtos_wait(iSem_Cadena_Put);
  36.    sprintf(cadena_put,"\rLa hora del sistemas es:\r%02u:%02u:%02u\rLas mediciones ADC son:\rCH08: %4Lu\rCH09: %4Lu\rCH10: %4Lu\rCH11: %4Lu %s", hs, min, seg, Canal8, Canal9, Canal10, Canal11, cadena_mensaje_disponible);
  37.    //Una vez cargados se borran para ver la frecuencia de lectura.
  38.    Canal8  = 0;
  39.    Canal9  = 0;
  40.    Canal10 = 0;
  41.    Canal11 = 0;
  42.    sprintf(cadena_mensaje_disponible,"\r\rNo hay Mensajes");
  43.    //Envia la mitad de los caracteres y devuelve el prosesador al administrador de tares, para regresar al punto de devolusion, llegado su proximo turno de ejecicion.
  44.    longi_char_put = strlen(cadena_put);
  45.    cont_char_put = 0;
  46.  
  47.  
  48.  
  49.    //***************************************************************************
  50.    //***************************************************************************
  51.    //Los siguientes bloques "while" realizan la misma tarea. El primero, no funciona como se necesita. El segundo si lo hace, pero si se compilan ambos "while", el primero continua sin funcionar como se necesita y el segundo deja de funcionar como lo hacía.
  52.    //***************************************************************************
  53.    //---------------------------------------------------------------------------
  54.  /*  
  55.    //***************************************************************************
  56.    //A continuación se presenta el bloque "while" donde se dan las anomalias de ejecucion, debido a errores del compilador.
  57.    //***************************************************************************
  58.     while(cont_char_put <= longi_char_put)
  59.    {  printf("%c%c%c", cadena_put[cont_char_put], cadena_put[++cont_char_put], cadena_put[++cont_char_put]);
  60.       cont_char_put++;
  61.       rtos_yield();
  62.    }
  63. */
  64.    //***************************************************************************
  65.    //A continuación se presenta el bloque "while" donde aparentemente la compilacion es corecta y se tiene una ejeción estable. De todas maneras se pierde la confianza de tener una compilación correcta.
  66.    while(cont_char_put <= longi_char_put)
  67.    //***************************************************************************
  68.    {  sprintf(cadena_put_now,"%c%c%c", cadena_put[cont_char_put], cadena_put[++cont_char_put], cadena_put[++cont_char_put]);
  69. //      cadena_put_now[0] = cadena_put[cont_char_put];
  70. //      cadena_put_now[1] = cadena_put[++cont_char_put];
  71. //      cadena_put_now[2] = cadena_put[++cont_char_put];
  72. //      cadena_put_now[3] = '\0';
  73.       cont_char_put ++;
  74.       printf(cadena_put_now);
  75.       rtos_yield();
  76.    }
  77.    //***************************************************************************
  78.    //***************************************************************************
  79.  
  80.  
  81.  
  82.    rtos_signal(iSem_Cadena_Put);
  83.    rtos_disable(envia_cadena);
  84. }

Cabe destacar que para esta compilacion que aparente mente funciona, no estan habilitadas las estadisticas, las cuales NO permiten que funcione como corresponde.
Tambien, aclaro que este codigo tiene pinta de funcionar bien, SIN las estadistias. Y si recompilan el mismo con el while que se encuentra comentado, encontraran dos deficiencias.
La Primera, si compilan sin las estadisticas, directamente no funciona.
La Segunda, si compilan con las estadisticas, veran que tiene pinta de que funciona, pero si leen con detenimiento las pequeñas cadenas que se están enviando por el puerto serie, veran que faltan caracteres al principio de la trama y que al final agrega un caracter que no tendria que estar allí, es más, si se compila con el segundo while, éste ultimo caracter no aparece por que, si se analiza la cadena, éste se encuentra despues del caracter 'fin de linea' de la cadena actual a enviar, por lo que la funcion 'printf' no deberia enviarlo.

Saludos desde Argentina, Córdoba.
« Última modificación: 02 de Septiembre de 2015, 11:24:58 por leobianco »

Desconectado JackPic

  • PIC10
  • *
  • Mensajes: 2
Re: ReinierTL - Problemas con RTOS CCS
« Respuesta #3 en: 06 de Septiembre de 2015, 06:12:12 »
Buen día Leobianco. Tomaré mi tiempo para analizar el código que posteaste, seguidamente me interesaría comentarte a ti y a la comunidad algunos problemas que he encontado al momento de hacer uso del kernel RTOS que incorpora el compilador CCS. Como anteriormente comenté, tenía problemas ya que al momento de ceder el control a la funcion rtos_run() era como que se perdìa el contenido de la variables almacenadas en RAM, por tanto, a pesar de que por ejemplo una comparaciòn sea veradera esta no se cumplir+ia, eso lo solucione de forma parcial quitando la funcion rtos_yield() pero estoy completamente conciente que esa no es la mejor manera de solucionar el problema desde el punto de vista de la programacion y mucho menos si lo que queremos es un robustes y escalabilidad del codigo. Pues bien, resulta que al ir completando mi código (estoy un poco largo de terminarlo) me di cuenta que el problema volvio a surguir, sin embargo ya no podía estar quitando rtos_yield() ya que la lógica que mi programa seguía no me lo permitía, concretamente yo estoy recibiento una cadena de caracteres atravez de uns ISR vía serial, cada cadena la almaceno en distintos buffer y luego, cuando termina de recibir todo el mensaje este activa una bandera que daria lugar a la ejecucion de una tarea que inicilamente tenia bloqueada cn rtos_await(), los datos alamacenado en el buffer los convierto a float de 32 bits con Atof(), estos datos  los proceso y su resultado los voy alamacenado en una seria de array que luego comparao su contenido para saber cuales de ellos almacenan valores distinto de cero, y es en esa comparacion donde surge el problema, a pesar que hay datos que son mayores que cero, este no los compara, de hecho almacena muchas veces valores completamente que no venian al caso y mi sospecha era que al usar rtos_yield() , el compilador asigna espacios de memria que  puede que sea insuficiente ya que en realidad estaba procesados muchos datos, ejecutando muchos ciclos y haciendo muchas comparaciones, pero estaba equivocado.

luego de  ver este pequeño problema  :5] :5] :? :? me di a la tarea de volver hacer uso del dissassembly de proteus y con la hoja de datos del 18f4550 ejecute paso a paso cada instruccion que el compilador asignaba a las subrutinas que habia programado, de lo que me di cuenta es que los array que antes mencione logicamente tienen asignado un espacio de memoria en RAM, pss verifique el contenido instruccion por instucción para ver si se modificaban en alguna parte  y me di cuenta que al "ceder el procesador" con rtos_yield() este consulta con rtos_run() la tarea que debe ejecutarse (si no hay ninguna tarea espera el timpo de ejecucion de la tarea en la que se hizo el llamano y contiua donde quedo) y precisamente al hacer esto, el compilador hacia una extrañisima modificacion a unas direcciones de memoria RAM que casualmente coincidian con el espacion de memoria en la que estaban mis array  :-/ , y aunque le asignara espaciosde memoria distinto este como que sabia ese "offset" e igual me las modificaba, pues bien, la solucion fue reservar los espacios de memoria con #reserve y los problemas se me solucionaron.

seguire trabajando con el Rtos de CCS y coincido contigo, seria oportuno que los que trabajan con esto compartieran sus experiencias ya si bien es cierto la programacion en C no es una forma eficiente de tratar este tipo de cosas, facilita mucho el trabajo ya sea para aplicaciones un tanto complejas donde el tiempo no es factor clave.

Saludos  :)


 

anything