cancel
Showing results for 
Search instead for 
Did you mean: 

DFU issue

przemyslaw
Associate II
Posted on May 21, 2014 at 15:54

I am trying to make DFU work on STM32F205ZF. At the moment it is recognized by the host PC. I can upload flash to PC, verify it, but ''DfuSe Demo'' stucks when it comes to updating a flash. It manages to erase just sector &sharp3, and then it freezes. I guess I need to change hex start location from default 0x08000000 to 0x0800C000, to reserve sectors &sharp0-&sharp2 for the temporary data, for update process, so I have changed:

rom (rx)        : org = 0x08000000, len = 768k

to:

rom (rx)        : org = 0x0800C000, len = 768k - 0xC000

in my linker script file.

The problem is that, although program starts and I can debug it, it doesn't go far - just configures pins, clocks and when it comes to the first delay loop, which checks SysTick it never returns. When I pause debuging I found PC somewhere near 0xffffffff, I get ''unknown instructions'', ''symbol is not define'' etc.

Of course the loop works fine, when program origin is set to 0x08000000. When it is set to 0x0800C000 and I enter the loop in instruction stepping mode I see SysTick works. Then it seems it's IRQ comes and isn't handled, or program goes to a wrong address. I have checked vector table in the LSS file and it is fine.

What may be the cause of such a behaviour and how to fix it?

#dfu
8 REPLIES 8
Posted on May 21, 2014 at 16:26

What may be the cause of such a behaviour and how to fix it?

The processor needs an executable image, or vectors, at 0x08000000
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
przemyslaw
Associate II
Posted on May 21, 2014 at 23:24

Why program starts at all, when vectors are located starting from 0x800C000? As I have written it does start, breakpoints at main, then it is able to step over basic inits like clocks and pins configuration. If it would not find vectors at 0x8000000, then I guess, it should not work at all.

Please don't get me wrong, I'm not saying you are wrong, I am just trying to understand.

But the most important to me is to get DFU FW update working. I am trying to learn how it should be done. When I have vectors at 0x8000000, so at the begining of the first flash sector (sector #0) and I try to update FW using ''DfuSe Demo'', it freezes just after earasing secotr #3. I guess this sector contains vital part of the program and that is a reason why ST's DFU code protects  first 3 sectors.

I have two hypothesis:

1. There should be some directives placing DFU code in those first 3 sectors, which are later protected allowing DFU code to run undisturbed and not become earased. Unfortunately there aren't any such a directives.

2. Those first 3 sectors are used as temporary place where program chunks received from PC host are stored. If that is true program should start at 0x800C000.

I will be thankfull if you could be so kind and shed some light onto this.
Posted on May 22, 2014 at 01:09

It probably runs because the debugger makes it run, try doing it without the debugger attached, and output telemetry via a serial port.

Are you using the System Loader (ROM) to do the DFU, or do you have some other IAP code at the base of flash? Code that is running from Flash is clearly not going to like being erased, and will probably stall as writes/erases complete.

I honestly don't believe there should be anything magic in the first three 16KB sectors, I've certainly built images with the DFU Manager which start at the base of flash, and span more than 3 sectors. These sectors aren't used to stage any data.

If you have an ST-LINK, you could use the Utilities to download the current flash content, and do a postmortem analysis.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
przemyslaw
Associate II
Posted on May 22, 2014 at 12:37

> It probably runs because the debugger makes it run, try doing it without the debugger attached, and output telemetry via a serial port.

It could be. It could be it starts because first 3 sectors weren't cleared and contain old program. When I perform chip earase, flash program starting at 0x800C000 and try to run it from ST-Link Utility I get ''Lockup'' core status. It seems to be a proof you're right.

> Are you using the System Loader (ROM) to do the DFU, or do you have some other IAP code at the base of flash?

I have just took DFU Example from ''STM32_USB-Host-Device_Lib_V2.1.0'' and put it into my code. I start from flash. I don't have IAP code or any special code at the begining of the flash.

> Code that is running from Flash is clearly not going to like being erased, and will probably stall as writes/erases complete.

Yes, you're right, I defenitely agree.

> I honestly don't believe there should be anything magic in the first three 16KB sectors,

> I've certainly built images with the DFU Manager which start at the base of flash, and span

> more than 3 sectors. These sectors aren't used to stage any data.

Important parts of the DFU code (coming from various source/header files):

static uint32_t Pointer = APP_DEFAULT_ADD;  /* Base Address to Erase, Program or Read */

#define APP_DEFAULT_ADD   0x0800C000 /* The first 3 sectores (48 KB) are reserved for DFU code */

/* Update this define to modify the DFU protected area.

   This area corresponds to the memory where the DFU code should be loaded

   and cannot be erased or everwritten by DFU application. */

#define DFU_MAL_IS_PROTECTED_AREA(add)    (uint8_t)(((add >= 0x08000000) && (add < (APP_DEFAULT_ADD)))? 1:0)

Furtermore code meant to be used to generate loadable DFU has:

FLASH (rx)      : ORIGIN = 0x0800C000, LENGTH = 1024K - 0xC000

in linker script file.

In the main app there is:

if(GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_4)==Bit_RESET)

