cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with Running Application from Bootloader

Pushpalatha
Associate II

I seek your assistance with an issue I'm encountering while attempting to jump from my bootloader to an application stored at a specific address in the flash memory of an STM32H723ZGT6TR microcontroller.

 

 

I am able to successfully flash the application binary from a USB to the flash memory using bootloader code. However, I am unable to run the application using the following code snippet:

 

 
 
 uint32_t msp_value = *(__IO uint32_t *)0x08040000;
__set_MSP(msp_value);
uint32_t resethandler_address = *(__IO uint32_t *) (0x08040000 + 4);
app_reset_handler = (void*) resethandler_address;
app_reset_handler();
NVIC_SystemReset();
 
I would appreciate your review and any  suggestions or corrections you might have. Thank you for your time and assistance.
12 REPLIES 12
Imen.D
ST Employee

Hello @Pushpalatha and welcome to the Community :)

Please have a look at these articles which will help you on how to Jump to bootloader from application:

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

When I flash the application code using STM32CubeIDE and then run the bootloader code, I am able to successfully jump to the application address and execute the application. However, when I attempt to flash the application code from within the bootloader itself, I encounter difficulties in running the application code afterward. I suspect the issue lies with the flash write process during the bootloader operation.

SMarie
Senior

Could you show us your process of how you write the flash in the bootloader?

void Flash_Write(uint32_t address, uint8_t *data, uint32_t length) {
    HAL_FLASH_Unlock();

    for (uint32_t i = 0; i < length; i += 8) {
        uint32_t data_word = *(uint32_t *)(data + i);
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, address + i, data_word) != HAL_OK) {
            Error_Handler();
        }
    }

Thanks.

First, you should call HAL_FLASH_Lock(); at the end of your function. Maybe you call it later in your code, but you should lock back your flash as soon as you stop writing it.
Also, in the HAL_FLASH_Program brief :

/**
  * @brief  Program a flash word at a specified address
  * @PAram  TypeProgram Indicate the way to program at a specified address.
  *         This parameter can be a value of @ref FLASH_Type_Program
  * @PAram  FlashAddress specifies the address to be programmed.
  *         This parameter shall be aligned to the Flash word:
  *          - 256 bits for STM32H74x/5X devices (8x 32bits words)
  *          - 128 bits for STM32H7Ax/BX devices (4x 32bits words)
  *          - 256 bits for STM32H72x/3X devices (8x 32bits words)
  * @PAram  DataAddress specifies the address of data to be programmed.
  *         This parameter shall be 32-bit aligned
  *
  * @retval HAL_StatusTypeDef HAL Status
  */
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)


It is specified that for STM32h72x devices, the writing data should be align with "256 bits for STM32H72x/3X devices (8x 32bits words)"

So I think your for loop indentation should be i += 32.


And last but not least, DataAddress isn't a pointer but still is the address of the data.

 

Here is how I think your function should work:

void Flash_Write(uint32_t address, uint8_t *data, uint32_t length) 
{
    HAL_FLASH_Unlock();

    uint32_t data_word = (uint32_t)data;
    for (uint32_t i = 0; i < length; i += 32) 
    {
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, address + i, data_word + i) != HAL_OK)
        {
            Error_Handler();
        }
    }
    
    HAL_FLASH_Unlock();
}


Can you try this out and give us a feedback?

Despite following the recommended procedures for writing an application binary to flash memory and subsequently jumping to the application, I am unable to access the flash memory correctly after the flash write operation. It appears that the memory might be overflowing, causing the application not to run as expected.        

 

 

Pushpalatha_0-1721134613785.png

 

I was able to successfully run the application from the bootloader on the STM32F413ZH. The bootloader reads the application binary from a file, writes it to the flash memory, and jumps to the application start address without any issues.                                                             

When I used the same bootloader code on the STM32H7 series, specifically the STM32H7xx devices, I encountered a problem. After writing the application binary to the flash memory, I am unable to access the flash memory properly. It appears that the flash write operation completes, but subsequent attempts to read from or execute code from the flash memory fail. 

 

I have tried 5-6 different flashing procedure methods, but none have resulted in a successful operation on the STM32H7xx series. Each method attempted to address potential issues with memory alignment, cache settings, and flash operation flags, but the problem persists.

I am now using the following code to write to the flash memory, and I am able to access the flash memory successfully: .In below code i'm reading application  bin file from pen drive through usb and writing that bin file to flash memory. But the write operation is not correct .

 

 

 

res = f_mount( &USBDISKFatFs, (TCHAR const*)USBDISKPath, 0 );

      if( res != FR_OK )

      {

        break;

      }

      FATFS *fatFs = &USBDISKFatFs;

      f_getfree("", &fre_clust, &fatFs);

      total_space = (uint32_t)((USBDISKFatFs.n_fatent - 2) * USBDISKFatFs.csize * 0.5);

      free_space = (uint32_t)(fre_clust * USBDISKFatFs.csize * 0.5);

      printf("USB Device Total Space = %lu MB\n", total_space/1024);

      printf("USB Device Free Space  = %lu MB\n", free_space/1024);

      HAL_NVIC_SetPriority(FLASH_IRQn, 0, 0);

           HAL_NVIC_EnableIRQ(FLASH_IRQn);

           // Unlock the flash memory

           FLASH->KEYR1 = 0x45670123;

           FLASH->KEYR1 = 0xCDEF89AB;

 

           // Wait for the flash memory to be ready

           while (FLASH->SR1 & FLASH_SR_BSY);

 

           // Erase sector 6

           FLASH->CR1 |= FLASH_CR_SER; // Set the sector erase bit

           FLASH->CR1 |= (6 << FLASH_CR_SNB_Pos); // Select sector 6

           FLASH->CR1 |= FLASH_CR_START; // Start the erase operation

 

           // Wait for the erase operation to finish

           while (FLASH->SR1 & FLASH_SR_BSY);

 

           // Check for any errors

           if (FLASH->SR1 & (FLASH_SR_PGSERR  | FLASH_SR_WRPERR))

           {

               // Handle errors here

           }

 

           // Clear the end of operation flag

           FLASH->SR1 |= FLASH_SR_EOP;

 

           // Lock the flash memory

           FLASH->CR1 |= FLASH_CR_LOCK;

 

      res=f_open(&file,"application.bin",FA_READ);

      if(res != FR_OK)

      {

        printf("error while opening file");

        break;

      }

 

      uint8_t buffer[31488];

      res=f_read(&file,buffer,sizeof(buffer),1);

      if(res != FR_OK)

      {

        printf("not able to read the data from file\n");

         f_close(&file);

        break;

      }

      f_close(&file);

      SCB_DisableICache();

      HAL_FLASH_Unlock();

 

      __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1);

 

      uint32_t flash_address = 0x08040000;

      uint32_t bytes_read;

 

 

      for(uint32_t i=0;i<=(sizeof(buffer));i+=DATA_WORD_SIZE)

      {

        HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD,flash_address+i,(uint32_t*)(buffer+(i/4)));

        printf("the data is given by and addres 0x%08lX",flash_address+i);

        for(uint32_t j=0;j<DATA_WORD_SIZE;j++)

        {

          printf("%02X",buffer[i+j]);

        }

      }

      HAL_FLASH_Lock();

      SCB_EnableICache();

 

 

 

Pushpalatha_1-1721135703520.png

 

Please write your code within the </> option, it makes it more readable.


As I said above, you shouldn't give HAL_FLASH_PROGRAM any pointer, did you try:

HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD,(flash_address + i),((uint32_t) buffer + i))

?