Hi,
i solved my previous problem in starting the main app from my own bootloader but now the same problems has returned if the application is coded with RTX kernel.
Summary
I'm using CortexM3 (STM32F103VB) with Keil uVision3 v.3.85 (DEMO). I've developed my own bootloader allocated between 0x08000000 and 0x08001FFF. 1 page (0x400) from 0x08002000 to 0x080023FF is used to store checksums and other stuff, 1 page from 0x08002400 to 0x080027FF is for application config. data Bytes from 0x080002800 on are used for main application. The bootloader terminates with the usual (from application notes) sequence:
JumpAddress = *(__IO uint32_t*) (0x08002800 + 4); Jump_To_Application = (pFunction) JumpAddress; __set_MSP(*(__IO uint32_t*) (0x08002800)); Jump_To_Application();
while the main app starts with the usual sequence:
SystemInit(); NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2800);
In the main app project target properties, the default memory area starts from 0x08002800 and is 0x1D800 bytes long, while in the linker tab the "Use Memory Layout from Target dialog" is checked.
The main app project decalres the checksum/data area as
const CHECKSUMS_ST C_Checksums __attribute__((at(0x08002000))); const CONFIGURTION_DATA_ST C_Config __attribute__((at(0x08002400)))
(both CHECKSUMS_ST and CONFIGURTION_DATA_ST are structures defined with filling fields in order to be exactly 0x400 bytes long).
I examined the result hex files and all seems correct, data and checksum are at correct addresses, the stack pointer stored at 8002800 point somewhere in RAM at 0x2000C60 and the reset address stored at 8002804 points to somewhere in flash at 0x80036C5 (they are stored in little endian, right?)
If the application is simply coded using just CMSIS and STD library (from ST), without RTX, all is fine.
PROBLEM If the application is coded with RL-RTX kernel support it goes in to hardfault handler after it sarts, somewhere between the NVIC_SetVectorTable call and os_sys_init call.
Off course I tested the sample app coded with RL-RTX at 0x08000000 WITHOUT the bootloader, and it works correctly.
Is there any issue about the RTX kernelthat I'm not considering ?
Thanks
RTX kernel needs to be started with Supervisor mode. If the bootloader calls the RTX kernel with User Mode, some problems will occur.
Hi John.
The bootloader does NOT change any privilege at startup, so the micro should start in thread/privileged mode and should remain in that mode when the bootloader calls the RTL-Application.
Is that wrong ?
I also edited the RTX_Config.c file and set OS_RUNPRIV to 1 in order to have all my task running in privileged mode.
I don't know things about Cortex-M. But for ATM7, there is some information, please see the below link, search for "Moshe Tal".
Read-Only Author: Moshe Tal Posted: 17-Feb-2009 15:15 GMT Toolset: ARM
In startup file (LPC2300.S) there is code that setup stacks for each ARM mode.
My Typo -> "But for ARM7"
I am so stupid/sleepy. the mentioned link is here:
http://www.keil.com/forum/docs/thread13707.asp
Hi John,
I had a look at the link and the post you mentioned but I think that is not applicable to my case/Cortex.
My startup_stm32f10x_md.s file is very simple (and standard, supplied by ST) and setup only the main stack. Also, my own bootloader does not change any running privlege before jumping to application, so all sw (both bootloader and application) should run in privileged mode.
Given that the bootloader uses systick and iwdg, what initialization sequence should be adopted by the application? My sequence is the following
//disable all devices enabled by bootloader, in reverse order __disable_irq(); //iwdg //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, DISABLE); //UART //RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE); //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, DISABLE); //systick SysTick->CTRL &= ~SysTick_CTRL_ENABLE; //NVIC NVIC_DeInit(); //clock RCC_DeInit(); __enable_irq(); /*==================================================================================*/ //re-initialize system SystemInit(); NVIC_SetVectorTable(NVIC_VectTab_FLASH, D_VECTORS_OFFSET); //enable LSI (to be used by Watchdog) RCC_LSICmd(ENABLE); //Wait till LSI is ready while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); // Configure one bit for preemption priority NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //enable AHB peripherals RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SRAM | RCC_AHBPeriph_FLITF | RCC_AHBPeriph_CRC, ENABLE);
The application behavior change a bit depending on __disable_irq()/__enable_irq() presence and position.
Any suggestion ?
Does the mentioned problem happen and only happen in a debug session?
the application had a subtle bug in the bootloader version that caused the hardfault exception. The bug was in one of the task, and my inexpereience in debugging with RTX did the rest.
Thanks to all who helped