Hello,
For more "simplicity" I have devised my own OTA update procedure. It relies on image information being embedded in a dedicated section (I have modified the linker script to do this) but now I am having trouble with the following:
I want to move the interrupt vectors to the start of my program (where they should be) and then insert this image information section after that vectors (with a known offset) and then begin the main .text/program section.
How would one go about doing this in the linker script/startup assembly? I am using mbed as my RTOS platform. The startup assembly/linker script for this platform can be found here
EDIT:
I have attempted to change the linker file to accomplish this... but it's apparently not as easy as I think it is.
The startup assembly looks like this:
.syntax unified
.arch armv7e-m
.section .Vectors
.align 2
.globl __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler
.long NMI_Handler
.long HardFault_Handler
.long MemoryManagement_Handler
.long BusFault_Handler
.long UsageFault_Handler
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long 0 /*Reserved */
.long SVC_Handler
.long 0 /*Reserved */
.long 0 /*Reserved */
.long PendSV_Handler
.long SysTick_Handler
/* External Interrupts */
.long POWER_CLOCK_IRQHandler
.long RADIO_IRQHandler
.long UARTE0_UART0_IRQHandler_v
.long SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler_v
.long SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler_v
.long NFCT_IRQHandler_v
.long GPIOTE_IRQHandler_v
.long SAADC_IRQHandler_v
.long TIMER0_IRQHandler_v
.long TIMER1_IRQHandler_v
.long TIMER2_IRQHandler_v
.long RTC0_IRQHandler
.long TEMP_IRQHandler_v
.long RNG_IRQHandler
.long ECB_IRQHandler
.long CCM_AAR_IRQHandler
.long WDT_IRQHandler_v
.long RTC1_IRQHandler_v
.long QDEC_IRQHandler_v
.long COMP_LPCOMP_IRQHandler_v
.long SWI0_EGU0_IRQHandler_v
.long SWI1_EGU1_IRQHandler_v
.long SWI2_EGU2_IRQHandler_v
.long SWI3_EGU3_IRQHandler_v
.long SWI4_EGU4_IRQHandler
.long SWI5_EGU5_IRQHandler
.long TIMER3_IRQHandler_v
.long TIMER4_IRQHandler_v
.long PWM0_IRQHandler_v
.long PDM_IRQHandler_v
.long 0 /*Reserved */
.long 0 /*Reserved */
.long MWU_IRQHandler
.long PWM1_IRQHandler_v
.long PWM2_IRQHandler_v
.long SPIM2_SPIS2_SPI2_IRQHandler_v
.long RTC2_IRQHandler_v
.long I2S_IRQHandler_v
.long FPU_IRQHandler_v
.size __Vectors, . - __Vectors
/* Reset Handler */
.text
.thumb
.thumb_func
.align 1
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
.fnstart
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
subs r3, r2
ble .LC0
.LC1:
subs r3, 4
ldr r0, [r1,r3]
str r0, [r2,r3]
bgt .LC1
.LC0:
LDR R0, =SystemInit
BLX R0
LDR R0, =nrf_reloc_vector_table
BLX R0
LDR R0, =_start
BX R0
.pool
.cantunwind
.fnend
.size Reset_Handler,.-Reset_Handler
.section ".text"
Now it appears to me that I should be able to just relocate the ".Vectors" section to the beginning of flash, insert my image info section between them, and then keep the Reset_Handler and other ISRs at the beginning of the ".text" section. To do this, I modified the linker script to this:
MEMORY
{
VECTORS(rx) : ORIGIN = 0, LENGTH = 0x400
IMAGEINFO(r): ORIGIN = 0x400, LENGTH = IMAGE_INFO_OFFSET
FLASH(rx) : ORIGIN = 0x400+IMAGE_INFO_OFFSET, LENGTH = MBED_APP_SIZE-(IMAGE_INFO_OFFSET+0x400)
RAM (rwx) : ORIGIN = 0x20002ef8, LENGTH = 0xd108
}
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
ENTRY(Reset_Handler)
SECTIONS
{
.vectors :
{
KEEP(*(.Vectors))
} > VECTORS
.imageinfo :
{
KEEP(*(.ImageInfo))
} > IMAGEINFO
.text :
{
/*KEEP(*(.Vectors))*/
*(.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*))
} > FLASH
But now I get linker errors such as:
warning: cannot find entry symbol Reset_Handler; defaulting to 0000000000078400
BUILD/./main.o: In function `mbed::SPI::~SPI()':
main.cpp:(.text._ZN4mbed3SPID2Ev[_ZN4mbed3SPID5Ev]+0x18): undefined reference to `vtable for mbed::SPI'
BUILD/./main.o: In function `_GLOBAL__sub_I_g_PowerEnable':
main.cpp:(.text.startup._GLOBAL__sub_I_g_PowerEnable+0xc): undefined reference to `gpio_init_out'
And so on. Can someone give me some direction here? Shouldn't it be simple to just insert some data between the vector table and .text sections?
SOLUTION EDIT:
I have achieved my desired code spacing in a slightly different way (referencing the first answer to this question).
I changed the .text section in the linker script to begin with this:
.text :
{
KEEP(*(.Vectors))
FILL(0xff)
. = 0x100;
KEEP(*(.ImageInfo))
. = 0x400;
*(.text*)
.....
And removed the .vectors section.