Author Topic: weird rprintf bug?  (Read 3502 times)

0 Members and 1 Guest are viewing this topic.

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,665
  • Helpful? 169
    • Society of Robots
weird rprintf bug?
« 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

Offline krich

  • Robot Overlord
  • ****
  • Posts: 165
  • Helpful? 0
Re: weird rprintf bug?
« Reply #1 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

Offline krich

  • Robot Overlord
  • ****
  • Posts: 165
  • Helpful? 0
Re: weird rprintf bug?
« Reply #2 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

Offline rgcustodio

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 0
  • Use "Search" and ye might find answers!
Re: weird rprintf bug?
« Reply #3 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".
« Last Edit: January 24, 2008, 06:54:44 PM by rgcustodio »
The best thing one can do when it's raining is to let it rain. - H. W. Longfellow

understanding is the path to enlightenment

Offline krich

  • Robot Overlord
  • ****
  • Posts: 165
  • Helpful? 0
Re: weird rprintf bug?
« Reply #4 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.

Offline AdminTopic starter

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,665
  • Helpful? 169
    • Society of Robots
Re: weird rprintf bug?
« Reply #5 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

Offline dolinay

  • Contest Winner
  • Jr. Member
  • ****
  • Posts: 18
  • Helpful? 0
Re: weird rprintf bug?
« Reply #6 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.

Offline pomprocker

  • Supreme Robot
  • *****
  • Posts: 1,430
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
Re: weird rprintf bug?
« Reply #7 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.
« Last Edit: June 12, 2008, 10:35:51 AM by pomprocker »

Offline dolinay

  • Contest Winner
  • Jr. Member
  • ****
  • Posts: 18
  • Helpful? 0
Re: weird rprintf bug?
« Reply #8 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

Offline Joe

  • Full Member
  • ***
  • Posts: 54
  • Helpful? 0
Re: weird rprintf bug?
« Reply #9 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???

Offline Razor Concepts

  • Supreme Robot
  • *****
  • Posts: 1,856
  • Helpful? 53
Re: weird rprintf bug?
« Reply #10 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)

 


Get Your Ad Here

data_list