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

Committer:
va009039
Date:
Sat Sep 14 12:55:29 2013 +0000
Revision:
5:2774358f5e4f
Parent:
4:5e4107edcbdb
Child:
6:5da6ad51a18f
deleted the code to access the data of unalignment.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 4:5e4107edcbdb 1 // Flash.cpp 2013/9/11
va009039 0:27d35fa263b5 2 #include "Flash.h"
va009039 0:27d35fa263b5 3 #include "Target2.h"
va009039 0:27d35fa263b5 4 #include "mydebug.h"
va009039 0:27d35fa263b5 5
va009039 3:d7a7cde0bfb8 6 #define SYSMEMREMAP 0x40048000
va009039 3:d7a7cde0bfb8 7 #define MAINCLKSEL 0x40048070
va009039 3:d7a7cde0bfb8 8 #define MAINCLKUEN 0x40048074
va009039 3:d7a7cde0bfb8 9 #define SYSAHBCLKDIV 0x40048078
va009039 3:d7a7cde0bfb8 10
va009039 0:27d35fa263b5 11 Flash::Flash(Target2* target, Serial* usbpc) :_target(target),_pc(usbpc)
va009039 0:27d35fa263b5 12 {
va009039 0:27d35fa263b5 13 _setup();
va009039 0:27d35fa263b5 14 }
va009039 0:27d35fa263b5 15
va009039 0:27d35fa263b5 16 void Flash::_setup()
va009039 0:27d35fa263b5 17 {
va009039 0:27d35fa263b5 18 _target->halt();
va009039 0:27d35fa263b5 19 _target->wait_status(TARGET_HALTED);
va009039 4:5e4107edcbdb 20 _target->prog_status();
va009039 0:27d35fa263b5 21 }
va009039 0:27d35fa263b5 22
va009039 3:d7a7cde0bfb8 23 bool Flash::init()
va009039 3:d7a7cde0bfb8 24 {
va009039 3:d7a7cde0bfb8 25 _pc->printf("Initializing.");
va009039 3:d7a7cde0bfb8 26 if (_target->idcode == 0x0bb11477) { // LPC1114FN28
va009039 3:d7a7cde0bfb8 27 _target->writeMemory(MAINCLKSEL, 0); // Select Internal RC Oscillator
va009039 3:d7a7cde0bfb8 28 _target->writeMemory(MAINCLKUEN, 1); // Update Main Clock Source
va009039 3:d7a7cde0bfb8 29 _target->writeMemory(MAINCLKUEN, 0); // Toggle Update Register
va009039 3:d7a7cde0bfb8 30 _target->writeMemory(MAINCLKUEN, 1);
va009039 3:d7a7cde0bfb8 31 uint32_t data = _target->readMemory(MAINCLKUEN); // Wait until updated
va009039 3:d7a7cde0bfb8 32 if (!(data & 1)) {
va009039 3:d7a7cde0bfb8 33 _pc->printf("\nerror MAINCLKUEN=%08x\n", data);
va009039 3:d7a7cde0bfb8 34 return false;
va009039 3:d7a7cde0bfb8 35 }
va009039 3:d7a7cde0bfb8 36 _target->writeMemory(SYSAHBCLKDIV, 1);// Set Main Clock divider to 1
va009039 3:d7a7cde0bfb8 37 _target->writeMemory(SYSMEMREMAP, 2); // User Flash Mode
va009039 3:d7a7cde0bfb8 38 } else {
va009039 3:d7a7cde0bfb8 39 _pc->printf("\nerror idcode=%08x\n", _target->idcode);
va009039 3:d7a7cde0bfb8 40 return false;
va009039 3:d7a7cde0bfb8 41 }
va009039 3:d7a7cde0bfb8 42 _pc->printf("passed.\n");
va009039 3:d7a7cde0bfb8 43 return true;
va009039 3:d7a7cde0bfb8 44 }
va009039 3:d7a7cde0bfb8 45
va009039 0:27d35fa263b5 46 bool Flash::write(const char* filename)
va009039 0:27d35fa263b5 47 {
va009039 0:27d35fa263b5 48 FILE* fp = fopen(filename, "rb");
va009039 0:27d35fa263b5 49 if (fp == NULL) {
va009039 0:27d35fa263b5 50 _pc->printf("file open error [%s]\n", filename);
va009039 0:27d35fa263b5 51 return false;
va009039 0:27d35fa263b5 52 }
va009039 0:27d35fa263b5 53 _pc->printf("Writing.");
va009039 0:27d35fa263b5 54 uint8_t buf[256];
va009039 0:27d35fa263b5 55 bool passed = false;
va009039 0:27d35fa263b5 56 for(int addr = 0; addr < 0x8000; addr += sizeof(buf)) {
va009039 3:d7a7cde0bfb8 57 int ret = fread(buf, 1, sizeof(buf), fp);
va009039 0:27d35fa263b5 58 if (!_patch(buf, sizeof(buf), addr)) {
va009039 0:27d35fa263b5 59 break;
va009039 0:27d35fa263b5 60 }
va009039 0:27d35fa263b5 61 const int ram = 0x10000200;
va009039 0:27d35fa263b5 62 if (!_write_to_ram(ram, sizeof(buf), buf)) {
va009039 0:27d35fa263b5 63 break;
va009039 0:27d35fa263b5 64 }
va009039 2:32e9437348ad 65 if (remoteIAP(PREPARE_SECTOR, _sector(addr), _sector(addr)) != CMD_SUCCESS) {
va009039 2:32e9437348ad 66 _pc->printf("faild. PREPARE_SECTOR %d %d\n", _sector(addr), _sector(addr));
va009039 0:27d35fa263b5 67 break;
va009039 0:27d35fa263b5 68 }
va009039 2:32e9437348ad 69 if (remoteIAP(COPY_RAM_TO_FLASH, addr, ram, sizeof(buf), IAP_CCLK) != CMD_SUCCESS) {
va009039 2:32e9437348ad 70 _pc->printf("faild. COPY_RAM_TO_FLASH %d %d %d %dn", addr, ram, sizeof(buf));
va009039 0:27d35fa263b5 71 break;
va009039 0:27d35fa263b5 72 }
va009039 4:5e4107edcbdb 73 if (remoteIAP(COMPARE, addr, ram, sizeof(buf)) != CMD_SUCCESS) {
va009039 4:5e4107edcbdb 74 _pc->printf("faild. COMPARE %d %d %d", addr, ram, sizeof(buf));
va009039 4:5e4107edcbdb 75 break;
va009039 0:27d35fa263b5 76 }
va009039 0:27d35fa263b5 77 _pc->printf(".");
va009039 3:d7a7cde0bfb8 78 if (ret < sizeof(buf)) {
va009039 3:d7a7cde0bfb8 79 passed = true;
va009039 3:d7a7cde0bfb8 80 break;
va009039 3:d7a7cde0bfb8 81 }
va009039 0:27d35fa263b5 82 }
va009039 0:27d35fa263b5 83 fclose(fp);
va009039 0:27d35fa263b5 84 if (passed) {
va009039 0:27d35fa263b5 85 _pc->printf("passed.\n");
va009039 0:27d35fa263b5 86 }
va009039 0:27d35fa263b5 87 return passed;
va009039 0:27d35fa263b5 88 }
va009039 0:27d35fa263b5 89
va009039 0:27d35fa263b5 90 bool Flash::eraseAll()
va009039 0:27d35fa263b5 91 {
va009039 0:27d35fa263b5 92 _pc->printf("Erasing.");
va009039 0:27d35fa263b5 93 for(int sector = 0; sector <= 7; sector++) {
va009039 2:32e9437348ad 94 IAP_STATUS status = remoteIAP(PREPARE_SECTOR, sector, sector);
va009039 2:32e9437348ad 95 if (status != CMD_SUCCESS) {
va009039 2:32e9437348ad 96 _pc->printf("faild. PREPARE_SECTOR %d %d status=%d\n", sector, sector, status);
va009039 0:27d35fa263b5 97 return false;
va009039 0:27d35fa263b5 98 }
va009039 2:32e9437348ad 99 if (remoteIAP(ERASE_SECTOR, sector, sector, IAP_CCLK) != CMD_SUCCESS) {
va009039 2:32e9437348ad 100 _pc->printf("faild. ERASE_SECTOR %d %d %d\n", sector, sector, IAP_CCLK);
va009039 0:27d35fa263b5 101 return false;
va009039 0:27d35fa263b5 102 }
va009039 2:32e9437348ad 103 if (remoteIAP(BLANK_CHECK, sector, sector, IAP_CCLK) != CMD_SUCCESS) {
va009039 2:32e9437348ad 104 _pc->printf("faild. BLANK_CHECK %d %d %d\n", sector, sector, IAP_CCLK);
va009039 0:27d35fa263b5 105 return false;
va009039 0:27d35fa263b5 106 }
va009039 0:27d35fa263b5 107 _pc->printf(".");
va009039 0:27d35fa263b5 108 }
va009039 0:27d35fa263b5 109 _pc->printf("passed.\n");
va009039 0:27d35fa263b5 110 return true;
va009039 0:27d35fa263b5 111 }
va009039 0:27d35fa263b5 112
va009039 0:27d35fa263b5 113 bool Flash::_write_to_ram(int addr, int size, uint8_t* buf)
va009039 0:27d35fa263b5 114 {
va009039 0:27d35fa263b5 115 _target->writeMemory(addr, (uint32_t*)buf, size / sizeof(uint32_t));
va009039 0:27d35fa263b5 116 return true;
va009039 0:27d35fa263b5 117 }
va009039 0:27d35fa263b5 118
va009039 0:27d35fa263b5 119 int Flash::_sector(int addr)
va009039 0:27d35fa263b5 120 {
va009039 0:27d35fa263b5 121 return addr / 4096;
va009039 0:27d35fa263b5 122 }
va009039 0:27d35fa263b5 123
va009039 5:2774358f5e4f 124 static uint32_t LD32(uint8_t* buf)
va009039 5:2774358f5e4f 125 {
va009039 5:2774358f5e4f 126 return buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24;
va009039 5:2774358f5e4f 127 }
va009039 5:2774358f5e4f 128
va009039 0:27d35fa263b5 129 bool Flash::_patch(uint8_t* buf, int size, int addr)
va009039 0:27d35fa263b5 130 {
va009039 0:27d35fa263b5 131 const int crp_start = 0x2fc; // Code Read Protection location
va009039 0:27d35fa263b5 132 if (crp_start >= addr && crp_start < addr+size) {
va009039 5:2774358f5e4f 133 uint32_t pat = LD32(crp_start-addr+buf);
va009039 0:27d35fa263b5 134 if (pat != 0xffffffff) { // NO_CRP ?
va009039 0:27d35fa263b5 135 _pc->printf("\nCAUTION: CRP Pattern is not NO_CRP; %08x\n", pat);
va009039 0:27d35fa263b5 136 return false;
va009039 0:27d35fa263b5 137 }
va009039 0:27d35fa263b5 138 }
va009039 0:27d35fa263b5 139 return true;
va009039 0:27d35fa263b5 140 }
va009039 0:27d35fa263b5 141
va009039 2:32e9437348ad 142 Flash::IAP_STATUS Flash::remoteIAP(Flash::IAP_CMD cmd, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3)
va009039 0:27d35fa263b5 143 {
va009039 0:27d35fa263b5 144 struct {
va009039 0:27d35fa263b5 145 uint32_t bkpt; // +0
va009039 0:27d35fa263b5 146 struct { // IAP Structure
va009039 0:27d35fa263b5 147 uint32_t cmd; // +4 Command
va009039 0:27d35fa263b5 148 uint32_t par[4]; // +8 Parameters
va009039 0:27d35fa263b5 149 uint32_t stat; // +24 Status
va009039 0:27d35fa263b5 150 uint32_t res[4]; // +28 Result
va009039 0:27d35fa263b5 151 } IAP; // +44
va009039 0:27d35fa263b5 152 } ram;
va009039 0:27d35fa263b5 153
va009039 2:32e9437348ad 154 ram.bkpt = 0xe00abe00; // bpkt #00
va009039 0:27d35fa263b5 155 ram.IAP.cmd = cmd;
va009039 0:27d35fa263b5 156 ram.IAP.par[0] = p0;
va009039 0:27d35fa263b5 157 ram.IAP.par[1] = p1;
va009039 0:27d35fa263b5 158 ram.IAP.par[2] = p2;
va009039 0:27d35fa263b5 159 ram.IAP.par[3] = p3;
va009039 0:27d35fa263b5 160 _target->halt();
va009039 0:27d35fa263b5 161 _target->wait_status(TARGET_HALTED);
va009039 0:27d35fa263b5 162 const uint32_t ram_addr = 0x10000100;
va009039 0:27d35fa263b5 163 _target->writeMemory(ram_addr, (uint32_t*)&ram, sizeof(ram)/sizeof(uint32_t));
va009039 2:32e9437348ad 164 _target->r0 = ram_addr + 4; // command addr
va009039 2:32e9437348ad 165 _target->r1 = ram_addr + 24; // status addr
va009039 2:32e9437348ad 166 _target->sp = 0x10000400-32; // IAP use ram top 32bytes
va009039 0:27d35fa263b5 167 _target->lr = ram_addr + 1; // return to bkpt
va009039 0:27d35fa263b5 168 _target->pc = 0x1fff1ff1; // IAP_Call
va009039 0:27d35fa263b5 169 _target->resume();
va009039 0:27d35fa263b5 170 _target->wait_status(TARGET_HALTED);
va009039 2:32e9437348ad 171 return (IAP_STATUS)_target->readMemory(ram_addr + 24);
va009039 0:27d35fa263b5 172 }
va009039 0:27d35fa263b5 173
va009039 0:27d35fa263b5 174 bool Flash::verify(const char* filename)
va009039 0:27d35fa263b5 175 {
va009039 0:27d35fa263b5 176 FILE* fp = fopen(filename, "rb");
va009039 0:27d35fa263b5 177 if (fp == NULL) {
va009039 0:27d35fa263b5 178 _pc->printf("file open error [%s]\n", filename);
va009039 0:27d35fa263b5 179 return false;
va009039 0:27d35fa263b5 180 }
va009039 0:27d35fa263b5 181 _pc->printf("Verifying.");
va009039 0:27d35fa263b5 182 uint8_t buf[256];
va009039 0:27d35fa263b5 183 bool passed = false;
va009039 0:27d35fa263b5 184 for(int addr = 0; addr < 0x8000; addr++) {
va009039 0:27d35fa263b5 185 int c = fgetc(fp);
va009039 0:27d35fa263b5 186 if (c == EOF) {
va009039 0:27d35fa263b5 187 passed = true;
va009039 0:27d35fa263b5 188 break;
va009039 0:27d35fa263b5 189 }
va009039 0:27d35fa263b5 190 if ((addr % sizeof(buf)) == 0) {
va009039 0:27d35fa263b5 191 _target->readMemory(addr, (uint32_t*)buf, sizeof(buf)/sizeof(uint32_t));
va009039 0:27d35fa263b5 192 _pc->printf(".");
va009039 0:27d35fa263b5 193 }
va009039 0:27d35fa263b5 194 if (c != buf[addr % sizeof(buf)]) {
va009039 0:27d35fa263b5 195 _pc->printf("\nError at %08x(%02x:%02x)\n", addr, c, buf[addr % sizeof(buf)]);
va009039 4:5e4107edcbdb 196 break;
va009039 0:27d35fa263b5 197 }
va009039 0:27d35fa263b5 198 }
va009039 0:27d35fa263b5 199 fclose(fp);
va009039 0:27d35fa263b5 200 if (passed) {
va009039 0:27d35fa263b5 201 _pc->printf("passed.\n");
va009039 0:27d35fa263b5 202 }
va009039 0:27d35fa263b5 203 return passed;
va009039 0:27d35fa263b5 204 }