Author Topic: STM32G0 dma can't read const data from flash in boot memory space  (Read 3687 times)

0 Members and 1 Guest are viewing this topic.

Offline Dan NTopic starter

  • Contributor
  • Posts: 25
  • Country: us
STM32G0 dma can't read const data from flash in boot memory space
« on: September 20, 2024, 07:19:33 pm »
While testing some bare-metal SPI-Tx using DMA on a STM32G030, I ran into a dma transfer error for which I can't find definitive documentation on adress spaces allowed for dma read.

With the default bootloader and linker setup that remaps flash to adress 00000000, const data like below will be stored in boot memory space after the code (00000244 for my example).  Apparently that address range isn't allowed for dma read and will shutdown with a transfer error (no spi activity):
Code: [Select]
const uint16_t spidat[] = {0x1234, 0x5678, 0x9abc, 0xdef0};
....
DMA1_Channel1->CMAR = ( uint32_t )&spidat ;
....
I tried enabling SYSCFG clocks and making sure SYSCFG->CFGR1 MEM_MODE[1:0] is *0 (flash is remapped) and dma still shutsdown with a transfer error.

This hack works (CMAR = 08000244), but is easily broken if the data is changed to not be "const":
Code: [Select]
DMA1_Channel1->CMAR = FLASH_BASE +  ( uint32_t )&spidat ;
« Last Edit: September 20, 2024, 09:40:59 pm by Dan N »
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6548
  • Country: es
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #1 on: September 21, 2024, 03:17:21 am »
Why are you remapping the flash instead leaving the default 0x8000000?
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 9717
  • Country: fi
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #2 on: September 21, 2024, 10:31:10 am »
IIRC for DMA you can't use the remapped address but need to use the actual adress. So just try orring your remapped 0-based address with 0x08000000 when writing to DMA memory address register.
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2717
  • Country: gb
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #3 on: September 21, 2024, 11:04:01 am »
linker setup that remaps flash to adress 00000000

You shouldn't use linker settings to remap flash, that's the job of hardware in the mcu. Linker should use the default 0x8000000, as David says.

That way &spidat will give real hardware addresses required by the dma unit, whether spidat is in flash or ram.

Also note that keyword 'const' by itself is not a guarantee that a variable is only stored in flash.
 
The following users thanked this post: Dan N

Offline Dan NTopic starter

  • Contributor
  • Posts: 25
  • Country: us
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #4 on: September 21, 2024, 11:52:55 am »
The default hardware config remaps flash to 00000000 after reset (BOOT0 pin has internal pulldown active after reset).  From the RM:
  • Boot from main Flash memory: the main Flash memory is aliased in the boot memory space (0x0000 0000), but still accessible from its original memory space (0x0800 0000). In other words, the Flash memory contents can be accessed starting from address 0x0000 0000 or 0x0800 0000.

I'm using this linker script:  https://github.com/ataradov/mcu-starter-projects/blob/master/stm32g031/linker/stm32g031x6.ld

Code: [Select]
MEMORY
{
  flash (rx) : ORIGIN = 0x00000000, LENGTH = 32K
  ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
}
I'll try changing the linker map.

I still haven't found docs that explicitly say dma can't read from boot memory space.  Is it the address or the 16-bit read that triggers the transfer error?
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2717
  • Country: gb
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #5 on: September 21, 2024, 12:32:57 pm »
DMA issues are a PITA to debug. Maybe try a more standard config and transfer first, just to get something working and go from there. You also have the dma mux to contend with.

Certainly in at least some other STM32 mcu's the dma needs physical addresses.
 
The following users thanked this post: Dan N

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6548
  • Country: es
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #6 on: September 21, 2024, 01:15:09 pm »
So did you try setting the Linker Script to 0x8000000?
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Dan NTopic starter

  • Contributor
  • Posts: 25
  • Country: us
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #7 on: September 21, 2024, 04:15:41 pm »
Thanks everyone.  It works with the linker map using flash physical address:
Code: [Select]
  flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K
DMA was working with the hack in the first post, but it's good to get rid of that.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16306
  • Country: fr
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #8 on: September 21, 2024, 07:23:36 pm »
Linker scripts in STM example projects for the STM32G0 do map the flash at 0x08000000. It's a reasonable approach to avoid the issues you saw with the DMA.