{ /* Test if user code is programmed starting from address 0x800C000 */

    if (((*(__IO uint32_t*)APP_DEFAULT_ADD) & 0x2FFE0000 ) == 0x20000000)

    { /* Jump to user application */

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

        Jump_To_Application = (pFunction) JumpAddress;

        /* Initialize user application's Stack Pointer */

        __set_MSP(*(__IO uint32_t*) APP_DEFAULT_ADD);

        Jump_To_Application();

    }

}

So clearly user defines area which is protected from writing/earasing. At the other hand there are no directives placing DFU code at the protected area.

Maybe I should take a look at LSS file and check were exactly DFU code is alocated and then modify the protected area accordingly? Or maybe I should protect area for one whole copy of my program or prepare separate one just to run the proper one? Now it seems to me it looks reasonable. I will try the way.

> If you have an ST-LINK, you could use the Utilities to download the current flash content, and do a postmortem analysis.

It has shown there is only one difference - earased sector #3.
Posted on May 22, 2014 at 15:57

Well I suspect if you want to replace the DFU Loader you have in 0x08000000..0x0800BFFF then you'd probably need to use the ROM based System Loader method to do that, or the app would also need a DFU module.

Also make sure if you've added code to the loader that it hasn't exceeded the 48KB allocated to it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
przemyslaw
Associate II
Posted on May 23, 2014 at 08:46

There was no DFU loader preflashed in 0x08000000..0x0800BFFF. I have flashed there ST's DFU Example customized a bit to fit my needs (DFU enter key, LEDs toggling to signal stage, APP_DEFAULT_ADD = 0x800C000). I link the main program to have origin at 0x800C000. DFU mode works fine. I am able to update the main program.

There is one ''but'' - DFU loader is not starting the main program. It gets to the Jump_To_Application(), but the main program does not start. I am trying to tackle it.

I've checked this. DFU loader has only some 12kB, so it is clearly separated from the main  program.
przemyslaw
Associate II
Posted on May 23, 2014 at 11:16

Jump to the main program is executed, but the main program hard faults. I am wondering why?

One more thing bothers me - DFU loader is located at the first 3 sectors and has it's own vector table pointing to it's own functions from those first 3 sectors. When the loader executes a jump to the main program with new IRQ service routines, vectors are still being read from the 0x8000000, right? If so, then the main program cannot work properly. Am I right?
przemyslaw
Associate II
Posted on May 26, 2014 at 15:33

I was right. To work properly the main program has to set Vector Table Offset Register (SCB->VTOR) to the main app's start origin. The easiest way is to modify

#define VECT_TAB_OFFSET

from 0x00 to, for example 0xC000 if the main program starts at 0x800C000.

The define is located in system_stm32f_xx.c.