cancel
Showing results for 
Search instead for 
Did you mean: 

IAP-Loader and own application at 0x40002000

mge
Associate II
Posted on April 26, 2006 at 03:16

IAP-Loader and own application at 0x40002000

5 REPLIES 5
mge
Associate II
Posted on April 25, 2006 at 06:41

Hello to all,

Has anyone a working application loaded with the IAP-Loader and using

KEIL UVision and RVCT 3.0.

Until the present moment my application (using interrupts) was not working when starting the program at address 0x40002000.

Has anyone experience how to modify the startup-programs and the compilertools for running such an application. I have asked Keil for this problem, but up to now they have only modified the IAP-Driver using

with Keil UVision and RVCT3.0. (can be downloaded from Keil)

http://www.keil.com/download/docs/313.asp

needing help urgently.

thanks maenni

cgrun
Associate II
Posted on April 25, 2006 at 14:09

I've done a bootloader for the STR710, like you describe. I'll describe you all that you need to do to create your own bootloader. Actually i've done it under RVDS, but Keil use the same compiler since it's ARM company.

Basicly my bootloader is stored at 0x4000 0000, in the first sector.

This loader is start at the reset.

First it check if the program (next sectors) are ok (check for a magic number), and optionnaly if a GPIO is tied high ( to tell to stay in loader program).

1/ Relocate your program :

a) You need to adapt the scatter file like this:

PROGRAM 0x40002000

{

FLASH_INT32 0x40002000 PADVALUE 0xFFffFFff 0x3E000

{

71x_vect.o (Vect, +First)

71x_init.o (Init)

* (+RO)

}

RAM_INT32 0x20000000 0x10000

{

* (+RW)

* (+ZI)

}

}

LOADER 0x40000000

{

LOADER 0x40000000 PADVALUE 0xFFffFFff 0x02000

{

wrapper.o (Vector,+First)

loader.o

}

}

This scatter has two program :

The loader @ 0x4000 0000

The programm @ 0x4000 2000

b) The wrapper:

it is an asm part that redirect all call to the vectors to the vectors @ 0x40002000, excet for the reset handler, it call a small part of the loader to check the GPIO etc.

PRESERVE8

AREA Vector, CODE, READONLY

CODE32

ENTRY

Mode_SVC EQU 0x13

I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled

F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled

Stack_Base EQU 0x20010000

IMPORT loader_resethandler

IMPORT loader_upgrade

;*******************************************************************************

; Exception vectors

;*******************************************************************************

LDR PC, =Loader_init

LDR PC, Load_Undefined_Addr

LDR PC, Load_SWI_Addr

LDR PC, Load_Prefetch_Addr

LDR PC, Load_Abort_Addr

NOP ; Reserved vector

LDR PC, Load_IRQ_Addr

LDR PC, Load_FIQ_Addr

;*******************************************************************************

; Exception handlers address table

;*******************************************************************************

Load_Reset_Addr DCD &40002000

Load_Undefined_Addr DCD &40002004

Load_SWI_Addr DCD &40002008

Load_Prefetch_Addr DCD &4000200C

Load_Abort_Addr DCD &40002010

Load_IRQ_Addr DCD &40002018

Load_FIQ_Addr DCD &4000201C

UPGRADE DCD loader_upgrade

Loader_init

MSR CPSR_c, #Mode_SVC:OR:F_Bit:OR:I_Bit

LDR SP, =Stack_Base

; jmp to loader in 'C'

BL loader_resethandler

LDR PC,Load_Reset_Addr

END

c) The STR710 library has to be modified to be able to run @ 0x40002000:

in eic.c:

/*******************************************************************************

* Function Name : EIC_Init

* Description : Initialise the EIC using the load PC instruction

* (PC = PC +offset)

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void EIC_Init(void)

{

extern u32 T0TIMI_Addr;

u8 bCounter;

u32 dOffset=((u32)&T0TIMI_Addr);

/* Disable FIQ and IRQ interrupts */

EIC->ICR = 0x00000000;

/* Disable all channels interrupts */

EIC->IER = 0x00000000;

/* Clear all pending bits */

EIC->IPR = 0xFFFFFFFF;

/* Disable all FIQ channels interrupts and clear FIQ */

EIC->FIR = 0x0000000C;

/* channels pending bits */

/* Ste the current priority level to zero */

EIC->CIPR = 0x00000000;

// LIBLOADER (IVR is adr directly)

EIC->IVR = dOffset&0xFFff0000;

dOffset <<=16;

/* Initialize SIRn registers*/

for(bCounter=0; bCounter

{

EIC->SIR[bCounter] = dOffset;

dOffset += 0x00000004 << 16;

}

}

and in 71x_vect.s in the irq handler :

;ADD pc,r0,r1 ; Branch to the IRQ handler.