Also, depending on the programming tool you use, having the flash section mapped at address 0 in the linker script may cause issues as you can't flash at address 0. (If you provide a .bin to the programming tool (from STM), then it will normally flash it at 0x08000000 by default anyway. But if you provide a .elf instead (or even a .hex), it may cause issues for flashing, as addresses in this case are usually taken from the file itself.

This is what I have for a STM32G0B1 (that I've used):
Code: [Select]
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 144K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 512K
}
 

Offline hans

  • Super Contributor
  • ***
  • Posts: 1729
  • Country: 00
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #9 on: September 22, 2024, 08:24:08 am »
The values in the linker script are used to link symbols together in the code space. It doesn't change anything on the hardware.

A lot of memory map configuration registers are only applicable for CPU access, sort of like virtual memory. For DMA you need to use the physical addresses.

E.g. this was one of the major downsides of bitbanding on Cortex-m3: although it would allow for atomic read-modify-write operations with an unique memory address for a particular peripheral bit, it was only a virtual memory mapping  only available to the CPU and hence inaccessible from DMA. They got rid of bitbanding on newer cores, because I don't think it was that often used, and if it was on e.g. GPIO, most GPIO peripherals have set-clear registers now.

 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4604
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #10 on: September 22, 2024, 08:30:28 am »
Why use the boot loader at all?

On my 32F4 project I have BOOT0=BOOT1=GND and never bothered with any of it.
« Last Edit: September 22, 2024, 09:10:41 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2717
  • Country: gb
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #11 on: September 22, 2024, 09:25:19 am »
Why use the boot loader at all?

IIUC when the OP mentions "default bootloader" what they mean is "default boot mode" i.e. flash remapped to 0x00000000 and executed.
There is nothing here about a bootloader.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4604
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #12 on: September 22, 2024, 11:13:19 am »
OK I saw

Quote
With the default bootloader and linker setup that remaps flash to adress 00000000

but that isn't right because the default boot mode puts the code base at 0x08000000. I have no idea how you could get the code base to 0x00000000 or indeed why you would want that. The linkfile alone, as already said, won't do it.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2717
  • Country: gb
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #13 on: September 22, 2024, 11:36:39 am »
I have no idea how you could get the code base to 0x00000000 or indeed why you would want that. The linkfile alone, as already said, won't do it.

It really is a testiment to the ease of use of cortex mcus that some folks get as far as they do with minimal reading and learning effort. It certainly helped me in the beginning.

From the RM of STM32G030, section 2.5 Boot Configuration:
Quote
Depending on the selected boot mode, main Flash memory, system memory or SRAM is accessible as follows:
• Boot from main Flash memory: the main Flash memory is aliased in the boot memory space (0x0000 0000), but still accessible from its original memory space (0x0800 0000). In other words, the Flash memory contents can be accessed starting from address 0x0000 0000 or 0x0800 0000.
• Boot from system memory: the system memory is aliased in the boot memory space (0x0000 0000), but still accessible from its original memory space  0x1FFF0000.
• Boot from the embedded SRAM: the SRAM is aliased in the boot memory space (0x0000 0000), but it is still accessible from its original memory space (0x2000 0000).
 
The following users thanked this post: thm_w

Offline Dan NTopic starter

  • Contributor
  • Posts: 25
  • Country: us
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #14 on: September 22, 2024, 11:51:47 am »
but that isn't right because the default boot mode puts the code base at 0x08000000. I have no idea how you could get the code base to 0x00000000 or indeed why you would want that. The linkfile alone, as already said, won't do it.
On a STM32G0xx the vector table must be at 00000000.  That's why hardware remaps (or alias) flash/sram/system-memory to 00000000.

IIUC when the OP mentions "default bootloader" what they mean is "default boot mode" i.e. flash remapped to 0x00000000 and executed.
There is nothing here about a bootloader.
I really did mean just the factory bootloader that is mask programmed into system memory space.  In other words not trying to do anything "clever" with custom boot/programming.
« Last Edit: September 22, 2024, 12:08:57 pm by Dan N »
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4604
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #15 on: September 22, 2024, 01:17:33 pm »
Quote
It really is a testiment to the ease of use of cortex mcus that some folks get as far as they do with minimal reading and learning effort.

