semihost server example program

Dependencies:   SWD mbed USBLocalFileSystem BaseDAP USBDAP

/media/uploads/va009039/kl46z-lpc800-360x480.jpg

LPCXpresso
LPC11U68
LPCXpresso
LPC1549
FRDM-KL46ZEA LPC4088 QSB
app-board
LPC1768
app-board
LPC810LPC1114FN28
serverserverserverserverserverclientclient
SWDIOD12D12D12p25p21p4(P0_2)p12
SWCLKD10D10D10p26p22p3(P0_3)p3
nRESET
*option
D6D6D6p34p30p1(P0_5)p23
GNDGNDGNDGNDp1p1p7p22
3.3VP3V3P3V3P3V3p44p40p6p21
flash writeSW2(P0_1)SW3(P1_9)SW1p14
joystick
center
p14
joystick
center

client example:

Import programlpc810-semihost_helloworld

semihost client example program

Revision:
0:27d35fa263b5
Child:
2:32e9437348ad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Flash.cpp	Sun Sep 01 08:25:28 2013 +0000
@@ -0,0 +1,167 @@
+// Flash.cpp 2013/9/1
+#include "Flash.h"
+#include "Target2.h"
+#include "mydebug.h"
+
+Flash::Flash(Target2* target, Serial* usbpc) :_target(target),_pc(usbpc)
+{
+    _setup();
+}
+
+void Flash::_setup()
+{
+    _target->halt();
+    _target->wait_status(TARGET_HALTED);
+}
+
+bool Flash::write(const char* filename)
+{
+    FILE* fp = fopen(filename, "rb");
+    if (fp == NULL) {
+        _pc->printf("file open error [%s]\n", filename);
+        return false;
+    }
+    _pc->printf("Writing.");
+    uint8_t buf[256];
+    bool passed = false;
+    for(int addr = 0; addr < 0x8000; addr += sizeof(buf)) {
+        if (feof(fp)) {
+            passed = true;
+            break;
+        }
+        fread(buf, sizeof(buf), 1, fp);
+        if (!_patch(buf, sizeof(buf), addr)) {
+            break;
+        }
+        const int ram = 0x10000200;
+        if (!_write_to_ram(ram, sizeof(buf), buf)) {
+            break;
+        }
+        if (remoteIAP(IAP_CMD_PREPARE_SECTOR, _sector(addr), _sector(addr)) != IAP_CMD_SUCCESS) {
+            break;
+        }
+        if (remoteIAP(IAP_CMD_COPY_RAM_TO_FLASH, addr, ram, sizeof(buf), IAP_CCLK) != IAP_CMD_SUCCESS) {
+            break;
+        }
+        if (addr >= 512) {
+            if (remoteIAP(IAP_CMD_COMPARE, addr, ram, sizeof(buf)) != IAP_CMD_SUCCESS) {
+                break;
+            }
+        }
+        _pc->printf(".");
+    }
+    fclose(fp);
+    if (passed) {
+        _pc->printf("passed.\n");
+    }
+    return passed;
+}
+
+bool Flash::eraseAll()
+{
+    _pc->printf("Erasing.");
+    for(int sector = 0; sector <= 7; sector++) {
+        if (remoteIAP(IAP_CMD_PREPARE_SECTOR, sector, sector) != IAP_CMD_SUCCESS) {
+            return false;
+        }
+        if (remoteIAP(IAP_CMD_ERASE_SECTOR, sector, sector, IAP_CCLK) != IAP_CMD_SUCCESS) {
+            return false;
+        }
+        if (remoteIAP(IAP_CMD_BLANK_CHECK, sector, sector, IAP_CCLK) != IAP_CMD_SUCCESS) {
+            return false;
+        }
+        _pc->printf(".");
+    }
+    _pc->printf("passed.\n");
+    return true;
+}
+
+bool Flash::_write_to_ram(int addr, int size, uint8_t* buf)
+{
+    _target->writeMemory(addr, (uint32_t*)buf, size / sizeof(uint32_t));
+    return true;
+}
+
+int Flash::_sector(int addr)
+{
+    return addr / 4096;
+}
+
+bool Flash::_patch(uint8_t* buf, int size, int addr)
+{
+    const int crp_start = 0x2fc; // Code Read Protection location
+    if (crp_start >= addr && crp_start < addr+size) {
+        uint32_t pat = *reinterpret_cast<uint32_t*>(crp_start-addr+buf);
+        if (pat != 0xffffffff) { // NO_CRP ?
+            _pc->printf("\nCAUTION: CRP Pattern is not NO_CRP; %08x\n", pat);
+            return false;
+        }
+    }
+    return true;
+}
+
+uint32_t Flash::remoteIAP(uint32_t cmd, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3)
+{
+    struct {
+        uint32_t bkpt;       // +0       
+        struct {             // IAP Structure
+            uint32_t cmd;    // +4 Command
+            uint32_t par[4]; // +8 Parameters
+            uint32_t stat;   // +24 Status
+            uint32_t res[4]; // +28 Result
+        } IAP;               // +44
+    } ram; 
+    
+    ram.bkpt = 0xe00abe00;
+    ram.IAP.cmd = cmd;
+    ram.IAP.par[0] = p0;
+    ram.IAP.par[1] = p1;
+    ram.IAP.par[2] = p2;
+    ram.IAP.par[3] = p3;
+    _target->halt();
+    _target->wait_status(TARGET_HALTED);
+    const uint32_t ram_addr = 0x10000100;
+    _target->writeMemory(ram_addr, (uint32_t*)&ram, sizeof(ram)/sizeof(uint32_t));
+    _target->r0 = ram_addr + 4;
+    _target->r1 = ram_addr + 24;
+    _target->sp = 0x10001000-256;
+    _target->lr = ram_addr + 1; // return to bkpt
+    _target->pc = 0x1fff1ff1; // IAP_Call
+    _target->resume();
+    _target->wait_status(TARGET_HALTED);
+    return _target->readMemory(ram_addr + 24);
+}
+
+bool Flash::verify(const char* filename)
+{
+    FILE* fp = fopen(filename, "rb");
+    if (fp == NULL) {
+        _pc->printf("file open error [%s]\n", filename);
+        return false;
+    }
+    _pc->printf("Verifying.");
+    uint8_t buf[256];
+    bool passed = false;
+    for(int addr = 0; addr < 0x8000; addr++) {
+        int c = fgetc(fp);
+        if (c == EOF) {
+            passed = true;
+            break;
+        }
+        if ((addr % sizeof(buf)) == 0) {
+            _target->readMemory(addr, (uint32_t*)buf, sizeof(buf)/sizeof(uint32_t));
+            _pc->printf(".");
+        }
+        if (c != buf[addr % sizeof(buf)]) {
+            _pc->printf("\nError at %08x(%02x:%02x)\n", addr, c, buf[addr % sizeof(buf)]);
+            if (addr >= 512) {
+                break;
+            }
+        }
+    }
+    fclose(fp);
+    if (passed) {
+        _pc->printf("passed.\n");
+    }
+    return passed;
+}