TheKikGen / stm32-tkg-hid-bootloader

A HID driverless bootloader and flash tool companion for the STM32F1 line
38 stars 12 forks source link
bluepill bootloader stm32

Check last release with binaries distribution for Windows and Linux platforms here :
https://github.com/TheKikGen/stm32-tkg-hid-bootloader/releases

Donate

STM32F10x TKG-HID-BOOTLOADER

This is a HID (Human Interface Device) driverless booloader for the STM32F10x family line, including the famous Bluepill. It was inspired by the original project from bootsector, but also from the derivated HID Bootloader from Vassilis Serasidis.

However this bootloader is not compatible anymore due to a lot of enhancements, code optimizations and bug corrections.

The bootloader supports transparently low-medium and high density devices without recompilation. The tkg-hid-bootloader doesn't use any ST libraries, but only CMSIS SDK. So, its size is under 4 Kbytes (2 high density pages), allowing more space for user programs (user flash memory starts at 0x08001000).

It was not possible (reasonable) to keep the size under the 2K ( 1 HD flash page) because before jumping to the user application, the bootloader must ensure that the current state of the MCU is correctly initialized. Depending on your own hardware, and GPIO settings, that size can vary, and we can't change everytime the "rom start" address in the linking process. So 4K is a good compromize between size and code quality, and will let room for new enhancements.

The TKG-FLASH has many new features, like info, dump, simulation mode, progression bar,compatibilty with the STM32DUINO platform, and can be easily integrated in the Arduino IDE

Since version 3.10, a xor checksum control is done at the end of the flashing process.

Entering the bootloader

TKG Bootloader logic

TKG-FLASH 3.1

+-----------------------------------------------------------------------+
|             TKG-Flash v3.1 STM32F103 HID Bootloader Flash Tool        |
|                     High density device support.                      |
|       (c) 2020 - The KikGen Labs     https://github.com/TheKikGen     |
+-----------------------------------------------------------------------+
Build : 3.210120.1702

  Usage: tkg-flash <firmware file name> [<options>]
         tkg-flash -info

  Options are :
  -info         : get only some information from the MCU without flashing.

  Flashing options :
  -d=16 -d=32   : hexa dump sectors by 16 or 32 bytes line length.
  -ide          : ide embedded, no progression bar, basic info.
  -o=<n>        : offset the default flash start page of 1-255 page(s)
  -p=<com port> : serial com port used to toggle DTR for MCU reset.
  -sim          : flashing simulation.
  -w=<time s>   : HID device waiting time (10s default).

  Examples :
  tkg-flash myfirmare.bin -p=COM4 -w=30
  tkg-flash myfirmare.bin -d=16 -s

The TKG-FLASH tool has the following features :

The page offset allows you to flash a firmware that was not linked with the tkg-hid-bootloader FLASH_BASE_ADDRESS at 0x08001000. For example, a firmware compiled with the stm32duino bootloader upload method will be linked with a base address at 0x08002000. So to make the bootloader to load that firmware at the right address, you can offset of 2 pages for a high density device (2048 * 2 = 0x1000 bytes per pages), or 4 for a medium density one ( 4 x 1024 = 0x1000 bytes par page).

Examples :

To flash myfirmware.bin under windows, using COM1 DTR as reset method :

tkg-flash myfirmware.bin -p=COM1

To do the same under Linux, with an offset of 2 pages :

tkg-flash myfirmware.bin -p=ttyACM0s -o=2

To get informations from a device in bootloader mode :

# tkf-flash -info

+-----------------------------------------------------------------------+
|             TKG-Flash v3.1 STM32F103 HID Bootloader Flash Tool        |
|                     High density device support.                      |
|       (c) 2020 - The KikGen Labs     https://github.com/TheKikGen     |
+-----------------------------------------------------------------------+
Build : 3.210120.1702

> Searching for [1209:BEBA] HID device...|
> [1209:BEBA] HID device found !
  INFO - Informations reported by the bootloader :
      Firmware version       : 0310
      MCU Flash memory size  : 128 K (medium density device)
      Page size              : 1024 bytes
      Page offset            : 4 pages
      Flash base address     : 0x08001000
  Bootloader mode still active.
> TKG-Flash end.

