printf from task

Hi, I try to use FreeRTOS on a ATMega64. I got a task like: void ManTask( void *pvParameters ) {     while(1)     {         if(intflag)         {             printf_P( PSTR("%.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X %.2X rn"),              manval, mantemp[0], mantemp[1], mantemp[2], mantemp[3],              mantemp[4], mantemp[5], mantemp[6], mantemp[7] );             intflag = 0;             vTaskDelay( portTICK_RATE_MS * 100 );             TIMSK |= _BV(TICIE1);         }         else             vTaskDelay( portTICK_RATE_MS * 5 );     } } Hope this is readable :-) In this case, printf sends lot of garbage. If I split the long printf for giving out only one value in a for() loop it works better. Playing around with the tasks stack value changes something. But it still doesn’t work. How do i calculate the stack size for a task? How do I calculate the portTOTAL_HEAP_SIZE ? And how is printf coming in? Thanks!

printf from task

printf is likely to use a LOT of stack, and is generally best avoided.  You can increase the stack of the task that calls printf, but how about writting a simple routined to do the same.  For example, from the wiznet demo source code: void ultoa( unsigned portLONG ulVal, unsigned portCHAR *pcBuffer, portLONG lIgnore ) { unsigned portLONG lNibble; portLONG lIndex; -—/* Simple routine to convert an unsigned long value into a -—string in hex format. */ -—/* For each nibble in the number we are converting. */ -—for( lIndex = 0; lIndex < ( sizeof( ulVal ) * 2 ); lIndex++ ) -—{ -——-/* Take the top four bits of the number. */ -——-lNibble = ( ulVal >> 28 ); -——-/* We are converting it to a hex string, so is the number -——-in the range 0-10 or A-F? */ -——-if( lNibble < 10 ) -——-{ -———–pcBuffer[ lIndex ] = ‘0’ + lNibble; -——-} -——-else -——-{ -———–lNibble -= 10; -———–pcBuffer[ lIndex ] = ‘A’ + lNibble; -——-} -——-/* Shift off the top nibble so we use the next nibble next -——-time around. */ -——-ulVal <<= 4; -—}    -—/* Mark the end of the string with a null terminator. */ -—pcBuffer[ lIndex ] = 0x00; } You have to call it for each value you want to add to the string. When a stack is created it is filled with a known value (0xa5 ?).  Using a debugger you can see the stack, how much is left at 0xa5 is how much spare stack you have.  Failing this you can write a CheckFreeStackSpace() function to walk up the stack until it runns out of 0xa5’s [I think there is an example in the PC port.c file in the download].  The number of 0xa5’s it finds is the size of the unused stack.  ISR’s, function calls, stack variables must all be taken into consideration when deciding how much stack you need. As with the stack size, portTOTAL_HEAP_SIZE is best determined through trial – if an allocation fails, you have too little :-)

printf from task

Which compiler are you using?  printf_P is not standard.

printf from task

It seems that printf out of a task has problems when printing out values of global variables. Sometimes it didn’t find the end of the string and prints out endlessly. Looks like something is wrong with the adressing of global variable out of a task? Never had problems with printf, printf_P before. I’m using WinAVR with libc 1.2.3.

printf from task

A few of quick questions – 1 Are you calling printf from within a critical section? 2 Is the behaviour the same with different optimisation levels? 3 Can you access global variables correctly other than within the printf()?  [The scheduler accesses file scope variables without a problem, so is there something different when using a library function?]

printf from task

1 Are you calling printf from within a critical section? -no 2 Is the behaviour the same with different optimisation levels? -no 3 Can you access global variables correctly other than within the printf()? [The scheduler accesses file scope variables without a problem, so is there something different when using a library function?] - Don’t know. The only way to show variables is printf. Something like printf_P( PSTR("%02X %02X %02X %02X %02X %02X %02X %02X rn"),         manval, mantemp[0], mantemp[1], mantemp[2], mantemp[3], mantemp[4], mantemp[5], mantemp[6] ); works from main, but nor from a task. I really don’t know where to look at eventually. I will drop FreeRTOS to see if all works standalone. Maybe I can say more then. Thank you

printf from task

I would guess definately stack problems.

printf from task

It looks like printfing short strings works while longer ones fail. Timer tick is every millisecond so its likely that a context-switch occurs or is tested for. But the context should be saved by portSaveContext right? So that the pointers printf holds for parsing the string and creating a new one should be restored. So if you say there’s a stack problem how can I verify this?

printf from task

Short strings working would also point towards a stack issue. printfing should be fine even if a context switch occurs PROVIDED the library function is reenterant – which it <should> be in this case. If you cannot check the stack area using a debugger, then how about finding the longest string you can printf, then increase the stack a bit, and see if the longest string you can printf also increases.  A bit crude, ideally the use of debugger or simulator would assist. Can you run your code in AVR studio?  You might not get the context switches occurring properly, but if you try the printf from the first task that executes, stepping through the code at the C source level and inspecting the RAM within the simulator IDE would provide a lot of clues.

printf from task

Hello again, I now got running GDB over JTAG (more or less). Observing the task with printf the backtrace command says: ‘previous frame inner to this frame (corrupt stack?)’ So I know the stack is corrupt. But why? Any suggestions where to go from here? Regards, Joerg

printf from task

Hi, I found the fault was on my side ;-) For the port I had to change the timer interrupt to update the OCR1 register, as I couldn’t use the timer overflow. OCR1A  += (unsigned portSHORT) ( (portCPU_CLOCK_HZ / portTICK_RATE_HZ) / portCLOCK_PRESCALER ); Unfortunatly the interrupt routine uses the ‘naked’ attribute. So because of the addition registers and flags get corrupted. Without the ‘naked’ everything seems to work fine. Maybe there’s is a way to avoid the double context saving ? Regards, Joerg

printf from task

Hi all: I’ve been fighting with printf’s on an atmega128 for a day and a half now, using gcc + freertos. It turns out that the task using printf MUST have the stack size increased to not crash the micro; I used a value of 255, since I only really have one task that uses printf. As the app develops, though, I think I’ll try to reduce/eliminate the printf calls, judging from some of the comments in this thread. Cheers, mvdw.