cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32F411 Software DFU (STM32CubeMX based)

Stanislav Silnicki
Associate III
Posted on December 07, 2017 at 19:21

Hi!

I'm facing a problem with flashing my firmware into dedicated sectors of MCU.

Memory layout I use is following (link script fragment):

/* Specify the memory areas */

MEMORY

{

FRAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 32K

RAM (xrw)      : ORIGIN = 0x20008000, LENGTH = 96K

STARTUP (rx)   : ORIGIN = 0x8000000, LENGTH = 16K

EEPROM (rw)    : ORIGIN = 0x8004000, LENGTH = 48K

FIRMWARE (rx)  : ORIGIN = 0x8010000, LENGTH = 64K

FLASH (rx)     : ORIGIN = 0x8020000, LENGTH = 374K

}

All CubeMX generated stuff go in FLASH section, FIRMWARE accumulates the code I wish to update time to time.

Software base DFU implementation in attachment and follows example code, provided with CubeMX. Basically, it works (HAL_FLASH_Program and HAL_FLASHEx_Erase return HAL_OK).

The problem, which I see, is frustrating:

If i upload and flash existing firmware (that is flashed alongside with main code when I reprogram MCU over SWD), MCU boots and everything looks fine after power reset. But when I modify firmware part and upload it, DFU process finishes without errors, but MCU doesn't reveal any signs of life after power reset. So I just forced to reprogram it in conventional way. I tied to align firmware to the size of sector (64K) and it doesn't help.

Any clues?

#dfu #stm32f411
5 REPLIES 5
Posted on December 07, 2017 at 20:00

>>But when I modify firmware part and upload it, DFU process finishes without errors, but MCU doesn't reveal any signs of life after power reset. So I just forced to reprogram it in conventional way.

Ok, so read out the FLASH memory using a ST-LINK, or whatever, and diff the two situations to see what in memory is changed or corrupted in a way that prevents it starting as expected.

Add code in startup to output diagnostic information about the boot process and the integrity of the data that has been flashed.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 07, 2017 at 21:21

very strange....

I have dumped flash with openocd and compared different parts (vector table / firmware / main code). And all of them look fine - vector tables and main code kept intact and only firmware part differs after DFU update. So, everything as expected. But still controlled doesn't boot with updated firmware.

main code is pretty simple and just turns the LED if it starts, but it doesn't...

/* USER CODE END 0 */

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_I2S3_Init();

  MX_SPI1_Init();

  MX_SPI2_Init();

  MX_TIM2_Init();

  MX_I2C1_Init();

  MX_TIM3_Init();

  MX_CRC_Init();

  MX_IWDG_Init();

  /* USER CODE BEGIN 2 */

    LED2_On;

    HAL_Delay(1000);

    GPIO_PinState state = HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin);

    // if platform started with button pressed - start DFU

    if(state == UserButton_Pressed)

    {

        LED1_On;

        MX_USB_DFU_DEVICE_Init();

        extern  PCD_HandleTypeDef hpcd_USB_OTG_FS;

        HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);

        HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x20);

        HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x20);

        HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 2, 0x20);

        HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x20);

        HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 4, 0x40);

        HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 5, 0x40);

    }

    else

        firmware_init();

  /* USER CODE END 2 */

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

    while (1)

    {

        HAL_IWDG_Refresh(&hiwdg);

        __WFI();

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

    }

  /* USER CODE END 3 */

}

Posted on December 07, 2017 at 21:56

Before it gets there it executes SystemInit()

You need to get instrumentation code as close to Reset_Handler as possible so you can confirm if it is starting or not, and then waypoint the code to see where it gets. Have your Hard Fault Handler indicate if it arrives there.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 07, 2017 at 23:46

hmm.....

It looks like your guide is worth following!

I've faked the sysinit code with ugly stuff like this:

/**

  * @brief  Setup the microcontroller system

  *         Initialize the FPU setting, vector table location and External memory

  *         configuration.

  * @param  None

  * @retval None

  */

&sharpinclude 'gpio.h'

void SystemInit(void)

{

    MX_GPIO_Init();

    HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_RESET); // LED2_On

...

and it really turns the led on! and dies somewhere in further code!

I'll dive in...

Thank you, Clive!

Posted on December 08, 2017 at 01:25

Looks like it worked.

the key problem was here (found in startup.s code):

/* Call the clock system intitialization function.*/

  bl  SystemInit   

/* Call static constructors */

  bl __libc_init_array

/* Call the application's entry point.*/

  bl  main

  bx  lr    

.size  Reset_Handler, .-Reset_Handler

calling __libc_init_array requires proper distribution of code among .init .ctor .preinit_array sections...