Author Topic: Guaranteed storage of const variable in flash  (Read 5235 times)

0 Members and 1 Guest are viewing this topic.

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 392
  • Country: be
Re: Guaranteed storage of const variable in flash
« Reply #25 on: August 29, 2022, 07:38:05 pm »
Just as a point of discussion, suppose I have a lookup table that I want it to be copied to RAM for faster access. Perhaps someone can explain how to guarantee that.

Decorate your LUT with section attribute.

Before:
Code: [Select]
static const uint32_t crc32_lut[16] = {
    ...
}

> arm-none-eabi-nm --print-size --size-sort --radix=x output/blahblah.elf | grep -i crc32_lut
000010a0 00000040 t crc32_lut.5558


After:
Code: [Select]
static const uint32_t crc32_lut[16] __attribute__ ((section (".data"))) = {
    ...
}

> arm-none-eabi-nm --print-size --size-sort --radix=x output/blahblah.elf | grep -i crc32_lut
10000000 00000040 d crc32_lut.5558

 
The following users thanked this post: eugene

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: Guaranteed storage of const variable in flash
« Reply #26 on: August 30, 2022, 05:19:45 am »
There is some variation in the above section names but with ARM32 GCC, statics are categorised thus:
int fred; goes into BSS (uninitialised data, used to go into COMMON in GCC versions before v10, now it is better because BSS gets zeroed)
int fred=0; goes into BSS (which by definition is zeroed by startup code)
int fred=1; goes into DATA (statics initialised to nonzero, copied to RAM at start)
int Fred; declared at file scope has static storage duration. Regardless of internal (if static is used) or external linkage (if not), and where the compiler decides to put it, it is NOT uninitialized data and never was for any vaguely standard compliant compiler.
There is no such thing in C for static duration objects, if an initializer is not provided, it is as if =0 (or equivalent for aggregates) was written. Chapter and verse of the standard on request.No request, but I am (sometimes) a pedant.

Quote
However, IME on the arm32, RAM resident stuff doesn't run faster than FLASH resident stuff - probably because the code cache works so well, being loaded 128 bytes at a time. I found delay loops run 20% faster from FLASH than in RAM resident code.
This is an overgeneralization, might be true for your specific MCU (STM32F4xx, IIRC) but absolutely not true in general.

EtA: Now I am at real keyboard:
Proof of initialization to 0
Standard ref, C11 but unchanged since, like, forever: 6.7.9 Initialization, §10:
Quote
[...]If an object that has static or thread storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
« Last Edit: August 30, 2022, 06:55:09 am by newbrain »
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 3699
  • Country: gb
  • Doing electronics since the 1960s...
Re: Guaranteed storage of const variable in flash
« Reply #27 on: September 01, 2022, 05:50:16 am »
Quote
it is NOT uninitialized data and never was for any vaguely standard compliant compiler.

I guess, it is possible (pre- GCC v10, when int fred; went into COMMON, not BSS) that your .s startup code didn't zero COMMON sections.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: Guaranteed storage of const variable in flash
« Reply #28 on: September 01, 2022, 01:09:47 pm »
I guess, it is possible (pre- GCC v10, when int fred; went into COMMON, not BSS) that your .s startup code didn't zero COMMON sections.
Yes, it's possible to have a broken startup.s...

A major change in gcc10 was finally stopping to silently accept multiple tentative definitions of the same object with (implicit) external linkage across translation units, and that's the reason for the section reshuffling.
That code was already not compliant, falling afoul of 6.7.9, and UB - so yes, it would have somehow been justified to have them not initialized, still better than nasal demons. I would still consider a startup.s + linker script that would not take that into account irremediably broken.

TBH it never affected me, as I (try to) write C, instead of something not totally unlike it, and use -std=c?? -Wall -Wextra -pedantic.
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: SiliconWizard

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 392
  • Country: be
Re: Guaranteed storage of const variable in flash
« Reply #29 on: September 01, 2022, 04:15:03 pm »
I would still consider a startup.s + linker script that would not take that into account irremediably broken.

True, but this is completely the responsibility of the developer, not the tool.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14481
  • Country: fr
Re: Guaranteed storage of const variable in flash
« Reply #30 on: September 01, 2022, 06:30:01 pm »
I would still consider a startup.s + linker script that would not take that into account irremediably broken.

True, but this is completely the responsibility of the developer, not the tool.

Well, yeah. But even using the right tools and setting them up correctly is the responsibility of the developer anyway.
 
The following users thanked this post: newbrain

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14481
  • Country: fr
Re: Guaranteed storage of const variable in flash
« Reply #31 on: September 01, 2022, 06:33:16 pm »
I guess, it is possible (pre- GCC v10, when int fred; went into COMMON, not BSS) that your .s startup code didn't zero COMMON sections.
Yes, it's possible to have a broken startup.s...

A major change in gcc10 was finally stopping to silently accept multiple tentative definitions of the same object with (implicit) external linkage across translation units, and that's the reason for the section reshuffling.
That code was already not compliant, falling afoul of 6.7.9, and UB - so yes, it would have somehow been justified to have them not initialized, still better than nasal demons. I would still consider a startup.s + linker script that would not take that into account irremediably broken.

TBH it never affected me, as I (try to) write C, instead of something not totally unlike it, and use -std=c?? -Wall -Wextra -pedantic.

Never affected me either, how hard was it to declare variables in one place only and then use 'extern' (of course then without any initializer) if you wanted access to them elsewhere? (Something that I do not particularly recommend these days anyway, I tend to prefer implementing accessor functions if I really need to access a global variable outside of where it's declared, and thus I'll usually declare them static, almost always.

Enough with the spaghetti code. Spaghetti is good in your plate. That's pretty much it. ;D
 
The following users thanked this post: newbrain


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf