2022-10-03 02:23 AM
Hi all,
Having developed a custom bootloader for our STM32L4R5ZITXP-based board, we are able to flash new applications using this bootloader and then jump onto them. Everything looks good until the FreeRTOS kernel is started at osKernelStart(). Then the applications gets halted and none of the tasks are started. This same application runs fine when running from base address 0x8000000.
This is where we do the jump to our application in the bootloader:
void boot_jump_to_main(void)
{
// Create MSP for main application
function_ptr boot_main;
// Create function pointer to main application location
boot_main = (function_ptr)(*(volatile uint32_t*)(BOOT_APP_START_ADDRESS + BOOT_HEADER_SIZE + 4U));
// Lock flash
boot_flash_lock();
__disable_irq();
// De-init clocks and peripherals
HAL_RCC_DeInit();
HAL_DeInit();
// Disable all interrupts
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
NVIC->ICER[2] = 0xFFFFFFFF;
// Clear pendings interrupts
NVIC->ICPR[0] = 0xFFFFFFFF;
NVIC->ICPR[1] = 0xFFFFFFFF;
NVIC->ICPR[2] = 0xFFFFFFFF;
// Reset systick
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
// Disable SysTick timer
SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
// Move vector table to app start address
__set_CONTROL(0);
__set_MSP(*(volatile uint32_t*)(BOOT_APP_START_ADDRESS + BOOT_HEADER_SIZE));
// Jump to application
boot_main();
}
This is our application main function:
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_DMA_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
MX_SPI2_Init();
MX_ADC1_Init();
MX_DAC1_Init();
MX_I2C1_Init();
MX_I2C2_Init();
MX_I2C3_Init();
MX_I2C4_SMBUS_Init();
MX_OCTOSPI1_Init();
MX_RTC_Init();
MX_SDMMC1_SD_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_TIM6_Init();
MX_TIM17_Init();
MX_UART4_Init();
MX_FATFS_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);
//TODO: remove relay-reset
HAL_GPIO_WritePin(RELAY_STB__RESET_GPIO_Port, RELAY_STB__RESET_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(RELAY_PORT__RESET_GPIO_Port, RELAY_PORT__RESET_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_STATUS0_GPIO_Port, LED_STATUS0_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED_STATUS1_GPIO_Port, LED_STATUS1_Pin, GPIO_PIN_SET);
__enable_irq();
/* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
Our Vector offset in our application's system_stm32l4xx.c source file:
#define VECT_TAB_OFFSET 0x10100
And this is finally our memory map in the linker scripts
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM3 (xrw) : ORIGIN = 0x20040000, LENGTH = 384K
BOOT (rx) : ORIGIN = 0x8000000, LENGTH = 64K
HEADER (rx) : ORIGIN = 0x8000000 + 64K , LENGTH = 0x100
FLASH (rx) : ORIGIN = 0x8000000 + 64K + 0x100, LENGTH = 2048K - 64K - 0x100
}
Your ideas are very welcome. Thanks in advance!
Daniel.