cancel
Showing results for 
Search instead for 
Did you mean: 

I am booting from bank 1 but program code is in the bank 0

vaclav2
Associate II
Posted on April 03, 2008 at 17:10

I am booting from bank 1 but program code is in the bank 0

14 REPLIES 14
enricol
Associate II
Posted on May 17, 2011 at 09:36

Hi,

I tried to port the IAP project supplied by ST (for IAR) into RIDE7 environment. But I did it without any success. I couldn't even build the project. I believe both my linker and startup script are not correct. Can you please post or send me a complete IAP project configured under RIDE7? Thanks alot!

Regards,

Enrico

jmullens
Associate II
Posted on May 17, 2011 at 09:36

I’ve been trying for some time to start from a bios routine in bank1 and jump to an application in bank0. It has been my experience that there are many ways to get this wrong, and I’m interested in a discussion in what other people may have tried. Has anyone actually got bank switching working?

There are a lot of ways to get this wrong, even if the actual code snippet to jump banks is correct.

I assume the mapping should be [0,6,0x80000,0] //for

[bootsize,nonbootsize,(bootbank_address >> 2),(nonbootbank_address>>2)]

I also assume that the linker file should be DROMSTART=0x80000, DROMEND=0xFFFFF.

But, should there be any additional changes made to the 91x_init.s initialization code, or the “Remap_Bank1�? flag?

I have tried a lot of permutations, and all of them have failed.

Perhaps even if I configured this second project properly, there may be other, more insidious issues associated with this specific chip, like an interrupt happening at the same time as the processor jumps, or that some registers need to be cleared.

would something like this be helpful?

//Interrupt Enable Clear Register 1 (VIC1_INTECR):

*(vu32 *)(0xFC000014) = 0xFFFFFFFF;

//Interrupt Enable Clear Register 0 (VIC0_INTECR):

*(vu32 *)(0xFFFFF014) = 0xFFFFFFFF;

// init current processor status to avoid interrupts.

//*(vu32 *)(cpsr) = 0x000000D3;

What is the address of cpsr?

What other registers might I need to clear? This is the only processor I’ve seen where resetting the processor is not the same as power cycling it, and makes me wonder about missing configuration settings or pitfalls I can run into when switching banks.

I’m using the IAR EW4.41A compiler, and am using HiTop for my debugger, and am using the STR912FAW44.

Some mentionable permutations:

I thought one reasonable choice was to load in a program in bank0, that was configured to boot from bank0, and a program in bank1 that was configured to boot from bank1. If I use the JLinkSTR91x.exe program to change the state of the CSx register, I could get each of the applications running after I power cycled the board. But I could not remap the flash, and jump to the application in bank0.

I also tried commenting out the 91x_init.s code for the 0x54000000-0x54000010 registers, and uncommenting Remap_Bank_1 in 91x_fmi.h.

I’ve also tried an assortment of linker address, from 0x0-0x7FFFF,0x80000-0xFFFFF, and 0x8000-0x87FFF; all to no avail.

Backtracking a bit, I tried to jump somewhere other than 0x0 to see if this function worked. Looking up the addresses in the map file of my bios code and my application code, I was able to execute functions in bank1, but I’d get a fatal exceptions when trying to run a function in the other bank. I was somehow wondering if I should be trying to call the address of the other main() routine rather than run through a second initialization.

Here is my test routine I’ve been using to experiment with bank-switching, and jumping to other function addresses other than 0x0:

I’ve been doing this so I don’t have to keep reinstalling the bios routine when I reconfigure the application program.

typedef void (*pfunc)(void);

/* bbs = boot bank size,nbbs = non boot bank size,

bbadr = boot bank address, nbbadr = non boot bank address

jump2app = a flag to enable me to jump to a function address

jump2Addr = address of the function I wish to jump to. */

__ramfunc void switchBank(unsigned char bbs,unsigned char nbbs,

unsigned int bbadr,unsigned int nbbadr,

unsigned char jump2app,

unsigned int jump2Addr)

{

pfunc Jump_To_Application;

FMI->BBSR = bbs;

FMI->NBBSR = nbbs;

FMI->BBADR = bbadr >> 2;

FMI->NBBADR = nbbadr >> 2 ;

FMI->CR |= 0x18; /* Enable banks 0 & 1 */

Jump_To_Application = (pfunc) jump2Addr;

if(jump2app) Jump_To_Application();

}

pm9341
Associate II
Posted on May 17, 2011 at 09:36

Quote:

@jmullens:

I thought one reasonable choice was to load in a program in bank0, that was configured to boot from bank0, and a program in bank1 that was configured to boot from bank1. If I use the JLinkSTR91x.exe program to change the state of the CSx register, I could get each of the applications running after I power cycled the board. But I could not remap the flash, and jump to the application in bank0.

