[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] printf and printf_P suggestions
From: |
Joerg Wunsch |
Subject: |
Re: [avr-gcc-list] printf and printf_P suggestions |
Date: |
Tue, 15 Aug 2006 16:11:02 +0200 (MET DST) |
(Please start a new thread for a new topic, rather than replying to an
old mail.)
"Trampas" <address@hidden> wrote:
> ..., however if you have:
>
> const char data[]="hello world";
>
> printf(data);
> This code is a problem, actually the compiler should catch the
> error.
There is no error to catch here.
> However what I did was make it such that in the printf() routine I
> checked the address of the format string. Thus if the address was in
> flash I knew to call the printf_P() version if it was in RAM then
> standard printf was used.
This is not possible on the AVR, as it is a true Harvard: the routine
gets passed a pointer, and from looking at the address, you cannot say
whether it's ROM or RAM -- it's up to the callee to interpret it his
way. That's why there are _P() pendants. If the function gets an
address 0 passed, it could point to the beginning of ROM or of RAM
(the latter would actually constitute an alias for register r0, but
that's another issue).
AVR-GCC marks the RAM addresses by an offset of 0x800000 internally
(and EEPROM addresses with 0x810000), but that's just a convention
followed inside the object files only: when it gets translated to the
target system (e. g. by producing an ihex file with avr-objcopy), this
offset gets filtered away. It's only a virtual flat address space, as
that is what GCC currently wants to work with.
> I would personally like to have a command line option to tell the
> compiler not to copy the strings to data memory in the above case.
This would make any and all strings violate the C standard (they
became incompatible with standard <string.h> functions).
> The reason I personally would like such features is that I am
> porting a large amount of code which has:
> sprintf(str, "results %d\n",data);
> Thus having the option would save me a lot of data memory and/or
> time correcting the sprintf calls to sprintf_P.
Using an editor that understands regular expressions, it's a matter of
5.2 minutes to convert these: five minutes to think over the RE, and
0.2 minutes to run the actual conversion. ;-)
For example, for the classical Unix editor vi, you might try this:
:g/sprintf/s/sprintf(\([^"]*\)\(".*"\)/sprintf_P(\1 PSTR(\2)/
--
J"org Wunsch Unix support engineer
address@hidden http://www.interface-systems.de/~j/
Re: [avr-gcc-list] [AVR] RTL prologue/epilogue ver.3, Anatoly Sokolov, 2006/08/20