[En-Nut-Discussion] Nut/OS port for H8/300H.

Harald Kipp harald.kipp at egnite.de
Wed Mar 17 14:31:24 CET 2004


Jan,

Answers come a bit late. Our DSL modem died and I have
to use GPRS. Wow, that is so slow.

At 07:01 17.03.2004 +0100, you wrote:

>I thought that if puts_P is used to print "prog_char" strings then a function
>without _P suffix (fprintf in this case) is used for simple "char" strigs.

This is correct.


>But I have just noticed a possible bug. Lets consider two programs:
>
>1. fprintf(stream, "a text");
>
>2. prog_char fmt[] = "a text";
>    fprintf(stream, fmt);

This will output garbage on AVR. It should be
fprintf_P(stream, fmt)
in the second case, as you mentioned.


>Have I found a bug? :-) There are much more such places in the Nut/OS sources.

Either I completely misunderstood you, or you need some
sleep. :-) There should be no such places.

The code would be much easier, but ICCAVR makes things
complicated:

ICCAVR uses the const keyword to mark variables living
in program space. There is also a compile option to put
all string literals in program space by default.

If we'd use the compile option, we would never be able
to write

printf("Hello world!");

or

strcpy(foo, "bar");

We need to call the program space variant each time,
as soon as we use string literals. And worse, every
function using string parameters must exist in two
flavors. IMHO, this compile flag is crap.

In addition, using const to specify a reference to
program space is not a smart choice. In standard C

int foo(const char *bar);

does not imply, that the parameter must be a constant.
It just tells the caller, that foo() will not _modify_
the memory bar is pointing at. In ICCAVR the parameter
_must_ point to program memory. Again, this is crap.

Nut/OS uses CONST and
#define CONST const
for GCC, because this keyword allows the compiler to
better optimize the code.

In addition, GCC allows

printf_P(PSTR("Hello"));

because of

#define PSTR(s) ({static char __c[] __attribute__((__progmem__)) = (s); __c;})

Unfortunately ICCAVR doesn't support constructs like

({static int i = 1; i;})

Because of this limitation we have to use

prog_char cstr[] = "Hello"
printf_P(cstr);

I tried several times but never succeeded in explaining
this to Richard clearly enough. :-(

Back to the H8 port.

Why not simply use

#define prog_char const char

and

#define printf_P  printf

Then

static prog_char cstr[] = "Hello";
printf_P(cstr);

will work on both platform variants.

Btw. IMO, the attribute specifiers are one of the great
advantages of GCC compared to this nasty #pragma extension.

>I have found also a typo bug in chat.h and a possible bug in atom.h -
>I used __AVR__ macro which is defined in avr-gcc but I don't know if
>Imagecraft does that. The patch is attached.

Already committed, thanks.

Harald




More information about the En-Nut-Discussion mailing list