How to upgrade from your current bootoader

A special stm32duino sketch project can be found at https://github.com/TheKikGen/stm32-tkg-hid-bootloader/tree/master/tools/tkg_hid_btl_uploader

Arduino IDE integration

Quit Arduino IDE if active.

First, to add a new upload method in the STM32F1 boards, you need to modify the "boards.txt" usally located in your Arduino installation directory at "Arduino\hardware\Arduino_STM32\STM32F1". Make a backup copy before editing the file :

Search the section "## Generic STM32F103C ##" in the board.txt file, then the sub section "#-- UPLOAD METHODS --", and add the following lines at the last part of the upload section, to create a new "TKG-HID" upload method that will be shown in the IDE menu :

genericSTM32F103C.menu.upload_method.TKG-HIDUploadMethod=TKG HID bootloader 3.1
genericSTM32F103C.menu.upload_method.TKG-HIDUploadMethod.upload.tool=tkg_hid_upload
genericSTM32F103C.menu.upload_method.TKG-HIDUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103C.menu.upload_method.TKG-HIDUploadMethod.build.vect=VECT_TAB_ADDR=0x8001000
genericSTM32F103C.menu.upload_method.TKG-HIDUploadMethod.build.ldscript=ld/tkg_hid_bootloader.ld

Save and close boards.txt file.

Create now a new linker script file for your board, as mentioned in the above upload method, named "tkg_hid_bootloader.ld" in the directory STM32F1/variants/generic_stm32f103c/ld/ , and copy paste the following content :

/*
 * TKG-HID FLASH BUILD LINKER SCRIPT - V3.1
 * STM32F103C8 / STM32F103CB
 */
MEMORY
{
  /* Real RAM size of the board */
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
  /* Flash RAM size of the board minus 4K */
  rom (rx)  : ORIGIN = 0x08001000, LENGTH = 124K
}

/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);

/* Let common.inc handle the real work. */
INCLUDE common.inc

The ram and rom origin and lengths are adjusted to match the uC/board specifications.

You must then add a new upload method in Arduino/hardware/Arduino_STM32/STM32F1/platform.txt (make a backup copy before editing the file) in the "# Uploader tools

" section :

# TKG-HID upload 3.1
tools.tkg_hid_upload.cmd=tkg-flash
tools.tkg_hid_upload.cmd.windows=tkg-flash.exe
tools.tkg_hid_upload.cmd.macosx=tkg-flash
tools.tkg_hid_upload.path={runtime.hardware.path}/tools/win
tools.tkg_hid_upload.path.macosx={runtime.hardware.path}/tools/macosx
tools.tkg_hid_upload.path.linux={runtime.hardware.path}/tools/linux
tools.tkg_hid_upload.path.linux64={runtime.hardware.path}/tools/linux64
tools.tkg_hid_upload.upload.params.verbose=-d
tools.tkg_hid_upload.upload.params.quiet=n
tools.tkg_hid_upload.upload.pattern="{path}/{cmd}" "{build.path}/{build.project_name}.bin" -p={serial.port.file} -w=15 -ide

and copy the tkg-flash tool in the Arduino\hardware\Arduino_STM32\tool(your platform).

Under Linux, and Mac-OSX, you probaly need to :

You need to restart the Arduino IDE to see your changes.

Make an Arduino application to reboot in bootloader mode

When the board is booting, the bootloader checks the value 0x424C in the DR10 backup register to eventually enter in bootloader mode. To write this value from your own application, you can use the following example:

 #define BOOT_BTL_REGISTER     DR10
///////////////////////////////////////////////////////////////////////////////
// Set magic bootloader mode
///////////////////////////////////////////////////////////////////////////////
void BootLoaderMode()
{
   // Write the Magic word bootloader

   RCC_BASE->APB1ENR |=  (RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN) ;
   // Enable write access to the backup registers and the RTC
   PWR_BASE->CR |= PWR_CR_DBP;

   // write register
   BKP_BASE->BOOT_BTL_REGISTER = 0x424C;

   // Disable write
   PWR_BASE->CR &= ~PWR_CR_DBP;
   RCC_BASE->APB1ENR &=  ~(RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN) ;

   // Reset
   nvic_sys_reset();
}