sprintf() crashes on AVR32

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I have spent the last 2 days chasing a mysterious software problem that causes my program to crash.

I have narrowed it down to an apparent problem with sprintf(). I can recreate the problem by starting with the EVK1100 - SERVICES - FreeRtos example project. I then change the vComTxTask (in src/Common/Minimal/comtest.c) to make use of sprintf() as shown in the attached source file.

On my target board this program crashes (ie. halts, no more serial output, LED's stop flashing) after only a few iterations. If I change the call to sprintf() to a simple strcpy() to put some text into buf[], then the program does not crash.

Note that the problem is sensitive to the amount of local variables defined. Without the buffer[] declaration the program still crashes, but it runs for quite a while before crashing.

Has anyone seen this problem before?

Is there a bug in sprintf()?

Any assistance would be greatly appreciated.

Regards,

Bert Menkveld
P.Eng.
Greentronics
Ph: 519-669-4698
E-mail: bert@greentronics.com

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like the task is getting out of stack space.
If it runs fine through some iterations then it shouldn't, but probably there is some stack which is not being freed by sprintf.
I don't know about the internals in newlib (if that's what avr32 is using), but maybe you have to modify the routines. Also I think sprintf uses the heap so maybe you have to redefine the heap functions to match the ones in FreeRTOS and make sure that you're using the memory method which allows freeing it.

A simple thing to see if the problem is related to stack overflow is to use the stack watermark function in FreeRTOS (available from v5.x onwards). Print the stack watermark after each iteration (avoid using printf if you can).
Also it's sometimes useful using a custom function to print the values rather than sprintf when it's just one or two numbers.

Carlos

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cbecker wrote:
Looks like the task is getting out of stack space.
...
A simple thing to see if the problem is related to stack overflow is to use the stack watermark function in FreeRTOS (available from v5.x onwards).
...
Carlos

Thanks for the response.

Unfortunately it appears that the AVR32 port does not support stack checking, and checking the stack high water mark looks to be non-trivial. Do you have experience with this? I'm trying not to learn more than I have to about the internals of the RTOS.

Regards,

Bert

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's an AVR32 port of FreeRTOS 5.02 available on the FreeRTOS.org site. I had made a couple changes to the RTOS (to select whether stacks & queues were malloc'd out of the heap or passed in), so I ended up diffing the sources and merging in the 5.02 changes. It took about half a day and wasn't particularly difficult. If you haven't made changes to the RTOS you should be able to just bring in the new source and build it with no problems. Note that a change in V5.0.2 required a one-line change in macb.c if you're using the LwIP port as well, but it's trivial.

I spent 3 weeks trying to get newlib's sprintf/printf stuff to work and finally gave up. It kept jumping to 0 and executing data, which would quickly cause an exception of some sort and hang the system. Luckily there's an acceptable substitute in the SW Framework Atmel provides, look for file "printf-stdarg.c". Since switching to that code I've had no trouble.

I know that stack space wasn't my problem because I put the stacks in SDRAM and made them 16 KB deep as a minimum. (Hey, I've got the RAM for free, might as well use it! :twisted: ) I suspect re-entrancy issues, but was never able to debug it since I can't re-build the newlib source.

System info: Win XP, WinAVR 20100110, AVR studio 4.18 build 700, JTAGICE MKII. Atmega 168 & 328, Xmega 192A3.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jeffhenshaw wrote:
There's an AVR32 port of FreeRTOS 5.02 available on the FreeRTOS.org site. I had made a couple changes to the RTOS (to select whether stacks & queues were malloc'd out of the heap or passed in), so I ended up diffing the sources and merging in the 5.02 changes. It took about half a day and wasn't particularly difficult. If you haven't made changes to the RTOS you should be able to just bring in the new source and build it with no problems. Note that a change in V5.0.2 required a one-line change in macb.c if you're using the LwIP port as well, but it's trivial.

I spent 3 weeks trying to get newlib's sprintf/printf stuff to work and finally gave up. It kept jumping to 0 and executing data, which would quickly cause an exception of some sort and hang the system. Luckily there's an acceptable substitute in the SW Framework Atmel provides, look for file "printf-stdarg.c". Since switching to that code I've had no trouble.

I know that stack space wasn't my problem because I put the stacks in SDRAM and made them 16 KB deep as a minimum. (Hey, I've got the RAM for free, might as well use it! :twisted: ) I suspect re-entrancy issues, but was never able to debug it since I can't re-build the newlib source.

Thanks for this *extremely* useful information! It's good to know I'm not the only one who has encountered this.

I found printf-stdarg.c, and will definitely try it out.

It seems surprising that such a basic piece of infrastructure as sprintf() can be so broken. You'd think everybody would be running into this.

Thanks again for your help.

Regards,
Bert

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just to round out this topic, I thought I'd report that I tried the printf-stdarg.c, and its sprintf() works perfectly. It appears to support only integers, but it's a great start, and gets me on my way with writing useful software again.

Thanks very much to both Carlos and Jeff for responding.

Regards,

Bert

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bmenkveld wrote:
Just to round out this topic, I thought I'd report that I tried the printf-stdarg.c, and its sprintf() works perfectly. It appears to support only integers, but it's a great start, and gets me on my way with writing useful software again.

Thanks very much to both Carlos and Jeff for responding.

Regards,

Bert

Just when I thought the issue was finished, I got a reply from Atmel tech support. It turns out that the sprintf() currently distributed with AVR32 Studio simply needs lots of stack space: 2KB. I increased the stack of my test task from the FreeRTOS default of 256 bytes to 256+2048. Now the sprintf() call works perfectly (without using printf-stdarg.c).

I guess I won't be using sprintf() in a lot of tasks, but it's good to be able to use it where I need it.

--
Bert Menkveld

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bert,
sprintf, printf and such are really stack consuming.
If you only need to print one integer sometimes it's better to use a custom function (on embedded systems specially where ram is not 'free').

You should try to get FreeRTOS 5.0.2 working. That way if you have a stack overflow issue FreeRTOS will warn you if you enable that option.
If the problem was clearly stack space then you'd solved it in a few minutes, FreeRTOS rocks :P

regards,
Carlos