1
votes

I have an embedded system with internal and external flash. The controller is an MSP430F22x2, the external flash is connected using SPI. I can load data from external flash but the external flash isn't memory mapped. Since the internal flash is not big enough I want to add functions into external flash. So the external flash has to be copied into internal flash, so that the functions can be executed. It is essentially like poor mans paging.

To do all this I have a function, that loads the right part of flash and then calls the function. It manages an internal page stack, seperate to the 'real' stack. If I want to call a function on another page I have to jump to this function. The function then calls the function on the now loaded page. When the function returns the execution continues in the management function (because it was called from there) which then loads the right page and jumps back.

The problem is, that the functions are all at the same location in memory, since they are copied. But the data in ram can't overlap. My current solution is to use seperate linker scripts for each parts of external code and setting the addresses of the ram sections manually. This is of course time consuming and everything has to be changed if a part needs more ram etc.

The separate linker scripts look like this:

ENTRY(part)
SECTIONS
{
    .data 0x2A4 :
      {
        . = ALIGN(2);
        *(.data .rodata*)
      }
    .text 0x4000 :
      {
        *(.text)
      }
}

Nothing fancy. Everything is set to specific addresses, no overflow is checked. To be able to call the functions I export the symbol table and add them to the main linker script. This is all automated using batch scripts.

enter image description here

So I need a linker script that essentially places multiple .text sections overlapping in the same address range and the .data sections continuosly.

I don't know if there is a way to do this. Really any solution (linker scripts, batch scripts etc.) would help me. The only thing I can't change is the hardware.

1
Specify the "embedded system" you are using? What "system" is that? Is that by chance any popular MCU lines available today, like PIC or STM32? Please post the separate linker scripts you are using? How are you manully setting the sections? What "external flash" are you using? How should others post a solution if they don't know what hardware and environment are you using? My code does keep track of all this How does "keep track of this" exactly works? Please edit your question and add additional information. - KamilCuk
Most importantly, is the external flash memory-mapped with an old external address bus, or is it placed in serial (SPI) memories? - Lundin
before implementing this i would implement dynamic library loading on bare metal (researchgate.net/publication/…) - ralf htp
@ralfhtp This looks interesting but they declined my request for a full text version. Can you provide me with the publication? - w7sbc
Loading code from external flash and burning it into internal flash doesn't sound wise, you'll risk exhausting the number of erase/write cycles. You could consider running that code from RAM instead, but then you should probably also add additional safety measures such as CRC and/or sync words. - Lundin

1 Answers

2
votes

You need to use the linker OVERLAY command. This allows the storage location and the execution location to differ. You need to implement an overlay manager (code to copy the code to the execution address at runtime) in your run time, but this resolves the linker issue.

Find a worked example, loading code from EEPROM at https://forums.parallax.com/discussion/163970/overlay-code-with-gcc