The Q I would ask is why is this feature needed?

I come from decades of doing assembler (Z80 onwards) and one just treats things literally.

But if

Quote
On a STM32G0xx the vector table must be at 00000000

then I can see the need for this, but why put the vector table at 0 in the first place?
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6548
  • Country: es
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #16 on: September 22, 2024, 02:33:49 pm »
This thread is pretty much solved and doesn't need further nosense discussion, it's all been said already.
Just leave the linker to 0x8000000, the vector table doesn't care, 0x00000000 access the same memory as 0x8000000.

From the RM of STM32G030, section 2.5 Boot Configuration:
Quote
Depending on the selected boot mode, main Flash memory, system memory or SRAM is accessible as follows:
• Boot from main Flash memory: the main Flash memory is aliased in the boot memory space (0x0000 0000), but still accessible from its original memory space (0x0800 0000). In other words, the Flash memory contents can be accessed starting from address 0x0000 0000 or 0x0800 0000.

For DMA you need to use the physical addresses.
...
They got rid of bitbanding on newer cores, because I don't think it was that often used, and if it was on e.g. GPIO, most GPIO peripherals have set-clear registers now.
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: bingo600, voltsandjolts

Online langwadt

  • Super Contributor
  • ***
  • Posts: 5005
  • Country: dk
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #17 on: September 22, 2024, 02:47:05 pm »
Quote
It really is a testiment to the ease of use of cortex mcus that some folks get as far as they do with minimal reading and learning effort.

The Q I would ask is why is this feature needed?

I come from decades of doing assembler (Z80 onwards) and one just treats things literally.

But if

Quote
On a STM32G0xx the vector table must be at 00000000

then I can see the need for this, but why put the vector table at 0 in the first place?

because that's a cortex-m expects it to be and coming out of reset starts execution from the address stored at 0x4 (0x0 is the stack pointer address)

how is that different from z80 et.al. ?
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 9717
  • Country: fi
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #18 on: September 22, 2024, 03:59:00 pm »
The Q I would ask is why is this feature needed?

Because ST wants to offer factory bootloader which can be swapped in by simple BOOT0 pin strapping. Aliasing different parts of actual memory into the expected boot address of 0, based on the voltage on the BOOT0 pin, is the simplest and most obvious way to achieve this feature.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 9717
  • Country: fi
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #19 on: September 22, 2024, 04:03:56 pm »
This thread is pretty much solved and doesn't need further nosense discussion, it's all been said already.

Again, this is not question-answer site like stackoverflow. This is a discussion forum.

This is an example of nonsense: banana qwerty mushroom yes snake.
The discussion in this thread isn't. Just because the discussion goes beyond your skill level does not make it nonsense.

Quote
Just leave the linker to 0x8000000

Yeah. But I have a suggestion: write that as 0x08000000. As you write it with 28 bits shown, it is way too easy for a human eye to mis-parse, unless you always use copy-paste. Especially because there is a long tradition of highest-bit-set-prefixed address spaces to signify... something, depending on architecture and product.
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6548
  • Country: es
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #20 on: September 22, 2024, 05:02:02 pm »
It's not that.
All programming threads end in the same way, writing the entire history back to the ENIAC times and Alan Turing's hair color on Sunday mornings when taking a coffee in his kitchen in spring, where the sun angle was slightly tilted torwards the 3rd window near the freezer causing a reflection in his face  :).
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline bson

  • Supporter
  • ****
  • Posts: 2570
  • Country: us
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #21 on: September 23, 2024, 12:39:49 am »
The following example would output text and rodata to 0x08000000, but relocate it for execution at 0x00000000.

Code: [Select]
MEMORY {
  flash (rx) : ORIGIN = 0x08000000, LENGTH = 32K
  ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
}

SECTIONS {
  .text : AT(0) {
      // ... usual stuffs ...
     ALIGN(4);  // so .rodata starts at a 32-bit boundary for simplified copying
  }
  .rodata : AT(ADDR(.text)+SIZEOF(.text)) {
     // ... usual stuffs ...
     ALIGN(4);  // make this a multiple of 32-bit words
  }

  // .data etc
}

