(This is a follow up of this question)
The following program doesn't work (in ATmega4809
)
#include <avr/io.h>
void f(const char str[])
{
if (str[0] == 'a') // <-- here is the problem. The program thinks that str[0] != 'a'
PORTC.OUT |= PIN0_bm;
else
PORTC.OUT &= ~PIN0_bm;
}
const char str[] = "abc"; // this string the compiler stores in the .rodata section
int main()
{
PORTC.DIR |= PIN0_bm;
while (1) { f(str); }
}
The problem is that the compiler writes str
in the .rodata
section.
If I change the definition of str
forcing the compiler to write it in the .data
section:
const char str[] __attribute__((section(".data"))) = "abc";
the program works.
(You can see all the details in my previous question)
My questions are:
How can I force the compiler to write all the const strings into the .data
section so my programs work?
is this a bug in avr-gcc
13.3.0?
How can I force the compiler to write all the const strings into the
.data
section so my programs work?
This is the wrong question for the wrong solution. The problem is somewhere else, for example you are uploading .text
and .data
to the device but are missing .rodata
. When I
$ avr-gcc-13 x.c -mmcu=atmega4809 -o x.elf && avr-objdump -h x.elf && avr-objdump -P mem-usage x.elf
x.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000000 00802800 00000130 000001c4 2**0
CONTENTS, ALLOC, LOAD, DATA
1 .text 0000012c 00000000 00000000 00000094 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 00000004 0000412c 0000012c 000001c0 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .comment 0000001b 00000000 00000000 000001c4 2**0
CONTENTS, READONLY
4 .note.gnu.avr.deviceinfo 00000040 00000000 00000000 000001e0 2**2
CONTENTS, READONLY, OCTETS
...
x.elf: file format elf32-avr
AVR Memory Usage
----------------
Device: atmega4809
Program: 304 bytes (0.6% Full)
(.text + .data + .rodata + .bootloader)
Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)
So your problem is how are you uploading the binary, or how are you building the binary, or both.
-mmcu=atmega4809
when linking (provided you do a separate link invokation). Flash loaders like avrdude
understand ELF; this is often easier and less error prone than building a HEX file..rodata
to the target. In the example above, (at least) 304 bytes have to be uploaded according to avr-objdump -P mem-usage
. Notice that .rodata
display is a relatively new addition, see PR31687: Output of avr-objdump -P mem-usage missing .rodata, fixed in Binutils v2.43.