Society of Robots - Robot Forum

Software => Software => Topic started by: Admin on January 24, 2008, 01:44:36 PM

Title: weird rprintf bug?
Post by: Admin on January 24, 2008, 01:44:36 PM
I'm running into this weird bug with rprintf, that if I output the variable elapsed_time, it requires using two %d commands . . .

Code: [Select]
//read timer0's overflow counter, add to timer
unsigned long int elapsed_time=timer0GetOverflowCount()*255+TCNT0;

int t1=77;
int t2=54;

rprintf("A %d %d %d\r\n",elapsed_time,t1,t2);
rprintf("B %d %d %d %d\r\n",elapsed_time,t1,t2);
rprintf("C %d %d %d\r\n",t1,t1,t2);

This is the output I get below. Notice a zero comes from magic land, and t2 is kicked out of A. Ideas on why this is happening?

Quote
A 350 0 77
B 350 0 77 54
C 77 77 54

I suspect it has something to do with the way I count time . . . it gives the correct time btw . . .

Also to note, it still does the same this if I just do this:
elapsed_time=timer0GetOverflowCount()*255
Title: Re: weird rprintf bug?
Post by: krich on January 24, 2008, 05:41:47 PM
The problem is because your elapsed_time variable is a long. You need to use %l in the format string.  On the AVR, a long is two bytes long.  The architecture is also, apparently, little-endian, so the %d directive instructs rprintf to print one byte.  This is why you get a 0 as the second number, that's the most significant byte in that word.

Ken
Title: Re: weird rprintf bug?
Post by: krich on January 24, 2008, 05:49:33 PM
Rereading my post, its unclear what I meant by "that word".  I meant to say "that long", referring to the elapsed_time variable.

Ken
Title: Re: weird rprintf bug?
Post by: rgcustodio on January 24, 2008, 06:46:55 PM
hi there Admin. hope you're not playing with the ER modules again :)  actually the issue you're encountering is not a bug.

i'm assuming you're using procyon avrlib.
http://hubbard.engr.scu.edu/embedded/avr/avrlib/docs/html/index.html

shows the code for the actual function doing the printing. there are 2 versions of the rprintf() function. One is simple which only allows %d, %x, %c and can not handle variables of type long, the other allows for complex formatting strings.

the simple rprintf() uses an "unsigned int" only, but you're passing an "unsigned long int", so this messes up things. first there is an overflow in the internal variable (u_val) of rprintf(). and since you're passing a long, the next memory location being consumed by va_arg() in rpritntf() on its next iteration actually still belongs to the variable (of type long) you passed earlier! if you use "%l" or "%ld" with the simple rprintf, you'll get the same erroneous output.

the complex version of rprintf() fixes this problem by allowing the user to use "%l" or "%ld". it's also smart enough to assign the value you passed to an internal variable that is long enough (no pun intended), and uses a correct call to var_arg() to allot for the size of the long data type. so var_arg() doesn't get confused when consuming the variables being passed to it.

define RPRINTF_COMPLEX in your makefile or somewhere, and recompile you avrlib. then relink your other code. what you want to use in rprintf() is "%ld" or as kirch mentioned "%l". if you're already using the complex version (verify your defines) of rprintf() then just use "%l" or "%ld".
Title: Re: weird rprintf bug?
Post by: krich on January 24, 2008, 07:39:35 PM
Thanks rgcustodio, for going into more detail on this.   :D

Additionally, I accomplished two things with my posts:

1)  I actually knew the answer to a question on the SoR forums.  Yay!   ;D
2)  I've proven you can post to the forums with a Blackberry, not that you'd ever want to on an even semi-regular basis...   :o

I was going to post a follow-up once I got back home tonight, but now I don't need to.

Cheers,

Ken.
Title: Re: weird rprintf bug?
Post by: Admin on June 12, 2008, 07:57:16 AM
Quote
define RPRINTF_COMPLEX in your makefile or somewhere, and recompile you avrlib.
Whenever I define RPRINTF_COMPLEX I get tons of compiling errors . . . exactly how should I do this?

Looking in rprintf.h, I found this below code at the top of the file. What exactly does this do?
Code: [Select]
#ifndef RPRINTF_COMPLEX
#define RPRINTF_SIMPLE
#endif
Title: Re: weird rprintf bug?
Post by: dolinay on June 12, 2008, 08:22:26 AM
It means "If the symbol "RPRINTF_COMPLEX" is not defined, then define symbol RPRINTF_SIMPLE."
It's kind of like telling the compiler: "if the programmer did not ask for RPRINTF_COMPLEX, then use RPRINTF_SIMPLE.

If your code looks like this:

#define RPRINTF_COMPLEX
#indude <rprintf.h>

It should be ok.
 
If you put the #define after the #include, this may cause troubles.
So this is not good:
#indude <rprintf.h>
#define RPRINTF_COMPLEX

The define will have no effect because rprintf.h will be already processed by the compiler and RPRINTF_SIMPLE will be already defined.
Moreover if you have more than one C file in your project which contains #include <rprintf.h>, you may get compiler errors because the file probably assumes either RPRINTF_COMPLEX or RPRINTF_SIMPLE is defined, but you will have both. At least I think so... simply weird things may happen.
Make sure you define the RPRINTF_COMPLEX before any #include <rprintf.h>
You could also make a local copy of rprintf.h in your project and simply replace the #ifndef part with #define RPRINTF_COMPLEX.
Title: Re: weird rprintf bug?
Post by: pomprocker on June 12, 2008, 10:32:40 AM
Looking in rprintf.h, I found this below code at the top of the file. What exactly does this do?
Code: [Select]
#ifndef RPRINTF_COMPLEX
#define RPRINTF_SIMPLE
#endif


Those are usually called "header guards" used in header files saying "if this header file has not already been defined in compile-time, then go ahead and define it"
usually where you see RPRINTF_COMPLEX, there would usually be the name of the header file.
Then in between #ifndef and #endif you would have your header file code.
Title: Re: weird rprintf bug?
Post by: dolinay on June 12, 2008, 12:23:04 PM
I don't think this is header guard. Header guard would be:
 
#ifndef RPRINTF_COMPLEX
   #define RPRINTF_COMPLEX
#endif
Title: Re: weird rprintf bug?
Post by: Joe on February 20, 2010, 10:43:26 PM
Wow! I'm learning to program AVRs and I just did a search for "rprintf" on google. This thread was one of 8 results found. Shouldn't there be like 30,000? What is the deal with that???
Title: Re: weird rprintf bug?
Post by: Razor Concepts on February 20, 2010, 11:41:25 PM
I got 25,000 results  ;)

But printf is much more widespread than rprintf and the other printfs (lprintf, uprintf, anyletterofthealphabetprintf)