LDR r1,[R0,R1]

LDR PC,[r1]

d) write your loadder in the c file nammed loader.c

in this file for me there is two void functions :

- one named loader_resethandler which do the check for GPIO, test the magic number, and then call the update program if something wrong or, exit to let the real program boot if it is ok.

- the loader (loader_upgrade) that use an uart and our protocol to do the upgarde of the flash.

This function are restricted :

- no use of other function ( everything need to be IN this file loader.o), for example to check the GPIO you need to use directly the register of the SRT710 or create your functions but you can't share the SRT710 library with your application...

- no use of interrupt, you need to disable interrupts to be sure that you will not exit of the loader

- you need to copy manually the flash routine to ram, because the STR710 can only erase/program his bank0 if the program that write is located outside this bank...

- You need to NEVER change this first sector, if you want to be sure that the loader is present all the time.

And with this, if you want to call the loader in you application you have just to add :

((void(*)(void))*(int*)0x4000003C)();

I hope that will help you.

Sincerely

Chris.

shangdawei1
Associate II
Posted on April 26, 2006 at 03:10

Loader :

DATA (0x20000000-0x2000FFFF),

CODE (0x40000000-0x40001FFF),

CONST (0x40000000-0x40001FFF),

CODE_IRQ (0x40000000-0x40001FFF)

void main (void)

{

u8 CheckAppResult;

InitDevice();

//RXD is Break, Boot will be excuted

if ((GPIO0->PD & RX_PIN) == 0)

{

Delayms(100);

if ((GPIO0->PD & (RX_PIN)) == 0)

{

while ((GPIO0->PD & (RX_PIN)) == 0);

ExecBoot();

}

}

//Check Application

// OK -- Run Application

// Fail -- Run Boot to get new application

CheckAppResult = CheckApp();

if (!CheckAppResult)

ExecBoot();

else

ExecApp();

}

u8 Application[32768] __at 0x20000000;

void LoadApplication(void)

{

// Some Var ...........

while(1)

{

GetChar(&AByte, 0xffffffff);

PutChar(AByte);

ByteCount = AByte;

GetChar(&AByte, 0xffffffff);

PutChar(AByte);

ByteCount += (((u16)AByte) << 8);

CS = 0;

for (i=0;i

{

GetChar(&AByte, 0xffffffff);

PutChar(AByte);

Application[i] = AByte;

CS += AByte;

}

GetChar(&AByte, 0xffffffff);

if (CS != AByte)

{

PutChar(0xAA);

continue;

}

PutChar(0x55);

break;

}

}

void RunApplication(void) __arm

{

EIC_IRQConfig(DISABLE);

EIC_FIQConfig( DISABLE );

__asm

{

MOV R1, #0x02

LDR R0, =0xA0000050

LDRH R2, [R0]

BIC R2, R2, #0x03

ORR R2, R2, R1

STRH R2, [R0]

MOV PC, #0

}

}

//Download code to RAM, run code from RAM to program Flash

// and something ...

void ExecBoot(void)

{

InitUART(115200, UART_NO_PARITY, UART_1_StopBits, UARTM_8D);

WaitPassword();

LoadApplication();

RunApplication();

while(1);

}

//Application is OK

//Copy Application IVT to 0x20000000

//Remap RAM to 0x00000000

//PC = 0x00000000

void ExecApp(void) __arm

{

EIC_IRQConfig(DISABLE);

EIC_FIQConfig( DISABLE );

__asm

{

LDR R0, =0x40002000

LDR R1, =0x20000000

LDMIA R0!, {R4-R11}

STMIA R1!, {R4-R11}

LDMIA R0!, {R4-R11}

STMIA R1!, {R4-R11}

MOV R1, #0x02

LDR R0, =0xA0000050

LDRH R2, [R0]

BIC R2, R2, #0x03

ORR R2, R2, R1

STRH R2, [R0]

MOV PC, #0

}

}

shangdawei1
Associate II
Posted on April 26, 2006 at 03:14

Application :

DATA (0x20000040-0x2000FFFF),

CODE (0x40002000-0x4003FFFF),

CONST (0x40002000-0x4003FFFF),

CONST (0x400C0000-0x400C3FFF),

CODE_IRQ (0x40002000-0x4000FFFF)

STARTUPCODE (0x40002000)

Flash Bank0 : as Code

Flash Bank1 : as Data/Const

RAM : 0x20000000..0x2000003F : Boot will copy Applicaton's IVT to here

void main (void)

{

InitDevice();

while(1)

{

}

}

shangdawei1
Associate II
Posted on April 26, 2006 at 03:16

Contact me :

MSN/GoogleTalk/email : shangdawei%gmail.com

[ This message was edited by: shangdawei on 27-04-2006 14:57 ]