Skip to main content
Visitor II
April 26, 2006
Question

IAP-Loader and own application at 0x40002000

  • April 26, 2006
  • 5 replies
  • 1264 views
Posted on April 26, 2006 at 03:16

IAP-Loader and own application at 0x40002000

    This topic has been closed for replies.

    5 replies

    mgeAuthor
    Visitor II
    April 25, 2006
    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

    Visitor II
    April 25, 2006
    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.

    Visitor II
    April 26, 2006
    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

    }

    }

    Visitor II
    April 26, 2006
    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)

    {

    }

    }

    Visitor II
    April 26, 2006
    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 ]