I have the same issues here, if i change CSx register (JLinkSTR91x.exe) then the bootloader and the application run for it self. But with bootloader remap and jump cant get application runing.

jmullens
Associate II
Posted on May 17, 2011 at 09:36

I figured out how to jump from bank1 to bank0:

typedef void (*pFunction)(void);

__ramfunc void Execute_STR9Application(void)

{

pFunction Jump_To_Application;

/* Disable the prefetch-queue and the Branch-cache for the Flash.

When remapping the flash, there might be some instructions that are still in the queue, and need to be flushed out, or else I might be trying to access an invalid flash address. Without this, there is a chance that I may get a fatal exception */

SCU_PFQBCCmd(DISABLE);

/* Disable all of the registers in the vector-interrupt controller. An interrupt might happen right before I jump to the other bank, and may try to access an invalid flash address, and crash. */

SCU_AHBPeriphReset(__VIC, ENABLE); /* VIC peripheral is under Reset (disables all interrupts)*/

/* prepare bank0 for user operation */

FMI->BBSR = 0;

FMI->NBBSR = 6;

FMI->BBADR = 0x20000; //0x80000 >> 2

FMI->NBBADR = 0x0;

FMI->CR |= 0x18; /* Enable banks 0 & 1 */

Jump_To_Application = (pFunction) BANK0_START_ADDR;

Jump_To_Application();

}

Please note, in the application you wish to jump to, you'll need to change the FMI registers in 91x_init.s . You'll also need to make sure that ''#define Remap_Bank_1'' is uncommented in 91x_fmi.h, and you must also make sure that FMI_Config is put in SRAM (via __ramfunc with the IAR compiler)

LDR R6, =0x54000000

LDR R7, =0x0

STR R7, [R6]

LDR R6, =0x54000004 ; non boot bank size

LDR R7, =0x6 ; 512K

STR R7, [R6]

LDR R6, =0x5400000C ; boot bank address = Bank 1

LDR R7, =0x20000

STR R7, [R6]

LDR R6, =0x54000010 ; non boot bank address = Bank 0

LDR R7, =0x0

STR R7, [R6]

LDR R6, =0x54000018 ; enable Non Boot bank

LDR R7, =0x18

STR R7, [R6]

Please note:

When booting from bank 1, and jumping to bank 0, and soft-resetting the processor will hang the processor. I will need to change my exception handler to deal with this..

pm9341
Associate II
Posted on May 17, 2011 at 09:36

So I am a step forward. 🙂

I found out that my bootloader remaps the flash and jumps OK.

__ramfunc void jump(void)

{

LDR R0, =0x54000000

LDR R1, =0x0 //32k

STR R1, [R0]

LDR R0, =0x54000004

LDR R1, =0x6 //512k

STR R1, [R0]

LDR R0, =0x5400000C

LDR R1, =0x20000 //80000>>2

STR R1, [R0]

LDR R0, =0x54000010

LDR R1, =0x0

STR R1, [R0]

LDR R0, =0x54000018

LDR R1, =0x18

STR R1, [R0]

LDR pc, =0x0

NOP

NOP

NOP

NOP

NOP

NOP

}

My error was that I built my application code as it was for BB0. This is wrong!!!

To run the application, you most make sure that your application startup_code.s doesn’t rewrite the upper FMI register values that are set from the bootloader.

So my concept is: debug APP with BB0 setup, release APP as in bootloader jump function.

So I have edited my application startup code like this:

#ifdef DEBUG

//must set microcontroler to boot from bank0(512k) for application debug

LDR R0, =0x54000000

LDR R1, =0x4 //512k

STR R1, [R0]

LDR R0, =0x54000004

LDR R1, =0x2 //32k

STR R1, [R0]

LDR R0, =0x5400000C

LDR R1, =0x0

STR R1, [R0]

LDR R0, =0x54000010

LDR R1, =0x20000

STR R1, [R0]

LDR R0, =0x54000018

LDR R1, =0x18

STR R1, [R0]

#else

//must set microcontroler to boot from bank1(32k)

//this is set so it can execute after bootloader flash remap and pc=0 jump

LDR R0, =0x54000000

LDR R1, =0x0 //32k

STR R1, [R0]

LDR R0, =0x54000004

LDR R1, =0x6 //512

STR R1, [R0]

LDR R0, =0x5400000C

LDR R1, =0x20000

STR R1, [R0]

LDR R0, =0x54000010

LDR R1, =0x0

STR R1, [R0]

LDR R0, =0x54000018

LDR R1, =0x18

STR R1, [R0]

#endif

Hope this helps someone.

My LED blink example works fine for now.