fprintf issue with ordinary strings

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

Hello,

I've discovered an issue using fprintf with ordinary strings. I am using avr-libc 1.7.0 with gcc 4.3.4.

I have stderr setup as follows:

FILE lcd_str = FDEV_SETUP_STREAM(LcdPutchar, NULL, _FDEV_SETUP_WRITE);
stderr = lcd_str;

My LcdPutchar function simply sends a character to display at the LCD. There are no issues here, it generally runs fine. By generally I mean all the time.

The issue is the following. In my application I try to use fprintf to display a string in two different ways:

a)

fprintf(stderr, "some string\n");

b)

static char* str = "some string";
fprintf(stderr, "*\n" , str);

(above by '*' I mean 'percent_sign followed by s', which I don't know why is not allowed by this website ... I keep getting bad request if I put that)

The first way only calls the LcdPutchar function once, thus displaying just "s" on the LCD.
The second way (b) displays the string correctly.

Looking at the avr-libc documentation we can see that fprintf could be used in ordinary strings (which I understand is case a). This is taken from vfprintf doc (which is referred by fprintf):
"vfprintf is the central facility of the printf family of functions. It outputs values to stream under control of a format string passed in fmt. ...
The format string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged to the output stream; ..."

What do you think?

Thanks.

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

goodhack wrote:

I have stderr setup as follows:

FILE lcd_str = FDEV_SETUP_STREAM(LcdPutchar, NULL, _FDEV_SETUP_WRITE);
stderr = lcd_str;

lcd_str has type FILE but stderr FILE *. So I think

stderr = &lcd_str;

is correct. But I dont believe this is the source of your strange effect.

Best regards, D@niel

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

Right,

I meant

stderr=&lcd_str

This is what I have in my code (I just retyped - obviously wrong - instead of copy paste from my source).

So, any ideas on this issue? Does anybody else has this? I can't believe it only happens in my source code. Must be something that I am missing or it is just "as designed" (but I would like to know).

Thanks.

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

I tried your code snippet (with added \r for my terminal program):

fprintf(stderr, "some string\r\n");
static char* str = "some string";
fprintf(stderr, "%s\r\n" , str);

with the correct result:
some string
some string
I use avr-gcc-4.4.2 avr-libc-1.6.7. Hardware was an atmega2560. Optimization-level -Os

Maybe you can check my strange effect with sscanf_P with your system in return :wink: https://www.avrfreaks.net/index.p...

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

I just tested this complete test program in the simulator:

#include 
#include 

int my_putc(char c, FILE *unused) {
	PORTB = c;
	return 0;
}

FILE out_str = FDEV_SETUP_STREAM(my_putc, NULL, _FDEV_SETUP_WRITE);

int main(void) { 
	static char* str = "some string"; 
	stderr = &out_str; 

	while ( 1 )	{ 
		fprintf(stderr, "other string");
		fprintf(stderr, "%s" , str); 
	} 
} 

Both methods work - so how does your program differ?

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

Daniel and Clawson, thanks for trying this. Unfortunately neither of you have the same configuration as me.

Daniel, I will take a look at your post.

I would be very happy if someone could confirm/infirm the problem using gcc_4.4 and avr-libc-1.7.0. (in real application preferably compared to simulation.

I have observed several brakes after updating to avr-libc-1.7.0.

thanks

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

dear goodhack,

There was an almost identical thread about streams.

It turned out that that particular OP had chosen some particularly inappropriate commands.

Please can you post the exact o/p from make or Studio.

First do a 'make clean' (F12 in Studio)
Then do a 'make all' (F7 in Studio)

Copy / paste the full response.

David.

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

Hello David,

Sorry for such a long delay.

If I understand correctly and you refer to the optimisation level by OP, then you are right.
I observed that the problem is gone after using Os instead of O1. The problem mentioned occurs only with O1.

I am happy to provide any additional information if you need it. I am using avr-libc with a Makefile, no studio.

Can you please give me the link for the stdio streams thread? Is the issue now resolved or taken into consideration?

Thanks.

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

I suggested the 'make clean' to give you a fresh start.

There is absolutely no reason for -O0, -O1 ... -Os to make any difference to the functions.

I can assure you that everything should work fine.
No, I will not give you a direct link. You will find it a good exercise for your Google skills. Or simply using the link in the Studio Help menu. Hint. FDEV or putchar.

David.

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

I don't know exactly why the optimisation level influences the stdio functions, but in my case this was the only difference.

With O1 the fprintf will not output the entire string if passing a textual string, while it would run fine with a char* parameter via 'percent's. However with Os it works fine.

I can go ahead and google of course, the point was to go straight to your mentioned post. Not sure why you feel I need Google exercise.

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

Quote:

I don't know exactly why the optimisation level influences the stdio functions, but in my case this was the only difference.

It doesn't - they are pre-compiled in libc.a (almost certainly with -Os being used). The only thing that changes with optimisation level is your code that invokes libc functions. If the overall program behaves differently then THAT is where the difference is located.

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

goodhack wrote:
I don't know exactly why the optimisation level influences the stdio functions, but in my case this was the only difference.

It should not affect the logic of any valid C program. The only bad effects might be extra code size.
Even those special timed sequences should work ok if you use the macros and functions.
However a special feature of avr-gcc -O0 is to break (1<<JTD) or (1<<CLKPSx) sequences. I am not aware of any avr-libc.a functions to do those jobs.

Quote:

With O1 the fprintf will not output the entire string if passing a textual string, while it would run fine with a char* parameter via 'percent's. However with Os it works fine.

Library functions are pre-compiled.

Quote:

I can go ahead and google of course, the point was to go straight to your mentioned post. Not sure why you feel I need Google exercise.

I find it as easy to Google as to trawl through wherever WinAvr or whatever installed docs on my hard disk.

Sometimes it is a bit embarassing to find something was in your current directory in the first place!

David.