Hello,
I want to load multiple applications onto my NUCLEO-F429ZI. This is for a production product.
The program at 0x08000000 will be a bootloader that decides whether to run the application in partition A or B. These are as follows:
Partition A will be the backup application that is field tested and guaranteed to work.
Partition B will be the beta application
The bootloader should run the program in partition B. If it faults, it will switch to partition A (I still have to figure out how to do this - for another day). To be clear, I am trying to figure out how to place the three separate applications (bootloader/A/B) at once. I have looked around for a solution, but these do not directly answer my question:
www.keil.com/.../ stackoverflow.com/.../running-multiple-applications-in-stm32-flash electronics.stackexchange.com/.../stm32f091-jump-to-bootloader-from-application
** I think I just answered my own question. It is unlikely you can place three applications at once, I will just flash the board three times and change the IROM1 value in settings.
Thank you
The .hex file reflects where binary data should be placed in memory - any memory. Unless you need to write more than one type of memory, you could make you life much easier by converting the .hex file into a .bin type file and handling this one in the bootloader - which is basically the same program code/data content stripped on addressing data. This is useful if you always need to write your data to a constant address in memory. You can find many free programs to convert a .hex file to a binary. You could of course add parsing a .hex file in your program but that seems rather an overkill for simple cases.
Update: I am able to flash the program into Partition A (@address 0x8060000) and verify it with a CRC check. The program runs anything in while loop fine (LED3 toggling, UART); however, the LED2 toggling based off of a timer interrupt does not work. When I flash the program normally (ie not with my bootloader) it works 100%, including LED2 toggling.
Below I include the jump function/linker file for the bootloader application at 0x8000000 and the main.c/linker file for the application at 0x8060000:
@@@@@@@@@@@@@@@@@@@@ JUMP FUNCTION IN BOOTLOADER PROGRAM AT 0x8000000 @@@@@@@@@@@@@@@@@
void ApplicationManager::RunActivePartition() { JumpToApplication = (void (*)(void)) (*((uint32_t *) (active_partition.address + 4)));
/* Reset RCC clock configuration */ HAL_RCC_DeInit();
/* Disable and reset systick timer */ SysTick->CTRL= 0; SysTick->LOAD = 0; SysTick->VAL = 0;
/* Disable all interrupts */ __disable_irq();
/* Set vector table offset register */ SetVectorTable(MemoryInfo::BTLR_ADDRESS, MemoryInfo::PARTITION_A_OFFSET_FROM_BTLR);
/* STM32 needs the stack pointer to start at the beginning of ** the application in flash. This must happen last */ __set_MSP(*(uint32_t*) active_partition.address);
JumpToApplication();
/*************** Other things I have tried ***************/ /* Remap system memory */ // SYSCFG->MEMRMP = SYSCFG_MEMRMP_MEM_MODE_0; //
// /* Clear pending interrupts */ // uint32_t isrflags = READ_REG(huart->Instance->SR); // Clears some UART interrupt
/* Disable peripheral clocks */ // __HAL_RCC_GPIOA_CLK_DISABLE(); // __HAL_RCC_GPIOB_CLK_DISABLE(); // __HAL_RCC_GPIOC_CLK_DISABLE(); // __HAL_RCC_GPIOD_CLK_DISABLE(); // __HAL_RCC_GPIOG_CLK_DISABLE(); // __HAL_RCC_GPIOH_CLK_DISABLE();
// __HAL_UART_DISABLE(&huart3);
// __HAL_RCC_PWR_CLK_DISABLE();
/*************** What I want to add when more basic implementation works ***************/ // /* Relocate vector interrupt table to RAM */ // CopyVectorInterruptTable();
// /* TODO: Patch VIT with bootloader interrupt handlers (ex: hard fault handler) */ // PatchVectorInterruptTable();
// if (!CopyandPatchOkay()) // { // LOG_DEBUG("Vector interrupt table not probably copied and/or patched \n"); // } // else // { // LOG_DEBUG("Device ready to jump into application \n"); // } }
@@@@@@@@@@@@@@@@@@@@ LINKER FILE FOR APPLICATION (BOOTLOADER) 0x8000000 @@@@@@@@@@@@@@@@@
/* Highest address of the user mode stack */ _estack = 0x20010000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ _Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K }
@@@@@@@@@@@@@@@@@@@@@@@@ APPLICATION TO JUMP TO AT 0x8060000 @@@@@@@@@@@@@@@@@@@@
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim10) { HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); } /* USER CODE END 0 */
/** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */ SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART3_UART_Init(); MX_TIM10_Init(); /* USER CODE BEGIN 2 */ uint32_t count = 0; HAL_TIM_Base_Start_IT(&htim10); /* USER CODE END 2 */
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { for (uint32_t i=0; i < 100000; i++); HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin); _printf("Hi %d \n", count); count++; /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
@@@@@@@@@@@@@@@@@@@@ LINKER FILE FOR APPLICATION (BLINKY) 0x8060000 @@@@@@@@@@@@@@@@@
/* Specify the memory areas */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K FLASH (rx) : ORIGIN = 0x8060000, LENGTH = 1024K }
I posted on SO because of the poor formatting stackoverflow.com/.../interrupts-not-working-when-i-jump-to-application-stm32. I just realised I could have used "pre" to format the source code better sorry.
I see you are disabling interrupts in the bootloader. Are you ever enabling them again?