2

I've created an application which has 2 firmware slots in its memory mapping. It works pretty fine and both slots are executed correctly based on a 32-bit sequencer number stored in FLASH.

The problem appears when I'm trying to use FreeRTOS. By default, firmware is compiled for the first slot... and there's no any problem in running this slot. However when the device starts firmware saved in the second slot, when RTOS starts its first task in prvPortStartFirstTask, then jumps to vPortSVCHandler it switches to the task in the first slot.

What am I doing wrong? I thought function addresses are relative after compilation, so there should be no difficulties running this application with 2 firmware slots.


EDIT

My flow during switching from bootloader to main application is as follows: 1. Check which firmware slot should be used. 2. Disable IRQs. 2. Copy vector table to RAM. That part of RAM is the same for both slots. During copying process I'm changing offset for each address, so they will be compatible with particular firmware slot. By default addresses don't have offset, it's removed in post-compiling stage. 3. Set stack pointer, according to the first word in vector table in RAM. That addresses is not changed while copying vector table to RAM. 4. Set SCB->VTOR. 5. Execute Data Sync Barrier DSB(). 6. Jump to the Reset Handler from vector table copied to RAM.


EDIT 2

When I compile application with changed FLASH memory address range to the secondary slot, it works properly. Is it possible compile code such that application will be PC independent, at least it will work in that case?


EDIT 3

# Generate position independent code.
-fPIC

# Access bss via the GOT.
-mno-pic-data-is-text-relative

# GOT is not PC-relative; store GOT location in a register.
-msingle-pic-base

# Store GOT location in r9.
-mpic-register=r9

However, now this slot stopped working.

I think my problem is similar to that one.

VIPPER
  • 326
  • 4
  • 24

1 Answers1

1

Generally, firmwares aren't built position independent, so I wouldn't trust that all "function addresses are relative after compilation". You compile firmware for a specific start location (either the first or the second firmware slot).

As for your main question, have you done anything to switch the interrupt handlers / interrupt vector from one firmware slot to the other? Or are you jumping to the first firmware's interrupt handlers when you call the SVC handler?

How to change the interrupt vector varies between architectures. For an stm32f429, you could perhaps look here

Pinetwig
  • 673
  • 5
  • 13
  • Vector table is updated for particular firmware slot. It fails while returning from vPortSVCHandler function called in prvPortStartFirstTask – VIPPER May 30 '18 at 21:05
  • Is it possible compile code such that application will be PC independent, at least it will work in that case? – VIPPER Jun 01 '18 at 15:55
  • @VIPPER pay more attention the vector table; there are at least two issues, first the address of the vector table the hardware will use, 2nd the fact that the contents of the vector table are **absolute** addresses. – Chris Stratton Jun 12 '18 at 05:33