Writing Programs for the USB Bootloader

You are here:
← All Topics

Writing Programs for the USB Bootloader

The default IronLink bootloader occupies the start of the flash memory on the board. The bootloader will enter DFU mode if GPIO1 is shorted to GND (Connecting the 2 pins in the bottom left-hand side of the board), otherwise, it will jump to the application in flash if it has been uploaded.

Bootloader DFU Mode (Program Upload)

When GPIO1 is connected to GND the board will boot into DFU mode upon being powered on. Programs can then be uploaded to the device using the flash loader software provided by ST Micro. Download Flash Loader Software You will need a program in the DFU format in order to successfully upload a program to the board.

Before we construct our DFU files we need to modify the code to ensure it will work with the default bootloader. The start of flash for the processor is located at 0x08000000 which is also the default location that code is executed from. However, the IronLink bootloader is located in this section of the memory. The bootloader will jump to 0x08008000 which is where the DFU bootloader uploads your program. To ensure your program runs correctly we need to modify the linker file with the new address and relocate the vector tables before we initialise the program.

Modifying your program

Define the boot location and setup the vector table

#include "main.h"
// The default boot location for the application
#define APPLICATION_ADDRESS     (uint32_t)0x08008000
// Define the vector tables
#if   (defined ( __CC_ARM ))
  __IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
  
#elif (defined (__ICCARM__))
#pragma location = 0x20000000
  __no_init __IO uint32_t VectorTable[48];
  
#elif defined ( __GNUC__ )
  __IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
#endif

Add a function to copy the vector tables from flash to the start of RAM

void remap_vector_table() {
	uint32_t Index = 0;
	for(Index = 0; Index < 48; Index++) {
		VectorTable[Index] = *(__IO uint32_t*)((uint32_t)APPLICATION_ADDRESS + (Index << 2));
	}
	__HAL_RCC_USB_FORCE_RESET();
	__HAL_RCC_GPIOA_FORCE_RESET();
	__HAL_RCC_USB_RELEASE_RESET();
	__HAL_RCC_GPIOA_RELEASE_RESET();
	__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
	__HAL_SYSCFG_REMAPMEMORY_SRAM();
}

Call the function to remap the vector tables before we initalize the code

int main(void)
{
  
	remap_vector_table();
. . .

We now need to modify the linkter script with the application address and vector table

MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000400, LENGTH = 15K
FLASH (rx)      : ORIGIN = 0x8008000, LENGTH = 128K-0x8000
SRAM(rx)        : ORIGIN = 0x20000000, LENGTH = 1K
}

We also need to add this just before the end of the linker script to ensure our vector table is loaded into the start of the RAM

.RAMVectorTable : {*(.RAMVectorTable)} >SRAM AT> FLASH

Building the DFU file

Compile the your program normally and located the .hex file in the in the Debug directory of your program. Using the "DFU File Manager" provided with the ST Micro tools you can convert the hex file into a DFU file which can be uploaded using the DFU upload tool.