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:
1:eb30547ba84d
Child:
2:32e9437348ad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Semihost.cpp	Mon Sep 02 17:33:08 2013 +0000
@@ -0,0 +1,246 @@
+// Semihost.cpp 2013/9/3
+#include "Semihost.h"
+#include "mydebug.h"
+
+Semihost::Semihost(Target2* target, Serial* usbpc) : _target(target),_pc(usbpc)
+{
+   _dirpath = "/local";
+}
+
+void Semihost::mount(const char* dirpath)
+{
+    _dirpath = (char*)dirpath;
+}
+
+int Semihost::poll()
+{
+    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;
+    }
+    _target->r0 = exec(_target->r0, _target->r1);
+    _target->pc = pc + 3; // skip bkpt #171
+    _target->resume();
+    return 0;
+}
+
+int Semihost::exec(uint32_t reason, uint32_t arg)
+{
+    int result = 0;
+    switch(reason) {
+        case 0x01: result = sys_open(arg); break;
+        case 0x02: result = sys_close(arg); break;
+        case 0x03: result = sys_writec(arg); break;
+        case 0x04: result = sys_write0(arg); break;
+        case 0x05: result = sys_write(arg); break;
+        case 0x06: result = sys_read(arg); break;
+        case 0x07: result = sys_readc(arg); break;
+        case 0x09: result = sys_istty(arg); break;
+        case 0x0a: result = sys_fseek(arg); break;
+        case 0x0b: result = sys_ensure(arg); break;
+        case 0x0c: result = sys_flen(arg); break;
+        case 0x0e: result = sys_remove(arg); break;
+        case 0x0f: result = sys_rename(arg); break;
+        case 0x18: result = sys_exit(arg); break;
+        
+        case 0x100: result = usr_xffind(arg); break;
+        case 0x101: result = usr_uid(arg); break;
+        case 0x102: result = usr_reset(arg); break;
+        case 0x103: result = usr_vbus(arg); break;
+        case 0x104: result = usr_powerdown(arg); break;
+        case 0x105: result = usr_disabledebug(arg); break;
+
+        default:
+            _pc->printf("[semihost]error reason=%08x arg=%08x\n", reason, arg);
+            result = -1;
+    }
+    return result;
+}
+
+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
+{
+    uint32_t p = rd<uint32_t>(arg);
+    _pc->putc(rd<uint8_t>(p) & 0xff);
+    return 0;
+}
+
+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 _pc->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");
+    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 uid = rd<uint32_t>(arg);
+    uint32_t len = rd<uint32_t>(arg+4);
+    const uint8_t mac[] = {0x00, 0x02, 0xf7, 0xf0, 0x00, 0x00};
+    for(int i = 0; i < sizeof(mac) && i < len; i++) {
+        wr<uint8_t>(uid+i, mac[i]);
+    }    
+    return 0;
+}
+
+int Semihost::usr_reset(uint32_t arg) // 0x102
+{
+    _target->Reset();
+    _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;
+}