This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32: Loading programs to different flash locations

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

Parents
  • 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.

Reply
  • 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.

Children
  • 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 @@@@@@@@@@@@@@@@@

    /* 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 = 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?