This technique of separating the load address from the relocation address is especially useful when one or more segments of code is intended to be copied into CC RAM or SRAM to be executed there.  In that case where it's loaded into the ROM is different from the location where it's to be run.  Avoids having to fiddle with generating PIC which is often inefficient.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4604
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #22 on: September 23, 2024, 03:55:57 pm »
There seems to be an alternative syntax for generating code which executes from an address different from where it lives in FLASH e.g.

Code: [Select]
  .loader :
  {
    . = ALIGN(4);
    _loader_ram_start = .;
    *loader.o (.text .text* .rodata .rodata* .data .data*)
      . = ALIGN(4);
      _loader_ram_end = .;
  } >RAM AT>FLASH_BOOT
 
  _loader_flash_start = LOADADDR(.loader);

and then it gets copied to RAM with

Code: [Select]
extern char _loader_ram_start;
extern char _loader_ram_end;
extern char _loader_flash_start;

// Copy loader code and its init data to RAM.
B_memcpy(&_loader_ram_start, &_loader_flash_start, &_loader_ram_end - &_loader_ram_start);

For more fun, I don't have memcpy() available to me at that point (it is boot block code) so I have

Code: [Select]
__attribute__((optimize("O0"))) // prevent replacement with memcpy()
static void B_memcpy (void *dest, const void *src, size_t len)
{
  char *d = dest;
  const char *s = src;
  while (len--)
    *d++ = *s++;
}

and the optimise 0 attrib is there to prevent the compiler detecting that the loop can be replaced with memcpy()  :-DD

You have the "AT" at the start while I have it at the end. No idea how this works :)
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2717
  • Country: gb
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #23 on: September 23, 2024, 04:12:47 pm »
https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Common-Function-Attributes.html#index-optimize-function-attribute

Quote
optimize
...
This attribute should be used for debugging purposes only. It is not suitable in production code.
 
The following users thanked this post: wek

Offline wek

  • Frequent Contributor
  • **
  • Posts: 561
  • Country: sk
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #24 on: September 23, 2024, 05:34:47 pm »
https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Common-Function-Attributes.html#index-optimize-function-attribute

Quote
optimize
...
This attribute should be used for debugging purposes only. It is not suitable in production code.
Interesting, but then we could also argue, whether any of the gazillion options and features of gcc in itself are suitable in production code. There are undoubtedly many of whose are poorly written, understood, maintained, ported to various platforms and targets; and worse of all, they interact.

The sentiment the above warning indicates is based probably on interaction of "local optimization suppression" with "global optimization enforcement" features like inlining and LTO. gcc bugzilla search appears to confirm at least partially.

JW
« Last Edit: September 23, 2024, 05:37:34 pm by wek »
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 887
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #25 on: September 23, 2024, 11:20:26 pm »
Quote
You have the "AT" at the start while I have it at the end. No idea how this works
The AT takes an expression, typically in the form of a symbol previously created from a location counter, the AT> uses a memory region. I guess the former is dependent on the sequence of the linker script where the latter resolves the symbol value independent of the script sequence and probably ends up with less location counter symbol clutter (assuming there is a need for a number of these kind of sections).

Quote
The following example would output text and rodata to 0x08000000, but relocate it for execution at 0x00000000.
Not quite sure how a load address for a .text section would ever be useful, unless a programmer needs to have an elf or hex file that is 0 based for some reason. The section is already loadable, and no one but a programmer would even see the LMA address. The VMA address remains the same in any case, and in the example since the flash region is not being used (>flash) the VMA address becomes 0 based and you end up with the original problem of this thread.

For most mcu scenarios, probably the only section that sees the need for AT is the .data section (and things like .ramfunc file sections usually live inside so startup code takes care of the runtime transfer). For something like a newer series avr, the .rodata section does require a VMA address for memory mapping (for direct access of flash data) and an LMA address for storage, in addition to the normal .data section use of AT.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4604
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #26 on: September 24, 2024, 07:36:25 am »
Quote
This attribute should be used for debugging purposes only. It is not suitable in production code.

