cancel
Showing results for 
Search instead for 
Did you mean: 

Newbe to stm32, need to write a bootloader for CAN

sima
Associate II
Posted on January 21, 2010 at 03:20

Newbe to stm32, need to write a bootloader for CAN

28 REPLIES 28
st3
Associate II
Posted on May 17, 2011 at 13:05

Have you actually read AN2557 ?

sima
Associate II
Posted on May 17, 2011 at 13:05

You must remember to deactivate all your interrupts before jumping to the application.

This must be done before __set_MSP(*(__IO uint32_t*) ApplicationAddress);

[ This message was edited by: sima1 on 10-11-2009 11:53 ]

szymon_stroba
Associate II
Posted on May 17, 2011 at 13:05

I've written user application at the address 0x08002000. I've compared user application bin file and the flash memory content from addres 0x08002000 upwards and it is equal. But there is a problem when I want to jump to this application. I`m using source code from AN2557 (listed below)

#define ApplicationAddress ((uint32_t)0x08002000)

/* Test if user code is programmed starting from address ''ApplicationAddress'' */

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

{

/* Jump to user application */

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

Jump_To_Application = (pFunction) JumpAddress;

/* Initialize user application's Stack Pointer */

__set_MSP(*(__IO uint32_t*) ApplicationAddress);

Jump_To_Application();

}

and I`m getting hard fault exception while exucuting blx r3 command in disassembly code. The address in r3 register is correct, it`s the address of the user application reset handler taken from the vector table (0x08002004) and the LSB of that address is set to 1 so the instruction set is not being set to ARM. When executing this command (blx r3) while the value in r3 is the address of any instruction in the boot loader code it runs well, but when executing the command while the value in r3 is the address of any other instruction from outside the bootloader it goes to hard fault handler. In the beggining of the bootloader source code I`m executing unlock Flash command from stdperiph_library. What should I do to jump to user application?

[ This message was edited by: szymon_stroba on 10-11-2009 11:55 ]

szymon_stroba
Associate II
Posted on May 17, 2011 at 13:05

I've added

__asm volatile ('' CPSID I \n'');

instruction before initialize the stuckpointer and it's still not working.

The hard fault exeption is being thrown when executing blx r3 instruction, no jump is being done.

But __asm volatile ('' CPSID F \n''); works fine:) THX

[ This message was edited by: szymon_stroba on 10-11-2009 12:44 ]

sima
Associate II
Posted on May 17, 2011 at 13:05

I have one more suggestion. Do you initialize the Vector Table base correctly in the application?

For example:

static void NVIC_Configuration(void)

{

// Set the Vector Table base location at 0x08002000

// Base address must be a multiple of 0x100

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000);

}

szymon_stroba
Associate II
Posted on May 17, 2011 at 13:05

Yes, I`m doing two things:

a) setting the vector table with offset in flash: NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000);

b) adding an offset in linker script:

MEMORY

{

RAM (RWX) : ORIGIN = 0x20000000+0, LENGTH = 64K-0

EXTSRAM (RWX) : ORIGIN = 0x68000000, LENGTH = 0

FLASH (RX) : ORIGIN = 0x08002000, LENGTH = 504K-2K

EEMUL (RWX) : ORIGIN = 0x08000000+504k-2K, LENGTH = 2k

}

But smth still goes wrong, I`m jumping into the user application, and program stops in the first instruction in main(), I will have to spend some time analyzing it. Maybe some sugestions??:)

sima
Associate II
Posted on May 17, 2011 at 13:05

The only thing I change when compiling to a higher memory address is the FLASH origin in the *.ld file and then the Vector base in the *.c file.

In the bootloader I don't think you turned of the interrupts the right way. You must disable every interrupt separately and not just the global interrupt flag.

szymon_stroba
Associate II
Posted on May 17, 2011 at 13:05

Could You tell me:

- how to disable all interrupts including fault handlers (I tried to do it with std_PeriphLibrary 3.1.2 but with no effects). In user application I can`t make interrupts firing, and I think it`s the consequence of disabling only the global interrupt flag in bootloader. I`ve tried to deinitialize NVIC in user application but in Library 3.1.0 there is no NVIC_DeInit function.

- why when I try to jump to user application I`m getting hard fault exception??

sima
Associate II
Posted on May 17, 2011 at 13:05

Maby in your application you activate some interrupt before seting the interrupt vector table to point to the right place? Remember, the bootloader vector table base address is 0x08000000 and the application must use 0x08002000.

So, call this or similar function before using any interrupt in the application.

static void NVIC_Configuration(void)

{

// Set the Vector Table base location at 0x08002000

// Base address must be a multiple of 0x100

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000);

}

szymon_stroba
Associate II
Posted on May 17, 2011 at 13:05

It seems that I`m doing everything right. But could You tell me is there some way to disable all interrupts like NVIC_DeInit(), which used to be in StdPeriphLibrary 2.0 and in 3.1.2 is missing:(?