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
Semihost.cpp
- Committer:
- va009039
- Date:
- 2014-06-22
- Revision:
- 18:5ed1759e863b
- Parent:
- 17:4e1205ce031f
File content as of revision 18:5ed1759e863b:
// Semihost.cpp 2014/6/22 #include "Semihost.h" #include "mydebug.h" Semihost::Semihost(Target2* target, Serial* usbpc, USBLocalFileSystem* usb) : _target(target),_pc(usbpc),_usb(usb) { _dirpath = "/local"; _writec_buf = -1; } void Semihost::mount(const char* dirpath) { _dirpath = (char*)dirpath; } int Semihost::poll() { TRACE(); if (_target->getStatus() != TARGET_HALTED) { return 0; } uint32_t pc = _target->pc; if (pc & 1) { return 0; } if (rd<uint16_t>(pc) != 0xbeab) { // BKPT #171 return 0; } uint32_t reason = _target->r0; _target->r0 = exec(reason, _target->r1); if (reason == SYS_EXIT) { return SYS_EXIT; } _target->pc = pc + 3; // skip bkpt #171 _target->resume(); return reason; } int Semihost::exec(uint32_t reason, uint32_t arg) { switch(reason) { case 0x01: return sys_open(arg); case 0x02: return sys_close(arg); case 0x03: return sys_writec(arg); case 0x04: return sys_write0(arg); case 0x05: return sys_write(arg); case 0x06: return sys_read(arg); case 0x07: return sys_readc(arg); case 0x09: return sys_istty(arg); case 0x0a: return sys_fseek(arg); case 0x0b: return sys_ensure(arg); case 0x0c: return sys_flen(arg); case 0x0e: return sys_remove(arg); case 0x0f: return sys_rename(arg); case 0x18: return sys_exit(arg); case 0x100: return usr_xffind(arg); case 0x101: return usr_uid(arg); case 0x102: return usr_reset(arg); case 0x103: return usr_vbus(arg); case 0x104: return usr_powerdown(arg); case 0x105: return usr_disabledebug(arg); } _pc->printf("[semihost]error reason=%08x arg=%08x\n", reason, arg); return -1; } int Semihost::sys_open(uint32_t arg) // 0x01 { char name[64]; _build_name(name, sizeof(name), arg, arg+8); const char* mode[] = {"r", "rb", "r+", "r+b", "w", "wb", "w+", "w+b", "a", "ab", "a+", "a+b"}; uint32_t mode_index = rd<uint32_t>(arg+4); FILE* fp = fopen(name, mode[mode_index]); if (fp) { return (uint32_t)fp; } _pc->printf("\n[semihost]file open error [%s]\n", name); return -1; } int Semihost::sys_close(uint32_t arg) // 0x02 { FILE* fp = reinterpret_cast<FILE*>(rd<uint32_t>(arg)); int r = fclose(fp); if (r == 0) { return 0; } return -1; } int Semihost::sys_writec(uint32_t arg) // 0x03 { int c = rd<uint8_t>(arg); _usb->putc(c); return c; } int Semihost::readable() { return (_writec_buf == (-1)) ? 0 : 1; } int Semihost::getc() { int c = _writec_buf; _writec_buf = -1; return c; } int Semihost::sys_write0(uint32_t arg) // 0x04 { uint32_t p = rd<uint32_t>(arg); while(1) { uint8_t c = rd<uint8_t>(p++); if (c == '\0') { break; } _pc->putc(c & 0xff); } return 0; } int Semihost::sys_write(uint32_t arg) // 0x05 { FILE* fp = reinterpret_cast<FILE*>(rd<uint32_t>(arg)); uint32_t p = rd<uint32_t>(arg+4); int count = rd<uint32_t>(arg+8); while(count > 0) { uint8_t c = rd<uint8_t>(p++); if (fputc(c, fp) == EOF) { return count; } count--; } return 0; } int Semihost::sys_read(uint32_t arg) // 0x06 { FILE* fp = reinterpret_cast<FILE*>(rd<uint32_t>(arg)); uint32_t p = rd<uint32_t>(arg+4); int count = rd<uint32_t>(arg+8); while(count > 0) { int c = fgetc(fp); if (c == EOF) { return count; } wr<uint8_t>(p++, c); count--; } return 0; } int Semihost::sys_readc(uint32_t arg) // 0x07 { return _usb->getc() & 0xff; } int Semihost::sys_istty(uint32_t arg) // 0x09 { FILE* fp = reinterpret_cast<FILE*>(rd<uint32_t>(arg)); return 0; } int Semihost::sys_fseek(uint32_t arg) // 0x0a { FILE* fp = reinterpret_cast<FILE*>(rd<uint32_t>(arg)); int offset = rd<uint32_t>(arg+4); return fseek(fp, offset, SEEK_SET); } int Semihost::sys_ensure(uint32_t arg) // 0x0b { FILE* fp = reinterpret_cast<FILE*>(rd<uint32_t>(arg)); return -1; } int Semihost::sys_flen(uint32_t arg) // 0x0c { FILE* fp = reinterpret_cast<FILE*>(rd<uint32_t>(arg)); return ftell(fp); } int Semihost::sys_remove(uint32_t arg) // 0x0e { char name[64]; _build_name(name, sizeof(name), arg, arg+4); return remove(name); } int Semihost::sys_rename(uint32_t arg) // 0x0f { char oldname[64]; char newname[64]; _build_name(oldname, sizeof(oldname), arg, arg+4); _build_name(newname, sizeof(newname), arg+8, arg+12); return rename(oldname, newname); } int Semihost::sys_exit(uint32_t arg) // 0x18 { _pc->printf("\n[semihost]EXIT!!!\n"); _pc->printf("r0=%08x r1=%08x r2=%08x r3=%08x\n", _target->r0.read(),_target->r1.read(),_target->r2.read(),_target->r3.read()); _pc->printf("r4=%08x r5=%08x r6=%08x r7=%08x\n", _target->r4.read(),_target->r5.read(),_target->r6.read(),_target->r7.read()); _pc->printf("sp=%08x lr=%08x pc=%08x xpsr=%08x\n", _target->sp.read(),_target->lr.read(),_target->pc.read(),_target->xpsr.read()); return -1; } void Semihost::_build_name(char* buf, int size, uint32_t arg1, uint32_t arg2) { strcpy(buf, _dirpath); uint32_t p = rd<uint32_t>(arg1); int len = rd<uint32_t>(arg2); int pos = strlen(buf); if (buf[pos-1] != '/') { buf[pos++] = '/'; buf[pos] = '\0'; } for(int i = 0; i < len && pos < size-1; i++) { buf[pos++] = rd<uint8_t>(p++); } buf[pos] = '\0'; } int Semihost::usr_xffind(uint32_t arg) // 0x100 { return -1; } int Semihost::usr_uid(uint32_t arg) // 0x101 { uint32_t p = rd<uint32_t>(arg); uint32_t len = rd<uint32_t>(arg+4); const char* uid = "101000000000000000000002F7F00000"; for(int i = 0; i < 32 && i < len; i++) { wr<uint8_t>(p++, uid[i]); } return 0; } int Semihost::usr_reset(uint32_t arg) // 0x102 { _target->SoftwareReset(); _target->setup(); return 0; } int Semihost::usr_vbus(uint32_t arg) // 0x103 { return -1; } int Semihost::usr_powerdown(uint32_t arg) // 0x104 { return -1; } int Semihost::usr_disabledebug(uint32_t arg) // 0x105 { return -1; }