cancel
Showing results for 
Search instead for 
Did you mean: 

Migrating code from IAR to GCC: __no_init, __ramfunc

AZube.2
Associate III

Hey,

I am trying to modify some compiler/linker directives from IAR to GCC. I think I already managed to solve the first two obstacles:

1 - In order to not initialize a variable saved in some register:

static volatile __no_init uint32_t SystemInfoFlags;

becomes,

static volatile __attribute__((section (".noinit"))) uint32_t SystemInfoFlags;

2- In order to save a function in RAM and execute it faster:

__ramfunc uint16_t CRC_calc(uint8_t *start, uint8_t *end);

becomes

__attribute__((section(".data.ram"))) uint16_t CRC_calc(uint8_t *start, uint8_t *end);

These are true (from what I understand, because I am new to all these) since in the linker file I could find both sections. The following is part of what I found when observing the linker file that I already had:

  /* Start placing output sections which are loaded into RAM */
  . = ORIGIN(RAM);
 
  .stack ALIGN(8) (NOLOAD):
  {
    __StackLimit = .;
    KEEP(*(.stack*))
    . = ALIGN(4);
    __StackTop = .;
    PROVIDE(__stack = __StackTop);
  } > RAM
 
 
  .noinit . (NOLOAD):
  {
    *(.noinit*);
  } > RAM
 
  .data . : AT (__etext)
  {
    . = ALIGN(4);
    __data_start__ = .;
    *(vtable)
    *(.data*)
    . = ALIGN (4);
 
    PROVIDE(__ram_func_section_start = .);
    *(.ram)
    PROVIDE(__ram_func_section_end = .);

Can anyone confirm that I understood correctly? Or can anyone tell me if I am wrong? This is the first time I am doing these kind of work and I am quite lost with it.

Thanks in advance and best regards,

Asier

1 REPLY 1

Seems like a reasonable start.

The thing to remember is that you have to implement the unpacking in startup.s.

In Keil and IAR the linker does a lot of things without specific direction or configuration, as they were build from an embedded perspective.

A lot of the load region handling is done via tables, where addresses and sizes are know by the linker and communicated, where as ST/GNU approach is to create all manner of global symbols, and has to pay a lot of attention of those, and the ordering and lay down of data in memory that needs copying later, and then a lot of linear code that copies one section, or zeros another. As the STM32 have become more complex, with more RAM regions, there initial approach doesn't scale. Similarly with expectations for heap and stack to reside within the same memory.

The approach that scales is to use tables, and have the linker, and its scripting, create those table automatically. Some of Arduino's more current ARM/GNU implementations have done this more effectively, so a review of those might be enlightening.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..