Autor Tema: implementacion de la funcion int sprintf(const char *format, ...);  (Leído 2571 veces)

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

Desconectado jgpeiro06

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 276
implementacion de la funcion int sprintf(const char *format, ...);
« en: 16 de Diciembre de 2008, 19:34:01 »
Hola a todos. Estoy empezando con freeRTOS y he tenido problemas al usar la funcion sprintf(). Se produce un error del tipo CORE-E0001: Trap due to stack error, occurred from instruction at 0x006466 mientras se esta ejecutando el _vPortYield del RTOS. La rutina _vPortYield se ejecuta muchas veces, y la sprintf() tambien, pero si esta esta ultima en el programa se "cuelga" a los 250uS.

static void vTaskGenerate( void *pvParameters )
{
   char text_message[] = "12345678901234567890";
   for( ;; )
   {
       vTaskDelay(250);
      //...mas codigo
      sprintf( text_message, "%02X:%02X", 0x10, 0x20);
      //...mas codigo
      glcd_text57(28,15,text_message,1,1);
   }
}

Si la funcion sprinf esta comentada el programa funciona correctamente, si no lo esta se produce un error en la rutina _vPortYield, concretamente en la linea 86(MOV W0, _uxCriticalNesting).

No se si es xq la funcion sprintf no es reentrante, pero no creo xq ninguna otra tarea la esta utilizando. Es mas, si muevo ese sprintf a otra tarea del RTOS el programa funciona correctamente.

No se si es problema del RTOS, de su configuracion, del tamaño de stack o el del stak, del stack de cada tarea...el caso es q de momento he intentado adaptar alguna implementacion sencilla del printf.
Encontre esta: http://www.menie.org/georges/embedded/printf.c, pero hay un problema que aun no he entendido. Es todo codigo ANSI C y aparentemente no hay ninguna dependencia del hardware, pero en el MPLAB C30 no me funciona correctamente y en el PC si.

Depurando paso a paso en el MPLAB y en el CodeBlocks he visto que hay alguna diferencia en como incrementa los punteros...no se...
volviendo al tema principal, necesito saber exactamente como se trabaja con una funcion que tiene un numero de argumentos variable, xq no estoy seguro si el fallo empieza por ahi...


la funcion tiene esta forma:

int printf(const char *format, ...)
{
   int *varg = (int *)(&format);
   return print(0, varg);
}

donde *varg apuntara a los argumentos opcionales, que unas veces seran char, int o float... ademas para apuntar al iguiente argumento utiliza (char *)(*varg++) si es un numero y *((char **)varg++) si es un string...

-Si alguien esta dispuesto esta dispuesto a ejecutar paso a paso el codigo en el MPLAB y en PC para aveiguar donde esta la diferencia, prometo hablar de él a todas las chicas con las que me cruce x la calle durante todo un mes... pensaoslo, son mucha chicas...
- Si alguien tiene mas experiencia con RTOS y cree que el fallo esta en algo de la configuracion o algo asi solo les hablare de él durante dos semanas, ya que esta cuestion requiere menos esfuerzo...


Saludos a todos..

PD:Si hay alguna chica y mi recompensa no le parece interesante o le parece machista o cualquier cosa asi, no hay problema,  volvere atras en el tiempo y no escribire este post.
-alguien

Desconectado jgpeiro06

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 276
Re: implementacion de la funcion int sprintf(const char *format, ...);
« Respuesta #1 en: 18 de Diciembre de 2008, 17:51:12 »
Bueno, ya esta resuelto, por lo menos la implementacion del sprintf. He estado depurando el codigo en ensamblador para observar como el compilador C30 manejaba el stack en las llamadas y tal...mas o menos me he echo una idea de donde podia estar el error y luego he ido pequeñas modificaciones en el codigo hasta dar con el funcionamiento correcto. Realmente NO se xq el codigo funciona correctamente en el PC y no en el MPLAB C30, y puede ser que en cualquier momento descrubra un mal funcionamiento en la funcion derivado de los cambios que hice...pero de momento es lo que hay...
Esta es la funcion que modifique, simplemente he añadido la linea varg-=2; donde pensaba que hacia falta...
Código: C
  1. static int print(char **out, int *varg)
  2. {
  3.         /*register*/ int width, pad;
  4.         /*register*/ int pc = 0;
  5.         /*register*/ char *format = (char *)(*varg++);
  6.         char scr[2];
  7.  
  8.         for (; *format != 0; ++format) {
  9.                 if (*format == '%') {
  10.                         ++format;
  11.                         width = pad = 0;
  12.                         if (*format == '\0') break;
  13.                         if (*format == '%') goto out;
  14.                         if (*format == '-') {
  15.                                 ++format;
  16.                                 pad = PAD_RIGHT;
  17.                         }
  18.                         while (*format == '0') {
  19.                                 ++format;
  20.                                 pad |= PAD_ZERO;
  21.                         }
  22.                         for ( ; *format >= '0' && *format <= '9'; ++format) {
  23.                                 width *= 10;
  24.                                 width += *format - '0';
  25.                         }
  26.                         if( *format == 's' ) {
  27.                                 varg-=2;        // Need for correct work. Unknown reason.
  28.                                 /*register*/ char *s = *((char **)varg++);
  29.                                 pc += prints (out, s?s:"(null)", width, pad);
  30.                                 continue;
  31.                         }
  32.                         if( *format == 'd' ) {
  33.                                 varg-=2;        // Need for correct work.  Unknown reason.
  34.                                 pc += printi (out, *varg++, 10, 1, width, pad, 'a');
  35.                                 continue;
  36.                         }
  37.                         if( *format == 'x' ) {
  38.                                 varg-=2;        // Need for correct work. Unknown reason.
  39.                                 pc += printi (out, *varg++, 16, 0, width, pad, 'a');
  40.                                 continue;
  41.                         }
  42.                         if( *format == 'X' ) {
  43.                                 varg-=2;        // Need for correct work. Unknown reason.
  44.                                 pc += printi (out, *varg++, 16, 0, width, pad, 'A');
  45.                                 continue;
  46.                         }
  47.                         if( *format == 'u' ) {
  48.                                 varg-=2;        // Need for correct work. Unknown reason.
  49.                                 pc += printi (out, *varg++, 10, 0, width, pad, 'a');
  50.                                 continue;
  51.                         }
  52.                         if( *format == 'c' ) {
  53.                                 varg-=2;        // Need for correct work. Unknown reason.
  54.                                 /* char are converted to int then pushed on the stack */
  55.                                 scr[0] = *varg++;
  56.                                 scr[1] = '\0';
  57.                                 pc += prints (out, scr, width, pad);
  58.                                 continue;
  59.                         }
  60.                 }
  61.                 else {
  62.                 out:
  63.                         printchar (out, *format);
  64.                         ++pc;
  65.                 }
  66.         }
  67.         if (out) **out = '\0';
  68.         return pc;
  69. }