I am using a micro-controller with ARM Cortex M4 processor and developing a bootloader application on it.
- Compiler : GCC- GNU ARM compiler
- Code flash size : 1MB
- Interface for application code download : USB CDC ACM class
- One application software at PC to transfer the application code binary file to MCU o USB
- I have two codes : a. main code(boot code), b. Application code
- In application code, run_my_app() function is written.
Flow of main code is as follow :
reset-> initialize MCU initialize USB boot status = CLEAR; while(1) { wait for command from USB : write/ erase if(boot status == BOOT_COMPLETE) { call a function name run_my_app() from application code; } } if erase command received : erase the application code at a flash location 0x0020000 if write command received : Write the application code to flash location 0x0020000 after completion successful write, boot status == BOOT_COMPLETE;
My question is how should i map the run_my_app() function from application code to boot code? How can i get the address of run_my_code() function so that using function pointer i can call that function?
Hello everyone, I have to modify the entry point of application code to location 0x0020000 in flash from location 0x0000000 using linker script. Currently generated linker script file is :
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x0100000 /* 1M */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0030000 /* 192K */
DATA_FLASH (rx) : ORIGIN = 0x40100000, LENGTH = 0x0004000 /* 16K */
QSPI_FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 0x4000000 /* 64M, Change in QSPI section below also */
}
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__ROM_Start = .;
/* Even though the vector table is not 256 entries (1KB) long, we still allocate that much
* space because ROM registers are at address 0x400 and there is very little space
* in between. */
KEEP(*(.vectors))
__Vectors_End = .;
__Vectors_Size = __Vectors_End - __Vectors;
__end__ = .;
/* ROM Registers start at address 0x00000400 */
. = __ROM_Start + 0x400;
KEEP(*(.rom_registers*))
/* Reserving 0x100 bytes of space for ROM registers. */
. = __ROM_Start + 0x500;
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
__ROM_End = .;
} > FLASH = 0xFF
.............
..........
Adding some details to my implementation:
A structure 'CodeInfoStruct' is defined in both boot and application code.
struct CodeInfoStruct
{
uint32_t RunCodeFunctionAddress;
};
In Application code :
Here, a instance of structure is created at a fixed location '0x0020100' and address of the function 'run_my_app' is stored there.
const struct CodeInfoStruct CodeInformation __attribute__((section(".ARM.__at_0x0020100")));
const struct CodeInfoStruct CodeInformation =
{
(uint32_t)run_my_app
};
Also, in linker file, the ROM start address is modified to 0x0020000:
MEMORY
{
FLASH (rx) : ORIGIN = 0x00020000, LENGTH = 0x0100000 /* 1M */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0030000 /* 192K */
DATA_FLASH (rx) : ORIGIN = 0x40100000, LENGTH = 0x0004000 /* 16K */
QSPI_FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 0x4000000 /* 64M, Change in QSPI section below also */
}
In boot code:
the structure pointer of 'COdeInfoStruct' is defined.
struct CodeInfoStruct* pCodeInfo = 0x0020100;
And then, the function 'run_my_code' is called from boot code as follow:
void (*trgt_fnc)(void);
trgt_fnc = (void (*)())(pCodeInfo->RunCodeFunctionAddress);
trgt_fnc();
But, i get zero value in this 'trgt_fnc'. Is it a correct way to share address of function run_my code? What is wrong here?