Need help in Keil 5 locating code for RAM execution

I am using an STM32F439VGTx, which has
flash starting at 0x08000000, length 0x00100000
and CCM RAM starting at 0x10000000, length 0x00010000
and normal RAM starting at 0x20000000, length 0x00030000
I want some of my code and constant data to be in flash,
and some code to be executed out of RAM.  How can I
tell the compiler to compile some functions or modules
to execute in RAM, but place the compiled code in flash
so I can copy it to RAM for execution?  For example,
I might have a function called RamFunc(), which I would like
placed in RAM at some address, (say 0x20000800 or maybe 0x100000800),
but I need the image of it in flash at a known address, say 0x08001000,
and a known length so I can copy it to RAM for execution.

I have tried many variations of settings in a .sct file, and also tried
various versions using a Debug_RAM.ini file, as in the CMSIS-RTOS Blinky (MCBSTM32E)
example.  Nothing has worked for me.

Any help would be greatly appreciated.

Parents
  • Thank you for this reply.  I tried many different variations of the .sct file, and looked at the .mp file generated.  Some attempts did not compile because it appears that the order of the sections in the .sct file makes a difference.  With the FLASH_EXEC section first, it works, but with it placed later in the file, I get these errors:

    RxModule\RxModule.axf: Error: L6788E: Scatter-loading of execution region FLASH_EXEC to execution address [0x08000000,0x0805aac4) will cause the contents of execution region FLASH_EXEC at load-address [0x08001fdc,0x0805caa0) to be corrupted at run-time.
    RxModule\RxModule.axf: Error: L6202E: __main.o(!!!main) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6202E: __scatter.o(!!!scatter) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6202E: __scatter_copy.o(!!handler_copy) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6202E: __scatter_zi.o(!!handler_zi) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6202E: anon$$obj.o(Region$$Table) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6203E: Entry point (0x080001ad) lies within non-root region FLASH_EXEC.

    This is the .sct file that worked for me:

    FLASH    0x08000000    0x000C0000
    {
        ;It appears this must be first to make it the root region
        FLASH_EXEC    0x08000000    0x000C0000
        {
            *.o (RESET, +First)
            * (+RO)
        }

        ;This code will be loaded into RAM from flash by library c_w.l
        NORMAL_RAM        0x20000000    0x00030000
        {
            main.o (+RO)
            Boot.o (+RO)
            Flash.o (+RO)
            AddPrintf.o (+RO)
            stm32f4xx_hal_msp.o (+RO)
            * (+RW +ZI)
        }

        ARM_LIB_STACKHEAP    0x10000000    EMPTY    0x00010000
        {
        }
    }

    Note that I am reserving flash after 0x000C0000 for other purposes.

    I still have a few of questions:

    1. In my .sct file, I have *.o and explicit lines line main.o.  It looks like main.o will be assigned before *.o, but I am not sure.  It would be a pain if I had to list every .o file explicitly.  Is there a syntax for *.o except main.o, ... ?

    2. If I include main.o, for example, in NORMAL_RAM and main calls printf, will the compiler include the C library code for printf in RAM as well?

    3. When I added the linker switch "--datacompressor=off", the resulting flash size was slightly smaller.  I would have expected it to be larger without compression.  Any idea why?

    4. It looks like all the work of moving code from flash to RAM, including decompression if needed, is performed by c_w.l.  Is the source code for this library available anywhere?  Or, is there documentation for this library indicating the format of the data in flash that it references, including the compression method?

    My goal is a very detailed understanding of how the startup code works.

    Thank you again to everyone who replied.

Reply
  • Thank you for this reply.  I tried many different variations of the .sct file, and looked at the .mp file generated.  Some attempts did not compile because it appears that the order of the sections in the .sct file makes a difference.  With the FLASH_EXEC section first, it works, but with it placed later in the file, I get these errors:

    RxModule\RxModule.axf: Error: L6788E: Scatter-loading of execution region FLASH_EXEC to execution address [0x08000000,0x0805aac4) will cause the contents of execution region FLASH_EXEC at load-address [0x08001fdc,0x0805caa0) to be corrupted at run-time.
    RxModule\RxModule.axf: Error: L6202E: __main.o(!!!main) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6202E: __scatter.o(!!!scatter) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6202E: __scatter_copy.o(!!handler_copy) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6202E: __scatter_zi.o(!!handler_zi) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6202E: anon$$obj.o(Region$$Table) cannot be assigned to non-root region 'FLASH_EXEC'
    RxModule\RxModule.axf: Error: L6203E: Entry point (0x080001ad) lies within non-root region FLASH_EXEC.

    This is the .sct file that worked for me:

    FLASH    0x08000000    0x000C0000
    {
        ;It appears this must be first to make it the root region
        FLASH_EXEC    0x08000000    0x000C0000
        {
            *.o (RESET, +First)
            * (+RO)
        }

        ;This code will be loaded into RAM from flash by library c_w.l
        NORMAL_RAM        0x20000000    0x00030000
        {
            main.o (+RO)
            Boot.o (+RO)
            Flash.o (+RO)
            AddPrintf.o (+RO)
            stm32f4xx_hal_msp.o (+RO)
            * (+RW +ZI)
        }

        ARM_LIB_STACKHEAP    0x10000000    EMPTY    0x00010000
        {
        }
    }

    Note that I am reserving flash after 0x000C0000 for other purposes.

    I still have a few of questions:

    1. In my .sct file, I have *.o and explicit lines line main.o.  It looks like main.o will be assigned before *.o, but I am not sure.  It would be a pain if I had to list every .o file explicitly.  Is there a syntax for *.o except main.o, ... ?

    2. If I include main.o, for example, in NORMAL_RAM and main calls printf, will the compiler include the C library code for printf in RAM as well?

    3. When I added the linker switch "--datacompressor=off", the resulting flash size was slightly smaller.  I would have expected it to be larger without compression.  Any idea why?

    4. It looks like all the work of moving code from flash to RAM, including decompression if needed, is performed by c_w.l.  Is the source code for this library available anywhere?  Or, is there documentation for this library indicating the format of the data in flash that it references, including the compression method?

    My goal is a very detailed understanding of how the startup code works.

    Thank you again to everyone who replied.

Children