2016-08-14 08:34 PM
Hello all,
I am working on a project where MCU will enter USB DFU mode via a command (STM32L151rd, USB-FS_4.0, 32MHz PLL driven by HSE) without sensing any button press or changing BOOT0 pin. I've configured USB VCP as the default mode. It'll switch role to DFU or MSC (in next USB connectivity) upon a command sending via VCP. DFU/MSC session will continue as long as USB cable is connected (via sensing a GPIO pin connected to USB). PC can recognize all three USB modes. Unfortunately, I am not clear about the register/vector table settings needed for DFU or which .hex file is needed to convert to .dfu and upload. Will this idea work at all for DFU ? Would you please give me some direction for this specific project and help me get out of this problem. Thank you for your kind time.2016-08-15 09:05 AM
I'm not using L1 parts, you'll have to review how to map and call the ROM in a viable manner, or implement your own DFU loader. This topic has been covered multiple times for several of the STM32 family devices, the concepts will not be unduly different here. If necessary review the technical manuals for the chip and core, and experiment.
The .DFU file is just a binary encapsulation of the data (firmware image) you are representing in your .HEX file. There is no magic about it, it is your firmware, it will get put exactly where you tell it to put it.2016-08-24 04:59 PM
Thank you Clive. I've explored your DFU example/discussions.
My Bootloader code can upload a sample .dfu but cant upload more than 4% of my application code. I apologize, I'm not getting the whole picture of what I need to configure. I request your kind suggestion. From STM32L1 datasheet: System Memory: 0x1FF0 0000 -- 0x1FF0 1FFF [2 Banks. Bank1upto 0x1FF0 0FFF] Flash: 0x0800 0000 -- 0x0805 FFFF [2 Banks. Bank1upto 0x0800 17FF] Data EEPROM: 0x0808 0000 -- 0x0808 2FFF [2 Banks. Bank1upto 0x0808 2FFF] SRAM: 0x2000 0000 -- 0x2000 BFFF In my bootloader project/code, MCU switch either Jump_To_Application() or initialize USB DFU mode + send .dfu via DfuSe Demo + perform a soft reset. Its around 13KB code. From Keil_u5 'Options for Target\Target', I've set IROM1:0x0800 0000 (start) and size 0x4000 IRAM1:0x2000 0000 (start) and size 0xC000 (Default) And 'Options for Target\Linker' : R/O Base: 0x0800 0000 (Default) R/W Base: 0x2000 0000 (Default) Code: ------ //#define BOOTLOADER_MAGIC_ADDR ((uint32_t*) ((uint32_t) 0x2000BFF0)) //#define BOOTLOADER_MAGIC_TOKEN 0xDEADBEEF //#define ApplicationAddress 0x08004000At the start of main() function:
tmp=*BOOTLOADER_MAGIC_ADDR; if (tmp != BOOTLOADER_MAGIC_TOKEN){ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; __set_MSP(*(__IO uint32_t*) ApplicationAddress); Jump_To_Application(); } else { USB_Connectivity_Pin_config(); // to check USB connectivity via PB12 GPIO pin *BOOTLOADER_MAGIC_ADDR=0; Set_System(); Set_USBClock(); USB_Init(); // DFU mode while (GPIOB->IDR & GPIO_Pin_12) ==SET); // Continue DFU mode as long as USB cable connected. NVIC_SystemReset (); // Reset after USB cable disconnected } --------------------------------------------------- And the application code (where I configured USB VCP/MSC, timers,FATFS SDIO, interrupts) is around 30KB. I've configured: IROM1:0x0800 4000 (start) and size 0x5C000 IRAM1:0x2000 0000 (start) and size 0xC000 (Default) 'Options for Target\Linker' R/O Base: 0x0800 4000 (Default) R/W Base: 0x2000 0000 (Default)with #define VECT_TAB_OFFSET 0x4000 NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000); In USB VCP mode, upon a user command: *BOOTLOADER_MAGIC_ADDR = BOOTLOADER_MAGIC_TOKEN; NVIC_SystemReset(); --------------------------------------------------------------------------- I saw your following assembly codes. I guess I don't need to add these for my project: Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main LDR R0, =0x2000BFF0 ; End of SRAM LDR R1, =0xDEADBEEF LDR R2, [R0, #0] STR R0, [R0, #0] ; Invalidate CMP R2, R1 BEQ Reboot_Loader LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP Reboot_Loader PROC EXPORT Reboot_Loader LDR R0, =0x40023844 ; RCC_APB2ENR LDR R1, =0x00004000 ; ENABLE SYSCFG CLOCK STR R1, [R0, #0] LDR R0, =0x40013800 ; SYSCFG_MEMRMP LDR R1, =0x00000001 ; MAP ROM AT ZERO STR R1, [R0, #0] LDR R0, =0x1FF00000 ; ROM BASE of L1 LDR SP,[R0, #0] ; SP @ +0 LDR R0,[R0, #4] ; PC @ +4 BX R0 ENDP ;
2016-08-24 06:22 PM
My Bootloader code can upload a sample .dfu but cant upload more than 4% of my application code.
Ok, but what does this mean? Can the ROM based System Loader take the whole .DFU image? Your DFU firmware bugs out at some point? If it is *your* DFU loader, can you instrument that and quantify where it is failing. The DFU format is not inherently complicated, it describes blocks of data with a size and destination address. If you can take the .HEX it was created from, and burn it in with the ST-LINK Utilities, then the DFU Loader should be able to digest/process it too. The DFU Manager can also take a .DFU and create a .HEX or .S19 file. One could build a HEX Loader that could take these same files, and prove if delivering them that way works, doing so would allow you to focus on where exactly the problem lays. Yes the memory division here looks reasonable enough. I'm not a fan of control transfer done this late in C. You need to be very careful that your SystemInit() code doesn't assume cold reset conditions, and that the Loader and App load the correct address for the Vector Table. My code example should allow it to boot into the ROM's System Loader.2016-10-06 08:33 PM
Hi Clive,
I apologize I was busy doing other stuffs and now back what I left unsolved. One query: hints that if MCU jumps to built-in boot loader of system ROM (0x1FF00000--ROM BASE of L1), it'll detect USB as a DFU device (without configuring USB DFU in code as provided in USB_FS library) and we can load .dfu file using DFUse utility. Am I understanding correctly? If so, may be I can configure the whole system in one project (code) using your RAM magic content. I was always getting wrong concept and wondering whether switch to 0x1FF00000 or 0x08004000 in Reboot_Loader section (or in which project: DFU boot loader or application code). I request your kind guidance.2016-10-07 02:26 PM
I've done it at last.
Yes, I was missing this point from the beginning ''if MCU jumps to built-in boot loader of system ROM, it'll detect USB as a DFU device (without configuring USB DFU in code as provided in USB_FS library example)''. For reference, in my code, user will send a character command from PC via USB VCP and MCU will enter DFU mode (*BOOTLOADER_MAGIC_ADDR = BOOTLOADER_MAGIC_TOKEN; NVIC_SystemReset();) and PC will recognize it as an USB DFU device. Thank you Cilve once again. Startup code for L151rd stands as: Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main LDR R0, =0x2000BFF0 ; End of SRAM 0x2000BFFF LDR R1, =0xDEADBEEF LDR R2, [R0, #0] STR R0, [R0, #0] ; Invalidate CMP R2, R1 BEQ Reboot_Loader LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP Reboot_Loader PROC EXPORT Reboot_Loader LDR R0, =0x40023820 ; RCC 0x40023800 base with 0x20 offset LDR R1, =0x00000001 ; ENABLE SYSCFG CLOCK STR R1, [R0, #0] LDR R0, =0x40010000 ; SYSCFG_MEMRMP base with 0x00 offset LDR R1, =0x00000001 ; MAP ROM AT ZERO LOCATION STR R1, [R0, #0] LDR R0, =0x1FF00000 ; ROM BASE of L1 LDR SP,[R0, #0] ; SP @ +0 LDR R0,[R0, #4] ; PC @ +4 BX R0 ENDP ;