Wow what a daft comment :) The compiler attribute either works or it does not. Currently it does (I would soon find out if it didn't in this case) and this is yet another reason to freeze the tools and stop chasing for ever moving targets like Cube and GCC, for the purist reasons that if a new compiler breaks your product then your code is crap, while introducing crazy levels of business risk.

I also have a command line thingy (-fno-tree-loop-distribute-patterns) which is supposed to stop identification of loop structures but I found (way back, maybe GCC 8 ) that it didn't work reliably. Now it googles to nothing... don't recall where I found it. But the attribute approach definitely works.

Quote
I guess the former is dependent on the sequence of the linker script where the latter resolves the symbol value independent of the script sequence and probably ends up with less location counter symbol clutter

To me, the AT at the end of a section reads more naturally, FWIW.
« Last Edit: September 24, 2024, 07:44:45 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 851
  • Country: es
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #27 on: September 24, 2024, 08:03:16 am »
Sure, freezing the foundation is essential in card house building 😁
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4266
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #28 on: September 24, 2024, 09:04:09 am »
Quote
This attribute should be used for debugging purposes only. It is not suitable in production code.

Wow what a daft comment :) The compiler attribute either works or it does not. Currently it does (I would soon find out if it didn't in this case) and this is yet another reason to freeze the tools and stop chasing for ever moving targets like Cube and GCC, for the purist reasons that if a new compiler breaks your product then your code is crap, while introducing crazy levels of business risk.

I also have a command line thingy (-fno-tree-loop-distribute-patterns) which is supposed to stop identification of loop structures but I found (way back, maybe GCC 8 ) that it didn't work reliably. Now it googles to nothing... don't recall where I found it. But the attribute approach definitely works.

Quote
I guess the former is dependent on the sequence of the linker script where the latter resolves the symbol value independent of the script sequence and probably ends up with less location counter symbol clutter

To me, the AT at the end of a section reads more naturally, FWIW.
The comment is not that daft. Sure you can use it now and freeze tools. However using unstable, deprecated or experimental features is a potential headache for future you.

Oh and, if you google something starting with - it will not search those keyword. :P
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-ftree-loop-distribute-patterns
 
--

The remap function is only in the chip because of limitation in the Cortex m0. Larger cores support vector table offset.
The remap allows you to substitute the code it will run in hardware. Since basically the first it will do is read where the reset handler is it doesn't really matter for the code itself, as long as the M0 is fooled.

Position independent linking (or offset) for bare metal has drawbacks as experienced.
You'd need to do tricks to obtain the actual physical address to give the DMA. I
It can be done! With exporting the linker symbols for example, but headaches guaranteed.
 
The following users thanked this post: peter-h

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4604
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #29 on: September 24, 2024, 09:11:34 am »
Quote
if you google something starting with - it will not search those keyword

I knew that really :) :) :)

Quote
However using unstable, deprecated or experimental features is a potential headache for future you.

Where would you draw the line? Change from GCC 11 to GCC 20 and you get a pile of warnings, and on this working product you spend days chasing them down, perhaps introducing problems.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4266
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #30 on: September 24, 2024, 09:27:05 am »
I typically avoid linker statements at all in the C code. They are not guaranteed to work and don't throw errors when they don't.
My limit is at __attribute__ ((aligned (n))). It specifies intent that is valid on all architectures, though not being perfectly portable.
 

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4604
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #31 on: September 24, 2024, 09:34:30 am »
Which linker statements are you thinking of?
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 9717
  • Country: fi
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #32 on: September 24, 2024, 02:16:29 pm »
Quote
This attribute should be used for debugging purposes only. It is not suitable in production code.

Wow what a daft comment :)

Yeah. I have been using per-function optimize attribute in production code for years, without noticing this warning in documentation. If they were serious about this, why not emit a compile-time message so that users could actually see it, and maybe silence manually it with something like -Wno-optimize-attribute-warning.

In any case, never noticed any problems whatsoever. I tend to use it when the module is -Os for obvious reasons but some particular function, usually an interrupt handler or a smaller function the ISR calls needs to be -O2 or even -O3, again for other obvious reasons.

