cancel
Showing results for 
Search instead for 
Did you mean: 

Fix for STM32G0B1 USB MSC Bootloader

etik
Associate

stm32-hotspot BOOTLOADER_USB_MSC_STM32G0 can be used as a good starting point for a USB MSC bootloader. The provided examples work, but if the application size increases, the bootloader will be erased, finally causing a hard fault.

It took a me while to find the reason: After loading the application the bootloader erases the unused flash memory. Due to an error in line 145 of main.c the wrong number of flash pages to erase is calculated:

flashErase.NbPages = flashErase.Page - 24

flashErase.Page is the first page to erase. For small application sizes the number of pages to be deleted will be small enough to not exceed the bank size and everything seems to be fine. But if the application size exceeds about 104K, the number of pages to be erased will get large enough to wrap around and also erase the boot loader. To calculate the correct number of unused pages, flashErase.Page should have been subtracted from the total number of pages.

I didn't test what happens if the application size increases further and Bank2 gets used.

See my changes to the code below that fixes the error and also to makes it easier to change the bootloader size by eliminating some hard coded constants.

If the size of the booloader changes, the linker file and the constant FLASH_PAGE_OFFSET in main.h must be changed. Don't forget to adjust the linker file of the application.

Also keep in mind that that code crossing the bank boundary can be problematic. (STM32G0B1 errata sheet, section 2.2.10 Prefetch failure when branching across flash memory banks"

Insert after line 61 of main.h 

#define FLASH_PAGE_OFFSET ((FLASH_APP_ADDR - FLASH_BASE) / FLASH_PAGE_SIZE)

Change line 136 of main.c

// flashErase.Page = (fatINFO.FileSize/FLASH_PAGE_SIZE) + 26;
flashErase.Page = FLASH_PAGE_OFFSET + (fatINFO.FileSize + FLASH_PAGE_SIZE-1)/FLASH_PAGE_SIZE;

Change lines from line 142 of main.c

//			if(flashErase.Page < 127)
//			{
//				/* Compute the Number of pages */
//				flashErase.NbPages = flashErase.Page - 24;
			if(flashErase.Page <= 127)
			{
				/* Compute the Number of pages */
				flashErase.NbPages = FLASH_PAGE_NB - flashErase.Page;

change line 158 of main.c

// flashErase.Page = 256;
flashErase.Page = 0;

Change lines 174-175 of main.c

// flashErase.Page += 129;
// flashErase.NbPages = 383 - flashErase.Page;
flashErase.Page &= (FLASH_PAGE_NB-1);
flashErase.NbPages = FLASH_PAGE_NB - flashErase.Page;

Remove line 323 of usbd_storage_if.c and insert code after

// uint16_t flashPage 		= blk_addr - fatINFO.FirstDataPosition + 25;

// block relative to file start
uint16_t blk_offset = blk_addr - fatINFO.FirstDataPosition;
// page offset of application
uint16_t flashPage = FLASH_PAGE_OFFSET + blk_offset;

Remove 4 line starting from line 328 of usbd_storage_if.c

//if (flashPage > 127)
//	{
//		flashPage += 129;
//	}

 

1 REPLY 1
FBL
ST Employee

Hi @etik 

Thank you for your precious feedback ! 

Just for your information, our ST website and our STMicroelectronics GitHub organization will give you access to official STM32 embedded software and other materials, supported and maintained. The materials delivered under this STM32 Hotspot GitHub organization may not be officially maintained, or supported by ST. Individual ST contributors may informally respond to questions and issues on a case by case.

For this particular case, I can forward your request to dedicated team of this project to adjust code to be more generic.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.