dmitrystu / sboot_stm32

Secure USB DFU1.1 bootloader for STM32
Apache License 2.0
313 stars 67 forks source link

Firmware stuck at start when using MX_USB_DEVICE_Init(); in user firmware. #29

Closed hojadurdy closed 3 years ago

hojadurdy commented 3 years ago

I built the bootloader for F070CB. I can upload my demo firmware and it works just fine. The issue appeared when I decided to make a demo firmware that jumps to bootloader from firmware with a command received from PC over virtual COM port. If I include MX_USB_DEVICE_Init(); in int main(void) my LED turns on at start and stops there. Is the issue caused by using different USB drivers from bootloader? Also reset after USB detach seem buggy. It doesn't matter if it is enabled or disabled, I get a reset when I unplug and plug USB cable back in.

EDIT: I am configuring USB interface as CDC Virtual Port Com in STM32CubeIDE.

dmitrystu commented 3 years ago

If you want to activate bootloader from any part of the user code you must do two things

  1. write DFU_BOOTKEY value to DFU_BOOTKEY_ADDR (in _AUTO it's usually _estack - 4. This stack record usually contains return address from main())
  2. call NVIC_SystemReset() or watchdog reset. Please provide more details. Does your firmware works without bootloader?
hojadurdy commented 3 years ago

JumpToBootloader_VCP.zip

Here is my test code. It is not finished but issue appears when MX_USB_DEVICE_Init(); is included in int main(void). I tested it by just uploading the firmware to address 0x08000000 and it works. But when it is uploaded to 0x08002000 with bootloader led turns on and stops there. If I comment out that line firmware works just fine.

Bootloader configs are below:

/* DEFAULT CONFIG STARTS HERE */
/* Skip unwanted dfuDNLOAD_SYNC phase. Slightly improve speed, but don't meets DFU1.1 state diagram */
#ifndef DFU_DNLOAD_NOSYNC
#define DFU_DNLOAD_NOSYNC   _ENABLE
#endif
/** Add extra DFU interface for EEPROM */
#ifndef DFU_INTF_EEPROM
#define DFU_INTF_EEPROM     _AUTO
#endif
/** Firmware can be uploaded from device */
#ifndef DFU_CAN_UPLOAD
#define DFU_CAN_UPLOAD      _ENABLE
#endif
/** Handle DFU_DETACH request in DFU mode. System reset will be issued. */
#ifndef DFU_DETACH
#define DFU_DETACH          _ENABLE
#endif
/** Whether application image is verified by a checksum algorithm */
#ifndef DFU_VERIFY_CHECKSUM
#define DFU_VERIFY_CHECKSUM _DISABLE
#endif
/** Memory Readout Protection level **/
#ifndef DFU_SEAL_LEVEL
#define DFU_SEAL_LEVEL      0
#endif
/* USB VID */
#ifndef DFU_VENDOR_ID
#define DFU_VENDOR_ID       0x0483
#endif
/* USB PID */
#ifndef DFU_DEVICE_ID
#define DFU_DEVICE_ID       0xF070
#endif
/* USB manufacturer string */
#ifndef DFU_STR_MANUF
#define DFU_STR_MANUF       "HD"
#endif
/* USB product sting */
#ifndef DFU_STR_PRODUCT
#define DFU_STR_PRODUCT     ""Secure bootloader""
#endif
/* USB string for DFU configureation string descriptor. */
#ifndef DFU_DSC_CONFIG
#define DFU_DSC_CONFIG      _ENABLE
#endif
#ifndef DFU_STR_CONFIG
#define DFU_STR_CONFIG      "DFU Mode"
#endif
/* USB string for DFU flash interface string descriptor. */
#ifndef DFU_DSC_FLASH
#define DFU_DSC_FLASH       _ENABLE
#endif
#ifndef DFU_STR_FLASH
#define DFU_STR_FLASH       "Internal Flash"
#endif
/* USB string for DFU EEPROM interface sreing descriptor */
#ifndef DFU_DSC_EEPROM
#define DFU_DSC_EEPROM      _ENABLE
#endif
#ifndef DFU_STR_EEPROM
#define DFU_STR_EEPROM       "Internal EEPROM"
#endif
/* USB EP0 size. Must be 8 for USB FS */
#define DFU_EP0_SIZE        8
/* DFU properties */
#ifndef DFU_POLL_TIMEOUT
#define DFU_POLL_TIMEOUT    20
#endif
#ifndef DFU_DETACH_TIMEOUT
#define DFU_DETACH_TIMEOUT  200
#endif
#ifndef DFU_BLOCKSZ
#define DFU_BLOCKSZ         0x80
#endif
/* 32 bit DFU bootkey value */
#ifndef DFU_BOOTKEY
#define DFU_BOOTKEY         0x157F32D4
#endif
/* DFU bootkey address. Top of the ram by default. _AUTO, _DISABLE or set address.
 * May be enabled internally. */
#ifndef DFU_BOOTKEY_ADDR
#define DFU_BOOTKEY_ADDR     _AUTO
#endif
/* DFU bootstrap port/pin settings. Set GPIOx or _DISABLE */
#ifndef DFU_BOOTSTRAP_GPIO
#define DFU_BOOTSTRAP_GPIO  GPIOB
#endif
#ifndef DFU_BOOTSTRAP_PIN
#define DFU_BOOTSTRAP_PIN   13
#endif
/* Active bootstrap pin logic level. _HIGH, _LOW */
#ifndef DFU_BOOTSTRAP_LEVEL
#define DFU_BOOTSTRAP_LEVEL _LOW
#endif
/* Pullup or pulldown settings for the bootstrap pin _AUTO, _DISABLE, _HIGH, _LOW */
#ifndef DFU_BOOTSTRAP_PULL
#define DFU_BOOTSTRAP_PULL  _HIGH
#endif
/* Double reset waiting time in mS. _DISABLE or time in mS */
#ifndef DFU_DBLRESET_MS
#define DFU_DBLRESET_MS     _DISABLE 
#endif
/* User application address. _AUTO or page aligned address.
 * for _AUTO check __app_start address in output linker map file*/
#ifndef DFU_APP_START
#define DFU_APP_START      0x08002000
#endif
/* User application size. _AUTO or required size in bytes. */
#ifndef DFU_APP_SIZE
#define DFU_APP_SIZE       122880
#endif
dmitrystu commented 3 years ago

Fixed a miscount of the IRQ's in #27 patch.

hojadurdy commented 3 years ago

Thanks a lot!! That solved the issue.

dmitrystu commented 3 years ago

Thanks for discovering this bug.