semihost server example program
Dependencies: SWD mbed USBLocalFileSystem BaseDAP USBDAP
LPCXpresso LPC11U68 | LPCXpresso LPC1549 | FRDM-KL46Z | EA LPC4088 QSB app-board | LPC1768 app-board | LPC810 | LPC1114FN28 | |
---|---|---|---|---|---|---|---|
server | server | server | server | server | client | client | |
SWDIO | D12 | D12 | D12 | p25 | p21 | p4(P0_2) | p12 |
SWCLK | D10 | D10 | D10 | p26 | p22 | p3(P0_3) | p3 |
nRESET *option | D6 | D6 | D6 | p34 | p30 | p1(P0_5) | p23 |
GND | GND | GND | GND | p1 | p1 | p7 | p22 |
3.3V | P3V3 | P3V3 | P3V3 | p44 | p40 | p6 | p21 |
flash write | SW2(P0_1) | SW3(P1_9) | SW1 | p14 joystick center | p14 joystick center |
client example:
Import programlpc810-semihost_helloworld
semihost client example program
Diff: Flash.cpp
- 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; +}