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

0 Members and 1 Guest are viewing this topic.

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 892
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: 4632
  • 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: 854
  • 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: 4286
  • 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: 4632
  • 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: 4286
  • 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: 4632
  • 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
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 9774
  • 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: 2577
  • 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: 4632
  • 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