cancel
Showing results for 
Search instead for 
Did you mean: 

str912 bootloader with KEIL tools - one more time

mikhailm
Associate II
Posted on July 02, 2008 at 09:23

str912 bootloader with KEIL tools - one more time

18 REPLIES 18
jjacobsen
Associate II
Posted on May 17, 2011 at 09:51

I am not sure what you are doing wrong but I am using Keil tools and able to do the IAP bank load. If you haven't already, check out Keil's Blinky-B0B1 example, all of it, to sucessfully boot from bank1 or bank0. Did you set the bank0 #define in the ST FMI library functions and rebuild that library? Make sure you're changing the 91x_fmi.h file that gets used in the library. I don't use IRAM2 so I don't know what you are doing with it. I only use IRAM1, IROM1 and IROM2.

I have documented all this for my own sake. Below is what I wrote about the bootloader, it is specific to my project, called Gap, but if it helps, here goes. I use the Keil startup file. I use the ST lib functions as little as possible. A lot of this is specific to the Keil IDE.

The Gap Bootloader Application:

• IROM1 is 32K, starting at 0, default

• IROM2 is 512K, starting at 0x40.0000

• So the code is built in one continuous chunk of code starting at address 0.

• This code uses bank1 as the boot bank. Set the CFG bit in STR91xCFG.s, it’s the only thing set.

• In STR91x.s, FMI is checked. The boot bank is enabled at 32K starting at 0. The non-boot bank is enabled at 512K starting at 0x40.0000.

• Add define for ‘BOOT_BANK1’ in the ASM options. This gets referenced in STR91x.s (See the file in the Blinky-B0B1 example – need all banking/fmi related code in this file).

• In the Flash Download Setup, check ‘erase sectors’ and ‘program’. For the algorithms, use Flash Bank1 ICP/ 32K/ starting at 0, and CFG and Security ICP/ 16/ starting at 520000H. By doing this, every flash download sets the CFG bit for boot bank1 so you can switch between this code and code that runs with boot bank0.

• In the Download Options for Debug Settings, do not verify code download.

• The bootloader code does a checksum over bank0 code (plus the trailing checksum), starting at 0x40.0000. It gets the code size at 0x40.0020. (Application code was built with code size at 0x20).

• To write to the flash in bank0, used ST’s library, functions from 91x_fmi.c. Used a local copy of 91x_fmi.h to set the #define for bank1 mapping. (Code below is from ST’s IAP UART example. All config/init was done via Keil’s STR91x.s, a la Blinky-B0B1, not from the ST example).

FMI_WriteProtectionCmd(FMI_B0S0, DISABLE);

FMI_WriteProtectionCmd(FMI_B0S1, DISABLE);

FMI_WriteProtectionCmd(FMI_B0S2, DISABLE);

FMI_WriteProtectionCmd(FMI_B0S3, DISABLE);

FMI_WriteProtectionCmd(FMI_B0S4, DISABLE);

FMI_WriteProtectionCmd(FMI_B0S5, DISABLE);

FMI_WriteProtectionCmd(FMI_B0S6, DISABLE);

FMI_WriteProtectionCmd(FMI_B0S7, DISABLE);

FMI_EraseBank(FMI_BANK_0);

FMI_WaitForLastOperation(FMI_BANK_0);

// in a loop, writing 2 bytes at a time, updating Ram_Source, do this

// write to flash, read back to verify write

FMI_WriteHalfWord(Flash_Destination, *(u16*)Ram_Source);

FMI_WaitForLastOperation(FMI_BANK_0);

if (*(u16*)Flash_Destination != *(u16*)Ram_Source) {

// verify failure, quit

}

Flash_Destination += 2;

• To execute code in bank0, remap and jump to 0. This function is in a separate file assigned to IRAM1. That means it gets copied to ram and executed from there. The compiler and linker take care of this, just put it in IRAM1. This function must also be executed as a software interrupt in order to set the processor back to Supervisor mode. It needs to be in Supervisor mode to begin executing the application code as if the application code had started from reset. The application code’s STR91x.s does stuff, like setting stacks for other processor modes, which require the processor to be in Supervisor mode. If the SWI were not done (as in the ST IAP UART example), the processor would be starting the application code in User mode and some of the init’ing would not work. Code below:

#include

typedef void (*pFunction)(void);

void __swi(8) ExecuteApp (void);

void __SWI_8 (void) {

pFunction JumpTo;

// before change mapping, disable all VIC ints

VIC0->INTER = 0;

VIC1->INTER = 0;

// if PFQ and BC are not disabled, then do this

//SCU_PFQBCCmd(DISABLE);

// Change mapping:

// bank1 (32K) starting addr 0 -> 0x40.0000

// bank0 (512K) starting addr 0x40.0000 -> 0

// Bank1 is still the boot bank, this does not change.

FMI->BBADR = 0x400000 >> 2; // first

FMI->NBBADR = 0x0 ;

// Jump to the user application and execute it

JumpTo = (pFunction) 0x00;

JumpTo();

}

