I am trying to write a bootloader that allows loading of a new image over ethernet. I did not really find anything recent regarding this topic, so I looked for inspiration in older STM32F4 code.
The bootloader shall always be started first and wait for a new image or boot signal over ethernet (alternatively, timeout). This is important for in application programming of many processors at once.
The first step is to write a ChibiOS based bootloader that just jumps to the user application. I found some code snippets and combined them to the following routine. As far as I understood, the steps to take are as follows (please correct me if this is wrong):
- A user application address is given. The start of the user application contains the vector table
- From this vector table, the actual application address (reset interrupt vector?) is extracted
- Disable and clear pending interrupts
- Move stack pointer to user application vector table
- The previously extracted application address is finally called
Here is the code so far, for loading a user program:
Code: Select all
void jumpToUser(uint32_t address)
{
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
/*
* variable that will be loaded with the start address of the application
*/
__IO uint32_t * JumpAddress;
const __IO uint32_t * ApplicationAddress = (__IO uint32_t *) address;
/*
* get jump address from application vector table
*/
JumpAddress = (__IO uint32_t *) ApplicationAddress[1];
/*
* load this address into function pointer
*/
Jump_To_Application = (pFunction) JumpAddress;
/* Stop system? */
chSysDisable();
/*
* Clear pending interrupts
* Removes the pending state from the PendSV exception.
*/
SCB_ICSR = ICSR_PENDSVCLR;
/* Disable all interrupts */
int i;
for(i = 0; i < 8; ++i)
NVIC->ICER[i] = NVIC->IABR[i];
/* set stack pointer as in application's vector table */
__set_MSP((uint32_t) (ApplicationAddress[0]));
Jump_To_Application();
}
I have some problems with compilation on STM32F7 processors.
This:
Code: Select all
/*
* Clear pending interrupts
* Removes the pending state from the PendSV exception.
*/
SCB_ICSR = ICSR_PENDSVCLR;
does not exist on STM32F7. How can I clear all pending interrupts (or is it even necessary)? I found "__disable_irq()" which disables all interrupts but does not clear pending interrupts. I guess it is similar to what "chSysDisable()" does.
Generally, the user programm shall find conditions just like after a reset. How can I accomplish that?
Thank you in advance,
Adrian