Having issues with accessing __flash strings in functions

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

I'm having issues accessing my string pointers in functions when using __flash. This is stuffed inside the XplainedA1 USART demo with relevant parts below. I'm using AS 6.2 and 3.4.1507 toolchain.

const __flash char	progString[] = "blah blah blah\r\n";

void sendstring(const char *data) {
    while (*data)
        usart_putchar(USART_SERIAL_EXAMPLE, *data++);
}

int main(void) {
    ...
    uint8_t tx_buf[] = "\n\rHello AVR world ! : ";

    sendstring(progString);
    sendstring(tx_buf);
    ...
}

If I set a breakpoint on the while loop inside sendstring(), *data is null even though data is pointing to the correct location:

data	0x01f4	char*{registers}@ R25 R24
*(data)	0x00	char{registers}@0x01f4

prog 0x0001EF  00 2e c0 00 00 62 6c 61 68 20 62  ..À..blah b
prog 0x0001FA  6c 61 68 20 62 6c 61 68 0d 0a 00  lah blah...

For tx_buf, *data is pointing to the first character of the string as expected:

data	0x3fe4	char*{registers}@ R25 R24
*(data)	0x0a	char{registers}@0x3fe4

data 0x003FE2  04 98 0a 0d 48 65 6c 6c 6f 20 41  .˜..Hello A
data 0x003FED  56 52 20 77 6f 72 6c 64 20 21 20  VR world ! 

The following function works for progString, but I'd like to get away from the pgm_read stuff:

void sendstring_P(const char *data) {
    while (pgm_read_byte(data))
        usart_putchar(USART_SERIAL_EXAMPLE, pgm_read_byte(data++));
}

What am I doing wrong? Am I just misunderstanding how to use __flash?

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

sendstring assumes *data is in SRAM, not in __flash.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

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

If you need your sendstring() to be able to handle both RAM and flash data, investigate __xmem : https://gcc.gnu.org/onlinedocs/g...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

sporadic, in case it's not clear the parameter needs to have "__flash" added, otherwise "const char *" is a RAM pointer.

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

Didn't 4.8 add a "universal pointer" that could do RAM or FLASH, at the expense of a longer pointer (and no library support?) How would that look?

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

Quote:

Didn't 4.8 add a "universal pointer" that could do RAM or FLASH

I mentioned __xmem three posts up..

And here's a long thread discussing the innards of it: https://www.avrfreaks.net/index.p...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

But Johan meant __memx

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

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

Gahhhhh.... (Still, anyone being confused would have gotten that it was a typo when the links where followed.)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Ahhh, thank you very much for the feedback! I now see the error in my ways. The contiguous 16bit address space representation in the debugger was tripping me up. Declaring sendstring as such works for both progString and tx_buf now:

void sendstring(const __memx char *data) {
  while (*data) 
    usart_putchar(USART_SERIAL_EXAMPLE, *data++); 
} 

The end goal for this is a menu driven system over serial so the convenience of __memx will far outweigh the overhead. Now with that figured out, I can switch over to my actual implementation. Thank you again!

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

Any tips or tricks on a printf implementation that supports __memx? End goal would be a mix of flash and sram strings as arguments. Am I missing something obvious, or is it a no-go?

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

Quote:

Any tips or tricks on a printf implementation that supports __memx?

The library has both printf() and printf_P() so you could write a composite function or maybe just wrap it in a macro. The format string is either going to be in RAM or ROM and the way to determine that is as described here:

https://gcc.gnu.org/onlinedocs/g...

Specifically:

Quote:

     char __builtin_avr_flash_segment (const __memx void*)

This built-in takes a byte address to the 24-bit address space __memx and returns the number of the flash segment (the 64 KiB chunk) where the address points to. Counting starts at 0. If the address does not point to flash memory, return -1.


So you can use that -1 return to know if the memx pointer is RAM or ROM. Call printf() if RAM and printf_P() if flash.

Of course you probably already know that as well as the standard %s the AVR version of printf() (either version) recognise %S to say "flash string" rather than "RAM string"

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

Took me a day to figure out why I couldn't reply.... Finally found the tidbit on the strings beginning with % bug in in the forum software.... arrghhh!!!!!!! Completely off topic, but how can I properly format strings prefixed with % and not break the forum software so I can edit my reply and have it formatted properly?

clawson wrote:

Of course you probably already know that as well as the standard % s the AVR version of printf() (either version) recognise %S to say "flash string" rather than "RAM string"

Actually, I hadn't... Big ol' face palm on my part :oops: This is my first time working with printf on AVRs and wasn't aware of it. I'm now able to put my format string in flash and mix everything up with printf_P like so:

const __flash char MSTR_FORMAT[] = "%S %s\t| %s\t| %s\n";
const __flash char MSTR_Channel[] = "[c]hannel\t|";

printf_P(MSTR_FORMAT, MSTR_Channel, "curval", "newval", "options");

With the help of FDEV_SETUP_STREAM, it's all easy-peasy now. Thanks for pointing me in the right direction!

Last Edited: Wed. Aug 20, 2014 - 07:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Completely off topic, but how can I properly format strings prefixed with % and not break the forum software so I can edit my reply and have it formatted properly?

Only members of the 7th level of the third dan know the lore grasshopper!

But a bit of searching will tell you about &-#-3-7-; ;-)

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

Quote:

Completely off topic, but how can I properly format strings prefixed with % and not break the forum software so I can edit my reply and have it formatted properly?

https://www.avrfreaks.net/index.p... , tip #2.

And... If you use FireFox, have the Greasemonkey add-on installed and perhaps know a bit of Javascript, then this might be your cup of tea: https://www.avrfreaks.net/index.p... . I wrote it and have used it ever since and it works just fine for me.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]