dynamic load and run users binary file. self write the flash memory.

Dependencies:   mbed

main.cpp

Committer:
okini3939
Date:
2011-12-27
Revision:
3:5cf31386b95d
Parent:
2:c56b5e682f0c

File content as of revision 3:5cf31386b95d:

/*
  dynamic load the binary file.
    binary -> Flash 0x00040000 & run

  lpc17xx.ld
        IROM (rx) : ORIGIN = 0x00040000, LENGTH = 256k
        IRAM0 (rwx) : ORIGIN = 0x10002000, LENGTH = 24k

  startup_LPC17xx.c
        //void Reset_Handler(void) __attribute__((__interrupt__));
        void Reset_Handler(void);
        //    SystemInit();

  compiled.bin --> test.dat
*/
#include "mbed.h"
#include "IAP.h"
#include <new>

#define BUF_SIZE        512
#define TARGET_SECTOR    22
#define TARGET_SECTOR_NUM 8

LocalFileSystem local("local");

void    memdump( char *p, int n );

IAP     iap;

extern "C"
void HardFault_Handler() {
    register unsigned int _msp __asm("msp");
    printf("Hard Fault! %x (%x)\r\n", SCB->HFSR, *((unsigned int *)(_msp + 24)));
    printf(" - %x\r\n", (*(volatile uint32_t*)0xe000ed24));
//    printf("Hard Fault! %x\r\n", SCB->HFSR);
    exit(-1);
}

void no_memory () {
    printf("panic: can't allocate to memory!\r\n");
    exit(-1);
}

void jump (int vect) {
    void (*func)();
    unsigned int *p;

    p = (unsigned int *)(sector_start_adress[TARGET_SECTOR] + 4 * vect);
    func = (void (*)())*p;
//    printf("jump vector %d (%08x)\r\n", vect, func);
    if ((char*)*p >= sector_start_adress[TARGET_SECTOR] && (char*)*p < sector_start_adress[TARGET_SECTOR] + FLASH_SECTOR_SIZE_16_TO_29 * TARGET_SECTOR_NUM) {
        func();
    }
}

int loadbinary (char *filename) {
    int i, r, num, sector, size = 0;
    FILE *fp;
    char buf[BUF_SIZE];
    
    fp = fopen(filename, "r");
    if (! fp) return -1;

    for (sector = TARGET_SECTOR; sector < TARGET_SECTOR + TARGET_SECTOR_NUM; sector ++) {
        if (iap.blank_check(sector, sector) == SECTOR_NOT_BLANK) {
            iap.prepare(sector, sector);
            r = iap.erase(sector, sector);
            if (r) {
                printf("iap.erase (%d) %d %x\r\n", r, sector, i);
                goto error;
            }
            printf("iap erase %d\r\n", sector);
        }

        for (i = 0; i < FLASH_SECTOR_SIZE_16_TO_29; i += BUF_SIZE) {
            num = fread(buf, sizeof(char), BUF_SIZE, fp);
            if (num <= 0) {
                // EOF
                goto exit;
            }
            
            // write Flash
            r = iap.prepare(sector, sector);
            if (r) {
                printf("iap.prepare (%d) %d %x\r\n", r, sector, i);
                goto error;
            }
            r = iap.write(buf, sector_start_adress[sector] + i, BUF_SIZE);
            if (r) {
                printf("iap.write (%d) %d %x\r\n", r, sector, i);
                goto error;
            }
            r = iap.compare(buf, sector_start_adress[sector] + i, BUF_SIZE);
            if (r) {
                printf("iap.compare (%d) %d %x\r\n", r, sector, i);
                goto error;
            }
            size += num;
        }
    }

exit:
    printf("write %d bytes, end sector %d\r\n", size, sector);
    fclose(fp);
    return 0;

error:
    printf("write error\r\n");
    fclose(fp);
    return r;
}

int main() {
    char *heap;

    set_new_handler(no_memory); // new handler function

    printf( "device-ID = 0x%08X, serial# = 0x%08X, CPU running %dkHz\r\n", iap.read_ID(), iap.read_serial(), SystemCoreClock / 1000 );

    if (loadbinary("/local/test.dat")) {
        printf("error loadbinary\r\n");
        return -1;
    }

//    memdump( sector_start_adress[ TARGET_SECTOR ], 48 * 4);

    heap = new char(2);
    delete[] heap;
    printf("stack %08x, heap %08x\r\n", (unsigned int)&heap, (unsigned int)heap);

    {
        register unsigned int _control __asm("control");
        register unsigned int _msp __asm("msp");
        register unsigned int _psp __asm("psp");
        printf("MSP %08x, PSP %08x, CONTROL %x\r\n", _msp, _psp, _control & 3);
    }
    
    jump(1);

    printf("exit\r\n");

    heap = new char(2);
    delete[] heap;
    printf("stack %08x, heap %08x\r\n", (unsigned int)&heap, (unsigned int)heap);

    return 0;
}


void memdump( char *base, int n ) {
    unsigned int    *p;

    printf( "  memdump from 0x%08X for %d bytes", (unsigned long)base, n );

    p   = (unsigned int *)((unsigned int)base & ~(unsigned int)0x3);

    for ( int i = 0; i < (n >> 2); i++, p++ ) {
        if ( !(i % 4) )
            printf( "\r\n  0x%08X :", (unsigned int)p );

        printf( " %08X", *p );
    }

    printf( "\r\n" );
}