Keil Logo

STM32: Loading programs to different flash locations

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Author
M Bards
Posted
21-Jan-2019 09:29 GMT
Toolset
None
New! 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:

http://www.keil.com/forum/17822/stm32-loading-programs-to-different-flash-locations/
https://stackoverflow.com/questions/216211/running-multiple-applications-in-stm32-flash
https://electronics.stackexchange.com/questions/312303/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

Author
M Bards
Posted
21-Jan-2019 09:36 GMT
Toolset
None
New! RE: STM32: Loading programs to different flash locations

My suggested strategy of changing the IROM1 location is wrong. It just places the application at the new location and leaves 0x08000000 empty. The search continues...

Author
Tamir Michael
Posted
21-Jan-2019 09:55 GMT
Toolset
None
New! RE: STM32: Loading programs to different flash locations

You should stop and reconsider the way you plan to get this work.
In order to get this done, you need a separate project per program type (bootloader, application A and B). Each must have a unique linker script, determining a unique entry point and vector table. Do not fiddle with IROM1 - use a linker script instead!
In addition to that, you will need a variable/RAM location, defined in the bootloader, indicating whether application B failed - such a variable must not be initialized to 0 upon startup of the bootloader (look up ZI and UNINIT elements in linker scripts).

Author
M Bards
Posted
21-Jan-2019 14:26 GMT
Toolset
None
New! RE: STM32: Loading programs to different flash locations

Thank you Tamir, very helpful. I do not have much experience with linker scripts, but I will take the time to learn and report back.

Author
Tamir Michael
Posted
21-Jan-2019 14:42 GMT
Toolset
None
New! RE: STM32: Loading programs to different flash locations

Another import point of interest: In the bootloader, before jumping to application, disable the interrupts and clear the pending ones. In the application initialization procedure, remap the vector table - then enable the interrupts.

Author
M Bards
Posted
24-Jan-2019 08:37 GMT
Toolset
None
New! RE: STM32: Loading programs to different flash locations

With respect to using the linker to select where the program goes, I would prefer to use the bootloader application at 0x08000000 to stream the incoming program to partition A/B. I have figured out how to erase/write flash using variables from SRAM, so all I have to do is give a starting address and it writes fine.

My question now is, what exactly do I write to "partition A" to get a working program. This runs along the lines of the question here https://stackoverflow.com/questions/216211/running-multiple-applications-in-stm32-flash. Is it as simple as sequentially writing all of the bytes seen in the hex file, and telling the bootloader application to jump to the starting address? For example, if this is my hex file in Intel Hex format and say my starting address is 0x08020000:

:020000040800F2
:1000000000000320F51E0008B1080008B30800082E
:10001000B5080008B7080008B9080008000000008B
:10002000000000000000000000000000BB08000805
:10003000BD08000800000000BF080008C108000853
:10004000451F0008451F0008451F0008451F000800
:10005000451F0008451F0008451F0008451F0008F0
:10006000451F0008451F0008451F0008451F0008E0

Should I just write:
@0x08020000: 0x08
@0x08020001: 0x00
@0x08020002: 0x00
@0x08020003: 0x00
@0x08020004: 0x03
@0x08020005: 0x20
...
@0x0802xxxx: 0x08

Just having a hard time finding resources on this. I would prefer to learn this myself so if anyone can point me in the right direction it would be much appreciated.

Author
Tamir Michael
Posted
24-Jan-2019 09:18 GMT
Toolset
None
New! RE: STM32: Loading programs to different flash locations

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.

Author
M Bards
Posted
12-Mar-2019 11:20 GMT
Toolset
ARM
New! RE: STM32: Loading programs to different flash locations

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
}

Author
M Bards
Posted
12-Mar-2019 11:45 GMT
Toolset
ARM
New! RE: STM32: Loading programs to different flash locations

I posted on SO because of the poor formatting https://stackoverflow.com/questions/55119482/interrupts-not-working-when-i-jump-to-application-stm32. I just realised I could have used "pre" to format the source code better sorry.

Author
Bob McNamara
Posted
12-Mar-2019 15:55 GMT
Toolset
ARM
New! RE: STM32: Loading programs to different flash locations

I see you are disabling interrupts in the bootloader. Are you ever enabling them again?

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.