Separating it to a different compilation unit is of course an option but when they clearly are part of the same module and share same static variables etc. anyway, such extra separation makes the project more messy, while the optimize attribute is neat and tidy.

But then again, in situations where it matters you have to verify the compiler output (execution time, code size) manually anyway and I fully expect to do that again every time compiler versions change, even if I used file-scope optimization settings. Luckily only very small % of actual projects are timing-critical code like that, so I'm not too afraid of changing versions - just that you shouldn't do it like every day for no reason whatsoever.
« Last Edit: September 24, 2024, 02:18:20 pm by Siwastaja »
 

Offline bson

  • Supporter
  • ****
  • Posts: 2570
  • Country: us
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #33 on: September 25, 2024, 12:54:26 am »

For more fun, I don't have memcpy() available to me at that point (it is boot block code) so I have

Code: [Select]
__attribute__((optimize("O0"))) // prevent replacement with memcpy()
static void B_memcpy (void *dest, const void *src, size_t len)
{
  char *d = dest;
  const char *s = src;
  while (len--)
    *d++ = *s++;
}

If you know your memory block is 32-bit aligned at both ends you could make it:

Code: [Select]
__attribute__((optimize("no-tree-loop-distribute-patterns")))  // Do not substitute function calls
static inline void B_memcpy32 (void *to, const void *from, size_t len) {
    len /= 4;
    uint32_t *dst = (uint32_t*)to;
    for (const uint32_t *src = (const uint32_t*)from; len > 0; len--)
      *dst++ = *src++;
}

'no-tree-loop-distribute-patterns' only blocks substituting code patterns with function calls to builtins.

Or IMO, even better would be C++ style, but that's just me:
Code: [Select]
#include <stdint.h>
#include <stddef.h>

// Compile with: g++ -c -S foo.cc -O2 -Wall

// Strongly suggest inlining to gcc on the premise that this is only
// used either in rare instances, or where performance really matters.
template <typename T1, typename T2>
[[gnu::optimize("no-tree-loop-distribute-patterns"), gnu::always_inline]]
static inline void B_memcpy_aligned (T1 *to, const T2 *from, size_t len) {
    static_assert(sizeof(T1) == sizeof(T2));

    len /= sizeof (T1);
    const T1* f = (const T1*)from;
    while (len-- > 0)
      *to++ = *f++;
}


uint8_t buf1[64], buf2[64];

volatile uint8_t buf3[64], buf4[64];

int main(int argc, char **argv) {
    B_memcpy_aligned((uint32_t*)buf2, (const uint32_t*)buf1, sizeof buf1);
    B_memcpy_aligned((volatile uint32_t*)buf4, (const volatile uint32_t*)buf3, sizeof buf3);
    B_memcpy_aligned((uint32_t*)buf2, (const volatile uint32_t*)buf3, sizeof buf3);
    B_memcpy_aligned((volatile uint32_t*)buf4, (const uint32_t*)buf1, sizeof buf1);
    return 0;
}
This also covers volatiles, although the copy does drop the volatileness of the second parameter.  If both parameters were the same type T it would only work if they were both volatile or non-volatile.  Still saves from having to write code using ' specialization by copy and paste.'  But I don't think it's possible to convert the 'from' argument into T1 while preserving its volatileness.

BTW, if compiled with -O2 or -O3, only the copies with volatile destinations will be kept, and with -O3 both of those are totally unrolled! (gcc 14)

Oh, and the 'optimize' attribute ONLY reliably reworks when reducing the optimization level.  You typically can't tell it to optimize only one function above the global level, although in this case it might work.
« Last Edit: September 25, 2024, 12:56:40 am by bson »
 
The following users thanked this post: peter-h

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4604
  • Country: gb
  • Doing electronics since the 1960s...
Re: STM32G0 dma can't read const data from flash in boot memory space
« Reply #34 on: September 25, 2024, 06:58:15 am »
Quote
If you know your memory block is 32-bit aligned at both ends you could make it:

I have such a function too for other uses :)

Quote
the 'optimize' attribute ONLY reliably reworks when reducing the optimization level.

Interesting, but actually that is how I use it.

If I wanted a specially fast individual function I would code it in asm.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 
The following users thanked this post: bson


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf