Author Topic: STM32G0 dma can't read const data from flash in boot memory space  (Read 3688 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 »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf