Skip to main content
NSR
Associate III
January 19, 2021
Solved

Using section attributes within a union

  • January 19, 2021
  • 3 replies
  • 3772 views

I've been assigning some of my storage areas into different memory areas as defined within the STM32H743ZITX_RAM.ld file in a project using STM32CubeIDE. This has first required me to insert the appropriate definitions where I've used memory domain D3 as an example:

MEMORY
{
 DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
 ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
 RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
 RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
 FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
}
 
/* Sections */
SECTIONS
/* snip .. */
 .myD3memory (NOLOAD):
 { 
 . = ALIGN(4);
 *(.myD3memory)
 . = ALIGN(4);
 } >RAM_D3
/* etc .. */
}

I can then utilize this in main() as follows:

uint16_t	buffer16[32768] __attribute__ ((section(".myD3memory")));

This works exactly as I intended and Build Analyzer shows the correct allocation. However, I now have a new case where I would like to reference the memory area not just as 16-bit unsigned shorts but also 8-bit unsigned bytes and have tried the following:

union
{
 uint8_t	buffer8[65536] __attribute__ ((section(".myD3memory")));
 uint16_t	buffer16[32768] __attribute__ ((section(".myD3memory")));
}

which unfortunately produces the errors:

../Core/Src/main.c: error: section attribute not allowed for 'buffer8'

 uint8_t buffer8[65536] __attribute__ ((section(".myD3memory")));

      ^~~~~~~~~~~

../Core/Src/main.c: error: section attribute not allowed for 'buffer16'

 uint16_t buffer16[32768] __attribute__ ((section(".myD3memory")));

Hopefully this will be an easy suggestion from someone more (GCC?) compiler savvy and any help in moving this forward would be greatly appreciated.

This topic has been closed for replies.
Best answer by waclawek.jan
 union
 {
 uint8_t	buffer8[65536];
 uint16_t	buffer16[32768];
 } foo __attribute__ ((section(".myD3memory")));

JW

3 replies

waclawek.jan
waclawek.janBest answer
Super User
January 19, 2021
 union
 {
 uint8_t	buffer8[65536];
 uint16_t	buffer16[32768];
 } foo __attribute__ ((section(".myD3memory")));

JW

Piranha
Principal III
January 20, 2021

All union members by definition represent the same physical memory. Therefore they cannot be placed at different addresses.

NSR
NSRAuthor
Associate III
January 20, 2021

Thanks JW, that's exactly what I was trying to achieve....I hadn't think of applying it to the end of the union. I knew it what something silly and an likely an easy remedy....sometimes the woods cannot be seen for the trees!

Piranha: placing the two variables was my intention for them to occupy the same physical memory but referenced differently according to the member type, but thanks for your input.

Piranha
Principal III
January 20, 2021

What I mean is, allowing to add an individual section attribute for each member is not logical, because they can be placed only at a single address. That's why the section attribute is allowed only for the whole union. :)

NSR
NSRAuthor
Associate III
January 20, 2021

When put like that then yes, I completely agree - I was really hoping it was something obvious that I hadn't considered. I've not long started using the attribute directive so it's still a little alien to me; although being able to access the whole of the memory map, including DTCMRAM and ITCMRAM has become somewhat liberating!