Adding HAL_Flash_program to code, without calling it, breaks things. Why?
Hi, I'm trying to develop a bootloader. I managed to jump to a program properly when it's already in the flash. I managed to program the flash but then I can't jump to the newly loaded code. Worse, when I add the "HAL_Flash_program" to my code, even when not using it I can't jump anymore. I'm struggling to understand why. Could you please help me ?
I can do both in separate programms, first loading the code and then jumping to it and it works. I checked with stm32cubeProgrammer, the code in flash memory is verified as the file i'm uploading.
My MCU is a STM32L4R9AI, and i'm using the discovery board and stm32cubeIDE. Please find the code here. Empty configuration except for a digital input on PG8, UART3 on PB10/P11 and digital output (user led) on PH4.
/* USER CODE BEGIN PM */
#define APP_FLASH_ADDR 0x080A0000 //Application's Flash Address
#define PROGSIZE 20000
/* USER CODE END PM */
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 */
uint32_t ms1,ms2,i;
uint8_t bootOrLoad = 0;
uint64_t *castedBuffer;
uint8_t progBuffer[PROGSIZE];
/* 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();
/* USER CODE BEGIN 2 */
//Detect button press at start. 1 -> update mode. 0 -> Start application mode.
ms1 = HAL_GetTick();
do{
if (HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_8))
{
bootOrLoad = 1;
break;
}
ms2 = HAL_GetTick();
}while((ms2-ms1) < 1000);
//Button was pressed -> update mode
if(bootOrLoad)
{
NS_UART_Transmit(&huart3, "UPDATE MODE\n\r", 500);
NS_UART_Transmit(&huart3, "you have 10 sec to send FW...\n\r", 500);
//Receiving FW ...
HAL_UART_Receive(&huart3,progBuffer,PROGSIZE,10000);
//Unlocking flash
HAL_FLASH_Unlock() ? NS_UART_Transmit(&huart3, "Unlock KO\n\r", 500)
: NS_UART_Transmit(&huart3, "Unlock OK\n\r", 500);
//Casting buffer as 64bits because it's the only supported format with L4R9AI
castedBuffer = (uint64_t*)progBuffer;
//flashing buffer to memory
for(i=0;i<PROGSIZE/8;i++)
{
//EVEN IF bootOrLoad IS AT 0, THIS PART STOPS THE START APPLICATION MODE FROM WORKING
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,(APP_FLASH_ADDR)+8*i,castedBuffer[i]))
NS_UART_Transmit(&huart3, "Write KO\n\r", 500);
}
//Locking flash back
HAL_FLASH_Lock() ? NS_UART_Transmit(&huart3, "Lock KO\n\r", 500)
: NS_UART_Transmit(&huart3, "Lock OK\n\r", 500);
//Reboot
NS_UART_Transmit(&huart3, "Update over. Reboot...\n\r", 500);
NVIC_SystemReset();
}
//Button not pressed -> start application mode
else
{
//
NS_UART_Transmit(&huart3, "APPLICATION START MODE\n\r", 500);
//Jump to app
void (*app_reset_handler)(void) = (void*)(*((volatile uint32_t*) (APP_FLASH_ADDR+4U)));
__set_PSP(*(volatile uint32_t*) APP_FLASH_ADDR+4U);
app_reset_handler();
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}