Skip to main content
dpn
Associate
September 27, 2016
Question

Jump to user application in the USB_Device/DFU_Standalone Example

  • September 27, 2016
  • 3 replies
  • 1224 views
Posted on September 27, 2016 at 14:48

Hello,

I am using STM32Cube_FW_L4_V1.5.1 library and I am trying to test the 

STM32Cube_FW_L4_V1.5.0\Projects\STM32L476G_EVAL\Applications\USB_Device\DFU_Standalone application. 

I have STM32L476RG-Nucleo + NUCLEO-CCA02M1 (for the USB support). 

I had to modify few small items in the DFU_Standalone application (as it is intended for STM32L476G_EVAL).

What I have achieved so far:

1. The DFU_Standalone builds and loads properly on my target

2. My Windows PC with DfuSe Demo recognize the connected target  as DFU device

3. I have build a small LED blinking application and tested it works OK if loaded using ST-link/v2

4. I have converted the blink.bin ->blink.dfu using DfuFileMgr.exe. I have set loading address to 0x0800C000 so it matches the USBD_DFU_APP_DEFAULT_ADD in DFU_Standalon

5. I am able to load blink.dfu using DfuSe Demo and I see the blinking code at offset 0x0800C000 exactly as I have in my bin file

6. If I set using the debugger the PC to 0x0800C000 and start the execution I see my blinking working fine.

7. If I reset the CPU the DFU_Standalon properly find application at 0x0800C000 and tries to jump to it and now my question. Jumping to my application (in DFU_Standalon) is done like this and it doesn't work but hit HardFault_Handler.

 JumpAddress = *(__IO uint32_t*) (USBD_DFU_APP_DEFAULT_ADD + 4);

 JumpToApplication = (pFunction) JumpAddress;

      

 __set_MSP(*(__IO uint32_t*) USBD_DFU_APP_DEFAULT_ADD);

 JumpToApplication();

Should my application code starts with stack pointer and then a jump to the actual code? It seems it is not true in my case. 

Or more general is there somewhere a description about the way user application needs to be written and linked to bin, so after loading it (as dfu) using  DFU_Standalone will start properly. 

Thank you!

Dimitar

    This topic has been closed for replies.

    3 replies

    Tesla DeLorean
    Guru
    September 27, 2016
    Posted on September 27, 2016 at 15:15

    If you want your app to run properly on a Cortex-M4 with interrupts and fault handling then it needs to be built with a vector table at the front of the image, and you need to point SCB->VTOR at this table. Build the image like you would a stand-alone one, but with an address deeper into FLASH, and on a 512-byte boundary.

    The processor provides all the context needed to see what caused the Hard Fault, a while(1) will not decode this, review examples from Joseph Yiu.

    When you hand over control you will want to do so without assorted interrupts firing, so make sure you tear-down things that can't be handled by the app when it first starts.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    dpn
    dpnAuthor
    Associate
    September 27, 2016
    Posted on September 27, 2016 at 15:43

    Hi Clive1,

    Thank you for the response. I am not clear how to place the vector table at the beginning of my bin file. Is this  a matter of linker configuration file? Sorry if this is very basic. 

    Could you please point me to an example (probably included in STM32Cube_FW_L4_V1.5.1) which I can check? 

     

    As for the Joseph Yiu example do you refer to the code in https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fHardFault%20Exception%20Why%20oh%20why%21&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=12869 ?

    Thank you very much!

    Dimitar

     

    Tesla DeLorean
    Guru
    September 27, 2016
    Posted on September 27, 2016 at 20:42

    The linker script and startup_stm32l4xx.s should control the vector table. The address usually in SystemInit().

    Joseph had authored several books and articles covering the Cortex-Mx parts. Hard Fault Handlers being an often covered topic.

    In Keil, I do it this way..

    //*****************************************************************************
    /*
    HardFault_Handler\
    PROC
    EXPORT HardFault_Handler
    TST lr, #4 ; Determine correct stack
    ITE EQ
    MRSEQ R0, MSP ; Read MSP (Main)
    MRSNE R0, PSP ; Read PSP (Process)
    MOV R1, R4 ; Registers R4-R6
    MOV R2, R5
    MOV R3, R6 ; sourcer32@gmail.com
    EXTERN hard_fault_handler_c
    B hard_fault_handler_c
    ENDP
    */
    void hard_fault_handler_c(unsigned int * hardfault_args, unsigned int r4, unsigned int r5, unsigned int r6)
    {
    printf (''[Hard Fault]
    ''); // After Joseph Yiu
    printf (''r0 = %08X, r1 = %08X, r2 = %08X, r3 = %08
    X'',
    hardfault_args[0], hardfault_args[1], hardfault_args[2], hardfault_args[3]);
    printf (''r4 = %08X, r5 = %08X, r6 = %08X, sp = %08
    X'',
    r4, r5, r6, (unsigned int)&hardfault_args[8]);
    printf (''r12= %08X, lr = %08X, pc = %08X, psr= %08
    X'',
    hardfault_args[4], hardfault_args[5], hardfault_args[6], hardfault_args[7]);
    printf (''bfar=%08X, cfsr=%08X, hfsr=%08X, dfsr=%08X, afsr=%08
    X'',
    *((volatile unsigned int *)(0xE000ED38)),
    *((volatile unsigned int *)(0xE000ED28)),
    *((volatile unsigned int *)(0xE000ED2C)),
    *((volatile unsigned int *)(0xE000ED30)),
    *((volatile unsigned int *)(0xE000ED3C)) );
    while(1);
    }
    //****************************************************************************

    0690X0000060MkuQAE.gif
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..