sprintf (avr libc) malfunction?!

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

Hi!

I'm using avr libc 1.4.6 and gcc 4.1.2 with patches from winavr.

I have written the following (simplified) code:

...
char sd[30];
uint8_t test;
...
test = 13;
... 
sprintf(sd, "%d", test);
...
sprintf(sd, "%d", test);

The first sprintf was working ok, but the second was not.

I've debuged it with JTAG and I've found this:
- After steped into the 1st sprintf, the "fmt" (format string was "%d" as expected. So far so good.
- After steped into the 2nd sprintf, the "fmt" was 0x04 0x02 0x00 !!! :S Then "sd" resulted in 0x04 0x02 0x00 confirming the bad "fmt"

I've checked RAM and there was no stack overflow.

What could be causing the problem?
Maybe the code between is misbehaving?

I've searched for similar problems and I've come across this old post with no answer:
https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=157&highlight=sprintf

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

A quick kludge would be to use printf_P(). Obviously your format string in SRAM is being overwritten by something. I would assume your other code is doing the overwriting. Where might you be writing 0x04 0x02 0x00 !!!

Please post a compilable source that illustrates the problem.

David.

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

Sorry, I cannot reproduce this. I've just tried something like that,
and it behaves completely normally. I added a memory initialization
routine to monitor the stack usage, and it seems sprintf might use
around 80 bytes of stack space. Are you perchance running out of
stack RAM?

If you've got an example program that reproducibly shows the behaviour
you are describing, please file an avr-libc bug report. Don't forget
to include the exact commands you've been using to compile and link
your program.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Hi,

I have experienced similar problems with printf and sprintf. They seam to malfunction when a quite intensive pin change interrupt routine is running concurrently. Then they only manage to print a couple of characters of the string and it gets worse the more often the interrupt occurs. I have tested to print the same string with calls straight to uart_putchar() without any error. What can be the cause of this, stack overflow? I have plenty of SRAM so it shouldn’t be a problem. I have no access to JTAG so it is kind of hard to debug.

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

The question is what you're doing inside your ISR then. Normally, interrupts
should not bother the interrupted code, but most of the standard library
functions are not reentrant, so if you call any of them inside your ISR, bad
things might happen.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

I’m not using printf from within the interrupt function so I am a bit confused. I have tested to disable interrupts before calling printf and that makes it work fine but is not an acceptable solution. I guess I’ll have to download the source code to printf and investigate what may be the problem.

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

As ISRs are supposed to save all state when entering, and restoring it
upon returning, this is never supposed to happen.

Get the entire avr-libc sourcecode. The central function is vfprintf()
(in libc/stdio/vfprintf.c), all other functions are just wrappers
around that.

If your ISR contains only compiler-generated code, as vfprintf also
only contains compiler-generated code, this would indicate a serious
compiler issue.

Again, if you've got a minimal test case that can reproduce the issue,
file an avr-libc bug report for it. I'll do my best to analyze (and
fix) the bug then.

Btw., I just see that large parts of vfprintf have been rewritten in
the CVS version of avr-libc. I intend to issue a version 1.5.1, based
on the current CVS, anytime soon. This is intended to be a kind of
experimental version, as many things have been changed recently (Dmitry
Xmelkov rewrote a major portion of the floating-point library), which
should eventually become the avr-libc 1.6 line. Perhaps you are
interested to test whether the rewritten vfprintf experiences the same
problem?

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

I haven't had time to test it, but I suppose David's right.
I guess the format string is being overwritten by something else.

Btw, how can I know the memory address where the format string ("%d") is stored? Or is it in stack?

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

Joerg, any chance that my atomic.h and interrupt.h header files will be incorporated into 1.6 instead of languishing in the tracker forevermore?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

I'll do my best...

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.