Re:data coruption with printf in user code

“long” Variables, or other Variables “Cast” to “long”, need a Format Specifier of “l” or “j”. (see line 221, in file “vfprintf.c”).
“unsigned int” Variables, or other Variables “Cast” to “unsigned int”, need a Format Specifier of “u”. (see line 351, in file “vfprintf.c”).

Re-Write your “printf(…)” like this:


printf ( "%4d %4l %4d %6l %6l %6l %6l %4d %4d %6u %6u\n", (int)loop, 
  (long)Timer_1, (int)Step, (long)Position_X, (long)Position_Y, 
  (long)ENC_X, (long)ENC_Y, (int)ACC_X, (int)ACC_Y, 
  (unsigned int)Ultrasonic_Front, (unsigned int)Ultrasonic_Rear );

You might want to expand the width of the Second Field, “(long)Timer_1” to a more “practical” width.

Further Information:

The MCC18 Compiler has 8 bit “char”, and 16, 24, and 32 bit “int” variables, than can be printed with the “printf(…)” function.

The “printf(…)” is a “wrapper” for the “vfprintf(…)” function. You can view the ‘C’ Source Code here, “.\mcc18\src\traditional\stdclib\vfprintf.c”

A note for future reference:
The MCC18 Library’s “printf(…)” function, does not support “float” and “double” variables. But does support alternate BASE Systems for “char” and “int” types, like Binary, Octal, and Hexadecimal.

MarkO,

Thank you for your response. I tried your suggestion and it also corrupted data. In addition several of the variables did not print out. I have not figured out which ones. I suspect it will be that last two.

Open for more suggestions!

Bob

Try to break up the printf into multiple printfs (one per variable) and see which one causes the problem.

Hm-mm…

I am seeing something similar…

I am doing some testing… I will post my results shortly…

Ah Ha!!

I got it figured out…

Very Weird…

The short answer is that “you can’t”…

In ANSI ‘C’ the “l” or “j” are used in combination with the ‘d’ or ‘u’.

(e.g. " %4ld" or “%5lu” )

With the MCC18 printf(…) function, using the “%l” or “%ld” or “%lu”, it always assumes “%lx”. This means that it gives Hexadecimal Output, ALWAYS… It appears that Binary and Octal are options too… But I get the feeling that there is maybe a little work that needs to be done on the printf(…) function…

MarkO,

Thank you for your time and persistence!

The part that really confuses me is that it really corrupts the variables in memory, not just on the print out. If I use the variables in a calculation or test, the actual variable is corrupted, not just the value that is printed out. I can understand the misinterpretation
of the print out but I am really concerned about it changing the value of the variable in memory!

What is the next step? Is there a process where I can file a “bug” report?

Bob

This is the kind of Detective Work I like to do…

Even if you break it down to One or Two Variables per printf(…), it still Corrupts the Values in the Variables??

Can you post All or Most of your Code??

I would suspect that depending on how the printf(…) is coded, that memory can be Corrupted because of the Call Stack Usage.

This may or may not not a bug…

IIRC, the Kiel 8051 compiler has a limit of 15 or 40 bytes per printf(…) call, depending on the Compile Options, because of Call Stack Limitations.

Bug Reports would need to be addressed to Microchip, since I believe that this is entirely their code…

I have attached some Code Examples, with multiple Calls to printf(…), no variables are changed between calls and the calls themselves do not alter the values…

OTOH, the vfprintf(…) seems to be setup for printing a “long int” (32 Bits) in Binary (needing 32 Bytes for the “1” and “0” Characters), so why Won’t it print in Binary, and why would that printing take less “space” than printing in Decimal???

Meaning there might be a Bug, and in more than one way…

I have “thought about” fixing the vfprintf(…) function, since it seems like it should work, but there is about 7 other steps to do to get it added to the Library and such… It seems worthwhile to attempt though…

I am still working on it…
rbellini_001.ZIP (1.4 KB)
rbellini_002.ZIP (1.46 KB)
rbellini_003.ZIP (1.57 KB)

Turns out that breaking the printf into 2 -3 variables each solved the problem. Therefore your thoughts of stack issues may be revelant. Maybe that is why the “Print to screen” function is limited to only one variable!

Thank you for your help!

Bob

The PrintToScreen function just calls printf, the purpose was to keep the code size down when printf is not used, as WPILib only compiles the code that is used.

We have rescently modified easyC V2 and Pro to optionally remove the “\n” so you can format many PrintToScreen commands to give single line output.

Honestly though I’d recommend using the graphic display for your project.

I’ll ask our programmer take a look at printf and see if he can fix it.