• File SWI_Table.s is added to the project and SWI number 8 is enabled in this file. (Keil help explained all this).

mikhailm
Associate II
Posted on May 17, 2011 at 09:51

As you may guess I am getting very frustrated with attempts to write bootloader for the STR912 chip.

Here is what I got:

I THINK that I am booting from the bank 1

Here is my settings:

Using all settings from

http://www.keil.com/support/docs/3347.htm

Now to the RAM setup (I THINK this is needed for loading bootloader functions to RAM)

IRAM1 0x4000000 size 0x7FFF

IRAM2 (checked) 0x4008000 size 0x10000

Code Generation: ARM Mode

Program seems to start and run just fine

Now to ST library configuration

One thing is changed in 91xfmi.h

#define Remap_Bank_1 is uncommented

91x_fmi.c is placed to IRAM1 and file that calls functions in 91xfmi also placed to IRAM1

PROBLEM:

Call to FMI_EraseSector is with parameter 0x00400000. OK

Execution of the FIRST line

*(vu16 *)FMI_Sector = 0x20;

corrupts ENTIRE memory starting from address 0x00 and all the way through

call to

FMI_WaitForLastOperation

never returns, stuck in

LDR PC, Undef_Addr

undev Vectors - not surprising - context of the memory is gone!

this is the code

 

SCU_AHBPeriphClockConfig(__FMI, ENABLE);

 

SCU_AHBPeriphReset(__FMI, DISABLE);

 

 

 

FMI_WriteProtectionCmd(FMI_B0S0, DISABLE);

 

FMI_EraseSector(FMI_B0S0);

 

FMI_Timeout_Status = FMI_WaitForLastOperation(FMI_BANK_0);

 

It appears that memory is erased, in bank 1! Program doesnt come back after power down â€'' have to reprogram the flash.

Any help?

Thank you

jjacobsen
Associate II
Posted on May 17, 2011 at 09:51

Correction: in the 91x_fmi.h file set the #define for bank1, it's normally set for bank0.

mikhailm
Associate II
Posted on May 17, 2011 at 09:51

I do set

#define Boot_Bank_1

in my LOCAL copy of 91x_fmi.h and verified that it is indeed the copy am using.

So obviously I am doing something wrong...... Do you mind sending bare-bones Keil project, so at least I won't worry about the settings?

mikhailm
Associate II
Posted on May 17, 2011 at 09:51

Thank YOU!

I think I got it. Just one more quick question

When I import SWI_Table.s and try to compile I get messages that _SWI_0 throug _SWI_7 is undefined.

That is of cause because I don't use RTL. and have no plans of using it in bootloader section.

what is your suggestion : use __SWI_0? or just provide dummy entrances for __SWI_0 through SWI_7 ?

jjacobsen
Associate II
Posted on May 17, 2011 at 09:51

Hope you caught the error disabling the VIC ints. The code should be

VIC0->INTECR = 0xff;

VIC1->INTECR = 0xff;

Another issue: In Keil's str91x.s the flash config register is set by writing to Bank1. This is ok from reset/powerup but if you restart this code by jumping to 0, and this is done while executing from Bank1, and you have changed the default wait states, it will fail. To fix, execute this code from ram. I removed this code from the startup file, created another file for ram-executed code, and did the flash config there. Basically, I used ST's FMI_Config function, only with just the writes to the flash config register.

When jumping to zero, watch the peripherals to make sure they restart ok. It would be nice to use the WDOG timer to force a reset with reset'ed registers but it doesn't preserve the FMI banking registers.

jjacobsen
Associate II
Posted on May 17, 2011 at 09:51

If it helps anyone, here's my complete documentation on how to do the code banking-bootloader-IAP stuff in .doc and .rtf formats. The code has been running fine for a while so I think I got it all. It is specific to my project. IAP updates by the end user are done via USB but not using the USB on the STR9. To the CPU it's just a serial interface.

mbalvert
Associate II
Posted on May 17, 2011 at 09:51

Hello,

I'm also trying to boot from bank1 and then try to jump to another application in bank0. I followed the steps mentioned above, but i can't get it to work. My question is how do you create an application for bank0? Do you also insert a startup file. And in Keil, what memory settings must be used for this bank0 application. Do you need to remap the banks? I'm able to run both applications just by toggling the CSX bit. But i still can't jump.

JJ, can i also get a copy of your uVision project? Because i'm stuck here.

Any help would be great, thank you.

MiesJah

jjacobsen
Associate II
Posted on May 17, 2011 at 09:51

And, here's the stripped down project files referenced in my documentation along with a few relevant config files. You should be able to see the project settings in here. Please keep in mind that there are probably lots of ways to do all this, I just found a way that works and stuck with it.