From 32acdd7445ccf2565e08c1b54b41c4422afcb804 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Fri, 8 Apr 2022 15:28:42 +0200 Subject: [PATCH 001/249] add interrupts to extract and upload state --- src/Debug/debugger.cpp | 447 ++++++++++++++++++++++++++++++++++++++++- src/Debug/debugger.h | 21 +- 2 files changed, 465 insertions(+), 3 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index c216eb75..f58826bf 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "../Memory/mem.h" #include "../Utils//util.h" @@ -172,6 +173,37 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { this->handleChangedLocal(m, interruptData); free(interruptData); break; + case interruptWOODDUMP: + *program_state = WARDUINOpause; + free(interruptData); + woodDump(m); + break; + case interruptOffset: { + free(interruptData); + dprintf(this->socket, "\"{\"offset\":\"%p\"}\"\n", (void *)m->bytes); + break; + } + case interruptRecvState: { + if (!this->receivingData) { + debug("paused program execution\n"); + *program_state = WARDUINOpause; + this->receivingData = true; + this->freeState(m, interruptData); + free(interruptData); + dprintf(this->socket, "ack!\n"); + } else { + printf("reeiving state\n"); + debug("receiving state\n"); + receivingData = !this->saveState(m, interruptData); + free(interruptData); + debug("sending %s!\n", receivingData ? "ack" : "done"); + dprintf(this->socket, "%s!\n", receivingData ? "ack" : "done"); + if(!this->receivingData){ + debug("receiving state done\n"); + } + } + break; + } default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); @@ -183,6 +215,53 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } // Private methods +void Debugger::printValue(StackValue *v, int idx, bool end = false){ + char buff[256]; + + switch (v->value_type) { + case I32: + snprintf(buff, 255, R"("type":"i32","value":%)" PRIi32, + v->value.uint32); + break; + case I64: + snprintf(buff, 255, R"("type":"i64","value":%)" PRIi64, + v->value.uint64); + break; + case F32: + snprintf(buff, 255, R"("type":"F32","value":%.7f)", + v->value.f32); + break; + case F64: + snprintf(buff, 255, R"("type":"F64","value":%.7f)", + v->value.f64); + break; + default: + snprintf(buff, 255, + R"("type":"%02x","value":"%)" PRIx64 "\"", + v->value_type, v->value.uint64); + } + dprintf(this->socket, R"({"idx":%d,%s}%s)", idx, buff, + end ? "": ","); + +} + +uint8_t * Debugger::findOpcode(Module *m, Block *block){ + auto find = + std::find_if(std::begin(m->block_lookup), std::end(m->block_lookup), + [&](const std::pair &pair) { + return pair.second == block; + }); + uint8_t *opcode = nullptr; + if (find != std::end(m->block_lookup)) { + opcode = find->first; + } else { + // FIXME FATAL? + debug("find_opcode: not found\n"); + exit(33); + } + return opcode; +} + void Debugger::handleInterruptRUN(Module *m, RunningState *program_state) { dprintf(this->socket, "GO!\n"); @@ -300,11 +379,11 @@ void Debugger::dumpLocals(Module *m) const { v->value.uint64); break; case F32: - snprintf(_value_str, 255, R"("type":"i64","value":%.7f)", + snprintf(_value_str, 255, R"("type":"F32","value":%.7f)", v->value.f32); break; case F64: - snprintf(_value_str, 255, R"("type":"i64","value":%.7f)", + snprintf(_value_str, 255, R"("type":"F64","value":%.7f)", v->value.f64); break; default: @@ -412,3 +491,367 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { dprintf(this->socket, "Local %u changed to %u\n", localId, v->value.uint32); return true; } +void Debugger::woodDump(Module *m) { + // FIXME replace write + + debug("asked for doDump\n"); + dprintf(this->socket, "DUMP!\n"); + dprintf(this->socket, "{"); + + // printf("asked for pc\n"); + // current PC + dprintf(this->socket, R"("pc":"%p",)", (void *)m->pc_ptr); + + // start of bytes + dprintf(this->socket, R"("start":["%p"],)", (void *)m->bytes); + // printf("asked for bps\n"); + + dprintf(this->socket, "\"breakpoints\":["); + size_t i = 0; + for (auto bp : this->breakpoints) { + dprintf(this->socket, R"("%p"%s)", bp, + (++i < this->breakpoints.size()) ? "," : ""); + } + dprintf(this->socket, "],"); + + // printf("asked for stack\n"); + //stack + dprintf(this->socket, "\"stack\":["); + char _value_str[256]; + for (int i = 0; i <= m->sp; i++) { + auto v = &m->stack[i]; + printValue(v, i, i == m->sp); + } + dprintf(this->socket, "],"); + + // Callstack + dprintf(this->socket, "\"callstack\":["); + for (int i = 0; i <= m->csp; i++) { + Frame *f = &m->callstack[i]; + uint8_t *block_key = + f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); + dprintf(this->socket, + R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p"}%s)", + f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, + static_cast(f->ra_ptr), (i < m->csp) ? "," : ""); + } + + // printf("asked for globals\n"); + // GLobals + dprintf(this->socket, "],\"globals\":["); + for (uint32_t i = 0; i < m->global_count; i++) { + auto v = m->globals + i; + printValue(v, i, i == (m->global_count - 1)); + } + dprintf(this->socket, "]"); // closing globals + + // printf("asked for table\n"); + dprintf(this->socket, ",\"table\":{\"max\":%d, \"init\":%d, \"elements\":[", + m->table.maximum, m->table.initial); + + write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); + dprintf(this->socket, "]}"); // closing table + + // printf("asked for mem\n"); + // memory + uint32_t total_elems = + m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE + dprintf(this->socket, ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", + m->memory.pages, m->memory.maximum, m->memory.initial); + + write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); + dprintf(this->socket, "]}"); // closing memory + + + // printf("asked for br_table\n"); + dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", BR_TABLE_SIZE); + write(this->socket, m->br_table, BR_TABLE_SIZE * sizeof(uint32_t)); + dprintf(this->socket, "]}}\n"); +} + +enum ReceiveState { + pcState = 0x01, + breakpointsState = 0x02, + callstackState = 0x03, + globalsState = 0x04, + tblState = 0x05, + memState = 0x06, + brtblState = 0x07, + stackvalsState = 0x08, + pcErrorState = 0x09 +}; + +void Debugger::freeState(Module *m, uint8_t *interruptData) { + debug("freeing the program state\n"); + printf("freeing the program state\n"); + uint8_t *first_msg = nullptr; + uint8_t *endfm = nullptr; + first_msg = interruptData + 1; // skip interruptRecvState + endfm = first_msg + read_B32(&first_msg); + + // nullify state + this->breakpoints.clear(); + m->csp = -1; + m->sp = -1; + memset(m->br_table, 0, BR_TABLE_SIZE); + + while (first_msg < endfm) { + switch (*first_msg++) { + case globalsState: { + debug("receiving globals info\n"); + printf("receiving globals info\n"); + uint32_t amount = read_B32(&first_msg); + debug("total globals %d\n", amount); + // TODO if global_count != amount Otherwise set all to zero + if (m->global_count != amount) { + debug("globals freeing state and then allocating\n"); + if (m->global_count > 0) free(m->globals); + if (amount > 0) + m->globals = (StackValue *)acalloc( + amount, sizeof(StackValue), "globals"); + } else { + debug("globals setting existing state to zero\n"); + for (uint32_t i = 0; i < m->global_count; i++) { + debug("decreasing global_count\n"); + StackValue *sv = &m->globals[i]; + sv->value_type = 0; + sv->value.uint32 = 0; + } + } + m->global_count = 0; + break; + } + case tblState: { + debug("receiving table info\n"); + printf("receiving table info\n"); + m->table.initial = read_B32(&first_msg); + m->table.maximum = read_B32(&first_msg); + uint32_t size = read_B32(&first_msg); + debug("init %d max %d size %d\n", m->table.initial, + m->table.maximum, size); + if (m->table.size != size) { + debug("old table size %d\n", m->table.size); + if (m->table.size != 0) free(m->table.entries); + m->table.entries = (uint32_t *)acalloc( + size, sizeof(uint32_t), "Module->table.entries"); + } + m->table.size = 0; // allows to accumulatively add entries + break; + } + case memState: { + debug("receiving memory info\n"); + printf("receiving memory info\n"); + // FIXME: init & max not needed + m->memory.maximum = read_B32(&first_msg); + m->memory.initial = read_B32(&first_msg); + uint32_t pages = read_B32(&first_msg); + debug("max %d init %d current page %d\n", m->memory.maximum, + m->memory.initial, pages); + printf("max %d init %d current page %d\n", m->memory.maximum, + m->memory.initial, pages); + // if(pages !=m->memory.pages){ + // if(m->memory.pages !=0) + if(m->memory.bytes != nullptr){ + free(m->memory.bytes); + } + m->memory.bytes = + (uint8_t *)acalloc(pages * PAGE_SIZE, sizeof(uint32_t), + "Module->memory.bytes"); + m->memory.pages = pages; + // } + // else{ + // //TODO fill memory.bytes with zeros + // memset(m->memory.bytes, 0, m->memory.pages * PAGE_SIZE) ; + // } + break; + } + default: { + FATAL("freeState: receiving unknown command\n"); + break; + } + } + } + debug("done with first msg\n"); + /* printf("done with first msg\n"); */ +} + +bool Debugger::saveState(Module *m, uint8_t *interruptData) { + uint8_t *program_state = nullptr; + uint8_t *endstate = nullptr; + program_state = interruptData + 1; // skip interruptRecvState + endstate = program_state + read_B32(&program_state); + + while (program_state < endstate) { + switch (*program_state++) { + case pcState: { // PC + printf("reciving pc\n"); + m->pc_ptr = (uint8_t *)readPointer(&program_state); + break; + } + case breakpointsState: { // breakpoints + uint8_t quantity_bps = *program_state++; + printf("receiving breakpoints %" PRIu8 "\n", quantity_bps); + for (size_t i = 0; i < quantity_bps; i++) { + auto bp = (uint8_t *)readPointer(&program_state); + this->addBreakpoint(bp); + } + break; + } + case callstackState: { + debug("receiving callstack\n"); + printf("receiving callstack\n"); + uint16_t quantity = read_B16(&program_state); + debug("quantity frames %" PRIu16 "\n", quantity); + for (size_t i = 0; i < quantity; i++) { + uint8_t block_type = *program_state++; + m->csp += 1; + Frame *f = m->callstack + m->csp; + f->sp = read_B32_signed(&program_state); + f->fp = read_B32_signed(&program_state); + f->ra_ptr = (uint8_t *)readPointer(&program_state); + if (block_type == 0) { // a function + debug("function block\n"); + uint32_t fidx = read_B32(&program_state); + debug("function block idx=%" PRIu32 "\n", fidx); + f->block = m->functions + fidx; + + if (f->block->fidx != fidx) { + FATAL("incorrect fidx: exp %" PRIu32 " got %" PRIu32 + ". Exiting program\n", + fidx, f->block->fidx); + } + m->fp = f->sp + 1; + } else { + printf("non function block\n"); + uint8_t *block_key = + (uint8_t *)readPointer(&program_state); + /* printf("block_key=%p\n", static_cast(block_key)); */ + f->block = m->block_lookup[block_key]; + if(f->block == nullptr){ + FATAL("block_lookup cannot be nullptr\n"); + } + } + } + break; + } + case globalsState: { // TODO merge globalsState stackvalsState into + // one case + debug("receiving global state\n"); + printf("receiving globals\n"); + uint32_t quantity_globals = read_B32(&program_state); + uint8_t valtypes[] = {I32, I64, F32, F64}; + + debug("receiving #%" PRIu32 " globals\n", quantity_globals); + for (uint32_t q = 0; q < quantity_globals; q++) { + uint8_t typeidx = *program_state++; + if (typeidx >= sizeof(valtypes)) { + FATAL("received unknown type %" PRIu8 "\n", typeidx); + } + StackValue *sv = &m->globals[m->global_count++]; + size_t qb = typeidx == 0 || typeidx == 2 ? 4 : 8; + debug("receiving type %" PRIu8 " and %d bytes \n", typeidx, + typeidx == 0 || typeidx == 2 ? 4 : 8); + + sv->value_type = valtypes[typeidx]; + memcpy(&sv->value, program_state, qb); + program_state += qb; + } + break; + } + case tblState: { + printf("receiving table\n"); + uint8_t tbl_type = + (uint8_t)*program_state++; // for now only funcref + uint32_t quantity = read_B32(&program_state); + for (size_t i = 0; i < quantity; i++) { + uint32_t ne = read_B32(&program_state); + m->table.entries[m->table.size++] = ne; + } + break; + } + case memState: { + debug("receiving memory\n"); + printf("receiving memory\n"); + uint32_t begin = read_B32(&program_state); + uint32_t end = read_B32(&program_state); + debug("memory offsets begin=%" PRIu32 " , end=%" PRIu32 "\n", + begin, end); + if (begin > end) { + FATAL("incorrect memory offsets\n"); + } + uint32_t totalbytes = end - begin + 1; + uint8_t *mem_end = + m->memory.bytes + m->memory.pages * (uint32_t)PAGE_SIZE; + debug("will copy #%" PRIu32 " bytes\n", totalbytes); + if ((m->bytes + begin) + totalbytes > mem_end) { + FATAL("memory overflow\n"); + } + memcpy(m->memory.bytes + begin, program_state, totalbytes + 1); + for (auto i = begin; i <= (begin + totalbytes - 1); i++) { + debug("GOT byte idx %" PRIu32 " =%" PRIu8 "\n", i, + m->memory.bytes[i]); + } + debug("outside the out\n"); + program_state += totalbytes; + break; + } + case brtblState: { + debug("receiving br_table\n"); + printf("receiving br_table\n"); + uint16_t beginidx = read_B16(&program_state); + uint16_t endidx = read_B16(&program_state); + debug("br_table offsets begin=%" PRIu16 " , end=%" PRIu16 "\n", + beginidx, endidx); + if (beginidx > endidx) { + FATAL("incorrect br_table offsets\n"); + } + if (endidx >= BR_TABLE_SIZE) { + FATAL("br_table overflow\n"); + } + for (auto idx = beginidx; idx <= endidx; idx++) { + // FIXME speedup with memcpy? + uint32_t el = read_B32(&program_state); + m->br_table[idx] = el; + } + break; + } + case stackvalsState: { + // FIXME the float does add numbers at the end. The extra + // numbers are present in the send information when dump occurs + printf("receiving stack\n"); + uint16_t quantity_sv = read_B16(&program_state); + uint8_t valtypes[] = {I32, I64, F32, F64}; + for (size_t i = 0; i < quantity_sv; i++) { + uint8_t typeidx = *program_state++; + if (typeidx >= sizeof(valtypes)) { + FATAL("received unknown type %" PRIu8 "\n", typeidx); + } + m->sp += 1; + StackValue *sv = &m->stack[m->sp]; + sv->value.uint64 = 0; // init whole union to 0 + size_t qb = typeidx == 0 || typeidx == 2 ? 4 : 8; + sv->value_type = valtypes[typeidx]; + memcpy(&sv->value, program_state, qb); + program_state += qb; + } + break; + } + default: { + FATAL("saveState: Reiceived unknown program state\n"); + } + } + } + uint8_t done = (uint8_t)*program_state; + return done == (uint8_t)1; +} + +uintptr_t Debugger::readPointer(uint8_t **data) { + uint8_t len = (*data)[0]; + uintptr_t bp = 0x0; + for (size_t i = 0; i < len; i++) { + bp <<= sizeof(uint8_t) * 8; + bp |= (*data)[i + 1]; + } + *data += 1 + len; // skip pointer + return bp; +} diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 27e13eca..4bd6b0f9 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -6,6 +6,8 @@ #include struct Module; +struct Block; +struct StackValue; enum RunningState { WARDUINOrun, WARDUINOpause, WARDUINOstep }; @@ -20,7 +22,10 @@ enum InterruptTypes { interruptDUMPLocals = 0x11, interruptDUMPFull = 0x12, interruptUPDATEFun = 0x20, - interruptUPDATELocal = 0x21 + interruptUPDATELocal = 0x21, + interruptWOODDUMP = 0x60, + interruptOffset = 0x61, + interruptRecvState = 0x62, }; class Debugger { @@ -37,6 +42,8 @@ class Debugger { // Private methods + void printValue(StackValue *v, int idx, bool end); + // TODO Move parsing to WARDuino class? uint8_t *parseDebugBuffer(size_t len, const uint8_t *buff); @@ -64,6 +71,15 @@ class Debugger { bool handleChangedLocal(Module *m, uint8_t *bytes) const; + + //WOOD + bool receivingData = false; + void freeState(Module *m, uint8_t * interruptData); + uint8_t *findOpcode(Module *m, Block *block); + bool saveState(Module *m, uint8_t *interruptData); + uintptr_t readPointer(uint8_t **data); + + public: int socket; @@ -88,4 +104,7 @@ class Debugger { void deleteBreakpoint(uint8_t *loc); bool isBreakpoint(uint8_t *loc); + + // WOOD + void woodDump(Module *m); }; \ No newline at end of file From 573dbb9ca2827d3128e4e7f1818381677bdc79eb Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Fri, 8 Apr 2022 15:29:30 +0200 Subject: [PATCH 002/249] read big endian --- src/Utils/util.cpp | 23 +++++++++++++++++++++++ src/Utils/util.h | 5 +++++ 2 files changed, 28 insertions(+) diff --git a/src/Utils/util.cpp b/src/Utils/util.cpp index c67b1ed0..a4cddfe9 100644 --- a/src/Utils/util.cpp +++ b/src/Utils/util.cpp @@ -161,3 +161,26 @@ double wa_fmin(double a, double b) { } return c; } + + +//WOOD +uint32_t read_B32(uint8_t **bytes) { + uint8_t *b = *bytes; + uint32_t n = (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3]; + *bytes += 4; + return n; +} + +uint16_t read_B16(uint8_t **bytes) { + uint8_t *b = *bytes; + uint32_t n = (b[0] << 8) + b[1]; + *bytes += 2; + return n; +} + +int read_B32_signed(uint8_t **bytes) { + uint8_t *b = *bytes; + int n = (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3]; + *bytes += 4; + return n; +} // TODO replace with read_LEB_32? If keep Big endian use memcpy? diff --git a/src/Utils/util.h b/src/Utils/util.h index 900a5565..1dea3a05 100644 --- a/src/Utils/util.h +++ b/src/Utils/util.h @@ -67,4 +67,9 @@ double wa_fmax(double a, double b); double wa_fmin(double a, double b); +//WOOD +uint32_t read_B32(uint8_t **bytes); +uint16_t read_B16(uint8_t **bytes); +int read_B32_signed(uint8_t **bytes); + #endif From b823b8bf18f78cb4d23edf4e055336f86c6d44df Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 13 Apr 2022 11:16:43 +0200 Subject: [PATCH 003/249] add idx to dump callstackframe --- src/Debug/debugger.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index f58826bf..5f1d3ae4 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -180,6 +180,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptOffset: { free(interruptData); + printf("here"); dprintf(this->socket, "\"{\"offset\":\"%p\"}\"\n", (void *)m->bytes); break; } @@ -531,9 +532,9 @@ void Debugger::woodDump(Module *m) { uint8_t *block_key = f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); dprintf(this->socket, - R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p"}%s)", + R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p", "idx":%d}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, - static_cast(f->ra_ptr), (i < m->csp) ? "," : ""); + static_cast(f->ra_ptr), i, (i < m->csp) ? "," : ""); } // printf("asked for globals\n"); @@ -549,7 +550,7 @@ void Debugger::woodDump(Module *m) { dprintf(this->socket, ",\"table\":{\"max\":%d, \"init\":%d, \"elements\":[", m->table.maximum, m->table.initial); - write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); + //write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); dprintf(this->socket, "]}"); // closing table // printf("asked for mem\n"); @@ -559,7 +560,7 @@ void Debugger::woodDump(Module *m) { dprintf(this->socket, ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", m->memory.pages, m->memory.maximum, m->memory.initial); - write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); + //write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); dprintf(this->socket, "]}"); // closing memory @@ -681,11 +682,12 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { program_state = interruptData + 1; // skip interruptRecvState endstate = program_state + read_B32(&program_state); + printf("saving program_state\n"); while (program_state < endstate) { switch (*program_state++) { case pcState: { // PC - printf("reciving pc\n"); m->pc_ptr = (uint8_t *)readPointer(&program_state); + /* printf("reciving pc %p\n", static_cast(m->pc_ptr)); */ break; } case breakpointsState: { // breakpoints @@ -702,7 +704,9 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { printf("receiving callstack\n"); uint16_t quantity = read_B16(&program_state); debug("quantity frames %" PRIu16 "\n", quantity); + /* printf("quantity frames %" PRIu16 "\n", quantity); */ for (size_t i = 0; i < quantity; i++) { + /* printf("frame IDX: %lu\n", i); */ uint8_t block_type = *program_state++; m->csp += 1; Frame *f = m->callstack + m->csp; @@ -712,7 +716,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { if (block_type == 0) { // a function debug("function block\n"); uint32_t fidx = read_B32(&program_state); - debug("function block idx=%" PRIu32 "\n", fidx); + /* printf("function block idx=%" PRIu32 "\n", fidx); */ f->block = m->functions + fidx; if (f->block->fidx != fidx) { From 4aaaf31937655637e75c04894d3380c51f8c2831 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 13 Apr 2022 11:16:56 +0200 Subject: [PATCH 004/249] add factorial example --- examples/factorial/fac.wast | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 examples/factorial/fac.wast diff --git a/examples/factorial/fac.wast b/examples/factorial/fac.wast new file mode 100644 index 00000000..3e153e3d --- /dev/null +++ b/examples/factorial/fac.wast @@ -0,0 +1,42 @@ +(module + (import "env" "print_int" (func $print (type $i2v))) + + (; Type declarations ;) + (type $i2v (func (param i32) (result))) + (type $i32toi32 (func (param i32) (result i32))) + (type $v2v (func (param) (result))) + + (; Define one function ;) + (export "main" (func $main)) + (memory 2) + (table funcref (elem $fac $dummy)) + + (global $g1 i32 (i32.const 0)) + (global $g2 (mut i32) (i32.const 0)) + + (func $dummy (type $i2v)) + (func $fac (type $i32toi32) + (i32.gt_s + (local.get 0) + (i32.const 1)) + (if (result i32) + (then + (i32.sub + (local.get 0) + (i32.const 1)) + (call $fac) + (local.get 0) + i32.mul) + (else + (i32.const 1)))) + + (func $main (type $v2v) + (local $arg i32) + (local.set $arg (i32.const 5)) + (loop + (local.get $arg) + (call $fac) + (call $print) + (br 0))) +) + From f82f2ab003f76d8e440b6ebd78aca7a5375e1f74 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 8 Apr 2022 15:32:42 +0200 Subject: [PATCH 005/249] Format + Add missing #include --- src/Debug/debugger.cpp | 101 ++++++++++++++++++++--------------------- src/Debug/debugger.h | 8 ++-- src/Utils/util.cpp | 3 +- src/Utils/util.h | 2 +- 4 files changed, 54 insertions(+), 60 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 5f1d3ae4..927c502f 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -1,14 +1,14 @@ #include "debugger.h" -#include +#include +#include +#include #include -#include #include "../Memory/mem.h" #include "../Utils//util.h" #include "../Utils/macros.h" -#include "../WARDuino.h" // Debugger @@ -180,8 +180,8 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptOffset: { free(interruptData); - printf("here"); - dprintf(this->socket, "\"{\"offset\":\"%p\"}\"\n", (void *)m->bytes); + dprintf(this->socket, "\"{\"offset\":\"%p\"}\"\n", + (void *)m->bytes); break; } case interruptRecvState: { @@ -199,7 +199,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { free(interruptData); debug("sending %s!\n", receivingData ? "ack" : "done"); dprintf(this->socket, "%s!\n", receivingData ? "ack" : "done"); - if(!this->receivingData){ + if (!this->receivingData) { debug("receiving state done\n"); } } @@ -216,37 +216,32 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } // Private methods -void Debugger::printValue(StackValue *v, int idx, bool end = false){ - char buff[256]; - - switch (v->value_type) { - case I32: - snprintf(buff, 255, R"("type":"i32","value":%)" PRIi32, - v->value.uint32); - break; - case I64: - snprintf(buff, 255, R"("type":"i64","value":%)" PRIi64, - v->value.uint64); - break; - case F32: - snprintf(buff, 255, R"("type":"F32","value":%.7f)", - v->value.f32); - break; - case F64: - snprintf(buff, 255, R"("type":"F64","value":%.7f)", - v->value.f64); - break; - default: - snprintf(buff, 255, - R"("type":"%02x","value":"%)" PRIx64 "\"", - v->value_type, v->value.uint64); - } - dprintf(this->socket, R"({"idx":%d,%s}%s)", idx, buff, - end ? "": ","); +void Debugger::printValue(StackValue *v, int idx, bool end = false) { + char buff[256]; + switch (v->value_type) { + case I32: + snprintf(buff, 255, R"("type":"i32","value":%)" PRIi32, + v->value.uint32); + break; + case I64: + snprintf(buff, 255, R"("type":"i64","value":%)" PRIi64, + v->value.uint64); + break; + case F32: + snprintf(buff, 255, R"("type":"F32","value":%.7f)", v->value.f32); + break; + case F64: + snprintf(buff, 255, R"("type":"F64","value":%.7f)", v->value.f64); + break; + default: + snprintf(buff, 255, R"("type":"%02x","value":"%)" PRIx64 "\"", + v->value_type, v->value.uint64); + } + dprintf(this->socket, R"({"idx":%d,%s}%s)", idx, buff, end ? "" : ","); } -uint8_t * Debugger::findOpcode(Module *m, Block *block){ +uint8_t *Debugger::findOpcode(Module *m, Block *block) { auto find = std::find_if(std::begin(m->block_lookup), std::end(m->block_lookup), [&](const std::pair &pair) { @@ -263,7 +258,6 @@ uint8_t * Debugger::findOpcode(Module *m, Block *block){ return opcode; } - void Debugger::handleInterruptRUN(Module *m, RunningState *program_state) { dprintf(this->socket, "GO!\n"); if (*program_state == WARDUINOpause && this->isBreakpoint(m->pc_ptr)) { @@ -511,12 +505,12 @@ void Debugger::woodDump(Module *m) { size_t i = 0; for (auto bp : this->breakpoints) { dprintf(this->socket, R"("%p"%s)", bp, - (++i < this->breakpoints.size()) ? "," : ""); + (++i < this->breakpoints.size()) ? "," : ""); } dprintf(this->socket, "],"); // printf("asked for stack\n"); - //stack + // stack dprintf(this->socket, "\"stack\":["); char _value_str[256]; for (int i = 0; i <= m->sp; i++) { @@ -531,7 +525,8 @@ void Debugger::woodDump(Module *m) { Frame *f = &m->callstack[i]; uint8_t *block_key = f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); - dprintf(this->socket, + dprintf( + this->socket, R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p", "idx":%d}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, static_cast(f->ra_ptr), i, (i < m->csp) ? "," : ""); @@ -542,30 +537,31 @@ void Debugger::woodDump(Module *m) { dprintf(this->socket, "],\"globals\":["); for (uint32_t i = 0; i < m->global_count; i++) { auto v = m->globals + i; - printValue(v, i, i == (m->global_count - 1)); + printValue(v, i, i == (m->global_count - 1)); } dprintf(this->socket, "]"); // closing globals // printf("asked for table\n"); dprintf(this->socket, ",\"table\":{\"max\":%d, \"init\":%d, \"elements\":[", - m->table.maximum, m->table.initial); + m->table.maximum, m->table.initial); - //write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); + // write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); dprintf(this->socket, "]}"); // closing table // printf("asked for mem\n"); // memory uint32_t total_elems = m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE - dprintf(this->socket, ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", - m->memory.pages, m->memory.maximum, m->memory.initial); + dprintf(this->socket, + ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", + m->memory.pages, m->memory.maximum, m->memory.initial); - //write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); + // write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); dprintf(this->socket, "]}"); // closing memory - // printf("asked for br_table\n"); - dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", BR_TABLE_SIZE); + dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", + BR_TABLE_SIZE); write(this->socket, m->br_table, BR_TABLE_SIZE * sizeof(uint32_t)); dprintf(this->socket, "]}}\n"); } @@ -649,10 +645,10 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) { debug("max %d init %d current page %d\n", m->memory.maximum, m->memory.initial, pages); printf("max %d init %d current page %d\n", m->memory.maximum, - m->memory.initial, pages); + m->memory.initial, pages); // if(pages !=m->memory.pages){ // if(m->memory.pages !=0) - if(m->memory.bytes != nullptr){ + if (m->memory.bytes != nullptr) { free(m->memory.bytes); } m->memory.bytes = @@ -687,7 +683,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { switch (*program_state++) { case pcState: { // PC m->pc_ptr = (uint8_t *)readPointer(&program_state); - /* printf("reciving pc %p\n", static_cast(m->pc_ptr)); */ + /* printf("receiving pc %p\n", static_cast(m->pc_ptr)); */ break; } case breakpointsState: { // breakpoints @@ -729,10 +725,11 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { printf("non function block\n"); uint8_t *block_key = (uint8_t *)readPointer(&program_state); - /* printf("block_key=%p\n", static_cast(block_key)); */ + /* printf("block_key=%p\n", static_cast(block_key)); */ f->block = m->block_lookup[block_key]; - if(f->block == nullptr){ - FATAL("block_lookup cannot be nullptr\n"); + if (f->block == nullptr) { + FATAL("block_lookup cannot be nullptr\n"); } } } diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 4bd6b0f9..a7405518 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -71,15 +71,13 @@ class Debugger { bool handleChangedLocal(Module *m, uint8_t *bytes) const; - - //WOOD + // WOOD bool receivingData = false; - void freeState(Module *m, uint8_t * interruptData); + void freeState(Module *m, uint8_t *interruptData); uint8_t *findOpcode(Module *m, Block *block); bool saveState(Module *m, uint8_t *interruptData); uintptr_t readPointer(uint8_t **data); - public: int socket; @@ -104,7 +102,7 @@ class Debugger { void deleteBreakpoint(uint8_t *loc); bool isBreakpoint(uint8_t *loc); - + // WOOD void woodDump(Module *m); }; \ No newline at end of file diff --git a/src/Utils/util.cpp b/src/Utils/util.cpp index a4cddfe9..1c0ef87b 100644 --- a/src/Utils/util.cpp +++ b/src/Utils/util.cpp @@ -162,8 +162,7 @@ double wa_fmin(double a, double b) { return c; } - -//WOOD +// WOOD uint32_t read_B32(uint8_t **bytes) { uint8_t *b = *bytes; uint32_t n = (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3]; diff --git a/src/Utils/util.h b/src/Utils/util.h index 1dea3a05..3c7e3e31 100644 --- a/src/Utils/util.h +++ b/src/Utils/util.h @@ -67,7 +67,7 @@ double wa_fmax(double a, double b); double wa_fmin(double a, double b); -//WOOD +// WOOD uint32_t read_B32(uint8_t **bytes); uint16_t read_B16(uint8_t **bytes); int read_B32_signed(uint8_t **bytes); From 4cc12a0a2a47381659805117913463532d36f473 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Mon, 11 Apr 2022 18:11:39 +0200 Subject: [PATCH 006/249] Small fixes Fix clone command in README.md Use debug() rather than printf() Add const and static keywords Comment out fflush(stdout) --- README.md | 2 +- src/Debug/debugger.cpp | 38 +++++++++++++------------------------- src/Debug/debugger.h | 10 +++++----- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 8a52c21b..3374493e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Supported platforms: Linux (Ubuntu), macOS, ESP-IDF, Arduino The project uses CMake. Quick install looks like this: ```bash -git clone git@github.com:TOPLLab/WARDuino.git +git clone --recursive git@github.com:TOPLLab/WARDuino.git cd WARDuino mkdir build-emu cd build-emu diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 927c502f..1b43367c 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -216,7 +216,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } // Private methods -void Debugger::printValue(StackValue *v, int idx, bool end = false) { +void Debugger::printValue(StackValue *v, int idx, bool end = false) const { char buff[256]; switch (v->value_type) { @@ -266,7 +266,7 @@ void Debugger::handleInterruptRUN(Module *m, RunningState *program_state) { *program_state = WARDUINOrun; } -void Debugger::handleInterruptBP(uint8_t *interruptData) { +void Debugger::handleInterruptBP(const uint8_t *interruptData) { // TODO: segfault may happen here! uint8_t len = interruptData[1]; uintptr_t bp = 0x0; @@ -305,7 +305,7 @@ void Debugger::dump(Module *m, bool full) const { } dprintf(this->socket, "}\n\n"); - fflush(stdout); +// fflush(stdout); } void Debugger::dumpBreakpoints(Module *m) const { @@ -350,7 +350,7 @@ void Debugger::dumpCallstack(Module *m) const { } void Debugger::dumpLocals(Module *m) const { - fflush(stdout); +// fflush(stdout); int firstFunFramePtr = m->csp; while (m->callstack[firstFunFramePtr].block->block_type != 0) { firstFunFramePtr--; @@ -360,7 +360,7 @@ void Debugger::dumpLocals(Module *m) const { } Frame *f = &m->callstack[firstFunFramePtr]; dprintf(this->socket, R"({"count":%u,"locals":[)", 0); - fflush(stdout); // FIXME: this is needed for ESP to propery print +// fflush(stdout); // FIXME: this is needed for ESP to propery print char _value_str[256]; for (size_t i = 0; i < f->block->local_count; i++) { auto v = &m->stack[m->fp + i]; @@ -387,12 +387,12 @@ void Debugger::dumpLocals(Module *m) const { v->value_type, v->value.uint64); } - dprintf(this->socket, "{%s, \"index\":%i}%s", _value_str, + dprintf(this->socket, "{%s, \"index\":%lu}%s", _value_str, i + f->block->type->param_count, (i + 1 < f->block->local_count) ? "," : ""); } dprintf(this->socket, "]}"); - fflush(stdout); +// fflush(stdout); } /** @@ -580,7 +580,6 @@ enum ReceiveState { void Debugger::freeState(Module *m, uint8_t *interruptData) { debug("freeing the program state\n"); - printf("freeing the program state\n"); uint8_t *first_msg = nullptr; uint8_t *endfm = nullptr; first_msg = interruptData + 1; // skip interruptRecvState @@ -596,7 +595,6 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) { switch (*first_msg++) { case globalsState: { debug("receiving globals info\n"); - printf("receiving globals info\n"); uint32_t amount = read_B32(&first_msg); debug("total globals %d\n", amount); // TODO if global_count != amount Otherwise set all to zero @@ -620,7 +618,6 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) { } case tblState: { debug("receiving table info\n"); - printf("receiving table info\n"); m->table.initial = read_B32(&first_msg); m->table.maximum = read_B32(&first_msg); uint32_t size = read_B32(&first_msg); @@ -637,15 +634,12 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) { } case memState: { debug("receiving memory info\n"); - printf("receiving memory info\n"); // FIXME: init & max not needed m->memory.maximum = read_B32(&first_msg); m->memory.initial = read_B32(&first_msg); uint32_t pages = read_B32(&first_msg); debug("max %d init %d current page %d\n", m->memory.maximum, m->memory.initial, pages); - printf("max %d init %d current page %d\n", m->memory.maximum, - m->memory.initial, pages); // if(pages !=m->memory.pages){ // if(m->memory.pages !=0) if (m->memory.bytes != nullptr) { @@ -669,7 +663,6 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) { } } debug("done with first msg\n"); - /* printf("done with first msg\n"); */ } bool Debugger::saveState(Module *m, uint8_t *interruptData) { @@ -678,7 +671,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { program_state = interruptData + 1; // skip interruptRecvState endstate = program_state + read_B32(&program_state); - printf("saving program_state\n"); + debug("saving program_state\n"); while (program_state < endstate) { switch (*program_state++) { case pcState: { // PC @@ -688,7 +681,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { } case breakpointsState: { // breakpoints uint8_t quantity_bps = *program_state++; - printf("receiving breakpoints %" PRIu8 "\n", quantity_bps); + debug("receiving breakpoints %" PRIu8 "\n", quantity_bps); for (size_t i = 0; i < quantity_bps; i++) { auto bp = (uint8_t *)readPointer(&program_state); this->addBreakpoint(bp); @@ -697,7 +690,6 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { } case callstackState: { debug("receiving callstack\n"); - printf("receiving callstack\n"); uint16_t quantity = read_B16(&program_state); debug("quantity frames %" PRIu16 "\n", quantity); /* printf("quantity frames %" PRIu16 "\n", quantity); */ @@ -712,7 +704,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { if (block_type == 0) { // a function debug("function block\n"); uint32_t fidx = read_B32(&program_state); - /* printf("function block idx=%" PRIu32 "\n", fidx); */ + /* debug("function block idx=%" PRIu32 "\n", fidx); */ f->block = m->functions + fidx; if (f->block->fidx != fidx) { @@ -722,10 +714,10 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { } m->fp = f->sp + 1; } else { - printf("non function block\n"); + debug("non function block\n"); uint8_t *block_key = (uint8_t *)readPointer(&program_state); - /* printf("block_key=%p\n", static_cast(block_key)); */ f->block = m->block_lookup[block_key]; if (f->block == nullptr) { @@ -738,7 +730,6 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { case globalsState: { // TODO merge globalsState stackvalsState into // one case debug("receiving global state\n"); - printf("receiving globals\n"); uint32_t quantity_globals = read_B32(&program_state); uint8_t valtypes[] = {I32, I64, F32, F64}; @@ -760,7 +751,6 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { break; } case tblState: { - printf("receiving table\n"); uint8_t tbl_type = (uint8_t)*program_state++; // for now only funcref uint32_t quantity = read_B32(&program_state); @@ -772,7 +762,6 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { } case memState: { debug("receiving memory\n"); - printf("receiving memory\n"); uint32_t begin = read_B32(&program_state); uint32_t end = read_B32(&program_state); debug("memory offsets begin=%" PRIu32 " , end=%" PRIu32 "\n", @@ -798,7 +787,6 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { } case brtblState: { debug("receiving br_table\n"); - printf("receiving br_table\n"); uint16_t beginidx = read_B16(&program_state); uint16_t endidx = read_B16(&program_state); debug("br_table offsets begin=%" PRIu16 " , end=%" PRIu16 "\n", @@ -819,7 +807,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { case stackvalsState: { // FIXME the float does add numbers at the end. The extra // numbers are present in the send information when dump occurs - printf("receiving stack\n"); + debug("receiving stack\n"); uint16_t quantity_sv = read_B16(&program_state); uint8_t valtypes[] = {I32, I64, F32, F64}; for (size_t i = 0; i < quantity_sv; i++) { diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index a7405518..bc250922 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -42,7 +42,7 @@ class Debugger { // Private methods - void printValue(StackValue *v, int idx, bool end); + void printValue(StackValue *v, int idx, bool end) const; // TODO Move parsing to WARDuino class? uint8_t *parseDebugBuffer(size_t len, const uint8_t *buff); @@ -51,7 +51,7 @@ class Debugger { void handleInterruptRUN(Module *m, RunningState *program_state); - void handleInterruptBP(uint8_t *interruptData); + void handleInterruptBP(const uint8_t *interruptData); //// Information dumps @@ -67,16 +67,16 @@ class Debugger { //// Handle live code update - bool handleChangedFunction(Module *m, uint8_t *bytes); + static bool handleChangedFunction(Module *m, uint8_t *bytes); bool handleChangedLocal(Module *m, uint8_t *bytes) const; // WOOD bool receivingData = false; void freeState(Module *m, uint8_t *interruptData); - uint8_t *findOpcode(Module *m, Block *block); + static uint8_t *findOpcode(Module *m, Block *block); bool saveState(Module *m, uint8_t *interruptData); - uintptr_t readPointer(uint8_t **data); + static uintptr_t readPointer(uint8_t **data); public: int socket; From 270a59f4f164d403f13001a0e77979c00d31a73c Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 12 Apr 2022 10:09:36 +0200 Subject: [PATCH 007/249] Clang format --- src/Debug/debugger.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 1b43367c..6e2470ec 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -305,7 +305,7 @@ void Debugger::dump(Module *m, bool full) const { } dprintf(this->socket, "}\n\n"); -// fflush(stdout); + // fflush(stdout); } void Debugger::dumpBreakpoints(Module *m) const { @@ -350,7 +350,7 @@ void Debugger::dumpCallstack(Module *m) const { } void Debugger::dumpLocals(Module *m) const { -// fflush(stdout); + // fflush(stdout); int firstFunFramePtr = m->csp; while (m->callstack[firstFunFramePtr].block->block_type != 0) { firstFunFramePtr--; @@ -360,7 +360,7 @@ void Debugger::dumpLocals(Module *m) const { } Frame *f = &m->callstack[firstFunFramePtr]; dprintf(this->socket, R"({"count":%u,"locals":[)", 0); -// fflush(stdout); // FIXME: this is needed for ESP to propery print + // fflush(stdout); // FIXME: this is needed for ESP to propery print char _value_str[256]; for (size_t i = 0; i < f->block->local_count; i++) { auto v = &m->stack[m->fp + i]; @@ -392,7 +392,7 @@ void Debugger::dumpLocals(Module *m) const { (i + 1 < f->block->local_count) ? "," : ""); } dprintf(this->socket, "]}"); -// fflush(stdout); + // fflush(stdout); } /** From 8875a730b2cdcc4c6d0fd836683a4d17052d3602 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 12 Apr 2022 10:18:36 +0200 Subject: [PATCH 008/249] Fix #46 --- platforms/CLI-Emulator/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 689fca8d..887b21a5 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -12,7 +12,6 @@ #include "../../src/Debug/debugger.h" #include "../../src/Utils/macros.h" -#include "../../src/WARDuino.h" #include "../../tests/integration/wasm_tests.h" // Constants @@ -47,6 +46,9 @@ void print_help() { "binaries (default: wat2wasm)\n"); fprintf(stdout, " --file Wasm file (module) to load and execute\n"); + fprintf(stdout, + " --no-socket Run without socket " + "(default: false)\n"); } Module *load(WARDuino wac, const char *file_name, Options opt) { @@ -116,7 +118,7 @@ void bindSocketToAddress(int socket_fd, struct sockaddr_in address) { } struct sockaddr_in createAddress(int port) { - struct sockaddr_in address; + struct sockaddr_in address {}; address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(port); From 8efbf5328b4abbe77846bf86fd473e3506820aa9 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 12 Apr 2022 11:03:59 +0200 Subject: [PATCH 009/249] Fix some Clang-Tidy warnings --- src/Debug/debugger.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 6e2470ec..59375900 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -163,7 +163,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptUPDATEFun: dprintf(this->socket, "CHANGE function!\n"); - this->handleChangedFunction(m, interruptData); + Debugger::handleChangedFunction(m, interruptData); // do not free(interruptData); // we need it to run that code // TODO: free double replacements @@ -513,36 +513,36 @@ void Debugger::woodDump(Module *m) { // stack dprintf(this->socket, "\"stack\":["); char _value_str[256]; - for (int i = 0; i <= m->sp; i++) { - auto v = &m->stack[i]; - printValue(v, i, i == m->sp); + for (int j = 0; j <= m->sp; j++) { + auto v = &m->stack[j]; + printValue(v, j, j == m->sp); } dprintf(this->socket, "],"); // Callstack dprintf(this->socket, "\"callstack\":["); - for (int i = 0; i <= m->csp; i++) { - Frame *f = &m->callstack[i]; + for (int j = 0; j <= m->csp; j++) { + Frame *f = &m->callstack[j]; uint8_t *block_key = f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); dprintf( this->socket, - R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p", "idx":%d}%s)", + R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p"}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, - static_cast(f->ra_ptr), i, (i < m->csp) ? "," : ""); + static_cast(f->ra_ptr), j, (j < m->csp) ? "," : ""); } // printf("asked for globals\n"); // GLobals dprintf(this->socket, "],\"globals\":["); - for (uint32_t i = 0; i < m->global_count; i++) { - auto v = m->globals + i; - printValue(v, i, i == (m->global_count - 1)); + for (uint32_t j = 0; j < m->global_count; j++) { + auto v = m->globals + j; + printValue(v, j, j == (m->global_count - 1)); } dprintf(this->socket, "]"); // closing globals // printf("asked for table\n"); - dprintf(this->socket, ",\"table\":{\"max\":%d, \"init\":%d, \"elements\":[", + dprintf(this->socket, R"(,"table":{"max":%d, "init":%d, "elements":[)", m->table.maximum, m->table.initial); // write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); @@ -553,14 +553,14 @@ void Debugger::woodDump(Module *m) { uint32_t total_elems = m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE dprintf(this->socket, - ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", + R"(,"memory":{"pages":%d,"max":%d,"init":%d,"bytes":[)", m->memory.pages, m->memory.maximum, m->memory.initial); // write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); dprintf(this->socket, "]}"); // closing memory // printf("asked for br_table\n"); - dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", + dprintf(this->socket, R"(,"br_table":{"size":"0x%x","labels":[)", BR_TABLE_SIZE); write(this->socket, m->br_table, BR_TABLE_SIZE * sizeof(uint32_t)); dprintf(this->socket, "]}}\n"); @@ -715,7 +715,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { m->fp = f->sp + 1; } else { debug("non function block\n"); - uint8_t *block_key = + auto *block_key = (uint8_t *)readPointer(&program_state); /* debug("block_key=%p\n", static_cast(block_key)); */ @@ -751,7 +751,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { break; } case tblState: { - uint8_t tbl_type = + auto tbl_type = (uint8_t)*program_state++; // for now only funcref uint32_t quantity = read_B32(&program_state); for (size_t i = 0; i < quantity; i++) { @@ -826,11 +826,11 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { break; } default: { - FATAL("saveState: Reiceived unknown program state\n"); + FATAL("saveState: Received unknown program state\n"); } } } - uint8_t done = (uint8_t)*program_state; + auto done = (uint8_t)*program_state; return done == (uint8_t)1; } From 48dcec2e8d23b2d1fa7892e6cf2e8619e1cf5fd5 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 12 Apr 2022 16:03:22 +0200 Subject: [PATCH 010/249] Add 0x60 to DumpFormat.md + cleanup --- documentation/DumpFormat.md | 76 +++++++++++++++++++++++++++++++++++++ platforms/Arduino/Makefile | 4 +- src/Debug/debugger.cpp | 14 ++----- src/Utils/macros.h | 1 - src/WARDuino.h | 5 +-- src/WARDuino/WARDuino.cpp | 1 - 6 files changed, 83 insertions(+), 18 deletions(-) diff --git a/documentation/DumpFormat.md b/documentation/DumpFormat.md index 95c970c1..f63728f1 100644 --- a/documentation/DumpFormat.md +++ b/documentation/DumpFormat.md @@ -91,3 +91,79 @@ The locals can also be retreived on their own with the 0x11 byte. } ``` +## WOOD Dump (0x60) + +```json +{ + "pc":"0x564df0c5e746", + "start":[ + "0x564df0c5e6a0" + ], + "breakpoints":[ + + ], + "stack":[ + { + "idx":0, + "type":"i32", + "value":1000 + } + ], + "callstack":[ + { + "type":0, + "fidx":"0x4", + "sp":-1, + "fp":-1, + "block_key":"(nil)", + "ra":"0x564df0c5e70f" + }, + { + "type":3, + "fidx":"0x0", + "sp":0, + "fp":0, + "block_key":"0x564df0c5e730", + "ra":"0x564df0c5e732" + } + ], + "globals":[ + { + "idx":0, + "type":"i32", + "value":23 + }, + { + "idx":1, + "type":"i32", + "value":1 + }, + { + "idx":2, + "type":"i32", + "value":0 + } + ], + "table":{ + "max":0, + "init":0, + "elements":[ + + ] + }, + "memory":{ + "pages":0, + "max":0, + "init":0, + "bytes":[ + + ] + }, + "br_table":{ + "size":"0x100", + "labels":[ + + ] + } +} +``` diff --git a/platforms/Arduino/Makefile b/platforms/Arduino/Makefile index 4b1f2ff8..8b9a77d6 100644 --- a/platforms/Arduino/Makefile +++ b/platforms/Arduino/Makefile @@ -1,8 +1,8 @@ flash: - arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:esp32wrover Arduino.ino + arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:esp32wrover Arduino.ino compile: arduino-cli -v compile --fqbn esp32:esp32:esp32wrover Arduino.ino monitor: - arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200 + arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200 diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 59375900..d5dbabbc 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -141,11 +141,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptBPAdd: // Breakpoint case interruptBPRem: // Breakpoint remove - { this->handleInterruptBP(interruptData); free(interruptData); break; - } case interruptDUMP: *program_state = WARDUINOpause; this->dump(m); @@ -178,13 +176,12 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { free(interruptData); woodDump(m); break; - case interruptOffset: { + case interruptOffset: free(interruptData); dprintf(this->socket, "\"{\"offset\":\"%p\"}\"\n", (void *)m->bytes); break; - } - case interruptRecvState: { + case interruptRecvState: if (!this->receivingData) { debug("paused program execution\n"); *program_state = WARDUINOpause; @@ -193,7 +190,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { free(interruptData); dprintf(this->socket, "ack!\n"); } else { - printf("reeiving state\n"); + printf("receiving state\n"); debug("receiving state\n"); receivingData = !this->saveState(m, interruptData); free(interruptData); @@ -204,7 +201,6 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } } break; - } default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); @@ -489,8 +485,7 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { void Debugger::woodDump(Module *m) { // FIXME replace write - debug("asked for doDump\n"); - dprintf(this->socket, "DUMP!\n"); + debug("asked for woodDump\n"); dprintf(this->socket, "{"); // printf("asked for pc\n"); @@ -512,7 +507,6 @@ void Debugger::woodDump(Module *m) { // printf("asked for stack\n"); // stack dprintf(this->socket, "\"stack\":["); - char _value_str[256]; for (int j = 0; j <= m->sp; j++) { auto v = &m->stack[j]; printValue(v, j, j == m->sp); diff --git a/src/Utils/macros.h b/src/Utils/macros.h index 581d2d40..89c21acb 100644 --- a/src/Utils/macros.h +++ b/src/Utils/macros.h @@ -1,4 +1,3 @@ - #pragma once #include diff --git a/src/WARDuino.h b/src/WARDuino.h index c91f36ea..3a39bd41 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -1,5 +1,4 @@ -#ifndef WAC_H -#define WAC_H +#pragma once #include #include @@ -197,5 +196,3 @@ class WARDuino { void handleInterrupt(size_t len, uint8_t *buff); }; - -#endif diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index 8d93bce2..d159cc24 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -3,7 +3,6 @@ #include // std::find #include #include -#include #include "../Interpreter/instructions.h" #include "../Memory/mem.h" From 390aeeda3def6edf2a3c29c72485edfa921fe28f Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 12 Apr 2022 17:11:35 +0200 Subject: [PATCH 011/249] Fix Arduino compile error Local variable `end` shadowed function from `macros.h`. --- src/Debug/debugger.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index d5dbabbc..78ab70fd 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -756,22 +756,22 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { } case memState: { debug("receiving memory\n"); - uint32_t begin = read_B32(&program_state); - uint32_t end = read_B32(&program_state); - debug("memory offsets begin=%" PRIu32 " , end=%" PRIu32 "\n", - begin, end); - if (begin > end) { + uint32_t start = read_B32(&program_state); + uint32_t limit = read_B32(&program_state); + debug("memory offsets start=%" PRIu32 " , limit=%" PRIu32 "\n", + start, limit); + if (start > limit) { FATAL("incorrect memory offsets\n"); } - uint32_t totalbytes = end - begin + 1; + uint32_t totalbytes = limit - start + 1; uint8_t *mem_end = m->memory.bytes + m->memory.pages * (uint32_t)PAGE_SIZE; debug("will copy #%" PRIu32 " bytes\n", totalbytes); - if ((m->bytes + begin) + totalbytes > mem_end) { + if ((m->bytes + start) + totalbytes > mem_end) { FATAL("memory overflow\n"); } - memcpy(m->memory.bytes + begin, program_state, totalbytes + 1); - for (auto i = begin; i <= (begin + totalbytes - 1); i++) { + memcpy(m->memory.bytes + start, program_state, totalbytes + 1); + for (auto i = start; i <= (start + totalbytes - 1); i++) { debug("GOT byte idx %" PRIu32 " =%" PRIu8 "\n", i, m->memory.bytes[i]); } From 68d9a6a8cfbf19a2fc6a01316730c34e81bd0c96 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 13 Apr 2022 13:05:58 +0200 Subject: [PATCH 012/249] Update docs --- documentation/DumpFormat.md | 159 ++++++++++++++++++++---------------- src/Debug/debugger.cpp | 3 +- 2 files changed, 91 insertions(+), 71 deletions(-) diff --git a/documentation/DumpFormat.md b/documentation/DumpFormat.md index f63728f1..cfa74fc2 100644 --- a/documentation/DumpFormat.md +++ b/documentation/DumpFormat.md @@ -95,75 +95,94 @@ The locals can also be retreived on their own with the 0x11 byte. ```json { - "pc":"0x564df0c5e746", - "start":[ - "0x564df0c5e6a0" - ], - "breakpoints":[ - - ], - "stack":[ - { - "idx":0, - "type":"i32", - "value":1000 - } - ], - "callstack":[ - { - "type":0, - "fidx":"0x4", - "sp":-1, - "fp":-1, - "block_key":"(nil)", - "ra":"0x564df0c5e70f" - }, - { - "type":3, - "fidx":"0x0", - "sp":0, - "fp":0, - "block_key":"0x564df0c5e730", - "ra":"0x564df0c5e732" - } - ], - "globals":[ - { - "idx":0, - "type":"i32", - "value":23 - }, - { - "idx":1, - "type":"i32", - "value":1 - }, - { - "idx":2, - "type":"i32", - "value":0 - } - ], - "table":{ - "max":0, - "init":0, - "elements":[ - - ] - }, - "memory":{ - "pages":0, - "max":0, - "init":0, - "bytes":[ - - ] - }, - "br_table":{ - "size":"0x100", - "labels":[ - - ] - } + "pc":"0x60000272806e", + "start":[ + "0x600002728000" + ], + "breakpoints":[ + + ], + "stack":[ + { + "idx":0, + "type":"i32", + "value":5 + }, + { + "idx":1, + "type":"i32", + "value":5 + }, + { + "idx":2, + "type":"i32", + "value":5 + } + ], + "callstack":[ + { + "type":0, + "fidx":"0x3", + "sp":-1, + "fp":-1, + "block_key":"0x0", + "ra":"0x60000272805a", + "idx":0 + }, + { + "type":3, + "fidx":"0x0", + "sp":0, + "fp":0, + "block_key":"0x600002728083", + "ra":"0x600002728085", + "idx":1 + }, + { + "type":0, + "fidx":"0x2", + "sp":0, + "fp":0, + "block_key":"0x0", + "ra":"0x600002728089", + "idx":2 + }, + { + "type":4, + "fidx":"0x0", + "sp":2, + "fp":1, + "block_key":"0x60000272806a", + "ra":"0x60000272806c", + "idx":3 + } + ], + "globals":[ + { + "idx":0, + "type":"i32", + "value":0 + }, + { + "idx":1, + "type":"i32", + "value":0 + } + ], + "table":{ + "max":2, + "init":2, + "elements":"" + }, + "memory":{ + "pages":2, + "max":32768, + "init":2, + "bytes":"" + }, + "br_table":{ + "size":"0x100", + "labels":"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00" + } } ``` diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 78ab70fd..e06729e4 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -670,7 +670,8 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { switch (*program_state++) { case pcState: { // PC m->pc_ptr = (uint8_t *)readPointer(&program_state); - /* printf("receiving pc %p\n", static_cast(m->pc_ptr)); */ + /* printf("receiving pc %p\n", static_cast(m->pc_ptr)); + */ break; } case breakpointsState: { // breakpoints From e7c17524153e43e65968f969fe1488876ba17a1a Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 13 Apr 2022 13:11:55 +0200 Subject: [PATCH 013/249] restore working woodDump --- src/Debug/debugger.cpp | 43 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index e06729e4..212f36ce 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -485,7 +485,9 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { void Debugger::woodDump(Module *m) { // FIXME replace write - debug("asked for woodDump\n"); + debug("asked for doDump\n"); + printf("asked for woodDump\n"); + dprintf(this->socket, "DUMP!\n"); dprintf(this->socket, "{"); // printf("asked for pc\n"); @@ -500,62 +502,61 @@ void Debugger::woodDump(Module *m) { size_t i = 0; for (auto bp : this->breakpoints) { dprintf(this->socket, R"("%p"%s)", bp, - (++i < this->breakpoints.size()) ? "," : ""); + (++i < this->breakpoints.size()) ? "," : ""); } dprintf(this->socket, "],"); // printf("asked for stack\n"); - // stack + //stack dprintf(this->socket, "\"stack\":["); - for (int j = 0; j <= m->sp; j++) { - auto v = &m->stack[j]; - printValue(v, j, j == m->sp); + for (int i = 0; i <= m->sp; i++) { + auto v = &m->stack[i]; + printValue(v, i, i == m->sp); } dprintf(this->socket, "],"); // Callstack dprintf(this->socket, "\"callstack\":["); - for (int j = 0; j <= m->csp; j++) { - Frame *f = &m->callstack[j]; + for (int i = 0; i <= m->csp; i++) { + Frame *f = &m->callstack[i]; uint8_t *block_key = f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); dprintf( this->socket, R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p"}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, - static_cast(f->ra_ptr), j, (j < m->csp) ? "," : ""); + static_cast(f->ra_ptr), i, (j < m->csp) ? "," : ""); } // printf("asked for globals\n"); // GLobals dprintf(this->socket, "],\"globals\":["); - for (uint32_t j = 0; j < m->global_count; j++) { - auto v = m->globals + j; - printValue(v, j, j == (m->global_count - 1)); + for (uint32_t i = 0; i < m->global_count; i++) { + auto v = m->globals + i; + printValue(v, i, i == (m->global_count - 1)); } dprintf(this->socket, "]"); // closing globals // printf("asked for table\n"); - dprintf(this->socket, R"(,"table":{"max":%d, "init":%d, "elements":[)", - m->table.maximum, m->table.initial); + dprintf(this->socket, ",\"table\":{\"max\":%d, \"init\":%d, \"elements\":[", + m->table.maximum, m->table.initial); - // write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); + write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); dprintf(this->socket, "]}"); // closing table // printf("asked for mem\n"); // memory uint32_t total_elems = m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE - dprintf(this->socket, - R"(,"memory":{"pages":%d,"max":%d,"init":%d,"bytes":[)", - m->memory.pages, m->memory.maximum, m->memory.initial); + dprintf(this->socket, ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", + m->memory.pages, m->memory.maximum, m->memory.initial); - // write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); + write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); dprintf(this->socket, "]}"); // closing memory + // printf("asked for br_table\n"); - dprintf(this->socket, R"(,"br_table":{"size":"0x%x","labels":[)", - BR_TABLE_SIZE); + dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", BR_TABLE_SIZE); write(this->socket, m->br_table, BR_TABLE_SIZE * sizeof(uint32_t)); dprintf(this->socket, "]}}\n"); } From 59fde686c94f1d1966f219975f342d70f7d14354 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 13 Apr 2022 13:20:02 +0200 Subject: [PATCH 014/249] fix incorrect index j --- src/Debug/debugger.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 212f36ce..a2d6fcf2 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -483,7 +483,6 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { return true; } void Debugger::woodDump(Module *m) { - // FIXME replace write debug("asked for doDump\n"); printf("asked for woodDump\n"); @@ -521,11 +520,10 @@ void Debugger::woodDump(Module *m) { Frame *f = &m->callstack[i]; uint8_t *block_key = f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); - dprintf( - this->socket, - R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p"}%s)", + dprintf(this->socket, + R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p", "idx":%d}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, - static_cast(f->ra_ptr), i, (j < m->csp) ? "," : ""); + static_cast(f->ra_ptr), i, (i < m->csp) ? "," : ""); } // printf("asked for globals\n"); From 09e2f7f50741736424442edd638eba2d3aa4d2f0 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 13 Apr 2022 17:53:30 +0200 Subject: [PATCH 015/249] bug fix: writing to memory bytes --- src/Debug/debugger.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index a2d6fcf2..343706a6 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -669,8 +669,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { switch (*program_state++) { case pcState: { // PC m->pc_ptr = (uint8_t *)readPointer(&program_state); - /* printf("receiving pc %p\n", static_cast(m->pc_ptr)); - */ + /* printf("receiving pc %p\n", static_cast(m->pc_ptr)); */ break; } case breakpointsState: { // breakpoints @@ -767,8 +766,8 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { uint8_t *mem_end = m->memory.bytes + m->memory.pages * (uint32_t)PAGE_SIZE; debug("will copy #%" PRIu32 " bytes\n", totalbytes); - if ((m->bytes + start) + totalbytes > mem_end) { - FATAL("memory overflow\n"); + if ((m->memory.bytes + start) + totalbytes > mem_end) { + FATAL("memory overflow %p > %p\n", static_cast( (m->bytes + start) + totalbytes), static_cast(mem_end)); } memcpy(m->memory.bytes + start, program_state, totalbytes + 1); for (auto i = start; i <= (start + totalbytes - 1); i++) { From ca60111a3ee1a764d18c0a25d3af5289e69fbf0d Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Tue, 19 Apr 2022 10:33:16 +0200 Subject: [PATCH 016/249] dump fully as json --- src/Debug/debugger.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 343706a6..e253bd48 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -539,7 +539,9 @@ void Debugger::woodDump(Module *m) { dprintf(this->socket, ",\"table\":{\"max\":%d, \"init\":%d, \"elements\":[", m->table.maximum, m->table.initial); - write(this->socket, m->table.entries, sizeof(uint32_t) * m->table.size); + for (uint32_t i = 0; i < m->table.size; i++) { + dprintf(this->socket, "%" PRIu32 "%s", m->table.entries[i], (i + 1) == m->table.size ? "" : ","); + } dprintf(this->socket, "]}"); // closing table // printf("asked for mem\n"); @@ -548,14 +550,18 @@ void Debugger::woodDump(Module *m) { m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE dprintf(this->socket, ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", m->memory.pages, m->memory.maximum, m->memory.initial); - - write(this->socket, m->memory.bytes, total_elems * sizeof(uint8_t)); + for (uint32_t i = 0; i < total_elems; i++) { + dprintf(this->socket, "%" PRIu8 "%s",m->memory.bytes[i], (i + 1) == total_elems ? "" : ","); + } dprintf(this->socket, "]}"); // closing memory // printf("asked for br_table\n"); dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", BR_TABLE_SIZE); - write(this->socket, m->br_table, BR_TABLE_SIZE * sizeof(uint32_t)); + total_elems = BR_TABLE_SIZE * sizeof(uint32_t); + for (uint32_t i = 0; i < total_elems; i++) { + dprintf(this->socket, "%" PRIu32 "%s", m->br_table[i], (i + 1) == total_elems ? "" : ","); + } dprintf(this->socket, "]}}\n"); } From ff2ac945ecd9260ec45d8a2ceca92285e420edce Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Tue, 19 Apr 2022 13:05:18 +0200 Subject: [PATCH 017/249] bug fix: incorrect loop end condition --- src/Debug/debugger.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index e253bd48..6c164f9f 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -558,9 +558,8 @@ void Debugger::woodDump(Module *m) { // printf("asked for br_table\n"); dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", BR_TABLE_SIZE); - total_elems = BR_TABLE_SIZE * sizeof(uint32_t); - for (uint32_t i = 0; i < total_elems; i++) { - dprintf(this->socket, "%" PRIu32 "%s", m->br_table[i], (i + 1) == total_elems ? "" : ","); + for (uint32_t i = 0; i < BR_TABLE_SIZE; i++) { + dprintf(this->socket, "%" PRIu32 "%s", m->br_table[i], (i + 1) == BR_TABLE_SIZE ? "" : ","); } dprintf(this->socket, "]}}\n"); } From 3ad13d0af4de99fdbaf8726df6e098d544b6e641 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Tue, 19 Apr 2022 13:07:19 +0200 Subject: [PATCH 018/249] clang-format --- src/Debug/debugger.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 6c164f9f..5910ac97 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -483,7 +483,6 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { return true; } void Debugger::woodDump(Module *m) { - debug("asked for doDump\n"); printf("asked for woodDump\n"); dprintf(this->socket, "DUMP!\n"); @@ -501,12 +500,12 @@ void Debugger::woodDump(Module *m) { size_t i = 0; for (auto bp : this->breakpoints) { dprintf(this->socket, R"("%p"%s)", bp, - (++i < this->breakpoints.size()) ? "," : ""); + (++i < this->breakpoints.size()) ? "," : ""); } dprintf(this->socket, "],"); // printf("asked for stack\n"); - //stack + // stack dprintf(this->socket, "\"stack\":["); for (int i = 0; i <= m->sp; i++) { auto v = &m->stack[i]; @@ -520,7 +519,8 @@ void Debugger::woodDump(Module *m) { Frame *f = &m->callstack[i]; uint8_t *block_key = f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); - dprintf(this->socket, + dprintf( + this->socket, R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p", "idx":%d}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, static_cast(f->ra_ptr), i, (i < m->csp) ? "," : ""); @@ -531,16 +531,17 @@ void Debugger::woodDump(Module *m) { dprintf(this->socket, "],\"globals\":["); for (uint32_t i = 0; i < m->global_count; i++) { auto v = m->globals + i; - printValue(v, i, i == (m->global_count - 1)); + printValue(v, i, i == (m->global_count - 1)); } dprintf(this->socket, "]"); // closing globals // printf("asked for table\n"); dprintf(this->socket, ",\"table\":{\"max\":%d, \"init\":%d, \"elements\":[", - m->table.maximum, m->table.initial); + m->table.maximum, m->table.initial); for (uint32_t i = 0; i < m->table.size; i++) { - dprintf(this->socket, "%" PRIu32 "%s", m->table.entries[i], (i + 1) == m->table.size ? "" : ","); + dprintf(this->socket, "%" PRIu32 "%s", m->table.entries[i], + (i + 1) == m->table.size ? "" : ","); } dprintf(this->socket, "]}"); // closing table @@ -548,18 +549,21 @@ void Debugger::woodDump(Module *m) { // memory uint32_t total_elems = m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE - dprintf(this->socket, ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", - m->memory.pages, m->memory.maximum, m->memory.initial); + dprintf(this->socket, + ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", + m->memory.pages, m->memory.maximum, m->memory.initial); for (uint32_t i = 0; i < total_elems; i++) { - dprintf(this->socket, "%" PRIu8 "%s",m->memory.bytes[i], (i + 1) == total_elems ? "" : ","); + dprintf(this->socket, "%" PRIu8 "%s", m->memory.bytes[i], + (i + 1) == total_elems ? "" : ","); } dprintf(this->socket, "]}"); // closing memory - // printf("asked for br_table\n"); - dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", BR_TABLE_SIZE); + dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", + BR_TABLE_SIZE); for (uint32_t i = 0; i < BR_TABLE_SIZE; i++) { - dprintf(this->socket, "%" PRIu32 "%s", m->br_table[i], (i + 1) == BR_TABLE_SIZE ? "" : ","); + dprintf(this->socket, "%" PRIu32 "%s", m->br_table[i], + (i + 1) == BR_TABLE_SIZE ? "" : ","); } dprintf(this->socket, "]}}\n"); } @@ -674,7 +678,8 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { switch (*program_state++) { case pcState: { // PC m->pc_ptr = (uint8_t *)readPointer(&program_state); - /* printf("receiving pc %p\n", static_cast(m->pc_ptr)); */ + /* printf("receiving pc %p\n", static_cast(m->pc_ptr)); + */ break; } case breakpointsState: { // breakpoints @@ -772,7 +777,9 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { m->memory.bytes + m->memory.pages * (uint32_t)PAGE_SIZE; debug("will copy #%" PRIu32 " bytes\n", totalbytes); if ((m->memory.bytes + start) + totalbytes > mem_end) { - FATAL("memory overflow %p > %p\n", static_cast( (m->bytes + start) + totalbytes), static_cast(mem_end)); + FATAL("memory overflow %p > %p\n", + static_cast((m->bytes + start) + totalbytes), + static_cast(mem_end)); } memcpy(m->memory.bytes + start, program_state, totalbytes + 1); for (auto i = start; i <= (start + totalbytes - 1); i++) { From 8dbca8ad2002e92f38023de47a4e84d9e459cf7f Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 19 Apr 2022 15:03:46 +0200 Subject: [PATCH 019/249] Fix WOOD offset JSON format --- src/Debug/debugger.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 5910ac97..11046ee8 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -178,8 +178,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptOffset: free(interruptData); - dprintf(this->socket, "\"{\"offset\":\"%p\"}\"\n", - (void *)m->bytes); + dprintf(this->socket, "{\"offset\":\"%p\"}\n", (void *)m->bytes); break; case interruptRecvState: if (!this->receivingData) { From 53afb4d79fafa3f047fd244c85657002b72ba652 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 19 Apr 2022 16:48:53 +0200 Subject: [PATCH 020/249] Split primitive file Closes #51 --- CMakeLists.txt | 2 +- examples/assemblyscript/main/CMakeLists.txt | 20 +- examples/blink/main/CMakeLists.txt | 20 +- platforms/ESP-IDF/CMakeLists.txt | 20 +- .../{primitives.cpp => arduino.cpp} | 294 +---------- src/Primitives/emulated.cpp | 487 ++++++++++++++++++ src/Primitives/primitives.h | 6 + 7 files changed, 528 insertions(+), 321 deletions(-) rename src/Primitives/{primitives.cpp => arduino.cpp} (76%) create mode 100644 src/Primitives/emulated.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2738064a..7c46a0bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ if (BUILD_EMULATOR) src/Utils/macros.cpp src/WARDuino/WARDuino.cpp src/WARDuino/CallbackHandler.cpp - src/Primitives/primitives.cpp + src/Primitives/primitives.h src/Interpreter/instructions.cpp ) set(TEST_FRAMEWORK diff --git a/examples/assemblyscript/main/CMakeLists.txt b/examples/assemblyscript/main/CMakeLists.txt index f9742f5a..399d84c3 100644 --- a/examples/assemblyscript/main/CMakeLists.txt +++ b/examples/assemblyscript/main/CMakeLists.txt @@ -1,14 +1,14 @@ set(SOURCE_FILES - ../../../src/Memory/mem.cpp - ../../../src/Utils/util.cpp - ../../../src/Utils/util_arduino.cpp - ../../../src/Debug/debugger.cpp - ../../../src/Utils/macros.cpp - ../../../src/WARDuino/WARDuino.cpp - ../../../src/Primitives/primitives.cpp - ../../../src/Interpreter/instructions.cpp - ../../../src/WARDuino/CallbackHandler.cpp - ) + ../../../src/Memory/mem.cpp + ../../../src/Utils/util.cpp + ../../../src/Utils/util_arduino.cpp + ../../../src/Debug/debugger.cpp + ../../../src/Utils/macros.cpp + ../../../src/WARDuino/WARDuino.cpp + ../../../src/Primitives/primitives.h + ../../../src/Interpreter/instructions.cpp + ../../../src/WARDuino/CallbackHandler.cpp + ) idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS "" REQUIRES driver) diff --git a/examples/blink/main/CMakeLists.txt b/examples/blink/main/CMakeLists.txt index f9742f5a..399d84c3 100644 --- a/examples/blink/main/CMakeLists.txt +++ b/examples/blink/main/CMakeLists.txt @@ -1,14 +1,14 @@ set(SOURCE_FILES - ../../../src/Memory/mem.cpp - ../../../src/Utils/util.cpp - ../../../src/Utils/util_arduino.cpp - ../../../src/Debug/debugger.cpp - ../../../src/Utils/macros.cpp - ../../../src/WARDuino/WARDuino.cpp - ../../../src/Primitives/primitives.cpp - ../../../src/Interpreter/instructions.cpp - ../../../src/WARDuino/CallbackHandler.cpp - ) + ../../../src/Memory/mem.cpp + ../../../src/Utils/util.cpp + ../../../src/Utils/util_arduino.cpp + ../../../src/Debug/debugger.cpp + ../../../src/Utils/macros.cpp + ../../../src/WARDuino/WARDuino.cpp + ../../../src/Primitives/primitives.h + ../../../src/Interpreter/instructions.cpp + ../../../src/WARDuino/CallbackHandler.cpp + ) idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS "" REQUIRES driver) diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index 694cad97..db903e01 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -1,14 +1,14 @@ set(SOURCE_FILES - ../../src/Memory/mem.cpp - ../../src/Utils/util.cpp - ../../src/Utils/util_arduino.cpp - ../../src/Debug/debugger.cpp - ../../src/Utils/macros.cpp - ../../src/WARDuino/WARDuino.cpp - ../../src/Primitives/primitives.cpp - ../../src/Interpreter/instructions.cpp - ../../src/WARDuino/CallbackHandler.cpp - ) + ../../src/Memory/mem.cpp + ../../src/Utils/util.cpp + ../../src/Utils/util_arduino.cpp + ../../src/Debug/debugger.cpp + ../../src/Utils/macros.cpp + ../../src/WARDuino/WARDuino.cpp + ../../src/Primitives/primitives.h + ../../src/Interpreter/instructions.cpp + ../../src/WARDuino/CallbackHandler.cpp + ) idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS "" REQUIRES driver) diff --git a/src/Primitives/primitives.cpp b/src/Primitives/arduino.cpp similarity index 76% rename from src/Primitives/primitives.cpp rename to src/Primitives/arduino.cpp index 89e5423d..ce1e97f3 100644 --- a/src/Primitives/primitives.cpp +++ b/src/Primitives/arduino.cpp @@ -9,8 +9,10 @@ * 4) Extend the install_primitives function * */ -#include "primitives.h" +#include "Arduino.h" +#include +#include #include #include @@ -21,12 +23,6 @@ #include "../Utils/macros.h" #include "../Utils/util.h" -#ifdef ARDUINO -#include -#include - -#include "Arduino.h" - // NEOPIXEL #include #define PIN 33 @@ -55,19 +51,8 @@ void write_spi_bytes_16_prim(int times, uint32_t color) { spi->endTransaction(); } -#else - -#include -#include - -#endif - #define NUM_PRIMITIVES 0 -#ifdef ARDUINO #define NUM_PRIMITIVES_ARDUINO 33 -#else -#define NUM_PRIMITIVES_ARDUINO 23 -#endif #define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) @@ -77,7 +62,7 @@ int prim_index = 0; double sensor_emu = 0; /* - Private macros to install a primitive + Private macros to install a primitive */ #define install_primitive(prim_name) \ { \ @@ -242,7 +227,6 @@ Type NoneToOneU64 = {.form = FUNC, .mask = 0x82000}; // Util function declarations -#ifdef ARDUINO void connect(const String ssid, const String password); @@ -254,12 +238,9 @@ int32_t http_post_request(Module *m, const String url, const String body, const String authorization_parsed, uint32_t response, uint32_t size); -#endif - //------------------------------------------------------ // Arduino Specific Functions //------------------------------------------------------ -#ifdef ARDUINO def_prim(abort, NoneToNoneU32) { sprintf(exception, "Trap: assertion failed."); @@ -735,235 +716,9 @@ def_prim(mqtt_loop, NoneToOneU32) { return true; } -#else - -def_prim(init_pixels, NoneToNoneU32) { - printf("init_pixels \n"); - return true; -} - -def_prim(set_pixel_color, fourToOneU32) { - printf("set_pixel_color \n"); - pop_args(4); - return true; -} - -def_prim(show_pixels, NoneToNoneU32) { - printf("show pixels \n"); - return true; -} - -def_prim(clear_pixels, NoneToNoneU32) { - printf("clear pixels \n"); - return true; -} - -def_prim(abort, NoneToNoneU32) { - debug("EMU: abort\n"); - return false; -} - -def_prim(micros, NoneToOneU64) { - struct timeval tv {}; - gettimeofday(&tv, nullptr); - unsigned long micros = 1000000 * tv.tv_sec + tv.tv_usec; - pushUInt64(micros); - return true; -} - -// call callback test function (temporary) -def_prim(test, oneToNoneU32) { - uint32_t fidx = arg0.uint32; - - std::string topic = "interrupt"; - topic.append(std::to_string(fidx)); - - Callback c = Callback(m, topic, fidx); - CallbackHandler::add_callback(c); - auto *payload = reinterpret_cast("TestPayload"); - CallbackHandler::push_event(topic, payload, 11); - pop_args(1); - return true; -} - -def_prim(print_int, oneToNoneU32) { - debug("EMU: print "); - printf("%u\n", arg0.uint32); - pop_args(1); - return true; -} - -def_prim(print_string, twoToNoneU32) { - uint32_t addr = arg1.uint32; - uint32_t size = arg0.uint32; - std::string text = parse_utf8_string(m->memory.bytes, size, addr); - debug("EMU: print string at %i: ", addr); - printf("%s\n", text.c_str()); - pop_args(2); - return true; -} - -def_prim(wifi_connect, fourToNoneU32) { - uint32_t ssid = arg3.uint32; - uint32_t len0 = arg2.uint32; - uint32_t pass = arg1.uint32; - uint32_t len1 = arg0.uint32; - - std::string ssid_str = parse_utf8_string(m->memory.bytes, len0, ssid); - std::string pass_str = parse_utf8_string(m->memory.bytes, len1, pass); - debug("EMU: connect to %s with password %s\n", ssid_str.c_str(), - pass_str.c_str()); - pop_args(4); - return true; -} - -def_prim(wifi_status, NoneToOneU32) { - pushInt32(3); // return WL_CONNECTED - return true; -} - -def_prim(wifi_localip, twoToOneU32) { - uint32_t buff = arg1.uint32; - uint32_t size = arg0.uint32; - std::string ip = "192.168.0.181"; - - for (unsigned long i = 0; i < ip.length(); i++) { - m->memory.bytes[buff + i] = (uint32_t)ip[i]; - } - pop_args(2); - pushInt32(buff); - return true; -} - -def_prim(http_get, fourToOneU32) { - // Get arguments - uint32_t url = arg3.uint32; - uint32_t length = arg2.uint32; - int32_t response = arg1.uint32; - uint32_t size = arg0.uint32; - // Parse url - std::string text = parse_utf8_string(m->memory.bytes, length, url); - debug("EMU: http get request %s\n", text.c_str()); - // Construct response - std::string answer = "Response code: 200."; - if (answer.length() > size) { - sprintf(exception, "GET: buffer size is too small for response."); - return false; // TRAP - } - for (unsigned long i = 0; i < answer.length(); i++) { - m->memory.bytes[response + i] = (uint32_t)answer[i]; - } - - // Pop args and return response address - pop_args(4); - pushInt32(response); - return true; -} - -def_prim(http_post, tenToOneU32) { - // Get arguments - uint32_t url = arg9.uint32; - uint32_t url_len = arg8.uint32; - uint32_t body = arg7.uint32; - uint32_t body_len = arg6.uint32; - uint32_t content_type = arg5.uint32; - uint32_t content_type_len = arg4.uint32; - uint32_t authorization = arg3.uint32; - uint32_t authorization_len = arg2.uint32; - int32_t response = arg1.uint32; - uint32_t size = arg0.uint32; - - std::string url_parsed = parse_utf8_string(m->memory.bytes, url_len, url); - std::string body_parsed = - parse_utf8_string(m->memory.bytes, body_len, body); - std::string content_type_parsed = - parse_utf8_string(m->memory.bytes, content_type_len, content_type); - std::string authorization_parsed = - parse_utf8_string(m->memory.bytes, authorization_len, authorization); - debug( - "EMU: POST %s\n\t Content-type: '%s'\n\t Authorization: '%s'\n\t " - "'%s'\n", - url_parsed.c_str(), content_type_parsed.c_str(), - authorization_parsed.c_str(), body_parsed.c_str()); - - pop_args(10); - pushInt32(response); - return true; -} - -def_prim(chip_pin_mode, twoToNoneU32) { - debug("EMU: chip_pin_mode(%u,%u) \n", arg1.uint32, arg0.uint32); - pop_args(2); - return true; -} - -def_prim(chip_digital_write, twoToNoneU32) { - debug("EMU: chip_digital_write(%u,%u) \n", arg1.uint32, arg0.uint32); - pop_args(2); - return true; -} - -def_prim(chip_digital_read, oneToOneU32) { - uint8_t pin = arg0.uint32; - pop_args(1); - pushUInt32(1); // HIGH - return true; -} - -def_prim(chip_analog_read, oneToOneI32) { - uint8_t pin = arg0.uint32; - pop_args(1); - pushInt32(sin(sensor_emu) * 100); - sensor_emu += .25; - return true; -} - -def_prim(chip_delay, oneToNoneU32) { - using namespace std::this_thread; // sleep_for, sleep_until - using namespace std::chrono; // nanoseconds, system_clock, seconds - debug("EMU: chip_delay(%u) \n", arg0.uint32); - sleep_for(milliseconds(arg0.uint32)); - debug("EMU: .. done\n"); - pop_args(1); - return true; -} - -def_prim(chip_delay_us, oneToNoneU32) { - using namespace std::this_thread; // sleep_for, sleep_until - using namespace std::chrono; // nanoseconds, system_clock, seconds - debug("EMU: chip_delay(%u ms) \n", arg0.uint32); - sleep_for(microseconds(arg0.uint32)); - debug("EMU: .. done\n"); - pop_args(1); - return true; -} - -// warning: undefined symbol: write_spi_byte -def_prim(write_spi_byte, oneToNoneU32) { - debug("EMU: write_spi_byte(%u) \n", arg0.uint32); - pop_args(1); - return true; -} - -// warning: undefined symbol: spi_begin -def_prim(spi_begin, NoneToNoneU32) { - debug("EMU: spi_begin \n"); - return true; -} - -def_prim(write_spi_bytes_16, twoToNoneU32) { - debug("EMU: write_spi_byte_16(%u, %u) \n", arg1.uint32, arg0.uint32); - pop_args(2); - return true; -} - -#endif - //------------------------------------------------------ // Util functions //------------------------------------------------------ -#ifdef ARDUINO - void connect(const String ssid, const String password) { char *ssid_buf = (char *)acalloc(ssid.length() + 1, sizeof(char), "ssid_buf"); @@ -1050,23 +805,11 @@ int32_t http_post_request(Module *m, const String url, const String body, return httpResponseCode; } -#endif - -/* -int analogRead(uint8_t pin) -void analogReference(uint8_t mode) -void analogWrite(uint8_t pin, int val) -void analogWriteFreq(uint32_t freq) -void analogWriteRange(uint32_t range) -*/ - //------------------------------------------------------ // Installing all the primitives //------------------------------------------------------ void install_primitives() { dbg_info("INSTALLING PRIMITIVES\n"); - // install_primitive(rand); -#ifdef ARDUINO dbg_info("INSTALLING ARDUINO\n"); install_primitive(abort); install_primitive(millis); @@ -1109,35 +852,6 @@ void install_primitives() { install_primitive(set_pixel_color); install_primitive(clear_pixels); install_primitive(show_pixels); - -#else - dbg_info("INSTALLING FAKE ARDUINO\n"); - install_primitive(abort); - install_primitive(micros); - install_primitive(test); - install_primitive(print_int); - install_primitive(print_string); - install_primitive(wifi_connect); - install_primitive(wifi_status); - install_primitive(wifi_localip); - install_primitive(http_get); - install_primitive(http_post); - install_primitive(chip_pin_mode); - install_primitive(chip_digital_write); - install_primitive(chip_delay); - install_primitive(chip_digital_read); - install_primitive(chip_analog_read); - install_primitive(chip_delay_us); - install_primitive(spi_begin); - install_primitive(write_spi_byte); - install_primitive(write_spi_bytes_16); - - install_primitive(init_pixels); - install_primitive(set_pixel_color); - install_primitive(clear_pixels); - install_primitive(show_pixels); - -#endif } //------------------------------------------------------ diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp new file mode 100644 index 00000000..7ab2aa33 --- /dev/null +++ b/src/Primitives/emulated.cpp @@ -0,0 +1,487 @@ +/** + * This file lists the primitives of the language and stores them in the + * primitives + * + * Adding a primitive: + * 1) Bump up the NUM_PRIMITIVES constant + * 2) Define _type + * 3) Define a function void primitive(Module* m) + * 4) Extend the install_primitives function + * + */ +#include + +#include +#include +#include +#include +#include + +#include "../Memory/mem.h" +#include "../Utils/macros.h" +#include "../Utils/util.h" + +#define NUM_PRIMITIVES 0 +#define NUM_PRIMITIVES_ARDUINO 23 + +#define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) + +// Global index for installing primitives +int prim_index = 0; + +double sensor_emu = 0; + +/* + Private macros to install a primitive +*/ +#define install_primitive(prim_name) \ + { \ + dbg_info("installing primitive number: %d of %d with name: %s\n", \ + prim_index + 1, ALL_PRIMITIVES, #prim_name); \ + if (prim_index < ALL_PRIMITIVES) { \ + PrimitiveEntry *p = &primitives[prim_index++]; \ + p->name = #prim_name; \ + p->f = &(prim_name); \ + } else { \ + FATAL("pim_index out of bounds"); \ + } \ + } + +#define def_prim(function_name, type) \ + Type function_name##_type = type; \ + bool function_name(Module *m) + +// TODO: use fp +#define pop_args(n) m->sp -= n +#define get_arg(m, arg) m->stack[(m)->sp - (arg)].value +#define pushUInt32(arg) m->stack[++m->sp].value.uint32 = arg +#define pushInt32(arg) m->stack[++m->sp].value.int32 = arg +#define pushUInt64(arg) \ + m->stack[++m->sp].value_type = I64; \ + m->stack[m->sp].value.uint64 = arg +#define arg0 get_arg(m, 0) +#define arg1 get_arg(m, 1) +#define arg2 get_arg(m, 2) +#define arg3 get_arg(m, 3) +#define arg4 get_arg(m, 4) +#define arg5 get_arg(m, 5) +#define arg6 get_arg(m, 6) +#define arg7 get_arg(m, 7) +#define arg8 get_arg(m, 8) +#define arg9 get_arg(m, 9) + +// The primitive table +PrimitiveEntry primitives[ALL_PRIMITIVES]; + +// +uint32_t param_arr_len0[0] = {}; +uint32_t param_I32_arr_len1[1] = {I32}; +uint32_t param_I32_arr_len2[2] = {I32, I32}; +uint32_t param_I32_arr_len3[3] = {I32, I32, I32}; +uint32_t param_I32_arr_len4[4] = {I32, I32, I32, I32}; +uint32_t param_I32_arr_len10[10] = {I32, I32, I32, I32, I32, + I32, I32, I32, I32, I32}; + +uint32_t param_I64_arr_len1[1] = {I64}; + +Type oneToNoneU32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 0, + .results = nullptr, + .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ +}; + +Type twoToNoneU32 = { + .form = FUNC, + .param_count = 2, + .params = param_I32_arr_len2, + .result_count = 0, + .results = nullptr, + .mask = 0x80011 /* 0x800 = no return ; 1 = I32; 1 = I32*/ +}; + +Type threeToNoneU32 = { + .form = FUNC, + .param_count = 3, + .params = param_I32_arr_len3, + .result_count = 0, + .results = nullptr, + .mask = 0x800111 /* 0x800 = no return ; 1=I32; 1=I32; 1=I32*/ +}; + +Type fourToNoneU32 = { + .form = FUNC, + .param_count = 4, + .params = param_I32_arr_len4, + .result_count = 0, + .results = nullptr, + .mask = + 0x8001111 /* 0x800 = no return ; 1 = I32; 1 = I32; 1 = I32; 1 = I32*/ +}; + +Type oneToOneU32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +Type oneToOneI32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +Type twoToOneU32 = { + .form = FUNC, + .param_count = 2, + .params = param_I32_arr_len2, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x81011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +Type threeToOneU32 = { + .form = FUNC, + .param_count = 3, + .params = param_I32_arr_len3, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x810111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32*/ +}; + +Type fourToOneU32 = { + .form = FUNC, + .param_count = 4, + .params = param_I32_arr_len4, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x8101111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32; 1=I32*/ +}; + +Type tenToOneU32 = { + .form = FUNC, + .param_count = 10, + .params = param_I32_arr_len10, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x8101111111111 /* 0x8 1=I32 0=endRet ; 10 params 1=I32*/ +}; + +Type NoneToNoneU32 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 0, + .results = nullptr, + .mask = 0x80000}; + +Type NoneToOneU32 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x81000}; + +Type NoneToOneU64 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 1, + .results = param_I64_arr_len1, + .mask = 0x82000}; + +def_prim(init_pixels, NoneToNoneU32) { + printf("init_pixels \n"); + return true; +} + +def_prim(set_pixel_color, fourToOneU32) { + printf("set_pixel_color \n"); + pop_args(4); + return true; +} + +def_prim(show_pixels, NoneToNoneU32) { + printf("show pixels \n"); + return true; +} + +def_prim(clear_pixels, NoneToNoneU32) { + printf("clear pixels \n"); + return true; +} + +def_prim(abort, NoneToNoneU32) { + debug("EMU: abort\n"); + return false; +} + +def_prim(micros, NoneToOneU64) { + struct timeval tv {}; + gettimeofday(&tv, nullptr); + unsigned long micros = 1000000 * tv.tv_sec + tv.tv_usec; + pushUInt64(micros); + return true; +} + +// call callback test function (temporary) +def_prim(test, oneToNoneU32) { + uint32_t fidx = arg0.uint32; + + std::string topic = "interrupt"; + topic.append(std::to_string(fidx)); + + Callback c = Callback(m, topic, fidx); + CallbackHandler::add_callback(c); + auto *payload = reinterpret_cast("TestPayload"); + CallbackHandler::push_event(topic, payload, 11); + pop_args(1); + return true; +} + +def_prim(print_int, oneToNoneU32) { + debug("EMU: print "); + printf("%u\n", arg0.uint32); + pop_args(1); + return true; +} + +def_prim(print_string, twoToNoneU32) { + uint32_t addr = arg1.uint32; + uint32_t size = arg0.uint32; + std::string text = parse_utf8_string(m->memory.bytes, size, addr); + debug("EMU: print string at %i: ", addr); + printf("%s\n", text.c_str()); + pop_args(2); + return true; +} + +def_prim(wifi_connect, fourToNoneU32) { + uint32_t ssid = arg3.uint32; + uint32_t len0 = arg2.uint32; + uint32_t pass = arg1.uint32; + uint32_t len1 = arg0.uint32; + + std::string ssid_str = parse_utf8_string(m->memory.bytes, len0, ssid); + std::string pass_str = parse_utf8_string(m->memory.bytes, len1, pass); + debug("EMU: connect to %s with password %s\n", ssid_str.c_str(), + pass_str.c_str()); + pop_args(4); + return true; +} + +def_prim(wifi_status, NoneToOneU32) { + pushInt32(3); // return WL_CONNECTED + return true; +} + +def_prim(wifi_localip, twoToOneU32) { + uint32_t buff = arg1.uint32; + uint32_t size = arg0.uint32; + std::string ip = "192.168.0.181"; + + for (unsigned long i = 0; i < ip.length(); i++) { + m->memory.bytes[buff + i] = (uint32_t)ip[i]; + } + pop_args(2); + pushInt32(buff); + return true; +} + +def_prim(http_get, fourToOneU32) { + // Get arguments + uint32_t url = arg3.uint32; + uint32_t length = arg2.uint32; + int32_t response = arg1.uint32; + uint32_t size = arg0.uint32; + // Parse url + std::string text = parse_utf8_string(m->memory.bytes, length, url); + debug("EMU: http get request %s\n", text.c_str()); + // Construct response + std::string answer = "Response code: 200."; + if (answer.length() > size) { + sprintf(exception, "GET: buffer size is too small for response."); + return false; // TRAP + } + for (unsigned long i = 0; i < answer.length(); i++) { + m->memory.bytes[response + i] = (uint32_t)answer[i]; + } + + // Pop args and return response address + pop_args(4); + pushInt32(response); + return true; +} + +def_prim(http_post, tenToOneU32) { + // Get arguments + uint32_t url = arg9.uint32; + uint32_t url_len = arg8.uint32; + uint32_t body = arg7.uint32; + uint32_t body_len = arg6.uint32; + uint32_t content_type = arg5.uint32; + uint32_t content_type_len = arg4.uint32; + uint32_t authorization = arg3.uint32; + uint32_t authorization_len = arg2.uint32; + int32_t response = arg1.uint32; + uint32_t size = arg0.uint32; + + std::string url_parsed = parse_utf8_string(m->memory.bytes, url_len, url); + std::string body_parsed = + parse_utf8_string(m->memory.bytes, body_len, body); + std::string content_type_parsed = + parse_utf8_string(m->memory.bytes, content_type_len, content_type); + std::string authorization_parsed = + parse_utf8_string(m->memory.bytes, authorization_len, authorization); + debug( + "EMU: POST %s\n\t Content-type: '%s'\n\t Authorization: '%s'\n\t " + "'%s'\n", + url_parsed.c_str(), content_type_parsed.c_str(), + authorization_parsed.c_str(), body_parsed.c_str()); + + pop_args(10); + pushInt32(response); + return true; +} + +def_prim(chip_pin_mode, twoToNoneU32) { + debug("EMU: chip_pin_mode(%u,%u) \n", arg1.uint32, arg0.uint32); + pop_args(2); + return true; +} + +def_prim(chip_digital_write, twoToNoneU32) { + debug("EMU: chip_digital_write(%u,%u) \n", arg1.uint32, arg0.uint32); + pop_args(2); + return true; +} + +def_prim(chip_digital_read, oneToOneU32) { + uint8_t pin = arg0.uint32; + pop_args(1); + pushUInt32(1); // HIGH + return true; +} + +def_prim(chip_analog_read, oneToOneI32) { + uint8_t pin = arg0.uint32; + pop_args(1); + pushInt32(sin(sensor_emu) * 100); + sensor_emu += .25; + return true; +} + +def_prim(chip_delay, oneToNoneU32) { + using namespace std::this_thread; // sleep_for, sleep_until + using namespace std::chrono; // nanoseconds, system_clock, seconds + debug("EMU: chip_delay(%u) \n", arg0.uint32); + sleep_for(milliseconds(arg0.uint32)); + debug("EMU: .. done\n"); + pop_args(1); + return true; +} + +def_prim(chip_delay_us, oneToNoneU32) { + using namespace std::this_thread; // sleep_for, sleep_until + using namespace std::chrono; // nanoseconds, system_clock, seconds + debug("EMU: chip_delay(%u ms) \n", arg0.uint32); + sleep_for(microseconds(arg0.uint32)); + debug("EMU: .. done\n"); + pop_args(1); + return true; +} + +// warning: undefined symbol: write_spi_byte +def_prim(write_spi_byte, oneToNoneU32) { + debug("EMU: write_spi_byte(%u) \n", arg0.uint32); + pop_args(1); + return true; +} + +// warning: undefined symbol: spi_begin +def_prim(spi_begin, NoneToNoneU32) { + debug("EMU: spi_begin \n"); + return true; +} + +def_prim(write_spi_bytes_16, twoToNoneU32) { + debug("EMU: write_spi_byte_16(%u, %u) \n", arg1.uint32, arg0.uint32); + pop_args(2); + return true; +} + +//------------------------------------------------------ +// Installing all the primitives +//------------------------------------------------------ +void install_primitives() { + dbg_info("INSTALLING PRIMITIVES\n"); + dbg_info("INSTALLING FAKE ARDUINO\n"); + install_primitive(abort); + install_primitive(micros); + install_primitive(test); + install_primitive(print_int); + install_primitive(print_string); + install_primitive(wifi_connect); + install_primitive(wifi_status); + install_primitive(wifi_localip); + install_primitive(http_get); + install_primitive(http_post); + install_primitive(chip_pin_mode); + install_primitive(chip_digital_write); + install_primitive(chip_delay); + install_primitive(chip_digital_read); + install_primitive(chip_analog_read); + install_primitive(chip_delay_us); + install_primitive(spi_begin); + install_primitive(write_spi_byte); + install_primitive(write_spi_bytes_16); + + install_primitive(init_pixels); + install_primitive(set_pixel_color); + install_primitive(clear_pixels); + install_primitive(show_pixels); +} + +//------------------------------------------------------ +// resolving the primitives +//------------------------------------------------------ +bool resolve_primitive(char *symbol, Primitive *val) { + debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); + + for (auto &primitive : primitives) { + // printf("Checking %s = %s \n", symbol, primitive.name); + if (!strcmp(symbol, primitive.name)) { + debug("FOUND PRIMITIVE\n"); + *val = primitive.f; + return true; + } + } + FATAL("Could not find primitive %s \n", symbol); + return false; +} + +Memory external_mem = {0, 0, 0, nullptr}; + +bool resolve_external_memory(char *symbol, Memory **val) { + if (!strcmp(symbol, "memory")) { + if (external_mem.bytes == nullptr) { + external_mem.initial = 256; + external_mem.maximum = 256; + external_mem.pages = 256; + external_mem.bytes = (uint8_t *)acalloc( + external_mem.pages * PAGE_SIZE, sizeof(uint32_t), + "Module->memory.bytes primitive"); + } + *val = &external_mem; + return true; + } + + FATAL("Could not find memory %s \n", symbol); + return false; +} diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 6ce1f4e8..b0d47fe1 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -26,4 +26,10 @@ bool resolve_external_memory(char *symbol, Memory **val); void install_primitives(); +#ifdef Arduino +#include "arduino.cpp" +#else +#include "emulated.cpp" +#endif + #endif From 75a9c7d252b212f9289367a6202b17c59f6a3b74 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 20 Apr 2022 08:55:02 +0200 Subject: [PATCH 021/249] Fix common header multiple implementation for Arduino Fix ESP-IDF compilation error in debugger.cpp --- CMakeLists.txt | 2 +- examples/assemblyscript/main/CMakeLists.txt | 2 +- examples/blink/main/CMakeLists.txt | 2 +- platforms/ESP-IDF/CMakeLists.txt | 2 +- src/Debug/debugger.cpp | 4 ++-- src/Primitives/arduino.cpp | 3 ++- src/Primitives/emulated.cpp | 5 +++++ src/Primitives/primitives.h | 6 ------ 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c46a0bb..f409cedb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ if (BUILD_EMULATOR) src/Utils/macros.cpp src/WARDuino/WARDuino.cpp src/WARDuino/CallbackHandler.cpp - src/Primitives/primitives.h + src/Primitives/emulated.cpp src/Interpreter/instructions.cpp ) set(TEST_FRAMEWORK diff --git a/examples/assemblyscript/main/CMakeLists.txt b/examples/assemblyscript/main/CMakeLists.txt index 399d84c3..3fdb8c1d 100644 --- a/examples/assemblyscript/main/CMakeLists.txt +++ b/examples/assemblyscript/main/CMakeLists.txt @@ -5,7 +5,7 @@ set(SOURCE_FILES ../../../src/Debug/debugger.cpp ../../../src/Utils/macros.cpp ../../../src/WARDuino/WARDuino.cpp - ../../../src/Primitives/primitives.h + ../../../src/Primitives/emulated.cpp ../../../src/Interpreter/instructions.cpp ../../../src/WARDuino/CallbackHandler.cpp ) diff --git a/examples/blink/main/CMakeLists.txt b/examples/blink/main/CMakeLists.txt index 399d84c3..3fdb8c1d 100644 --- a/examples/blink/main/CMakeLists.txt +++ b/examples/blink/main/CMakeLists.txt @@ -5,7 +5,7 @@ set(SOURCE_FILES ../../../src/Debug/debugger.cpp ../../../src/Utils/macros.cpp ../../../src/WARDuino/WARDuino.cpp - ../../../src/Primitives/primitives.h + ../../../src/Primitives/emulated.cpp ../../../src/Interpreter/instructions.cpp ../../../src/WARDuino/CallbackHandler.cpp ) diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index db903e01..845b0f2c 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -5,7 +5,7 @@ set(SOURCE_FILES ../../src/Debug/debugger.cpp ../../src/Utils/macros.cpp ../../src/WARDuino/WARDuino.cpp - ../../src/Primitives/primitives.h + ../../src/Primitives/emulated.cpp ../../src/Interpreter/instructions.cpp ../../src/WARDuino/CallbackHandler.cpp ) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 11046ee8..c9a5e2a1 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -357,7 +357,7 @@ void Debugger::dumpLocals(Module *m) const { dprintf(this->socket, R"({"count":%u,"locals":[)", 0); // fflush(stdout); // FIXME: this is needed for ESP to propery print char _value_str[256]; - for (size_t i = 0; i < f->block->local_count; i++) { + for (uint32_t i = 0; i < f->block->local_count; i++) { auto v = &m->stack[m->fp + i]; switch (v->value_type) { case I32: @@ -382,7 +382,7 @@ void Debugger::dumpLocals(Module *m) const { v->value_type, v->value.uint64); } - dprintf(this->socket, "{%s, \"index\":%lu}%s", _value_str, + dprintf(this->socket, "{%s, \"index\":%u}%s", _value_str, i + f->block->type->param_count, (i + 1 < f->block->local_count) ? "," : ""); } diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index ce1e97f3..a9e00067 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -22,6 +22,7 @@ #include "../Memory/mem.h" #include "../Utils/macros.h" #include "../Utils/util.h" +#include "primitives.h" // NEOPIXEL #include @@ -890,4 +891,4 @@ bool resolve_external_memory(char *symbol, Memory **val) { FATAL("Could not find memory %s \n", symbol); return false; -} +} \ No newline at end of file diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 7ab2aa33..2d81a42b 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -1,3 +1,5 @@ +#ifndef ARDUINO + /** * This file lists the primitives of the language and stores them in the * primitives @@ -20,6 +22,7 @@ #include "../Memory/mem.h" #include "../Utils/macros.h" #include "../Utils/util.h" +#include "primitives.h" #define NUM_PRIMITIVES 0 #define NUM_PRIMITIVES_ARDUINO 23 @@ -485,3 +488,5 @@ bool resolve_external_memory(char *symbol, Memory **val) { FATAL("Could not find memory %s \n", symbol); return false; } + +#endif // ARDUINO \ No newline at end of file diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index b0d47fe1..6ce1f4e8 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -26,10 +26,4 @@ bool resolve_external_memory(char *symbol, Memory **val); void install_primitives(); -#ifdef Arduino -#include "arduino.cpp" -#else -#include "emulated.cpp" -#endif - #endif From 7acdbe39c5c1b2d86159092b0adc4d2741903d65 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 20 Apr 2022 10:39:40 +0200 Subject: [PATCH 022/249] Fix warnings --- src/Debug/debugger.cpp | 106 ++++++++++++++++++++--------------------- src/Debug/debugger.h | 2 +- 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index c9a5e2a1..8bdc0d9c 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -1,7 +1,5 @@ #include "debugger.h" -#include - #include #include #include @@ -211,7 +209,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } // Private methods -void Debugger::printValue(StackValue *v, int idx, bool end = false) const { +void Debugger::printValue(StackValue *v, uint32_t idx, bool end = false) const { char buff[256]; switch (v->value_type) { @@ -506,41 +504,41 @@ void Debugger::woodDump(Module *m) { // printf("asked for stack\n"); // stack dprintf(this->socket, "\"stack\":["); - for (int i = 0; i <= m->sp; i++) { - auto v = &m->stack[i]; - printValue(v, i, i == m->sp); + for (int j = 0; j <= m->sp; j++) { + auto v = &m->stack[j]; + printValue(v, j, j == m->sp); } dprintf(this->socket, "],"); // Callstack dprintf(this->socket, "\"callstack\":["); - for (int i = 0; i <= m->csp; i++) { - Frame *f = &m->callstack[i]; + for (int j = 0; j <= m->csp; j++) { + Frame *f = &m->callstack[j]; uint8_t *block_key = f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); dprintf( this->socket, R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p", "idx":%d}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, - static_cast(f->ra_ptr), i, (i < m->csp) ? "," : ""); + static_cast(f->ra_ptr), j, (j < m->csp) ? "," : ""); } // printf("asked for globals\n"); // GLobals dprintf(this->socket, "],\"globals\":["); - for (uint32_t i = 0; i < m->global_count; i++) { - auto v = m->globals + i; - printValue(v, i, i == (m->global_count - 1)); + for (uint32_t j = 0; j < m->global_count; j++) { + auto v = m->globals + j; + printValue(v, j, j == (m->global_count - 1)); } dprintf(this->socket, "]"); // closing globals // printf("asked for table\n"); - dprintf(this->socket, ",\"table\":{\"max\":%d, \"init\":%d, \"elements\":[", + dprintf(this->socket, R"(,"table":{"max":%d, "init":%d, "elements":[)", m->table.maximum, m->table.initial); - for (uint32_t i = 0; i < m->table.size; i++) { - dprintf(this->socket, "%" PRIu32 "%s", m->table.entries[i], - (i + 1) == m->table.size ? "" : ","); + for (uint32_t j = 0; j < m->table.size; j++) { + dprintf(this->socket, "%" PRIu32 "%s", m->table.entries[j], + (j + 1) == m->table.size ? "" : ","); } dprintf(this->socket, "]}"); // closing table @@ -549,20 +547,20 @@ void Debugger::woodDump(Module *m) { uint32_t total_elems = m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE dprintf(this->socket, - ",\"memory\":{\"pages\":%d,\"max\":%d,\"init\":%d,\"bytes\":[", + R"(,"memory":{"pages":%d,"max":%d,"init":%d,"bytes":[)", m->memory.pages, m->memory.maximum, m->memory.initial); - for (uint32_t i = 0; i < total_elems; i++) { - dprintf(this->socket, "%" PRIu8 "%s", m->memory.bytes[i], - (i + 1) == total_elems ? "" : ","); + for (uint32_t j = 0; j < total_elems; j++) { + dprintf(this->socket, "%" PRIu8 "%s", m->memory.bytes[j], + (j + 1) == total_elems ? "" : ","); } dprintf(this->socket, "]}"); // closing memory // printf("asked for br_table\n"); - dprintf(this->socket, ",\"br_table\":{\"size\":\"0x%x\",\"labels\":[", + dprintf(this->socket, R"(,"br_table":{"size":"0x%x","labels":[)", BR_TABLE_SIZE); - for (uint32_t i = 0; i < BR_TABLE_SIZE; i++) { - dprintf(this->socket, "%" PRIu32 "%s", m->br_table[i], - (i + 1) == BR_TABLE_SIZE ? "" : ","); + for (uint32_t j = 0; j < BR_TABLE_SIZE; j++) { + dprintf(this->socket, "%" PRIu32 "%s", m->br_table[j], + (j + 1) == BR_TABLE_SIZE ? "" : ","); } dprintf(this->socket, "]}}\n"); } @@ -668,12 +666,12 @@ void Debugger::freeState(Module *m, uint8_t *interruptData) { bool Debugger::saveState(Module *m, uint8_t *interruptData) { uint8_t *program_state = nullptr; - uint8_t *endstate = nullptr; + uint8_t *end_state = nullptr; program_state = interruptData + 1; // skip interruptRecvState - endstate = program_state + read_B32(&program_state); + end_state = program_state + read_B32(&program_state); debug("saving program_state\n"); - while (program_state < endstate) { + while (program_state < end_state) { switch (*program_state++) { case pcState: { // PC m->pc_ptr = (uint8_t *)readPointer(&program_state); @@ -737,24 +735,24 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { debug("receiving #%" PRIu32 " globals\n", quantity_globals); for (uint32_t q = 0; q < quantity_globals; q++) { - uint8_t typeidx = *program_state++; - if (typeidx >= sizeof(valtypes)) { - FATAL("received unknown type %" PRIu8 "\n", typeidx); + uint8_t type_index = *program_state++; + if (type_index >= sizeof(valtypes)) { + FATAL("received unknown type %" PRIu8 "\n", type_index); } StackValue *sv = &m->globals[m->global_count++]; - size_t qb = typeidx == 0 || typeidx == 2 ? 4 : 8; - debug("receiving type %" PRIu8 " and %d bytes \n", typeidx, - typeidx == 0 || typeidx == 2 ? 4 : 8); + size_t qb = type_index == 0 || type_index == 2 ? 4 : 8; + debug("receiving type %" PRIu8 " and %d bytes \n", + type_index, + type_index == 0 || type_index == 2 ? 4 : 8); - sv->value_type = valtypes[typeidx]; + sv->value_type = valtypes[type_index]; memcpy(&sv->value, program_state, qb); program_state += qb; } break; } case tblState: { - auto tbl_type = - (uint8_t)*program_state++; // for now only funcref + program_state++; // for now only funcref uint32_t quantity = read_B32(&program_state); for (size_t i = 0; i < quantity; i++) { uint32_t ne = read_B32(&program_state); @@ -771,37 +769,37 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { if (start > limit) { FATAL("incorrect memory offsets\n"); } - uint32_t totalbytes = limit - start + 1; + uint32_t total_bytes = limit - start + 1; uint8_t *mem_end = m->memory.bytes + m->memory.pages * (uint32_t)PAGE_SIZE; - debug("will copy #%" PRIu32 " bytes\n", totalbytes); - if ((m->memory.bytes + start) + totalbytes > mem_end) { + debug("will copy #%" PRIu32 " bytes\n", total_bytes); + if ((m->memory.bytes + start) + total_bytes > mem_end) { FATAL("memory overflow %p > %p\n", - static_cast((m->bytes + start) + totalbytes), + static_cast((m->bytes + start) + total_bytes), static_cast(mem_end)); } - memcpy(m->memory.bytes + start, program_state, totalbytes + 1); - for (auto i = start; i <= (start + totalbytes - 1); i++) { + memcpy(m->memory.bytes + start, program_state, total_bytes + 1); + for (auto i = start; i <= (start + total_bytes - 1); i++) { debug("GOT byte idx %" PRIu32 " =%" PRIu8 "\n", i, m->memory.bytes[i]); } debug("outside the out\n"); - program_state += totalbytes; + program_state += total_bytes; break; } case brtblState: { debug("receiving br_table\n"); - uint16_t beginidx = read_B16(&program_state); - uint16_t endidx = read_B16(&program_state); + uint16_t begin_index = read_B16(&program_state); + uint16_t end_index = read_B16(&program_state); debug("br_table offsets begin=%" PRIu16 " , end=%" PRIu16 "\n", - beginidx, endidx); - if (beginidx > endidx) { + begin_index, end_index); + if (begin_index > end_index) { FATAL("incorrect br_table offsets\n"); } - if (endidx >= BR_TABLE_SIZE) { + if (end_index >= BR_TABLE_SIZE) { FATAL("br_table overflow\n"); } - for (auto idx = beginidx; idx <= endidx; idx++) { + for (auto idx = begin_index; idx <= end_index; idx++) { // FIXME speedup with memcpy? uint32_t el = read_B32(&program_state); m->br_table[idx] = el; @@ -815,15 +813,15 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { uint16_t quantity_sv = read_B16(&program_state); uint8_t valtypes[] = {I32, I64, F32, F64}; for (size_t i = 0; i < quantity_sv; i++) { - uint8_t typeidx = *program_state++; - if (typeidx >= sizeof(valtypes)) { - FATAL("received unknown type %" PRIu8 "\n", typeidx); + uint8_t type_index = *program_state++; + if (type_index >= sizeof(valtypes)) { + FATAL("received unknown type %" PRIu8 "\n", type_index); } m->sp += 1; StackValue *sv = &m->stack[m->sp]; sv->value.uint64 = 0; // init whole union to 0 - size_t qb = typeidx == 0 || typeidx == 2 ? 4 : 8; - sv->value_type = valtypes[typeidx]; + size_t qb = type_index == 0 || type_index == 2 ? 4 : 8; + sv->value_type = valtypes[type_index]; memcpy(&sv->value, program_state, qb); program_state += qb; } diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index bc250922..7f13fb84 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -42,7 +42,7 @@ class Debugger { // Private methods - void printValue(StackValue *v, int idx, bool end) const; + void printValue(StackValue *v, uint32_t idx, bool end) const; // TODO Move parsing to WARDuino class? uint8_t *parseDebugBuffer(size_t len, const uint8_t *buff); From 30e399f0cc0a0d91f08bb8abbca31be8a25c717b Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:25:51 +0200 Subject: [PATCH 023/249] add other blink examples --- platforms/Arduino/examples/blink.c | 21 +++++++++++ platforms/Arduino/examples/blink.wast | 54 +++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 platforms/Arduino/examples/blink.c create mode 100644 platforms/Arduino/examples/blink.wast diff --git a/platforms/Arduino/examples/blink.c b/platforms/Arduino/examples/blink.c new file mode 100644 index 00000000..0013ee79 --- /dev/null +++ b/platforms/Arduino/examples/blink.c @@ -0,0 +1,21 @@ +unsigned char blink_wasm[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, + 0x4f, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, + 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, + 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x00, 0x01, 0x03, 0x03, 0x02, 0x02, + 0x02, 0x06, 0x10, 0x03, 0x7f, 0x00, 0x41, 0x0a, 0x0b, 0x7f, 0x00, 0x41, + 0x01, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, + 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x33, 0x02, 0x08, 0x00, 0x23, 0x00, + 0x41, 0x02, 0x10, 0x01, 0x0b, 0x28, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, + 0x21, 0x00, 0x10, 0x04, 0x03, 0x40, 0x23, 0x00, 0x23, 0x00, 0x10, 0x03, + 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x23, 0x00, 0x23, 0x02, + 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x0b +}; +unsigned int blink_wasm_len = 190; +/* +*/ diff --git a/platforms/Arduino/examples/blink.wast b/platforms/Arduino/examples/blink.wast new file mode 100644 index 00000000..0e0ed2df --- /dev/null +++ b/platforms/Arduino/examples/blink.wast @@ -0,0 +1,54 @@ +(module + ;; Type declarations + (type $int32->int32->void (func (param i32 i32))) + (type $int32->void (func (param i32))) + (type $void->void (func)) + + ;; Imports from the WARDuino VM + (import "env" "chip_delay" (func $env.chip_delay (type $int32->void))) + (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $int32->int32->void))) + (import "env" "chip_digital_write" (func $env.chip_digital_write (type $int32->int32->void))) + (import "env" "print_int" (func $env.print_int (type $int32->void))) + + + ;; Non-mutable globals + (global $led i32 (i32.const 10)) + (global $on i32 (i32.const 1)) + (global $off i32 (i32.const 0)) + + ;; Initialise function (private) + (func $init (type $void->void) + ;; Set pin mode + global.get $led + i32.const 2 + call $env.chip_pin_mode) + + ;; Blink function (public) + (func $blink (type $void->void) + ;; Declare local $delay + (local $delay i32) + i32.const 1000 + local.set $delay + + ;; Initialise + call $init + + ;; Blink in infinite loop + loop $infinite + global.get $led + global.get $led + call $env.print_int ;;print led nr + global.get $on + call $env.chip_digital_write ;; turn led on + local.get $delay + call $env.chip_delay ;; wait + global.get $led + global.get $off + call $env.chip_digital_write ;; turn led off + local.get $delay + call $env.chip_delay ;; wait + br $infinite ;; jump back to start of loop + end) + + ;; Export blink as function + (export "main" (func $blink))) From 6a0dfec961ed12c332648ba4a9568c8694bdd249 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:26:55 +0200 Subject: [PATCH 024/249] compile and flash for esp32doit-devkit-v1 --- platforms/Arduino/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platforms/Arduino/Makefile b/platforms/Arduino/Makefile index 8b9a77d6..14be536e 100644 --- a/platforms/Arduino/Makefile +++ b/platforms/Arduino/Makefile @@ -6,3 +6,12 @@ compile: monitor: arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200 + +flash-dev: + arduino-cli upload -p /dev/cu.usbserial-2952919DA8 --fqbn esp32:esp32:esp32doit-devkit-v1:UploadSpeed=115200 Arduino.ino + +compile-dev: + arduino-cli -v compile --fqbn esp32:esp32:esp32doit-devkit-v1 Arduino.ino + +monitor: + arduino-cli monitor -p /dev/cu.usbserial-2952919DA8 -c baudrate=115200 From 749059de70d342115f3950319435e1c09e78431c Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:27:18 +0200 Subject: [PATCH 025/249] add other blink example wasm --- platforms/Arduino/upload.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/platforms/Arduino/upload.h b/platforms/Arduino/upload.h index efac27f4..88268537 100644 --- a/platforms/Arduino/upload.h +++ b/platforms/Arduino/upload.h @@ -1,3 +1,4 @@ +// blinks led on pin 23 unsigned char upload_wasm[] = { 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, @@ -24,3 +25,25 @@ unsigned char upload_wasm[] = { 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; unsigned int upload_wasm_len = 282; + +/* blink pin 10 (M5stickC internal led) platforms/Arduino/examples/blink.wast + */ +// unsigned char upload_wasm[] = { +// 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, +// 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, +// 0x4f, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, +// 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, +// 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, +// 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, +// 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, +// 0x74, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x70, 0x72, 0x69, +// 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x00, 0x01, 0x03, 0x03, 0x02, 0x02, +// 0x02, 0x06, 0x10, 0x03, 0x7f, 0x00, 0x41, 0x0a, 0x0b, 0x7f, 0x00, 0x41, +// 0x01, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, +// 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x33, 0x02, 0x08, 0x00, 0x23, 0x00, +// 0x41, 0x02, 0x10, 0x01, 0x0b, 0x28, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, +// 0x21, 0x00, 0x10, 0x04, 0x03, 0x40, 0x23, 0x00, 0x23, 0x00, 0x10, 0x03, +// 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x23, 0x00, 0x23, 0x02, +// 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x0b +// }; +// unsigned int upload_wasm_len = 190; From 0972ea796a4d03d5273c68e089850767b6a1fae6 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:28:24 +0200 Subject: [PATCH 026/249] add util functions for wood --- src/Utils/util.cpp | 18 ++++++++++++++++++ src/Utils/util.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/src/Utils/util.cpp b/src/Utils/util.cpp index 1c0ef87b..5777a44c 100644 --- a/src/Utils/util.cpp +++ b/src/Utils/util.cpp @@ -183,3 +183,21 @@ int read_B32_signed(uint8_t **bytes) { *bytes += 4; return n; } // TODO replace with read_LEB_32? If keep Big endian use memcpy? + +uint32_t read_L32(uint8_t **bytes) { + // uint8_t *b = *bytes; + uint32_t n = 0; + memcpy(&n, *bytes, sizeof(uint32_t)); + *bytes += 4; + return n; +} // TODO replace with read_LEB_32? If keep Big endian use memcpy? + +void chars_as_hexa(unsigned char *dest, unsigned char *source, + uint32_t len_source) { + for (uint32_t i = 0; i < len_source; i++) { + unsigned c = source[i] >> 4; + unsigned c2 = source[i] & 0xF; + dest[i * 2 + 0] = c > 9 ? (c - 10 + 'A') : (c + '0'); + dest[i * 2 + 1] = c2 > 9 ? (c2 - 10 + 'A') : (c2 + '0'); + } +} diff --git a/src/Utils/util.h b/src/Utils/util.h index 3c7e3e31..28f036f0 100644 --- a/src/Utils/util.h +++ b/src/Utils/util.h @@ -71,5 +71,8 @@ double wa_fmin(double a, double b); uint32_t read_B32(uint8_t **bytes); uint16_t read_B16(uint8_t **bytes); int read_B32_signed(uint8_t **bytes); +uint32_t read_L32(uint8_t **bytes); +void chars_as_hexa(unsigned char *dest, unsigned char *source, + uint32_t len_source); #endif From 6c6c5ba52b1dd43a21a0c6f39bff08963c2ab80a Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:30:11 +0200 Subject: [PATCH 027/249] add emulator's socket communication to mcu --- src/RFC/proxy_server.cpp | 139 +++++++++++++++++++++++++++++++++++++++ src/RFC/proxy_server.h | 31 +++++++++ 2 files changed, 170 insertions(+) create mode 100644 src/RFC/proxy_server.cpp create mode 100644 src/RFC/proxy_server.h diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp new file mode 100644 index 00000000..61b829c1 --- /dev/null +++ b/src/RFC/proxy_server.cpp @@ -0,0 +1,139 @@ +#include "proxy_server.h" +/* #include */ // Might be needed +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../Utils/util.h" + +// TODO exceptionmsg +const char NO_HOST_ERR[] = "No host and port set"; +const char CREATE_SOCK_ERR[] = "Could not create Socket"; +const char INVALID_HOST[] = "Invalid host"; +const char CONNECT_ERR[] = "Socket failed to connect"; +const char WRITE_ERR[] = "ERROR writing to socket"; +const char READ_ERR[] = "ERROR reading from socket"; + +struct ProxyServer::Address { + struct sockaddr_in aserv_addr; + struct hostent *aServer; +}; + +ProxyServer *ProxyServer::proxyServer = nullptr; + +ProxyServer *ProxyServer::getServer() { + if (proxyServer == nullptr) proxyServer = new ProxyServer(); + return proxyServer; +} + +void ProxyServer::registerMCUHost(uint8_t **data) { + int portno = (int)read_B32(data); + uint8_t hostsize = (uint8_t)(*data)[0]; + char *hostname = new char[hostsize + 1]; + memcpy((void *)hostname, ++(*data), hostsize); + hostname[hostsize] = '\0'; + printf("Registering Proxy Host: %s PORT=%d\n", hostname, portno); + ProxyServer::getServer()->registerAdress(hostname, portno); +} + +void ProxyServer::registerAdress(char *t_host, int t_port) { + if (this->host != nullptr) { + this->closeConnection(); + free(this->host); + } + this->host = t_host; + this->port = t_port; +} + +void ProxyServer::updateExcpMsg(const char *msg) { + if (this->exceptionMsg != nullptr) delete[] this->exceptionMsg; + auto msg_len = strlen(msg); + this->exceptionMsg = new char[(msg_len + 1) / sizeof(char)]; + this->exceptionMsg[msg_len] = '\0'; + memcpy(this->exceptionMsg, msg, msg_len); +} + +ProxyServer::ProxyServer() { + host = exceptionMsg = nullptr; + port = 0; + sockfd = -1; + address = (struct Address *)malloc(sizeof(struct Address)); +} + +bool ProxyServer::openConnection() { + if (this->host == nullptr) { + this->updateExcpMsg(NO_HOST_ERR); + return false; + } + + this->sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (this->sockfd < 0) { + this->updateExcpMsg(CREATE_SOCK_ERR); + return false; + } + + struct hostent *aServer = gethostbyname(this->host); + if (aServer == NULL) { + this->updateExcpMsg(INVALID_HOST); + return false; + } + + this->address->aServer = aServer; + struct sockaddr_in *aserv_addr = &this->address->aserv_addr; + bzero((char *)aserv_addr, sizeof(*aserv_addr)); + aserv_addr->sin_family = AF_INET; + bcopy((char *)aServer->h_addr, (char *)&aserv_addr->sin_addr.s_addr, + aServer->h_length); + aserv_addr->sin_port = htons(this->port); + if (connect(sockfd, (struct sockaddr *)aserv_addr, sizeof(*aserv_addr)) < + 0) { + this->updateExcpMsg(CONNECT_ERR); + return false; + } + return true; +} + +void ProxyServer::closeConnection() { + if (this->sockfd != -1) { + if (close(this->sockfd) == -1) { + if (errno == EINTR) close(this->sockfd); + } + this->sockfd = -1; + } +} + +bool ProxyServer::send(void *buffer, int size) { + int n = write(this->sockfd, buffer, size); + if (n == size) return true; + + if (n < 0 && errno == EINTR) // write interrupted, thus retry + return this->send(buffer, size); + else if (n < 0) { + this->updateExcpMsg(WRITE_ERR); + return false; + } + // send remaining bytes + char *buf = (char *)buffer + n; + return this->send((void *)buf, size - n); +} + +char *ProxyServer::readReply(short int amount) { + char *buffer = new char[amount + 1]; + bzero(buffer, amount + 1); + int n = read(this->sockfd, buffer, amount); + if (n > 0) return buffer; + + delete[] buffer; + if (errno == EINTR) // read interrupted, thus retry + return this->readReply(amount); + + this->updateExcpMsg(READ_ERR); + return nullptr; +} diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h new file mode 100644 index 00000000..9a575e85 --- /dev/null +++ b/src/RFC/proxy_server.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +class ProxyServer { + private: + // for singleton + static ProxyServer *proxyServer; + + char *host; + int port, sockfd; + + struct Address; + struct Address *address; + + // private constructor for singleton + ProxyServer(); + + public: + char *exceptionMsg; + + void registerAdress(char *t_host, int t_port); + void closeConnection(void); + bool openConnection(void); + void updateExcpMsg(const char *msg); + bool send(void *t_buffer, int t_size); + char *readReply(short int amount = 1024); + + static void registerMCUHost(uint8_t **data); + static ProxyServer *getServer(void); +}; From 1e115a5fd69f8c3e23e71ecfb1d93f3b62c6e55b Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:37:39 +0200 Subject: [PATCH 028/249] add remote function call class RFC runs either on the emulator or MCU. When executed on the emulator it takes a monitoring rol i.e., it keeps track of function identifiers that need to be executed remotely on the MCU. Functions that need to be executed remote are registered via `RFC::registerRFCs` or `RFC::registerRFC`. When executed on the MCU, the class takes the rol of executing a function on the MCU: functions that need to be executed on the MCU are registered via `RFC::registerRFCallee`. --- src/RFC/rfc.cpp | 378 ++++++++++++++++++++++++++++++++++++++++++++++++ src/RFC/rfc.h | 61 ++++++++ 2 files changed, 439 insertions(+) create mode 100644 src/RFC/rfc.cpp create mode 100644 src/RFC/rfc.h diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp new file mode 100644 index 00000000..03f1cda3 --- /dev/null +++ b/src/RFC/rfc.cpp @@ -0,0 +1,378 @@ +#include "rfc.h" + +#include + +#include +#include +#include +#include +#include + +#include "../Debug/debugger.h" +#include "../Utils/macros.h" +#include "../Utils/util.h" +#include "proxy_server.h" + +// TODO tests with exceptions +////TODO test with many args proxy +////TODO test with no return proxy + +unsigned short int sizeof_valuetype(uint32_t); +unsigned short int sizeSerializationRFC(const Type *); +unsigned short int sizeSerializationRFCallee(RFC *); +void arguments_copy(unsigned char *, StackValue *, uint32_t); + +std::map functions; +std::queue callees; + +/* + * Proxy Manager Client Side + */ + +RFC *RFC::registerRFC(uint32_t t_fid, Type *t_type) { + RFC *rfc = new RFC(t_fid, t_type); + functions[t_fid] = rfc; + return rfc; +} + +void RFC::unregisterRFC(uint32_t fid) { + auto it = functions.find(fid); + if (it != functions.end()) functions.erase(it); +} + +void RFC::clearRFCs() { + std::map::iterator it; + for (it = functions.begin(); it != functions.end(); it++) delete it->second; + functions.clear(); +} + +bool RFC::isRFC(uint32_t fid) { + auto it = functions.find(fid); + return it != functions.end(); +} + +RFC *RFC::getRFC(uint32_t fid) { + auto it = functions.find(fid); + return it->second; +} + +/* + * Proxy Manager Server Side + */ + +RFC *RFC::registerRFCallee(uint32_t t_fid, Type *t_type, StackValue *t_args, + ExecutionState *t_executionState) { + RFC *rfc = new RFC(t_fid, t_type, t_args, t_executionState); + callees.push(rfc); + return rfc; +} + +bool RFC::hasRFCallee() { return !callees.empty(); } + +RFC *RFC::currentCallee() { return callees.front(); } + +void RFC::removeRFCallee() { callees.pop(); } + +/* + * RFC methods + */ + +RFC::RFC(uint32_t t_fid, Type *t_type, StackValue *t_args, + ExecutionState *t_exState) + : fid(t_fid), args(t_args), type(t_type), executionState(t_exState) { + this->exceptionMsg = nullptr; + this->excpMsgSize = 0; + this->succes = true; + this->result = nullptr; + if (t_type->result_count > 0) { + this->result = new StackValue; + this->result->value_type = t_type->results[0]; + } +} + +void RFC::returnResult(Module *m) { + // reading result from stack + if (this->succes && this->type->result_count > 0) { + this->result->value_type = m->stack[m->sp].value_type; + this->result->value = m->stack[m->sp].value; + } else if (!this->succes) { + printf("some exeception will be returned\n"); + // TODO exception msg + } + + // returning the result to the client + struct SerializeData *rfc_result = this->serializeRFCallee(); + FATAL("writing into socketdf\n"); + write(m->warduino->debugger->socket, rfc_result->raw, rfc_result->size); +} + +void RFC::restoreExecutionState(Module *m, RunningState *program_state) { + // restoring the original execution state + *program_state = this->executionState->program_state; + m->csp = this->executionState->csp; + m->sp = this->executionState->sp; + m->pc_ptr = this->executionState->pc_ptr; +} + +bool RFC::callCompleted(Module *m) { + return !this->succes || this->executionState->csp == m->csp; +} + +/* + * + * output: 1 byte | 4 bytes | sizeof(arg1.value_type) bytes | + * sizeof(arg2.value_type) bytes | ... interrupt | funID | arg1.value + * + * Output is also transformed to hexa + * + */ + +struct RFC::SerializeData *RFC::serializeRFC() { + const unsigned short serializationSize = sizeSerializationRFC(this->type); + unsigned char *buffer = new unsigned char[serializationSize]; + + // write to array: interrupt, function identifier and arguments + const unsigned char interrupt = interruptProxyCall; + memcpy(buffer, &interrupt, sizeof(unsigned char)); + memcpy(buffer + 1, &fid, sizeof(uint32_t)); + arguments_copy(buffer + 5, args, type->param_count); + + // array as hexa + const uint32_t hexa_size = serializationSize * 2; + unsigned char *hexa = + new unsigned char[hexa_size + 2]; //+2 for '\n' and '0' termination + chars_as_hexa(hexa, buffer, serializationSize); + hexa[hexa_size] = '\n'; + hexa[hexa_size + 1] = '\0'; // TODO remove zero termination and +2 above + + delete[] buffer; + struct SerializeData *ser = new SerializeData; + ser->size = hexa_size + 1; + ser->raw = hexa; + return ser; +} + +struct RFC::SerializeData *RFC::serializeRFCallee() { + const unsigned short serializationSize = sizeSerializationRFCallee(this); + unsigned char *raw = new unsigned char[serializationSize]; + uint8_t suc = this->succes ? 1 : 0; + + memcpy(raw, &suc, sizeof(uint8_t)); + if (this->succes && this->type->result_count > 0) { + printf("serializeRFCallee: success value size=%u \n", + sizeof_valuetype(this->result->value_type)); + memcpy(raw + 1, &this->result->value, + sizeof_valuetype(this->result->value_type)); + } else if (!this->succes) { + printf("serializeRFCallee: serializing exception\n"); + memcpy(raw + 1, &this->excpMsgSize, sizeof(uint16_t)); + memcpy(raw + 1 + sizeof(uint16_t), this->exceptionMsg, + this->excpMsgSize); + } + + struct SerializeData *ser = new struct SerializeData; + ser->raw = raw; + ser->size = serializationSize; + return ser; +} + +/* + * returns the quantity of bytes needed to serialize a RFC. + * The size includes: Interrupt + Id of the function + parameters + */ +unsigned short int sizeSerializationRFC(const Type *type) { + short unsigned int paramSize = 0; + for (uint32_t i = 0; i < type->param_count; i++) + paramSize += sizeof_valuetype(type->params[i]); + + return 1 + sizeof(uint32_t) + paramSize; +} + +unsigned short int sizeSerializationRFCallee(RFC *callee) { + if (!callee->succes) return 1 + sizeof(uint16_t) + callee->excpMsgSize; + + if (callee->type->result_count > 0) + return 1 + sizeof_valuetype(callee->type->results[0]); + else + return 1; +} + +unsigned short int sizeof_valuetype(uint32_t vt) { + switch (vt) { + case I32: + return 4; + case I64: + return 8; + case F32: + return sizeof(float); + default: + return sizeof(double); + } +} + +void arguments_copy(unsigned char *dest, StackValue *args, + uint32_t param_count) { + uint32_t offset = 0; + for (uint32_t i = 0; i < param_count; i++) { + switch (args[i].value_type) { + case I32: { + memcpy(dest + offset, &args[i].value.uint32, sizeof(uint32_t)); + offset += sizeof(uint32_t); + break; + } + case F32: { + memcpy(dest + offset, &args[i].value.f32, sizeof(float)); + offset += sizeof(float); + break; + } + case I64: { + memcpy(dest + offset, &args[i].value.uint64, sizeof(uint64_t)); + offset += sizeof(uint64_t); + break; + } + case F64: { + memcpy(dest + offset, &args[i].value.f64, sizeof(double)); + offset += sizeof(double); + break; + } + default: + FATAL("incorrect StackValue type\n"); + break; + } + } +} + +void RFC::deserializeRFCResult() { + ProxyServer *host = ProxyServer::getServer(); + + uint8_t *call_result = (uint8_t *)host->readReply(); + this->succes = (uint8_t)call_result[0] == 1; + + if (!this->succes) { + uint16_t msg_size = 0; + memcpy(&msg_size, call_result + 1, sizeof(uint16_t)); + if (msg_size > this->excpMsgSize) { + delete[] this->exceptionMsg; + this->exceptionMsg = new char[msg_size]; + this->excpMsgSize = msg_size; + } + memcpy(this->exceptionMsg, call_result + 1 + sizeof(uint16_t), + msg_size); + delete[] call_result; + return; + } + + if (this->type->result_count == 0) { + delete[] call_result; + return; + } + + this->result->value.uint64 = 0; + switch (this->result->value_type) { + case I32: + memcpy(&result->value.uint32, call_result + 1, sizeof(uint32_t)); + dbg_info("deserialized U32 %" PRIu32 "\n", result->value.uint32); + break; + case F32: + memcpy(&result->value.f32, call_result + 1, sizeof(float)); + dbg_info("deserialized f32 %f \n", result->value.f32); + break; + case I64: + memcpy(&result->value.uint64, call_result + 1, sizeof(uint64_t)); + dbg_info("deserialized I64 %" PRIu64 "\n", result->value.uint64); + break; + case F64: + memcpy(&result->value.f64, call_result + 1, sizeof(double)); + dbg_info("deserialized f32 %f \n", result->value.f64); + break; + default: + FATAL("Deserialization RFCResult\n"); + } + delete[] call_result; +} + +void RFC::call(StackValue *args) { + this->args = args; + struct SerializeData *rfc_request = this->serializeRFC(); + + ProxyServer *host = ProxyServer::getServer(); + printf("making the RFC call\n"); + bool sent = host->send((void *)rfc_request->raw, rfc_request->size); + if (!sent) { + this->succes = false; + this->exceptionMsg = host->exceptionMsg; + + delete[] rfc_request->raw; + delete rfc_request; + return; + } + this->deserializeRFCResult(); +} + +void RFC::registerRFCs(Module *m, uint8_t **data) { + printf("registering_rfc_functions\n"); + RFC::clearRFCs(); + uint32_t amount_funcs = read_B32(data); + printf("funcs_total %" PRIu32 "\n", amount_funcs); + for (uint32_t i = 0; i < amount_funcs; i++) { + uint32_t fid = read_B32(data); + printf("registering fid=%" PRIu32 "\n", fid); + Type *type = (m->functions[fid]).type; + RFC::registerRFC(fid, type); + } +} + +StackValue *RFC::readRFCArgs(Block *func, uint8_t *data) { + if (func->type->param_count == 0) { + printf("ProxyFunc %" PRIu32 "takes no arg\n", func->fidx); + return nullptr; + } + + StackValue *args = new StackValue[func->type->param_count]; + uint32_t *params = func->type->params; + for (uint32_t i = 0; i < func->type->param_count; i++) { + args[i].value.uint64 = 0; // init whole union to 0 + args[i].value_type = params[i]; + + switch (params[i]) { + case I32: { + memcpy(&args[i].value.uint32, data, sizeof(uint32_t)); + data += sizeof(uint32_t); + printf("arg %d: i32 value %" PRIu32 "\n", i, + args[i].value.uint32); + break; + } + case F32: { + memcpy(&args[i].value.f32, data, sizeof(float)); + data += sizeof(float); + printf("arg %d: F32 value %.7f \n", i, args[i].value.f32); + break; + } + case I64: { + memcpy(&args[i].value.uint64, data, sizeof(uint64_t)); + data += sizeof(uint64_t); + printf("arg %d: I64 value %" PRIu64 "\n", i, + args[i].value.uint64); + break; + } + case F64: { + memcpy(&args[i].value.f64, data, sizeof(double)); + data += sizeof(double); + printf("arg %d: f64 value %.7f \n", i, args[i].value.f64); + break; + } + default: { + FATAL("incorrect argument type: %" PRIu32 "\n", params[i]); + break; + } + } + } + return args; +} + +void RFC::setupCalleeArgs(Module *m, RFC *callee) { + // adding arguments to the stack + StackValue *args = callee->args; + for (uint32_t i = 0; i < callee->type->param_count; i++) + m->stack[++m->sp] = args[i]; +} diff --git a/src/RFC/rfc.h b/src/RFC/rfc.h new file mode 100644 index 00000000..2591daf7 --- /dev/null +++ b/src/RFC/rfc.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +#include "../WARDuino.h" + +typedef struct { + int csp; + int sp; + uint8_t *pc_ptr; + RunningState program_state; +} ExecutionState; + +class RFC { + private: + // short unsigned serializationSize; + struct SerializeData { + const unsigned char *raw; + uint32_t size; + }; + + struct SerializeData *serializeRFC(); + struct SerializeData *serializeRFCallee(); + void deserializeRFCResult(void); + + public: + const uint32_t fid; + StackValue *args; + const Type *type; + StackValue *result; + bool succes; + char *exceptionMsg; + uint16_t excpMsgSize; + const ExecutionState *executionState; + + RFC(uint32_t t_fid, Type *t_type, StackValue *t_args = nullptr, + ExecutionState *t_exState = nullptr); + void call(StackValue *args); + void returnResult(Module *m); + void restoreExecutionState(Module *m, RunningState *program_state); + bool callCompleted(Module *m); + + // Client side + static RFC *registerRFC(uint32_t t_fid, Type *t_type); + static void registerRFCs(Module *m, uint8_t **data); + static void unregisterRFC(uint32_t fid); + static bool isRFC(uint32_t fid); + static RFC *getRFC(uint32_t fid); + static void clearRFCs(void); + + // Server side + static RFC *registerRFCallee(uint32_t t_fid, Type *t_type, + StackValue *t_args, + ExecutionState *t_executionState); + static bool hasRFCallee(void); + static RFC *currentCallee(void); + static void removeRFCallee(void); + static StackValue *readRFCArgs(Block *func, uint8_t *data); + static void setupCalleeArgs(Module *m, RFC *callee); +}; From 3d3ce38b86c0a138aff11b880e65a187f887363c Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:44:27 +0200 Subject: [PATCH 029/249] add rfc and proxy_server source files --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2738064a..82509b06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ if (BUILD_EMULATOR) src/WARDuino/CallbackHandler.cpp src/Primitives/primitives.cpp src/Interpreter/instructions.cpp + src/RFC/rfc.cpp + src/RFC/proxy_server.cpp ) set(TEST_FRAMEWORK tests/integration/wasm_tests.cpp From 552bf8db8097052d4c1fa8a60f95f303608120b1 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:46:00 +0200 Subject: [PATCH 030/249] add interrupts to monitor and perform rfc added `interruptMinitorProxies` to tell the emulator which functions need to be executed on the MCU. And added `interruptProxyCall` for requesting the MCU to execute the requested function. --- src/Debug/debugger.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++ src/Debug/debugger.h | 21 ++++++++++++++++--- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 5910ac97..378aae4b 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -7,6 +7,8 @@ #include #include "../Memory/mem.h" +#include "../RFC/proxy_server.h" +#include "../RFC/rfc.h" #include "../Utils//util.h" #include "../Utils/macros.h" @@ -201,6 +203,18 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } } break; +#ifdef ARDUINO + case interruptProxyCall: { + this->handleProxyCall(m, program_state, interruptData + 1); + free(interruptData); + } break; +#else + case interruptMonitorProxies: { + printf("receiving functions list to proxy\n"); + this->handleMonitorProxies(m, interruptData + 1); + free(interruptData); + } break; +#endif default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); @@ -849,3 +863,36 @@ uintptr_t Debugger::readPointer(uint8_t **data) { *data += 1 + len; // skip pointer return bp; } + +#ifdef ARDUINO +void Debugger::handleProxyCall(Module *m, RunningState *program_state, + uint8_t *interruptData) { + uint8_t *data = interruptData + 1; + uint32_t fidx = read_L32(&data); + printf("Call func %" PRIu32 "\n", fidx); + + Block *func = &m->functions[fidx]; + StackValue *args = RFC::readRFCArgs(func, data); + printf("Registering %" PRIu32 "as Callee\n", func->fidx); + + // preserving execution state of call that got interrupted + ExecutionState *executionState = new ExecutionState; + executionState->program_state = *program_state; + executionState->sp = m->sp; + executionState->pc_ptr = m->pc_ptr; + executionState->csp = m->csp; + RFC::registerRFCallee(fidx, func->type, args, executionState); + + *program_state = WARDuinoProxyRun; +} +#else +void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { + RFC::registerRFCs(m, &interruptData); + ProxyServer::registerMCUHost(&interruptData); + ProxyServer *mcuhost = ProxyServer::getServer(); + if (!mcuhost->openConnection()) { + FATAL("problem opening socket to MCU: %s\n", mcuhost->exceptionMsg); + } + dprintf(this->socket, "done!\n"); +} +#endif diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index bc250922..39e8e816 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -9,7 +9,12 @@ struct Module; struct Block; struct StackValue; -enum RunningState { WARDUINOrun, WARDUINOpause, WARDUINOstep }; +enum RunningState { + WARDUINOrun, + WARDUINOpause, + WARDUINOstep, + WARDuinoProxyRun +}; enum InterruptTypes { interruptRUN = 0x01, @@ -26,6 +31,8 @@ enum InterruptTypes { interruptWOODDUMP = 0x60, interruptOffset = 0x61, interruptRecvState = 0x62, + interruptMonitorProxies = 0x63, + interruptProxyCall = 0x64 }; class Debugger { @@ -71,7 +78,9 @@ class Debugger { bool handleChangedLocal(Module *m, uint8_t *bytes) const; - // WOOD + // WOOD Private Methods + + // receiving and dumping State bool receivingData = false; void freeState(Module *m, uint8_t *interruptData); static uint8_t *findOpcode(Module *m, Block *block); @@ -105,4 +114,10 @@ class Debugger { // WOOD void woodDump(Module *m); -}; \ No newline at end of file +#ifdef ARDUINO + void handleProxyCall(Module *m, RunningState *program_state, + uint8_t *interruptData); +#else + void handleMonitorProxies(Module *m, uint8_t *interruptData); +#endif +}; From e497b9ddd89661082f2d34b784643ec748288600 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 12:49:25 +0200 Subject: [PATCH 031/249] interpret performs or answers RFC --- src/Interpreter/instructions.cpp | 78 ++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 3a81608f..dcda415a 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -5,10 +5,15 @@ #include "../Debug/debugger.h" #include "../Memory/mem.h" +#include "../RFC/rfc.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "../Utils/util_arduino.h" +#ifndef ARDUINO +// performs proxy calls to an MCU +bool proxy_call(uint32_t fidx, Module *m); +#endif // Size of memory load. // This starts with the first memory load operator at opcode 0x28 uint32_t LOAD_SIZE[] = {4, 8, 4, 8, 1, 1, 2, 2, 1, 1, 2, 2, 4, 4, // loads @@ -339,6 +344,9 @@ bool i_instr_return(Module *m) { */ bool i_instr_call(Module *m) { uint32_t fidx = read_LEB_32(&m->pc_ptr); +#ifndef ARDUINO + if (RFC::isRFC(fidx)) return proxy_call(fidx, m); +#endif if (fidx < m->import_count) { return ((Primitive)m->functions[fidx].func_ptr)(m); } else { @@ -355,6 +363,27 @@ bool i_instr_call(Module *m) { return true; } +#ifndef ARDUINO +bool proxy_call(uint32_t fidx, Module *m) { + printf("Remote Function Call %d\n", fidx); + RFC *rf = RFC::getRFC(fidx); + StackValue *args = nullptr; + if (rf->type->param_count > 0) { + m->sp -= rf->type->param_count; + args = &m->stack[m->sp + 1]; + } + + rf->call(args); + if (!rf->succes) { + // TODO exception bugger might be too small and msg not null terminated? + memcpy(&exception, rf->exceptionMsg, strlen(rf->exceptionMsg)); + return false; + } + if (rf->type->result_count > 0) m->stack[++m->sp] = *rf->result; + return true; +} +#endif + /** * 0x11 call_indirect */ @@ -386,6 +415,10 @@ bool i_instr_call_indirect(Module *m) { val, fidx); } +#ifndef ARDUINO + if (RFC::isRFC(fidx)) return proxy_call(fidx, m); +#endif + if (fidx < m->import_count) { // THUNK thunk_out(m, fidx); // import/thunk call } else { @@ -1467,6 +1500,8 @@ bool interpret(Module *m) { // TODO: this is actually a property of warduino RunningState program_state = WARDUINOrun; + // needed for RFC + RFC *callee = nullptr; while (!program_done && success) { if (program_state == WARDUINOstep) { program_state = WARDUINOpause; @@ -1477,21 +1512,52 @@ bool interpret(Module *m) { fflush(stdout); reset_wdt(); +#ifdef ARDUINO + // handle RFC requested by emulator + if (program_state == WARDuinoProxyRun) { + if (callee == nullptr) { // TODO maybe use RFC::hasRFCallee() + // call happens for the first time + callee = RFC::currentCallee(); + RFC::setupCalleeArgs(m, callee); + + // Primitive function RFC happen instantly + if (callee->fid < m->import_count) { + callee->succes = + ((Primitive)m->functions[callee->fid].func_ptr)(m); + callee->returnResult(m); + callee->restoreExecutionState(m, &program_state); + RFC::removeRFCallee(); + callee = nullptr; + } else + setup_call(m, callee->fid); + } else { + // check if call completes + if (callee->callCompleted(m)) { + callee->returnResult(m); + callee->restoreExecutionState(m, &program_state); + RFC::removeRFCallee(); + callee = nullptr; + } + } + } +#endif + if (program_state == WARDUINOpause) { continue; } // Program state is not paused - // Resolve 1 callback event if queue is not empty and no event currently - // resolving + // Resolve 1 callback event if queue is not empty and no event + // currently resolving // if (!CallbackHandler::resolving_event) { CallbackHandler::resolve_event(); // } // if BP and not the one we just unpaused if (m->warduino->debugger->isBreakpoint(m->pc_ptr) && - m->warduino->debugger->skipBreakpoint != m->pc_ptr) { + m->warduino->debugger->skipBreakpoint != m->pc_ptr && + program_state != WARDuinoProxyRun) { program_state = WARDUINOpause; printf("AT %p!\n", (void *)m->pc_ptr); continue; @@ -1690,6 +1756,12 @@ bool interpret(Module *m) { } return false; } + if (program_state == WARDuinoProxyRun && !success) { + // RFC was unsuccesful + RFC::currentCallee()->succes = false; + // TODO copy exceptionMsg + success = true; + } } // Resolve all unhandled callback events From 4398556109f88a5fdcb7e8edb7b888b22bc102da Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 13:01:42 +0200 Subject: [PATCH 032/249] format --- platforms/Arduino/examples/blink.c | 35 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/platforms/Arduino/examples/blink.c b/platforms/Arduino/examples/blink.c index 0013ee79..c64c74a4 100644 --- a/platforms/Arduino/examples/blink.c +++ b/platforms/Arduino/examples/blink.c @@ -1,21 +1,20 @@ unsigned char blink_wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, - 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, - 0x4f, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, - 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, - 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, - 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, - 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x00, 0x01, 0x03, 0x03, 0x02, 0x02, - 0x02, 0x06, 0x10, 0x03, 0x7f, 0x00, 0x41, 0x0a, 0x0b, 0x7f, 0x00, 0x41, - 0x01, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, - 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x33, 0x02, 0x08, 0x00, 0x23, 0x00, - 0x41, 0x02, 0x10, 0x01, 0x0b, 0x28, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, - 0x21, 0x00, 0x10, 0x04, 0x03, 0x40, 0x23, 0x00, 0x23, 0x00, 0x10, 0x03, - 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x23, 0x00, 0x23, 0x02, - 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x0b -}; + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, + 0x4f, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, + 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, + 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x00, 0x01, 0x03, 0x03, 0x02, 0x02, + 0x02, 0x06, 0x10, 0x03, 0x7f, 0x00, 0x41, 0x0a, 0x0b, 0x7f, 0x00, 0x41, + 0x01, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, + 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x33, 0x02, 0x08, 0x00, 0x23, 0x00, + 0x41, 0x02, 0x10, 0x01, 0x0b, 0x28, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, + 0x21, 0x00, 0x10, 0x04, 0x03, 0x40, 0x23, 0x00, 0x23, 0x00, 0x10, 0x03, + 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x23, 0x00, 0x23, 0x02, + 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x0b}; unsigned int blink_wasm_len = 190; /* -*/ + */ From ae494c2e89cb4a70b6d0e1b25042f631cdab164c Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 20 Apr 2022 13:02:56 +0200 Subject: [PATCH 033/249] format --- src/Debug/debugger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index c6cb86d4..27cce6ef 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -863,7 +863,7 @@ uintptr_t Debugger::readPointer(uint8_t **data) { #ifdef ARDUINO void Debugger::handleProxyCall(Module *m, RunningState *program_state, - uint8_t *interruptData) { + uint8_t *interruptData) { uint8_t *data = interruptData + 1; uint32_t fidx = read_L32(&data); printf("Call func %" PRIu32 "\n", fidx); From 109bf0704482e35476a2a82bfbb607aa7de0899d Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 10:20:53 +0200 Subject: [PATCH 034/249] save draft socket server --- examples/blinkm5stickc/blink.wast | 54 ++++++++++++++ platforms/Arduino/Arduino.ino | 18 ++++- platforms/Arduino/upload.h | 90 +++++++++++------------ src/Debug/debugger.cpp | 2 +- src/Primitives/arduino.cpp | 2 +- src/RFC/SocketServer.cpp | 117 ++++++++++++++++++++++++++++++ src/RFC/SocketServer.h | 39 ++++++++++ src/RFC/rfc.cpp | 13 +++- src/RFC/rfc.h | 2 + 9 files changed, 283 insertions(+), 54 deletions(-) create mode 100644 examples/blinkm5stickc/blink.wast create mode 100644 src/RFC/SocketServer.cpp create mode 100644 src/RFC/SocketServer.h diff --git a/examples/blinkm5stickc/blink.wast b/examples/blinkm5stickc/blink.wast new file mode 100644 index 00000000..0e0ed2df --- /dev/null +++ b/examples/blinkm5stickc/blink.wast @@ -0,0 +1,54 @@ +(module + ;; Type declarations + (type $int32->int32->void (func (param i32 i32))) + (type $int32->void (func (param i32))) + (type $void->void (func)) + + ;; Imports from the WARDuino VM + (import "env" "chip_delay" (func $env.chip_delay (type $int32->void))) + (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $int32->int32->void))) + (import "env" "chip_digital_write" (func $env.chip_digital_write (type $int32->int32->void))) + (import "env" "print_int" (func $env.print_int (type $int32->void))) + + + ;; Non-mutable globals + (global $led i32 (i32.const 10)) + (global $on i32 (i32.const 1)) + (global $off i32 (i32.const 0)) + + ;; Initialise function (private) + (func $init (type $void->void) + ;; Set pin mode + global.get $led + i32.const 2 + call $env.chip_pin_mode) + + ;; Blink function (public) + (func $blink (type $void->void) + ;; Declare local $delay + (local $delay i32) + i32.const 1000 + local.set $delay + + ;; Initialise + call $init + + ;; Blink in infinite loop + loop $infinite + global.get $led + global.get $led + call $env.print_int ;;print led nr + global.get $on + call $env.chip_digital_write ;; turn led on + local.get $delay + call $env.chip_delay ;; wait + global.get $led + global.get $off + call $env.chip_digital_write ;; turn led off + local.get $delay + call $env.chip_delay ;; wait + br $infinite ;; jump back to start of loop + end) + + ;; Export blink as function + (export "main" (func $blink))) diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index 919bee00..833e5a3a 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -5,6 +5,7 @@ //#include #include +#include #include "Arduino.h" #include "upload.h" @@ -17,6 +18,9 @@ unsigned char* wasm = upload_wasm; WARDuino wac; Module* m; +ServerCredentials serverCredentials = {"telenet-3689855", "bhdkeswun6Fz"}; +uint16_t portno = 8080; +SocketServer *server; #define UART_PIN 3 @@ -59,16 +63,22 @@ void setup(void) { Serial.println(ESP.getPsramSize()); Serial.println("\nFree PSRAM: "); Serial.println(ESP.getFreePsram()); + + SocketServer::initializeServer(portno, &wac); + SocketServer *server = SocketServer::getServer(); + server->connect2Wifi(&serverCredentials); } void loop() { disableCore0WDT(); m = wac.load_module(wasm, wasm_len, {}); - + printf("PRIOR BEGIN\n"); + server->begin(); + printf("POST BEGIN\n"); printf("LOADED \n\n"); - uint8_t command[] = {'0', '3', '\n'}; - wac.handleInterrupt(3, command); - xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); + //uint8_t command[] = {'0', '3', '\n'}; + //wac.handleInterrupt(3, command); + //xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); Serial.println("\nFree heap:"); diff --git a/platforms/Arduino/upload.h b/platforms/Arduino/upload.h index 88268537..9fb205e7 100644 --- a/platforms/Arduino/upload.h +++ b/platforms/Arduino/upload.h @@ -1,49 +1,49 @@ // blinks led on pin 23 -unsigned char upload_wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, - 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, - 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, - 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, - 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, - 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, - 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, - 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, - 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, - 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, - 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, - 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, - 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, - 0x0b, 0x0b, 0x00, 0x6e, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x49, 0x05, - 0x00, 0x0e, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, - 0x65, 0x6c, 0x61, 0x79, 0x01, 0x11, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, - 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x02, - 0x16, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, 0x69, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x03, - 0x04, 0x69, 0x6e, 0x69, 0x74, 0x04, 0x05, 0x62, 0x6c, 0x69, 0x6e, 0x6b, - 0x02, 0x1c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, - 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, - 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; -unsigned int upload_wasm_len = 282; +// unsigned char upload_wasm[] = { +// 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, +// 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, +// 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, +// 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, +// 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, +// 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, +// 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, +// 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, +// 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, +// 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, +// 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, +// 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, +// 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, +// 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, +// 0x0b, 0x0b, 0x00, 0x6e, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x49, 0x05, +// 0x00, 0x0e, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, +// 0x65, 0x6c, 0x61, 0x79, 0x01, 0x11, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, +// 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x02, +// 0x16, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, 0x69, +// 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x03, +// 0x04, 0x69, 0x6e, 0x69, 0x74, 0x04, 0x05, 0x62, 0x6c, 0x69, 0x6e, 0x6b, +// 0x02, 0x1c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, +// 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, +// 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; +// unsigned int upload_wasm_len = 282; /* blink pin 10 (M5stickC internal led) platforms/Arduino/examples/blink.wast */ -// unsigned char upload_wasm[] = { -// 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, -// 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, -// 0x4f, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, -// 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, -// 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, -// 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, -// 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, -// 0x74, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x70, 0x72, 0x69, -// 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x00, 0x01, 0x03, 0x03, 0x02, 0x02, -// 0x02, 0x06, 0x10, 0x03, 0x7f, 0x00, 0x41, 0x0a, 0x0b, 0x7f, 0x00, 0x41, -// 0x01, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, -// 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x33, 0x02, 0x08, 0x00, 0x23, 0x00, -// 0x41, 0x02, 0x10, 0x01, 0x0b, 0x28, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, -// 0x21, 0x00, 0x10, 0x04, 0x03, 0x40, 0x23, 0x00, 0x23, 0x00, 0x10, 0x03, -// 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x23, 0x00, 0x23, 0x02, -// 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x0b -// }; -// unsigned int upload_wasm_len = 190; +unsigned char upload_wasm[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, + 0x4f, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, + 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, + 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x00, 0x01, 0x03, 0x03, 0x02, 0x02, + 0x02, 0x06, 0x10, 0x03, 0x7f, 0x00, 0x41, 0x0a, 0x0b, 0x7f, 0x00, 0x41, + 0x01, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, + 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x33, 0x02, 0x08, 0x00, 0x23, 0x00, + 0x41, 0x02, 0x10, 0x01, 0x0b, 0x28, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, + 0x21, 0x00, 0x10, 0x04, 0x03, 0x40, 0x23, 0x00, 0x23, 0x00, 0x10, 0x03, + 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x23, 0x00, 0x23, 0x02, + 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x0b +}; +unsigned int upload_wasm_len = 190; diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 27cce6ef..85527ee1 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -864,7 +864,7 @@ uintptr_t Debugger::readPointer(uint8_t **data) { #ifdef ARDUINO void Debugger::handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData) { - uint8_t *data = interruptData + 1; + uint8_t *data = interruptData; uint32_t fidx = read_L32(&data); printf("Call func %" PRIu32 "\n", fidx); diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index a9e00067..7d0b5d36 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -891,4 +891,4 @@ bool resolve_external_memory(char *symbol, Memory **val) { FATAL("Could not find memory %s \n", symbol); return false; -} \ No newline at end of file +} diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp new file mode 100644 index 00000000..82ed68ed --- /dev/null +++ b/src/RFC/SocketServer.cpp @@ -0,0 +1,117 @@ +#ifdef ARDUINO +#include "SocketServer.h" + +#include "Arduino.h" + +#include +#include +#include + +SocketServer *SocketServer::socketServer = nullptr; + +SocketServer::SocketServer(uint16_t t_port, WARDuino *t_wrd) : portno(t_port) { + asyncServer = nullptr; + warduino = t_wrd; +} + +void SocketServer::initializeServer(uint16_t t_port, WARDuino *t_wrd) { + if (socketServer == nullptr) socketServer = new SocketServer(t_port, t_wrd); +} + +SocketServer *SocketServer::getServer() { return socketServer; } + +void SocketServer::connect2Wifi(ServerCredentials *t_credentials) { + Serial.println("Connecting to WiFi.."); + WiFi.begin(t_credentials->ssid, t_credentials->pswd); + while (WiFi.status() != WL_CONNECTED) { + delay(10); + } + + Serial.printf("%d.%d.%d.%d\n\n", WiFi.localIP()[0], WiFi.localIP()[1], + WiFi.localIP()[2], WiFi.localIP()[3]); + printf("Connected and this is %p\n", this); +} + +void SocketServer::begin() { + printf("prior new AsyncServer()\n"); + printf("%p\n", this); + if (this == nullptr) { + printf("yes nullptr!!!\n"); + } + printf("portno %d\n", this->portno); + + this->asyncServer = new AsyncServer(this->portno); + printf("this->asyncServer->begin()\n"); + this->asyncServer->begin(); + printf("this->asyncServer->onClient()\n"); + this->asyncServer->onClient( + [this](void *s, AsyncClient *c) { + printf("A client connected!\n"); + this->registerClient(c); + }, + NULL); + printf("done with SocketServer::begin()\n"); +} + +void SocketServer::registerClient(AsyncClient *t_client) { + if (t_client == NULL) { + printf("Client is NULL\n"); + return; + } + + if (this->client == nullptr) { + this->client = t_client; + } else { + printf("Only one socket client allowed.\n"); + t_client->close(true); + t_client->free(); + delete t_client; + return; + } + + WARDuino *wrd = this->warduino; + SocketServer *thisServer = this; + t_client->onError( + [thisServer](void *r, AsyncClient *t_client, int8_t error) { + printf("ClientSocket Error %" PRIu8 "\n", error); + }, + NULL); + t_client->onDisconnect( + [thisServer](void *r, AsyncClient *t_client) { + printf("Client Disconnected\n"); + thisServer->unregisterClient(t_client); + }, + NULL); + t_client->onTimeout( + [thisServer](void *r, AsyncClient *t_client, uint32_t time) { + printf("Client timeouted\n"); + thisServer->unregisterClient(t_client); + }, + NULL); + t_client->onData( + [wrd](void *r, AsyncClient *t_client, void *buf, size_t len) { + wrd->handleInterrupt(len, (uint8_t *)buf); + }, + NULL); +} + +void SocketServer::unregisterClient(AsyncClient *t_client) { + if (this->client == t_client) { + this->client = nullptr; + } + t_client->close(true); // TODO potential issue: close twice same client + t_client->free(); + delete t_client; +} + +void SocketServer::write2Client(const char *buf, size_t size_buf) { + if (this->client == nullptr) return; + // const char* cbuf = (char*)buf; + // size_t size_buf = (size_t) count; + size_t space_left = client->space(); + client->add(buf, size_buf > space_left ? space_left : size_buf); + client->send(); + if (size_buf <= space_left) return; + write2Client(buf + space_left, size_buf - space_left); +} +#endif ARDUINO diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h new file mode 100644 index 00000000..54bebee3 --- /dev/null +++ b/src/RFC/SocketServer.h @@ -0,0 +1,39 @@ +#pragma once +#ifdef ARDUINO +#include +#include +#include +#include + +#include "WARDuino.h" + +typedef struct { + const char *ssid; + const char *pswd; +} ServerCredentials; + +class SocketServer { + private: + AsyncServer *asyncServer; + AsyncClient *client; + WARDuino *warduino; + + const uint16_t portno; + ServerCredentials *credentials; + + void registerClient(AsyncClient *t_client); + void unregisterClient(AsyncClient *t_client); + + public: + // singleton + static SocketServer *socketServer; + SocketServer(uint16_t t_port, WARDuino *t_wrd); + + void begin(); + void connect2Wifi(ServerCredentials *t_credentials); + void write2Client(const char *buf, size_t size_buf); + + static SocketServer *getServer(void); + static void initializeServer(uint16_t t_port, WARDuino *t_wrd); +}; +#endif diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index 03f1cda3..4d02bb9e 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -12,6 +12,9 @@ #include "../Utils/macros.h" #include "../Utils/util.h" #include "proxy_server.h" +#ifdef ARDUINO +#include "SocketServer.h" +#endif // TODO tests with exceptions ////TODO test with many args proxy @@ -89,7 +92,7 @@ RFC::RFC(uint32_t t_fid, Type *t_type, StackValue *t_args, this->result->value_type = t_type->results[0]; } } - +#ifdef ARDUINO void RFC::returnResult(Module *m) { // reading result from stack if (this->succes && this->type->result_count > 0) { @@ -102,9 +105,13 @@ void RFC::returnResult(Module *m) { // returning the result to the client struct SerializeData *rfc_result = this->serializeRFCallee(); - FATAL("writing into socketdf\n"); - write(m->warduino->debugger->socket, rfc_result->raw, rfc_result->size); + const char * data = (const char*) rfc_result->raw; + size_t data_size = (size_t) rfc_result->size; + SocketServer::getServer()->write2Client(data, data_size); + // FATAL("writing into socketdf\n"); + // write(m->warduino->debugger->socket, rfc_result->raw, rfc_result->size); } +#endif void RFC::restoreExecutionState(Module *m, RunningState *program_state) { // restoring the original execution state diff --git a/src/RFC/rfc.h b/src/RFC/rfc.h index 2591daf7..e446a9cc 100644 --- a/src/RFC/rfc.h +++ b/src/RFC/rfc.h @@ -37,7 +37,9 @@ class RFC { RFC(uint32_t t_fid, Type *t_type, StackValue *t_args = nullptr, ExecutionState *t_exState = nullptr); void call(StackValue *args); +#ifdef ARDUINO void returnResult(Module *m); +#endif ARDUINO void restoreExecutionState(Module *m, RunningState *program_state); bool callCompleted(Module *m); From 5927f209baca02d2461117d272f7bcb4370847e1 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 14:00:54 +0200 Subject: [PATCH 035/249] add SocketServer.cpp --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc2ba869..91afb2fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ if (BUILD_EMULATOR) src/Interpreter/instructions.cpp src/RFC/rfc.cpp src/RFC/proxy_server.cpp + src/RFC/SocketServer.cpp ) set(TEST_FRAMEWORK tests/integration/wasm_tests.cpp From 61f11f62fe8b9b388e20e9ff214c08cf56c12872 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 14:26:56 +0200 Subject: [PATCH 036/249] code refactor SocketServer constructor takes a handler to process incoming client's socket data. AsyncServer is now constructed when SocketServer is constructed. --- src/RFC/SocketServer.cpp | 64 ++++++++++++++++------------------------ src/RFC/SocketServer.h | 25 +++++++++------- 2 files changed, 39 insertions(+), 50 deletions(-) diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp index 82ed68ed..8ba64909 100644 --- a/src/RFC/SocketServer.cpp +++ b/src/RFC/SocketServer.cpp @@ -1,98 +1,86 @@ #ifdef ARDUINO #include "SocketServer.h" -#include "Arduino.h" - #include -#include -#include + +#include "../Utils/macros.h" SocketServer *SocketServer::socketServer = nullptr; -SocketServer::SocketServer(uint16_t t_port, WARDuino *t_wrd) : portno(t_port) { - asyncServer = nullptr; - warduino = t_wrd; +SocketServer::SocketServer(uint16_t t_port, + void (*t_handler)(size_t, uint8_t *)) + : portno(t_port) { + this->asyncServer = new AsyncServer(t_port); + this->handler = t_handler; } -void SocketServer::initializeServer(uint16_t t_port, WARDuino *t_wrd) { - if (socketServer == nullptr) socketServer = new SocketServer(t_port, t_wrd); +void SocketServer::initializeServer(uint16_t t_port, + void (*t_handler)(size_t, uint8_t *)) { + if (socketServer == nullptr) + socketServer = new SocketServer(t_port, t_handler); } SocketServer *SocketServer::getServer() { return socketServer; } void SocketServer::connect2Wifi(ServerCredentials *t_credentials) { - Serial.println("Connecting to WiFi.."); + debug("Connecting to WiFi.."); WiFi.begin(t_credentials->ssid, t_credentials->pswd); while (WiFi.status() != WL_CONNECTED) { delay(10); } - Serial.printf("%d.%d.%d.%d\n\n", WiFi.localIP()[0], WiFi.localIP()[1], - WiFi.localIP()[2], WiFi.localIP()[3]); - printf("Connected and this is %p\n", this); + debug("%d.%d.%d.%d\n\n", WiFi.localIP()[0], WiFi.localIP()[1], + WiFi.localIP()[2], WiFi.localIP()[3]); } void SocketServer::begin() { - printf("prior new AsyncServer()\n"); - printf("%p\n", this); - if (this == nullptr) { - printf("yes nullptr!!!\n"); - } - printf("portno %d\n", this->portno); - - this->asyncServer = new AsyncServer(this->portno); - printf("this->asyncServer->begin()\n"); this->asyncServer->begin(); - printf("this->asyncServer->onClient()\n"); this->asyncServer->onClient( [this](void *s, AsyncClient *c) { - printf("A client connected!\n"); + debug("A new client connected!\n"); this->registerClient(c); }, NULL); - printf("done with SocketServer::begin()\n"); } void SocketServer::registerClient(AsyncClient *t_client) { if (t_client == NULL) { - printf("Client is NULL\n"); + debug("a new Client is NULL\n"); return; } if (this->client == nullptr) { this->client = t_client; } else { - printf("Only one socket client allowed.\n"); + debug("Only one socket client allowed.\n"); t_client->close(true); t_client->free(); delete t_client; return; } - WARDuino *wrd = this->warduino; + void (*handler)(size_t, uint8_t *) = this->handler; SocketServer *thisServer = this; t_client->onError( [thisServer](void *r, AsyncClient *t_client, int8_t error) { - printf("ClientSocket Error %" PRIu8 "\n", error); + debug("ClientSocket Error %" PRIu8 "\n", error); }, NULL); t_client->onDisconnect( [thisServer](void *r, AsyncClient *t_client) { - printf("Client Disconnected\n"); + debug("Client Disconnected\n"); thisServer->unregisterClient(t_client); }, NULL); t_client->onTimeout( [thisServer](void *r, AsyncClient *t_client, uint32_t time) { - printf("Client timeouted\n"); + debug("Client timeouted\n"); thisServer->unregisterClient(t_client); }, NULL); - t_client->onData( - [wrd](void *r, AsyncClient *t_client, void *buf, size_t len) { - wrd->handleInterrupt(len, (uint8_t *)buf); - }, - NULL); + t_client->onData([handler](void *r, AsyncClient *t_client, void *buf, + size_t len) { handler(len, (uint8_t *)buf); }, + NULL); } void SocketServer::unregisterClient(AsyncClient *t_client) { @@ -106,12 +94,10 @@ void SocketServer::unregisterClient(AsyncClient *t_client) { void SocketServer::write2Client(const char *buf, size_t size_buf) { if (this->client == nullptr) return; - // const char* cbuf = (char*)buf; - // size_t size_buf = (size_t) count; size_t space_left = client->space(); client->add(buf, size_buf > space_left ? space_left : size_buf); client->send(); if (size_buf <= space_left) return; write2Client(buf + space_left, size_buf - space_left); } -#endif ARDUINO +#endif diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h index 54bebee3..ded71593 100644 --- a/src/RFC/SocketServer.h +++ b/src/RFC/SocketServer.h @@ -1,11 +1,10 @@ #pragma once #ifdef ARDUINO -#include -#include #include +#include //FreeRTOS has to be imported before AsyncTCP.h #include -#include "WARDuino.h" +#include typedef struct { const char *ssid; @@ -14,26 +13,30 @@ typedef struct { class SocketServer { private: + // SocketServer configuration + const uint16_t portno; + ServerCredentials *credentials; + AsyncServer *asyncServer; AsyncClient *client; - WARDuino *warduino; - const uint16_t portno; - ServerCredentials *credentials; + // handler for client's received data + void (*handler)(size_t, uint8_t *); + + // singleton + static SocketServer *socketServer; + SocketServer(uint16_t t_port, void (*t_handler)(size_t, uint8_t *)); void registerClient(AsyncClient *t_client); void unregisterClient(AsyncClient *t_client); public: - // singleton - static SocketServer *socketServer; - SocketServer(uint16_t t_port, WARDuino *t_wrd); - void begin(); void connect2Wifi(ServerCredentials *t_credentials); void write2Client(const char *buf, size_t size_buf); static SocketServer *getServer(void); - static void initializeServer(uint16_t t_port, WARDuino *t_wrd); + static void initializeServer(uint16_t t_port, + void (*t_handler)(size_t, uint8_t *)); }; #endif From 9e96e4673b4780d729c5491598e2ab088c11b0a5 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 14:29:32 +0200 Subject: [PATCH 037/249] include SocketServer.h when deployed on MCU --- src/WARDuino.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/WARDuino.h b/src/WARDuino.h index 3a39bd41..3f0b39dc 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -10,6 +10,9 @@ #include "Debug/debugger.h" #include "WARDuino/CallbackHandler.h" +#ifdef ARDUINO +#include "RFC/SocketServer.h" +#endif // Constants #define WA_MAGIC 0x6d736100 From aab9b37707494fcae490c4eb04ddd5c9d83d7e94 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 15:04:09 +0200 Subject: [PATCH 038/249] restore original arduino template --- platforms/Arduino/Arduino.ino | 18 ++------- platforms/Arduino/upload.h | 73 ++++++++++++----------------------- 2 files changed, 29 insertions(+), 62 deletions(-) diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index 833e5a3a..919bee00 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -5,7 +5,6 @@ //#include #include -#include #include "Arduino.h" #include "upload.h" @@ -18,9 +17,6 @@ unsigned char* wasm = upload_wasm; WARDuino wac; Module* m; -ServerCredentials serverCredentials = {"telenet-3689855", "bhdkeswun6Fz"}; -uint16_t portno = 8080; -SocketServer *server; #define UART_PIN 3 @@ -63,22 +59,16 @@ void setup(void) { Serial.println(ESP.getPsramSize()); Serial.println("\nFree PSRAM: "); Serial.println(ESP.getFreePsram()); - - SocketServer::initializeServer(portno, &wac); - SocketServer *server = SocketServer::getServer(); - server->connect2Wifi(&serverCredentials); } void loop() { disableCore0WDT(); m = wac.load_module(wasm, wasm_len, {}); - printf("PRIOR BEGIN\n"); - server->begin(); - printf("POST BEGIN\n"); + printf("LOADED \n\n"); - //uint8_t command[] = {'0', '3', '\n'}; - //wac.handleInterrupt(3, command); - //xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); + uint8_t command[] = {'0', '3', '\n'}; + wac.handleInterrupt(3, command); + xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); Serial.println("\nFree heap:"); diff --git a/platforms/Arduino/upload.h b/platforms/Arduino/upload.h index 9fb205e7..efac27f4 100644 --- a/platforms/Arduino/upload.h +++ b/platforms/Arduino/upload.h @@ -1,49 +1,26 @@ -// blinks led on pin 23 -// unsigned char upload_wasm[] = { -// 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, -// 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, -// 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, -// 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, -// 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, -// 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, -// 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, -// 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, -// 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, -// 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, -// 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, -// 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, -// 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, -// 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, -// 0x0b, 0x0b, 0x00, 0x6e, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x49, 0x05, -// 0x00, 0x0e, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, -// 0x65, 0x6c, 0x61, 0x79, 0x01, 0x11, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, -// 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x02, -// 0x16, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, 0x69, -// 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x03, -// 0x04, 0x69, 0x6e, 0x69, 0x74, 0x04, 0x05, 0x62, 0x6c, 0x69, 0x6e, 0x6b, -// 0x02, 0x1c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, -// 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, -// 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; -// unsigned int upload_wasm_len = 282; - -/* blink pin 10 (M5stickC internal led) platforms/Arduino/examples/blink.wast - */ unsigned char upload_wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, - 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, - 0x4f, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, - 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, - 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, - 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, - 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x00, 0x01, 0x03, 0x03, 0x02, 0x02, - 0x02, 0x06, 0x10, 0x03, 0x7f, 0x00, 0x41, 0x0a, 0x0b, 0x7f, 0x00, 0x41, - 0x01, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, - 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x33, 0x02, 0x08, 0x00, 0x23, 0x00, - 0x41, 0x02, 0x10, 0x01, 0x0b, 0x28, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, - 0x21, 0x00, 0x10, 0x04, 0x03, 0x40, 0x23, 0x00, 0x23, 0x00, 0x10, 0x03, - 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x23, 0x00, 0x23, 0x02, - 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0b, 0x0b -}; -unsigned int upload_wasm_len = 190; + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, + 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, + 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, + 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, + 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, + 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, + 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, + 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, + 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, + 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x0b, 0x0b, 0x00, 0x6e, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x49, 0x05, + 0x00, 0x0e, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, + 0x65, 0x6c, 0x61, 0x79, 0x01, 0x11, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, + 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x02, + 0x16, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, 0x69, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x03, + 0x04, 0x69, 0x6e, 0x69, 0x74, 0x04, 0x05, 0x62, 0x6c, 0x69, 0x6e, 0x6b, + 0x02, 0x1c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, + 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, + 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; +unsigned int upload_wasm_len = 282; From 1f4ee73774d58445fd3430d8854e10c85db00dc8 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 15:21:06 +0200 Subject: [PATCH 039/249] rename static method + bug fix: reorder include RTOS --- src/RFC/SocketServer.cpp | 4 ++-- src/RFC/SocketServer.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp index 8ba64909..f406d896 100644 --- a/src/RFC/SocketServer.cpp +++ b/src/RFC/SocketServer.cpp @@ -14,8 +14,8 @@ SocketServer::SocketServer(uint16_t t_port, this->handler = t_handler; } -void SocketServer::initializeServer(uint16_t t_port, - void (*t_handler)(size_t, uint8_t *)) { +void SocketServer::createServer(uint16_t t_port, + void (*t_handler)(size_t, uint8_t *)) { if (socketServer == nullptr) socketServer = new SocketServer(t_port, t_handler); } diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h index ded71593..04cdd368 100644 --- a/src/RFC/SocketServer.h +++ b/src/RFC/SocketServer.h @@ -1,7 +1,7 @@ #pragma once #ifdef ARDUINO -#include #include //FreeRTOS has to be imported before AsyncTCP.h +#include #include #include @@ -36,7 +36,7 @@ class SocketServer { void write2Client(const char *buf, size_t size_buf); static SocketServer *getServer(void); - static void initializeServer(uint16_t t_port, - void (*t_handler)(size_t, uint8_t *)); + static void createServer(uint16_t t_port, + void (*t_handler)(size_t, uint8_t *)); }; #endif From 07b2a4bcf6984c5baeada7d0f243f22f21f866e8 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 15:21:28 +0200 Subject: [PATCH 040/249] add arduino socket template --- platforms/Arduino-socket/Arduino-socket.ino | 95 +++++++++++++++++++++ platforms/Arduino-socket/do_build.sh | 3 + platforms/Arduino-socket/upload.h | 26 ++++++ 3 files changed, 124 insertions(+) create mode 100644 platforms/Arduino-socket/Arduino-socket.ino create mode 100755 platforms/Arduino-socket/do_build.sh create mode 100644 platforms/Arduino-socket/upload.h diff --git a/platforms/Arduino-socket/Arduino-socket.ino b/platforms/Arduino-socket/Arduino-socket.ino new file mode 100644 index 00000000..b32b71c4 --- /dev/null +++ b/platforms/Arduino-socket/Arduino-socket.ino @@ -0,0 +1,95 @@ +// +// WARDuino - WebAssembly interpreter for embedded devices. +// +// +//#include + +#include + +#include "Arduino.h" +#include "upload.h" + +// unsigned int wasm_len = _tmp_warduino_upload_wasm_len; +// unsigned char* wasm = _tmp_warduino_upload_wasm; + +unsigned int wasm_len = upload_wasm_len; +unsigned char* wasm = upload_wasm; + +WARDuino wac; +Module* m; + +SocketServer *server; +ServerCredentials serverCredentials = {"SSID", "Password"}; +uint16_t portno = 8080; + + +#define UART_PIN 3 + +void startDebuggerStd(void* pvParameter) { + int valread; + uint8_t buffer[1024] = {0}; + wac.debugger->socket = fileno(stdout); + write(fileno(stdout), "Got a message ... \n", 19); + while (true) { + // taskYIELD(); + // vTaskDelay(100 / portTICK_PERIOD_MS); + yield(); + + while (Serial.available()) { + size_t buff_len = 0; + while (Serial.available()) { + buffer[buff_len++] = (int8_t)Serial.read(); + } + if (buff_len) { + write(fileno(stdout), "Reading message ..... \n", 19); + fflush(stdout); + wac.handleInterrupt(valread - 1, buffer); + write(fileno(stdout), buffer, valread); + fflush(stdout); + } + } + } +} + +void handleInterrupt(size_t len, uint8_t *buff){ + wac.handleInterrupt(len, buff); +} + +void setup(void) { + Serial.begin(115200); + // attachInterrupt(UART_PIN, handleInput, CHANGE); + + Serial.println(ESP.getFreeHeap()); + Serial.println("Total heap:"); + Serial.println(ESP.getHeapSize()); + Serial.println("\nFree heap:"); + Serial.println(ESP.getFreeHeap()); + Serial.println("\nTotal PSRAM:"); + Serial.println(ESP.getPsramSize()); + Serial.println("\nFree PSRAM: "); + Serial.println(ESP.getFreePsram()); + + //create & connect SocketServer + SocketServer::createServer(portno, &handleInterrupt); + server = SocketServer::getServer(); + server->connect2Wifi(&serverCredentials); +} + +void loop() { + disableCore0WDT(); + m = wac.load_module(wasm, wasm_len, {}); + server->begin(); + + printf("LOADED \n\n"); + uint8_t command[] = {'0', '3', '\n'}; + wac.handleInterrupt(3, command); + xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); + printf("START\n\n"); + + Serial.println("\nFree heap:"); + Serial.println(ESP.getFreeHeap()); + + wac.run_module(m); + printf("END\n\n"); + wac.unload_module(m); +} diff --git a/platforms/Arduino-socket/do_build.sh b/platforms/Arduino-socket/do_build.sh new file mode 100755 index 00000000..979ae93d --- /dev/null +++ b/platforms/Arduino-socket/do_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash +make compile-dev && make flash-dev && make monitor + diff --git a/platforms/Arduino-socket/upload.h b/platforms/Arduino-socket/upload.h new file mode 100644 index 00000000..efac27f4 --- /dev/null +++ b/platforms/Arduino-socket/upload.h @@ -0,0 +1,26 @@ +unsigned char upload_wasm[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, + 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, + 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, + 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, + 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, + 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, + 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, + 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, + 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, + 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x0b, 0x0b, 0x00, 0x6e, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x49, 0x05, + 0x00, 0x0e, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, + 0x65, 0x6c, 0x61, 0x79, 0x01, 0x11, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, + 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x02, + 0x16, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, 0x69, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x03, + 0x04, 0x69, 0x6e, 0x69, 0x74, 0x04, 0x05, 0x62, 0x6c, 0x69, 0x6e, 0x6b, + 0x02, 0x1c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, + 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, + 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; +unsigned int upload_wasm_len = 282; From f97c1438e29412562e37b6c00ca6aa295f019d8e Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 15:22:42 +0200 Subject: [PATCH 041/249] remove unneeded scripts --- do_build.sh | 8 ++++++++ platforms/Arduino-socket/do_build.sh | 3 --- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100755 do_build.sh delete mode 100755 platforms/Arduino-socket/do_build.sh diff --git a/do_build.sh b/do_build.sh new file mode 100755 index 00000000..8b73aa04 --- /dev/null +++ b/do_build.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +cd build/ +make && cd .. + +echo Starting CLI + +./build/wdcli --file examples/blinkm5stickc/blink.wasm diff --git a/platforms/Arduino-socket/do_build.sh b/platforms/Arduino-socket/do_build.sh deleted file mode 100755 index 979ae93d..00000000 --- a/platforms/Arduino-socket/do_build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -make compile-dev && make flash-dev && make monitor - From c626e7857a6d76e68f31fa5c64543442d6d8d98c Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 15:32:28 +0200 Subject: [PATCH 042/249] clang-format ignore includes --- src/RFC/SocketServer.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h index 04cdd368..19ced7a3 100644 --- a/src/RFC/SocketServer.h +++ b/src/RFC/SocketServer.h @@ -1,7 +1,10 @@ #pragma once #ifdef ARDUINO -#include //FreeRTOS has to be imported before AsyncTCP.h +// clang-format off +// FreeRTOS has to be imported before AsyncTCP.h +#include #include +// clang-format on #include #include From 748ea58652c68bda8414a64b4299f89283474f1c Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 21 Apr 2022 15:33:20 +0200 Subject: [PATCH 043/249] Format --- platforms/Arduino-socket/Arduino-socket.ino | 9 ++++----- src/RFC/rfc.cpp | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/platforms/Arduino-socket/Arduino-socket.ino b/platforms/Arduino-socket/Arduino-socket.ino index b32b71c4..3f51ec55 100644 --- a/platforms/Arduino-socket/Arduino-socket.ino +++ b/platforms/Arduino-socket/Arduino-socket.ino @@ -18,11 +18,10 @@ unsigned char* wasm = upload_wasm; WARDuino wac; Module* m; -SocketServer *server; +SocketServer* server; ServerCredentials serverCredentials = {"SSID", "Password"}; uint16_t portno = 8080; - #define UART_PIN 3 void startDebuggerStd(void* pvParameter) { @@ -51,8 +50,8 @@ void startDebuggerStd(void* pvParameter) { } } -void handleInterrupt(size_t len, uint8_t *buff){ - wac.handleInterrupt(len, buff); +void handleInterrupt(size_t len, uint8_t* buff) { + wac.handleInterrupt(len, buff); } void setup(void) { @@ -69,7 +68,7 @@ void setup(void) { Serial.println("\nFree PSRAM: "); Serial.println(ESP.getFreePsram()); - //create & connect SocketServer + // create & connect SocketServer SocketServer::createServer(portno, &handleInterrupt); server = SocketServer::getServer(); server->connect2Wifi(&serverCredentials); diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index 4d02bb9e..78463242 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -105,8 +105,8 @@ void RFC::returnResult(Module *m) { // returning the result to the client struct SerializeData *rfc_result = this->serializeRFCallee(); - const char * data = (const char*) rfc_result->raw; - size_t data_size = (size_t) rfc_result->size; + const char *data = (const char *)rfc_result->raw; + size_t data_size = (size_t)rfc_result->size; SocketServer::getServer()->write2Client(data, data_size); // FATAL("writing into socketdf\n"); // write(m->warduino->debugger->socket, rfc_result->raw, rfc_result->size); From e9b4fc2b3080c75a17c9e2520e5d868c7168aff4 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 21 Apr 2022 15:46:56 +0200 Subject: [PATCH 044/249] include libs for socketserver support --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 3374493e..e8b5d9f9 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,13 @@ arduino-cli lib install "PubSubClient" arduino-cli lib install "Adafruit NeoPixel" ``` +To build for Arduino with WIFI support you need to also install the following third-party libraries + +```bash +arduino-cli lib install FreeRTOS +arduino-cli lib install --git-url https://github.com/me-no-dev/AsyncTCP.git +``` + After this initial installation steps you can start using WARDuino with the Arduino toolchain. You can upload the example file as follows, starting from the project root: From 5ebb563bf6b53adf6009990715e91d0513a7d29b Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 21 Apr 2022 15:45:54 +0200 Subject: [PATCH 045/249] Update CI --- .github/workflows/compile.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 0f539724..f808ba60 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -56,6 +56,8 @@ jobs: - name: HTTPClient - name: PubSubClient - name: Adafruit NeoPixel + - name: FreeRTOS + - source-url: https://github.com/me-no-dev/AsyncTCP.git strategy: fail-fast: false matrix: From 8678d37770e0a2c9d74c6a1a26513c77ad3fe33c Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 21 Apr 2022 17:10:54 +0200 Subject: [PATCH 046/249] Fix Arduino compilation --- .github/workflows/compile.yml | 1 - src/RFC/SocketServer.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index f808ba60..e89e0bb9 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -56,7 +56,6 @@ jobs: - name: HTTPClient - name: PubSubClient - name: Adafruit NeoPixel - - name: FreeRTOS - source-url: https://github.com/me-no-dev/AsyncTCP.git strategy: fail-fast: false diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h index 19ced7a3..12710642 100644 --- a/src/RFC/SocketServer.h +++ b/src/RFC/SocketServer.h @@ -2,7 +2,7 @@ #ifdef ARDUINO // clang-format off // FreeRTOS has to be imported before AsyncTCP.h -#include +#include "freertos/FreeRTOS.h" #include // clang-format on #include From 4c7de41e3aa14e57467f7f3692e27d05c2e5676e Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 22 Apr 2022 09:57:25 +0200 Subject: [PATCH 047/249] Templatize Arduino-socket + add Makefile Use overridable variables in Arduino Makefiles Add READMEs Use .config file for SSID and network password --- platforms/Arduino-socket/.gitignore | 2 ++ ...socket.ino => Arduino-socket.ino.template} | 5 +--- platforms/Arduino-socket/Makefile | 28 +++++++++++++++++++ platforms/Arduino-socket/README.md | 3 ++ platforms/Arduino/Makefile | 19 ++++++------- platforms/README.md | 9 ++++++ 6 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 platforms/Arduino-socket/.gitignore rename platforms/Arduino-socket/{Arduino-socket.ino => Arduino-socket.ino.template} (93%) create mode 100644 platforms/Arduino-socket/Makefile create mode 100644 platforms/Arduino-socket/README.md create mode 100644 platforms/README.md diff --git a/platforms/Arduino-socket/.gitignore b/platforms/Arduino-socket/.gitignore new file mode 100644 index 00000000..a71162b0 --- /dev/null +++ b/platforms/Arduino-socket/.gitignore @@ -0,0 +1,2 @@ +.config +Arduino-socket.ino diff --git a/platforms/Arduino-socket/Arduino-socket.ino b/platforms/Arduino-socket/Arduino-socket.ino.template similarity index 93% rename from platforms/Arduino-socket/Arduino-socket.ino rename to platforms/Arduino-socket/Arduino-socket.ino.template index 3f51ec55..464967fd 100644 --- a/platforms/Arduino-socket/Arduino-socket.ino +++ b/platforms/Arduino-socket/Arduino-socket.ino.template @@ -9,9 +9,6 @@ #include "Arduino.h" #include "upload.h" -// unsigned int wasm_len = _tmp_warduino_upload_wasm_len; -// unsigned char* wasm = _tmp_warduino_upload_wasm; - unsigned int wasm_len = upload_wasm_len; unsigned char* wasm = upload_wasm; @@ -19,7 +16,7 @@ WARDuino wac; Module* m; SocketServer* server; -ServerCredentials serverCredentials = {"SSID", "Password"}; +ServerCredentials serverCredentials = {"{{SSID}}", "{{Password}}"}; uint16_t portno = 8080; #define UART_PIN 3 diff --git a/platforms/Arduino-socket/Makefile b/platforms/Arduino-socket/Makefile new file mode 100644 index 00000000..a1b6eeaa --- /dev/null +++ b/platforms/Arduino-socket/Makefile @@ -0,0 +1,28 @@ +# Arduino Socket Platform + +PORT = /dev/ttyUSB0 +FQBN = esp32:esp32:esp32wrover + +CONFIG = .config +include ${CONFIG} + +ifndef SSID +$(error SSID is not set. Use a .config file.) +endif + +ifndef PASSWORD +$(error PASSWORD is not set. Use a .config file.) +endif + +Arduino-socket.ino: .config Arduino-socket.ino.template + sed 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' Arduino-socket.ino.template >> $@ + +compile: Arduino-socket.ino + arduino-cli -v compile --fqbn $(FQBN) Arduino-socket.ino + +flash: + arduino-cli upload -p $(PORT) --fqbn $(FQBN) Arduino-socket.ino + +monitor: + arduino-cli monitor -p $(PORT) -c baudrate=115200 + diff --git a/platforms/Arduino-socket/README.md b/platforms/Arduino-socket/README.md new file mode 100644 index 00000000..a77e5361 --- /dev/null +++ b/platforms/Arduino-socket/README.md @@ -0,0 +1,3 @@ +# Arduino Socket Platform + +The code in this folder sets up the WARDuino for the Arduino socket platform, where the device creates a socket server to communicate with other WARDuino instances over Wi-Fi. diff --git a/platforms/Arduino/Makefile b/platforms/Arduino/Makefile index 14be536e..d2003eef 100644 --- a/platforms/Arduino/Makefile +++ b/platforms/Arduino/Makefile @@ -1,17 +1,14 @@ +# Arduino Platform + +PORT = /dev/ttyUSB0 +FQBN = esp32:esp32:esp32wrover + flash: - arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:esp32wrover Arduino.ino + arduino-cli upload -p $(PORT) --fqbn $(FQBN) Arduino-socket.ino compile: - arduino-cli -v compile --fqbn esp32:esp32:esp32wrover Arduino.ino + arduino-cli -v compile --fqbn $(FQBN) Arduino-socket.ino monitor: - arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200 - -flash-dev: - arduino-cli upload -p /dev/cu.usbserial-2952919DA8 --fqbn esp32:esp32:esp32doit-devkit-v1:UploadSpeed=115200 Arduino.ino + arduino-cli monitor -p $(PORT) -c baudrate=115200 -compile-dev: - arduino-cli -v compile --fqbn esp32:esp32:esp32doit-devkit-v1 Arduino.ino - -monitor: - arduino-cli monitor -p /dev/cu.usbserial-2952919DA8 -c baudrate=115200 diff --git a/platforms/README.md b/platforms/README.md new file mode 100644 index 00000000..20d0e805 --- /dev/null +++ b/platforms/README.md @@ -0,0 +1,9 @@ +# Platforms + +This folder contains the code necessary to compile WARDuino for the different supported platforms. + +- Arduino: WARDuino with primitives implemented for the Arduino platform +- Arduino-socket: WARDuino with primitives implemented for the Arduino platform and a socket server to debug over Wi-Fi +- CLI-EMULATOR: a cli for WARDuino with emulated primitives, to run on desktop environments +- ESP-IDF: WARDuino compiled with the ESP-IDF toolchain + From eec646f812cae3cde748087af5a3512019f6df71 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 22 Apr 2022 13:51:33 +0200 Subject: [PATCH 048/249] Fix Arduino socket compilation + add to CI --- .github/workflows/compile.yml | 50 +++++++++++++++++++++++++++++-- platforms/Arduino-socket/Makefile | 2 +- platforms/Arduino-socket/upload | 1 + 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 platforms/Arduino-socket/upload diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index e89e0bb9..c2604fd7 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -6,7 +6,7 @@ concurrency: cancel-in-progress: true # Cancel in-flight jobs for the same branch or PR env: - BENCHMARKS_CACHE: "build-benchmarks" + INO_SOCKET_CACHE: "template-socket" jobs: formatting-check: @@ -43,9 +43,39 @@ jobs: run: cmake .. -D BUILD_EMULATOR=ON ; cmake --build . working-directory: build-emu + fill-out-template: + name: Fill out template files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: 'recursive' + + - name: Retrieve version + id: version + run: | + echo "::set-output name=COMMIT::$(sha1sum Arduino-socket.ino.template | grep '^[^ ]*' -o)" + working-directory: platforms/Arduino-socket + + - name: Cache filled out templates + id: cache-ino + uses: actions/cache@v2 + with: + path: | + platforms/Arduino-socket + key: ${{ env.INO_SOCKET_CACHE }}-${{ steps.version.outputs.COMMIT }} + + - name: Fill out Arduino-socket.ino.template + if: steps.cache-ino.outputs.cache-hit != 'true' + run: | + echo -e "SSID=ssid\nPASSWORD=password" > .config + make Arduino-socket.ino + working-directory: platforms/Arduino-socket + compile-with-arduino: name: (Arduino) Compile on ${{matrix.board.platform-name}} - needs: formatting-check + needs: [formatting-check, fill-out-template] runs-on: ubuntu-latest env: SKETCHES_REPORTS_PATH: sketches-reports @@ -72,8 +102,21 @@ jobs: source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json sketches: | - platforms/Arduino + - platforms/Arduino-socket steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: 'recursive' + + - name: Get Template Cache + id: cache-ino + uses: actions/cache@v2 + with: + path: | + platforms/Arduino-socket + key: ${{ env.INO_SOCKET_CACHE }}-${{ steps.version.outputs.COMMIT }} + - name: Compile sketches uses: arduino/compile-sketches@v1 with: @@ -85,6 +128,7 @@ jobs: ${{ env.LIBRARIES }} enable-deltas-report: true sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + - name: Upload sketches report to workflow artifact uses: actions/upload-artifact@v2 with: diff --git a/platforms/Arduino-socket/Makefile b/platforms/Arduino-socket/Makefile index a1b6eeaa..27abe906 100644 --- a/platforms/Arduino-socket/Makefile +++ b/platforms/Arduino-socket/Makefile @@ -15,7 +15,7 @@ $(error PASSWORD is not set. Use a .config file.) endif Arduino-socket.ino: .config Arduino-socket.ino.template - sed 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' Arduino-socket.ino.template >> $@ + sed 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' Arduino-socket.ino.template > $@ compile: Arduino-socket.ino arduino-cli -v compile --fqbn $(FQBN) Arduino-socket.ino diff --git a/platforms/Arduino-socket/upload b/platforms/Arduino-socket/upload new file mode 100644 index 00000000..ae837a40 --- /dev/null +++ b/platforms/Arduino-socket/upload @@ -0,0 +1 @@ +arduino-cli upload -p $1 --fqbn esp32:esp32:esp32wrover Arduino-socket.ino From 191fc143d478d4683426942033317b94419b4bd0 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 26 Apr 2022 09:28:36 +0200 Subject: [PATCH 049/249] Fix compilation and clang tidy warnings --- src/RFC/rfc.cpp | 26 ++++++++++++-------------- src/RFC/rfc.h | 18 +++++++++--------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index 78463242..4de42a7b 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -1,14 +1,12 @@ #include "rfc.h" -#include - +#include #include #include #include #include #include -#include "../Debug/debugger.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "proxy_server.h" @@ -113,7 +111,7 @@ void RFC::returnResult(Module *m) { } #endif -void RFC::restoreExecutionState(Module *m, RunningState *program_state) { +void RFC::restoreExecutionState(Module *m, RunningState *program_state) const { // restoring the original execution state *program_state = this->executionState->program_state; m->csp = this->executionState->csp; @@ -121,7 +119,7 @@ void RFC::restoreExecutionState(Module *m, RunningState *program_state) { m->pc_ptr = this->executionState->pc_ptr; } -bool RFC::callCompleted(Module *m) { +bool RFC::callCompleted(Module *m) const { return !this->succes || this->executionState->csp == m->csp; } @@ -136,7 +134,7 @@ bool RFC::callCompleted(Module *m) { struct RFC::SerializeData *RFC::serializeRFC() { const unsigned short serializationSize = sizeSerializationRFC(this->type); - unsigned char *buffer = new unsigned char[serializationSize]; + auto *buffer = new unsigned char[serializationSize]; // write to array: interrupt, function identifier and arguments const unsigned char interrupt = interruptProxyCall; @@ -146,14 +144,14 @@ struct RFC::SerializeData *RFC::serializeRFC() { // array as hexa const uint32_t hexa_size = serializationSize * 2; - unsigned char *hexa = + auto *hexa = new unsigned char[hexa_size + 2]; //+2 for '\n' and '0' termination chars_as_hexa(hexa, buffer, serializationSize); hexa[hexa_size] = '\n'; hexa[hexa_size + 1] = '\0'; // TODO remove zero termination and +2 above delete[] buffer; - struct SerializeData *ser = new SerializeData; + auto *ser = new SerializeData; ser->size = hexa_size + 1; ser->raw = hexa; return ser; @@ -161,7 +159,7 @@ struct RFC::SerializeData *RFC::serializeRFC() { struct RFC::SerializeData *RFC::serializeRFCallee() { const unsigned short serializationSize = sizeSerializationRFCallee(this); - unsigned char *raw = new unsigned char[serializationSize]; + auto *raw = new unsigned char[serializationSize]; uint8_t suc = this->succes ? 1 : 0; memcpy(raw, &suc, sizeof(uint8_t)); @@ -177,7 +175,7 @@ struct RFC::SerializeData *RFC::serializeRFCallee() { this->excpMsgSize); } - struct SerializeData *ser = new struct SerializeData; + auto *ser = new struct SerializeData; ser->raw = raw; ser->size = serializationSize; return ser; @@ -252,7 +250,7 @@ void arguments_copy(unsigned char *dest, StackValue *args, void RFC::deserializeRFCResult() { ProxyServer *host = ProxyServer::getServer(); - uint8_t *call_result = (uint8_t *)host->readReply(); + auto *call_result = (uint8_t *)host->readReply(); this->succes = (uint8_t)call_result[0] == 1; if (!this->succes) { @@ -298,8 +296,8 @@ void RFC::deserializeRFCResult() { delete[] call_result; } -void RFC::call(StackValue *args) { - this->args = args; +void RFC::call(StackValue *arguments) { + this->args = arguments; struct SerializeData *rfc_request = this->serializeRFC(); ProxyServer *host = ProxyServer::getServer(); @@ -335,7 +333,7 @@ StackValue *RFC::readRFCArgs(Block *func, uint8_t *data) { return nullptr; } - StackValue *args = new StackValue[func->type->param_count]; + auto *args = new StackValue[func->type->param_count]; uint32_t *params = func->type->params; for (uint32_t i = 0; i < func->type->param_count; i++) { args[i].value.uint64 = 0; // init whole union to 0 diff --git a/src/RFC/rfc.h b/src/RFC/rfc.h index e446a9cc..70addba7 100644 --- a/src/RFC/rfc.h +++ b/src/RFC/rfc.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include "../WARDuino.h" @@ -22,7 +22,7 @@ class RFC { struct SerializeData *serializeRFC(); struct SerializeData *serializeRFCallee(); - void deserializeRFCResult(void); + void deserializeRFCResult(); public: const uint32_t fid; @@ -39,9 +39,9 @@ class RFC { void call(StackValue *args); #ifdef ARDUINO void returnResult(Module *m); -#endif ARDUINO - void restoreExecutionState(Module *m, RunningState *program_state); - bool callCompleted(Module *m); +#endif //ARDUINO + void restoreExecutionState(Module *m, RunningState *program_state) const; + bool callCompleted(Module *m) const; // Client side static RFC *registerRFC(uint32_t t_fid, Type *t_type); @@ -49,15 +49,15 @@ class RFC { static void unregisterRFC(uint32_t fid); static bool isRFC(uint32_t fid); static RFC *getRFC(uint32_t fid); - static void clearRFCs(void); + static void clearRFCs(); // Server side static RFC *registerRFCallee(uint32_t t_fid, Type *t_type, StackValue *t_args, ExecutionState *t_executionState); - static bool hasRFCallee(void); - static RFC *currentCallee(void); - static void removeRFCallee(void); + static bool hasRFCallee(); + static RFC *currentCallee(); + static void removeRFCallee(); static StackValue *readRFCArgs(Block *func, uint8_t *data); static void setupCalleeArgs(Module *m, RFC *callee); }; From 7b11dc3735cdb80391228fcb682c6d2d758496a9 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 26 Apr 2022 11:49:42 +0200 Subject: [PATCH 050/249] Add button demo in Rust --- examples/rust/.cargo/config | 5 + examples/rust/.gitignore | 17 ++++ examples/rust/CMakeLists.txt | 5 + examples/rust/Cargo.toml | 21 +++++ examples/rust/README.md | 14 +++ examples/rust/button.wat | 57 ++++++++++++ examples/rust/lib/warduino/.gitignore | 5 + examples/rust/lib/warduino/Cargo.toml | 9 ++ examples/rust/lib/warduino/src/lib.rs | 127 ++++++++++++++++++++++++++ examples/rust/main/CMakeLists.txt | 16 ++++ examples/rust/main/button.rs | 27 ++++++ examples/rust/main/main.cpp | 52 +++++++++++ 12 files changed, 355 insertions(+) create mode 100644 examples/rust/.cargo/config create mode 100644 examples/rust/.gitignore create mode 100644 examples/rust/CMakeLists.txt create mode 100644 examples/rust/Cargo.toml create mode 100644 examples/rust/README.md create mode 100644 examples/rust/button.wat create mode 100644 examples/rust/lib/warduino/.gitignore create mode 100644 examples/rust/lib/warduino/Cargo.toml create mode 100644 examples/rust/lib/warduino/src/lib.rs create mode 100644 examples/rust/main/CMakeLists.txt create mode 100644 examples/rust/main/button.rs create mode 100644 examples/rust/main/main.cpp diff --git a/examples/rust/.cargo/config b/examples/rust/.cargo/config new file mode 100644 index 00000000..e4f6290f --- /dev/null +++ b/examples/rust/.cargo/config @@ -0,0 +1,5 @@ +[build] +target = "wasm32-unknown-unknown" +rustflags = [ + "-C", "link-args=-zstack-size=2048 -s", +] diff --git a/examples/rust/.gitignore b/examples/rust/.gitignore new file mode 100644 index 00000000..40fac1ff --- /dev/null +++ b/examples/rust/.gitignore @@ -0,0 +1,17 @@ +.idea +idf/ + +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb diff --git a/examples/rust/CMakeLists.txt b/examples/rust/CMakeLists.txt new file mode 100644 index 00000000..bb72b053 --- /dev/null +++ b/examples/rust/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(rust) + diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml new file mode 100644 index 00000000..86d0c3f6 --- /dev/null +++ b/examples/rust/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "button" +version = "0.1.0" +authors = ["Tom Lauwaerts "] +edition = "2018" + +[lib] +path = "main/button.rs" +crate-type = ["cdylib"] + +[dependencies] +warduino = { path = "lib/warduino" } + +[profile.dev] +panic = "abort" +opt-level = 2 + +[profile.release] +panic = "abort" +opt-level = 3 +debug = true diff --git a/examples/rust/README.md b/examples/rust/README.md new file mode 100644 index 00000000..259df2ce --- /dev/null +++ b/examples/rust/README.md @@ -0,0 +1,14 @@ +# Button demo + +This demo is used to show case that interrupts on pins can also be subscribed on with the WARDuino callback system. + +## Running the demo + +Flash the wasm code and WARDuino VM onto the esp with the following commands: + +``` +./build.sh +``` + +The program listens for changes on pin 26. + diff --git a/examples/rust/button.wat b/examples/rust/button.wat new file mode 100644 index 00000000..e7eefecf --- /dev/null +++ b/examples/rust/button.wat @@ -0,0 +1,57 @@ +(module + (type $t0 (func (param i32 i32))) + (type $t1 (func (param i32) (result i32))) + (type $t2 (func (param i32 i32 i32))) + (type $t3 (func (param i32 i32 i32 i32 i32))) + (type $t4 (func)) + (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $t0))) + (import "env" "chip_digital_write" (func $env.chip_digital_write (type $t0))) + (import "env" "chip_digital_read" (func $env.chip_digital_read (type $t1))) + (import "env" "subscribe_interrupt" (func $env.subscribe_interrupt (type $t2))) + (func $f4 (type $t3) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (param $p4 i32) + i32.const 26 + i32.const 26 + call $f8 + i32.const 1 + i32.ne + call $f7) + (func $main (type $t4) + i32.const 25 + i32.const 0 + call $f6 + i32.const 26 + i32.const 2 + call $f6 + i32.const 25 + i32.const 1 + i32.const 2 + call $f9 + loop $L0 + br $L0 + end) + (func $f6 (type $t0) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + call $env.chip_pin_mode) + (func $f7 (type $t0) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + call $env.chip_digital_write) + (func $f8 (type $t1) (param $p0 i32) (result i32) + local.get $p0 + call $env.chip_digital_read) + (func $f9 (type $t2) (param $p0 i32) (param $p1 i32) (param $p2 i32) + local.get $p0 + local.get $p1 + local.get $p2 + call $env.subscribe_interrupt) + (table $T0 2 2 funcref) + (memory $memory 1) + (global $g0 (mut i32) (i32.const 2048)) + (global $__data_end i32 (i32.const 2048)) + (global $__heap_base i32 (i32.const 2048)) + (export "memory" (memory $memory)) + (export "main" (func $main)) + (export "__data_end" (global $__data_end)) + (export "__heap_base" (global $__heap_base)) + (elem $e0 (i32.const 1) func $f4)) diff --git a/examples/rust/lib/warduino/.gitignore b/examples/rust/lib/warduino/.gitignore new file mode 100644 index 00000000..20694291 --- /dev/null +++ b/examples/rust/lib/warduino/.gitignore @@ -0,0 +1,5 @@ +target/ +*.wasm* +*.wat +*.log +*.h diff --git a/examples/rust/lib/warduino/Cargo.toml b/examples/rust/lib/warduino/Cargo.toml new file mode 100644 index 00000000..524c4d2e --- /dev/null +++ b/examples/rust/lib/warduino/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "warduino" +version = "0.1.0" +authors = ["Tom Lauwaerts "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/examples/rust/lib/warduino/src/lib.rs b/examples/rust/lib/warduino/src/lib.rs new file mode 100644 index 00000000..63d7a4d2 --- /dev/null +++ b/examples/rust/lib/warduino/src/lib.rs @@ -0,0 +1,127 @@ +#![allow(dead_code)] + +use std::mem; + +#[link(wasm_import_module = "env")] +//#[link(wasm_import_module = "arduino")] +extern { + #[link_name = "test"] pub fn test(f: fn(&str, &str, u32)); + + #[link_name = "millis"] fn _millis() -> u32; + #[link_name = "chip_delay"] fn _delay(ms: u32); + #[link_name = "getPinLED"] fn _getPinLED() -> u32; + #[link_name = "chip_pin_mode"] fn _pinMode(pin: u32, mode: u32); + #[link_name = "chip_digital_write"] fn _digitalWrite(pin: u32, value: u32); + #[link_name = "chip_digital_read"] fn _digitalRead(pin: u32) -> u32; + #[link_name = "chip_analog_read"] fn _analogRead(pin: u32) -> i32; +//} + + +//#[link(wasm_import_module = "serial")] +//extern { + #[link_name = "print_string"] fn _print_buffer(text: *const u8, length: usize); + #[link_name = "print_int"] fn _print_int(integer: i32); +//} + +//#[link(wasm_import_module = "wifi")] +//extern { + #[link_name = "wifi_connect"] fn _connect(ssid: &str, password: &str); + #[link_name = "wifi_status"] fn _status() -> i32; + #[link_name = "wifi_localip"] fn _localip(buffer: *const u8, buffer_length: usize) -> i32; +//} + +//#[link(wasm_import_module = "http")] +//extern { + #[link_name = "http_get"] fn _get(url: *const u8, url_len: usize, buffer: *const u8, buffer_size: usize) -> i32; + #[link_name = "http_post"] fn _post(url: *const u8, url_len: usize, + body: *const u8, body_len: usize, + content_type: *const u8, content_type_len: usize, + authorization: *const u8, authorization_len: usize, + buffer: *const u8, buffer_size: usize) + -> i32; + + +//#[link(wasm_import_module = "interrupt")] +//extern { + #[link_name = "subscribe_interrupt"] fn _sub_interrupt(pin: u32, f: fn(&str, &str, u32), mode: u32); + #[link_name = "unsubscribe_interrupt"] fn _unsub_interrupt(pin: u32); + +//#[link(wasm_import_module = "mqtt")] +//extern { + #[link_name = "mqtt_init"] fn _mqtt_init(server: *const u8, server_length: usize, port: u32); + #[link_name = "mqtt_connect"] fn _mqtt_connect(client_id: *const u8, client_id_length: usize) -> i32; + #[link_name = "mqtt_connected"] fn _mqtt_connected() -> i32; + #[link_name = "mqtt_state"] fn _mqtt_state() -> i32; + #[link_name = "mqtt_publish"] fn _mqtt_publish(topic: *const u8, topic_length: usize, payload: *const u8, payload_length: usize) -> i32; + #[link_name = "mqtt_subscribe"] fn _mqtt_subscribe(topic: *const u8, topic_length: usize, f: fn(&str, &str, u32)) -> i32; + #[link_name = "mqtt_unsubscribe"] fn _mqtt_unsubscribe(topic: *const u8, topic_length: usize, f: fn(&str, &str, u32)) -> i32; + #[link_name = "mqtt_loop"] fn _mqtt_loop() -> i32; +} + +#[repr(C)] +pub struct Headers { + pub content_type: &'static str, + pub authorization: &'static str, // TODO make optional +} + +#[repr(C)] +pub struct PostOptions { + pub uri: &'static str, + pub body: String, + pub headers: Headers, +} + +fn size_of_post_options(options: &PostOptions) -> usize { + options.uri.len() + options.body.len() + options.headers.content_type.len() +} + +pub static LOW : u32 = 0x0; +pub static HIGH : u32 = 0x1; + +pub static CHANGE : u32 = 1; +pub static FALLING : u32 = 2; +pub static RISING : u32 = 3; + +pub static INPUT : u32 = 0x0; +pub static OUTPUT : u32 = 0x2; + +pub fn millis () -> u32 { unsafe { _millis() } } +pub fn delay (ms: u32) { unsafe { _delay(ms); } } +pub fn get_pin_led () -> u32 { unsafe { _getPinLED() } } +pub fn pin_mode (pin: u32, mode: u32) { unsafe { _pinMode(pin, mode) } } +pub fn digital_write(pin: u32, value: u32) { unsafe { _digitalWrite(pin, value) } } +pub fn digital_read (pin: u32) -> u32 { unsafe { _digitalRead(pin) } } +pub fn analog_read (pin: u32) -> i32 { unsafe { _analogRead(pin) } } + +pub fn wifi_connect (ssid: &str, password: &str) { unsafe { _connect(ssid, password) } } +pub fn wifi_status () -> i32 { unsafe { _status() } } +pub fn wifi_localip () -> String { unsafe { let buffer: [u8; 100] = [0; 100]; + _localip(buffer.as_ptr(), mem::size_of_val(&buffer) / mem::size_of::()); + std::str::from_utf8(&buffer).unwrap().to_owned() + } } + +pub fn get (url: &str, buffer: &[u8]) -> i32 { unsafe { _get(url.as_ptr(), url.len(), buffer.as_ptr(), mem::size_of_val(buffer) / mem::size_of::()) } } +pub fn post (options: &PostOptions, buffer: &[u8]) -> i32 { unsafe { + _post(options.uri.as_ptr(), options.uri.len(), + options.body.as_ptr(), options.body.len(), + options.headers.content_type.as_ptr(), options.headers.content_type.len(), + options.headers.authorization.as_ptr(), options.headers.authorization.len(), + buffer.as_ptr(), mem::size_of_val(buffer) / mem::size_of::()) + } +} + +pub fn print (text: &[u8]) { unsafe { _print_buffer(text.as_ptr(), text.len()) } } +pub fn print_int (integer: i32) { unsafe { _print_int(integer) } } + +pub fn sub_interrupt (pin: u32, f: fn(&str, &str, u32), mode: u32) { unsafe { _sub_interrupt(pin, f, mode) } } +pub fn unsub_interrupt (pin: u32) { unsafe { _unsub_interrupt(pin) } } + +pub fn mqtt_init (server: &str, port: u32) { unsafe { _mqtt_init(server.as_ptr(), server.len(), port) } } +pub fn mqtt_connect (client_id: &str) -> bool { unsafe { _mqtt_connect(client_id.as_ptr(), client_id.len()) != 0 } } +pub fn mqtt_connected () -> bool { unsafe { _mqtt_connected() > 0 } } +pub fn mqtt_state () -> i32 { unsafe { _mqtt_state() } } +pub fn mqtt_publish (topic: &str, payload: &str) -> i32 { unsafe { _mqtt_publish(topic.as_ptr(), topic.len(), payload.as_ptr(), payload.len()) } } +pub fn mqtt_subscribe (topic: &str, f: fn(&str, &str, u32)) -> i32 { unsafe { _mqtt_subscribe(topic.as_ptr(), topic.len(), f) } } +pub fn mqtt_unsubscribe (topic: &str, f: fn(&str, &str, u32)) -> i32 { unsafe { _mqtt_unsubscribe(topic.as_ptr(), topic.len(), f) } } +pub fn mqtt_loop () -> i32 { unsafe { _mqtt_loop() } } + diff --git a/examples/rust/main/CMakeLists.txt b/examples/rust/main/CMakeLists.txt new file mode 100644 index 00000000..3fdb8c1d --- /dev/null +++ b/examples/rust/main/CMakeLists.txt @@ -0,0 +1,16 @@ +set(SOURCE_FILES + ../../../src/Memory/mem.cpp + ../../../src/Utils/util.cpp + ../../../src/Utils/util_arduino.cpp + ../../../src/Debug/debugger.cpp + ../../../src/Utils/macros.cpp + ../../../src/WARDuino/WARDuino.cpp + ../../../src/Primitives/emulated.cpp + ../../../src/Interpreter/instructions.cpp + ../../../src/WARDuino/CallbackHandler.cpp + ) + +idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS "" REQUIRES driver) + +add_definitions(-DESP=1) + diff --git a/examples/rust/main/button.rs b/examples/rust/main/button.rs new file mode 100644 index 00000000..6688a6b2 --- /dev/null +++ b/examples/rust/main/button.rs @@ -0,0 +1,27 @@ +use warduino::*; + +static BUTTON : u32 = 25; +static LED : u32 = 26; + +fn callback(_topic: &str, _payload: &str, _length: u32) { + let val = digital_read(LED); + //print(format!("Switch LED to {}\n", (val + 1) % 2).as_bytes()); + if val == HIGH { + digital_write(LED, LOW); + } else { + digital_write(LED, HIGH); + } +} + +#[no_mangle] +pub fn main() { + pin_mode(BUTTON, INPUT); + pin_mode(LED, OUTPUT); + + sub_interrupt(BUTTON, callback, FALLING); + + loop { + //delay(1); + } +} + diff --git a/examples/rust/main/main.cpp b/examples/rust/main/main.cpp new file mode 100644 index 00000000..133c2ad3 --- /dev/null +++ b/examples/rust/main/main.cpp @@ -0,0 +1,52 @@ +// +// WARDuino - WebAssembly interpreter for embedded devices. +// +// +#include + +#include "../../../../src/WARDuino.h" +#include "driver/gpio.h" +#include "driver/uart.h" +#include "esp_err.h" +#include "esp_task_wdt.h" +#include "esp_vfs_dev.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "sdkconfig.h" + +volatile bool handelingInterrupt = false; + +#include "src.wasm.h" + +extern "C" { +extern void app_main(void); +} + +WARDuino wac; +Module* m; + +void startDebuggerStd(void* pvParameter) { + int valread; + uint8_t buffer[1024] = {0}; + wac.debugger->socket = fileno(stdout); + while (true) { + taskYIELD(); + vTaskDelay(1000 / portTICK_PERIOD_MS); + + while ((valread = read(fileno(stdin), buffer, 1024)) != -1) { + write(fileno(stdout), "got a message ... \n", 19); + wac.handleInterrupt(valread - 1, buffer); + write(fileno(stdout), buffer, valread); + fflush(stdout); + } + } +} + +void app_main(void) { + m = wac.load_module(src_wasm, src_wasm_len, {}); + xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); + printf("START\n\n"); + wac.run_module(m); + printf("END\n\n"); + wac.unload_module(m); +} From 129204e1c2bd41ae02e29d99e8aeff8ac32b1207 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 26 Apr 2022 11:56:28 +0200 Subject: [PATCH 051/249] Clang format --- src/RFC/SocketServer.cpp | 6 +++--- src/RFC/rfc.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp index f406d896..121d5aba 100644 --- a/src/RFC/SocketServer.cpp +++ b/src/RFC/SocketServer.cpp @@ -23,14 +23,14 @@ void SocketServer::createServer(uint16_t t_port, SocketServer *SocketServer::getServer() { return socketServer; } void SocketServer::connect2Wifi(ServerCredentials *t_credentials) { - debug("Connecting to WiFi.."); + printf("Connecting to WiFi...\n"); WiFi.begin(t_credentials->ssid, t_credentials->pswd); while (WiFi.status() != WL_CONNECTED) { delay(10); } - debug("%d.%d.%d.%d\n\n", WiFi.localIP()[0], WiFi.localIP()[1], - WiFi.localIP()[2], WiFi.localIP()[3]); + printf("localip: %d.%d.%d.%d\n\n", WiFi.localIP()[0], WiFi.localIP()[1], + WiFi.localIP()[2], WiFi.localIP()[3]); } void SocketServer::begin() { diff --git a/src/RFC/rfc.h b/src/RFC/rfc.h index 70addba7..20cb74c3 100644 --- a/src/RFC/rfc.h +++ b/src/RFC/rfc.h @@ -1,8 +1,9 @@ #pragma once -#include #include +#include + #include "../WARDuino.h" typedef struct { @@ -39,7 +40,7 @@ class RFC { void call(StackValue *args); #ifdef ARDUINO void returnResult(Module *m); -#endif //ARDUINO +#endif // ARDUINO void restoreExecutionState(Module *m, RunningState *program_state) const; bool callCompleted(Module *m) const; From 1fa70e65fd2b8b0e8e1be36a5793560b0d836203 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 27 Apr 2022 16:37:19 +0200 Subject: [PATCH 052/249] Move connection code to createConnection function Move Address struct out the ProxyServer class --- src/RFC/proxy_server.cpp | 60 +++++++++++++++++++++++++--------------- src/RFC/proxy_server.h | 3 +- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 61b829c1..897dace0 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -2,18 +2,18 @@ /* #include */ // Might be needed #include #include -#include -#include -#include #include -#include #include #include +#include +#include +#include #include "../Utils/util.h" -// TODO exceptionmsg +// TODO exception msg +const char SUCCESS[] = ""; const char NO_HOST_ERR[] = "No host and port set"; const char CREATE_SOCK_ERR[] = "Could not create Socket"; const char INVALID_HOST[] = "Invalid host"; @@ -21,11 +21,37 @@ const char CONNECT_ERR[] = "Socket failed to connect"; const char WRITE_ERR[] = "ERROR writing to socket"; const char READ_ERR[] = "ERROR reading from socket"; -struct ProxyServer::Address { +struct Address { struct sockaddr_in aserv_addr; struct hostent *aServer; }; +const char *createConnection(int socketfd, char *host, int port, + struct Address *address) { + struct hostent *server = gethostbyname(host); + if (server == nullptr) { + return INVALID_HOST; + } + + address->aServer = server; + struct sockaddr_in *server_address = &address->aserv_addr; + bzero((char *)server_address, sizeof(*server_address)); + server_address->sin_family = AF_INET; + bcopy((char *)server->h_addr, (char *)&server_address->sin_addr.s_addr, + server->h_length); + server_address->sin_port = htons(port); + if (connect(socketfd, (struct sockaddr *)server_address, + sizeof(*server_address)) < 0) { + return CONNECT_ERR; + } + + return SUCCESS; +} + +bool is_success(const char *msg) { + return (msg != nullptr) && (msg[0] == '\0'); +} + ProxyServer *ProxyServer::proxyServer = nullptr; ProxyServer *ProxyServer::getServer() { @@ -68,6 +94,7 @@ ProxyServer::ProxyServer() { } bool ProxyServer::openConnection() { + printf("connecting"); if (this->host == nullptr) { this->updateExcpMsg(NO_HOST_ERR); return false; @@ -79,24 +106,13 @@ bool ProxyServer::openConnection() { return false; } - struct hostent *aServer = gethostbyname(this->host); - if (aServer == NULL) { - this->updateExcpMsg(INVALID_HOST); - return false; - } - - this->address->aServer = aServer; - struct sockaddr_in *aserv_addr = &this->address->aserv_addr; - bzero((char *)aserv_addr, sizeof(*aserv_addr)); - aserv_addr->sin_family = AF_INET; - bcopy((char *)aServer->h_addr, (char *)&aserv_addr->sin_addr.s_addr, - aServer->h_length); - aserv_addr->sin_port = htons(this->port); - if (connect(sockfd, (struct sockaddr *)aserv_addr, sizeof(*aserv_addr)) < - 0) { - this->updateExcpMsg(CONNECT_ERR); + const char *msg = + createConnection(sockfd, this->host, this->port, this->address); + if (!is_success(msg)) { + this->updateExcpMsg(msg); return false; } + printf("connected"); return true; } diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h index 9a575e85..543aa56c 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_server.h @@ -2,6 +2,8 @@ #include +struct Address; + class ProxyServer { private: // for singleton @@ -10,7 +12,6 @@ class ProxyServer { char *host; int port, sockfd; - struct Address; struct Address *address; // private constructor for singleton From caeb192c54fa1b2eae273be685bee56eaecf7edf Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 27 Apr 2022 17:09:47 +0200 Subject: [PATCH 053/249] Add skeleton code push connection Move util code for sockets to separate file --- CMakeLists.txt | 2 +- platforms/CLI-Emulator/main.cpp | 53 +-------------------- src/Debug/debugger.cpp | 2 +- src/RFC/proxy_server.cpp | 82 +++++++++++++++++++++++---------- src/RFC/proxy_server.h | 14 +++--- src/Utils/sockets.cpp | 59 ++++++++++++++++++++++++ src/Utils/sockets.h | 13 ++++++ 7 files changed, 141 insertions(+), 84 deletions(-) create mode 100644 src/Utils/sockets.cpp create mode 100644 src/Utils/sockets.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 91afb2fc..8dd8bb4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ if (BUILD_EMULATOR) src/RFC/rfc.cpp src/RFC/proxy_server.cpp src/RFC/SocketServer.cpp - ) + src/Utils/sockets.cpp) set(TEST_FRAMEWORK tests/integration/wasm_tests.cpp tests/integration/assertion.cpp diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 887b21a5..c4118d21 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -12,6 +12,7 @@ #include "../../src/Debug/debugger.h" #include "../../src/Utils/macros.h" +#include "../../src/Utils/sockets.h" #include "../../tests/integration/wasm_tests.h" // Constants @@ -91,58 +92,6 @@ Module *load(WARDuino wac, const char *file_name, Options opt) { return nullptr; } -// Socket Debugger Interface -void setFileDescriptorOptions(int socket_fd) { - int opt = 1; - if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { - perror("Failed to set socket file descriptor options"); - exit(EXIT_FAILURE); - } -} - -int createSocketFileDescriptor() { - int socket_fd; - if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { - perror("Failed to make a new socket file descriptor"); - exit(EXIT_FAILURE); - } - setFileDescriptorOptions(socket_fd); - return socket_fd; -} - -void bindSocketToAddress(int socket_fd, struct sockaddr_in address) { - if (bind(socket_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { - perror("Binding socket to address failed"); - exit(EXIT_FAILURE); - } -} - -struct sockaddr_in createAddress(int port) { - struct sockaddr_in address {}; - address.sin_family = AF_INET; - address.sin_addr.s_addr = INADDR_ANY; - address.sin_port = htons(port); - return address; -} - -void startListening(int socket_fd) { - if (listen(socket_fd, 1) < 0) { - perror("listen"); - exit(EXIT_FAILURE); - } -} - -int listenForIncomingConnection(int socket_fd, struct sockaddr_in address) { - int new_socket; - int size = sizeof(address); - if ((new_socket = accept(socket_fd, (struct sockaddr *)&address, - (socklen_t *)&size)) < 0) { - perror("Failed to listen for incoming connections"); - exit(EXIT_FAILURE); - } - return new_socket; -} - void startDebuggerStd(WARDuino *wac, Module *m) { int valread; uint8_t buffer[1024] = {0}; diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 85527ee1..6dbea237 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -887,7 +887,7 @@ void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { RFC::registerRFCs(m, &interruptData); ProxyServer::registerMCUHost(&interruptData); ProxyServer *mcuhost = ProxyServer::getServer(); - if (!mcuhost->openConnection()) { + if (!mcuhost->openConnections()) { FATAL("problem opening socket to MCU: %s\n", mcuhost->exceptionMsg); } dprintf(this->socket, "done!\n"); diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 897dace0..27468fff 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -10,10 +10,11 @@ #include #include +#include "../Utils/sockets.h" #include "../Utils/util.h" // TODO exception msg -const char SUCCESS[] = ""; +const char SUCCESS[] = ""; // Empty denotes success const char NO_HOST_ERR[] = "No host and port set"; const char CREATE_SOCK_ERR[] = "Could not create Socket"; const char INVALID_HOST[] = "Invalid host"; @@ -26,6 +27,10 @@ struct Address { struct hostent *aServer; }; +bool is_success(const char *msg) { + return (msg != nullptr) && (msg[0] == '\0'); // check if string is empty +} + const char *createConnection(int socketfd, char *host, int port, struct Address *address) { struct hostent *server = gethostbyname(host); @@ -48,10 +53,6 @@ const char *createConnection(int socketfd, char *host, int port, return SUCCESS; } -bool is_success(const char *msg) { - return (msg != nullptr) && (msg[0] == '\0'); -} - ProxyServer *ProxyServer::proxyServer = nullptr; ProxyServer *ProxyServer::getServer() { @@ -61,21 +62,21 @@ ProxyServer *ProxyServer::getServer() { void ProxyServer::registerMCUHost(uint8_t **data) { int portno = (int)read_B32(data); - uint8_t hostsize = (uint8_t)(*data)[0]; + auto hostsize = (uint8_t)(*data)[0]; char *hostname = new char[hostsize + 1]; memcpy((void *)hostname, ++(*data), hostsize); hostname[hostsize] = '\0'; printf("Registering Proxy Host: %s PORT=%d\n", hostname, portno); - ProxyServer::getServer()->registerAdress(hostname, portno); + ProxyServer::getServer()->registerAddress(hostname, portno); } -void ProxyServer::registerAdress(char *t_host, int t_port) { +void ProxyServer::registerAddress(char *t_host, int t_port) { if (this->host != nullptr) { - this->closeConnection(); + this->closeConnections(); free(this->host); } this->host = t_host; - this->port = t_port; + this->pull_port = t_port; } void ProxyServer::updateExcpMsg(const char *msg) { @@ -88,45 +89,78 @@ void ProxyServer::updateExcpMsg(const char *msg) { ProxyServer::ProxyServer() { host = exceptionMsg = nullptr; - port = 0; - sockfd = -1; + pull_port = 0; + push_port = 0; + pull_socket = -1; + push_socket = -1; address = (struct Address *)malloc(sizeof(struct Address)); } -bool ProxyServer::openConnection() { +void ProxyServer::startPushDebuggerSocket() const { + struct sockaddr_in _address = createAddress(this->push_port); + bindSocketToAddress(this->push_socket, _address); + startListening(this->push_socket); + + int valread; + uint8_t buffer[1024] = {0}; + while (true) { + int socket = listenForIncomingConnection(this->push_socket, _address); + while ((valread = read(socket, buffer, 1024)) != -1) { + write(socket, "got a push message ... \n", 19); + // TODO process push message + } + } +} + +bool ProxyServer::openConnections() { printf("connecting"); if (this->host == nullptr) { this->updateExcpMsg(NO_HOST_ERR); return false; } - this->sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (this->sockfd < 0) { + // Create sockets + this->pull_socket = socket(AF_INET, SOCK_STREAM, 0); + this->push_socket = socket(AF_INET, SOCK_STREAM, 0); + if (this->pull_socket < 0 || this->push_socket < 0) { this->updateExcpMsg(CREATE_SOCK_ERR); return false; } - const char *msg = - createConnection(sockfd, this->host, this->port, this->address); + // Connect to pull socket + const char *msg = createConnection(pull_socket, this->host, this->pull_port, + this->address); if (!is_success(msg)) { this->updateExcpMsg(msg); return false; } + + // Connect to push socket + msg = createConnection(push_socket, this->host, this->pull_port, + this->address); + if (!is_success(msg)) { + this->updateExcpMsg(msg); // TODO differentiate between ports + return false; + } + + // Listen to push socket on new thread + // TODO + printf("connected"); return true; } -void ProxyServer::closeConnection() { - if (this->sockfd != -1) { - if (close(this->sockfd) == -1) { - if (errno == EINTR) close(this->sockfd); +void ProxyServer::closeConnections() { + if (this->pull_socket != -1) { + if (close(this->pull_socket) == -1) { + if (errno == EINTR) close(this->pull_socket); } - this->sockfd = -1; + this->pull_socket = -1; } } bool ProxyServer::send(void *buffer, int size) { - int n = write(this->sockfd, buffer, size); + int n = write(this->pull_socket, buffer, size); if (n == size) return true; if (n < 0 && errno == EINTR) // write interrupted, thus retry @@ -143,7 +177,7 @@ bool ProxyServer::send(void *buffer, int size) { char *ProxyServer::readReply(short int amount) { char *buffer = new char[amount + 1]; bzero(buffer, amount + 1); - int n = read(this->sockfd, buffer, amount); + int n = read(this->pull_socket, buffer, amount); if (n > 0) return buffer; delete[] buffer; diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h index 543aa56c..50de85a5 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_server.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Address; @@ -10,23 +10,25 @@ class ProxyServer { static ProxyServer *proxyServer; char *host; - int port, sockfd; + int pull_port, push_port, pull_socket, push_socket; struct Address *address; // private constructor for singleton ProxyServer(); + void startPushDebuggerSocket() const; + public: char *exceptionMsg; - void registerAdress(char *t_host, int t_port); - void closeConnection(void); - bool openConnection(void); + void registerAddress(char *t_host, int t_port); + void closeConnections(); + bool openConnections(); void updateExcpMsg(const char *msg); bool send(void *t_buffer, int t_size); char *readReply(short int amount = 1024); static void registerMCUHost(uint8_t **data); - static ProxyServer *getServer(void); + static ProxyServer *getServer(); }; diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp new file mode 100644 index 00000000..c93a88fb --- /dev/null +++ b/src/Utils/sockets.cpp @@ -0,0 +1,59 @@ +#include "sockets.h" + +#include +#include + +#include +#include + +// Socket Debugger Interface +void setFileDescriptorOptions(int socket_fd) { + int opt = 1; + if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { + perror("Failed to set socket file descriptor options"); + exit(EXIT_FAILURE); + } +} + +int createSocketFileDescriptor() { + int socket_fd; + if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { + perror("Failed to make a new socket file descriptor"); + exit(EXIT_FAILURE); + } + setFileDescriptorOptions(socket_fd); + return socket_fd; +} + +void bindSocketToAddress(int socket_fd, struct sockaddr_in address) { + if (bind(socket_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { + perror("Binding socket to address failed"); + exit(EXIT_FAILURE); + } +} + +struct sockaddr_in createAddress(int port) { + struct sockaddr_in address {}; + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(port); + return address; +} + +void startListening(int socket_fd) { + if (listen(socket_fd, 1) < 0) { + perror("listen"); + exit(EXIT_FAILURE); + } +} + +int listenForIncomingConnection(int socket_fd, struct sockaddr_in address) { + int new_socket; + int size = sizeof(address); + if ((new_socket = accept(socket_fd, (struct sockaddr *)&address, + (socklen_t *)&size)) < 0) { + perror("Failed to listen for incoming connections"); + exit(EXIT_FAILURE); + } + return new_socket; +} \ No newline at end of file diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h new file mode 100644 index 00000000..d0908c87 --- /dev/null +++ b/src/Utils/sockets.h @@ -0,0 +1,13 @@ +#pragma once + +void setFileDescriptorOptions(int socket_fd); + +int createSocketFileDescriptor(); + +void bindSocketToAddress(int socket_fd, struct sockaddr_in address); + +struct sockaddr_in createAddress(int port); + +void startListening(int socket_fd); + +int listenForIncomingConnection(int socket_fd, struct sockaddr_in address); From 86663bd5ff5878e623c2f36ccf2c2997ea7a6084 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 27 Apr 2022 17:16:03 +0200 Subject: [PATCH 054/249] Set push port on MCU register --- src/RFC/proxy_server.cpp | 16 ++++++++++------ src/RFC/proxy_server.h | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 27468fff..f7f42a14 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -61,22 +61,26 @@ ProxyServer *ProxyServer::getServer() { } void ProxyServer::registerMCUHost(uint8_t **data) { - int portno = (int)read_B32(data); + int pull = (int)read_B32(data); + int push = pull + 1; auto hostsize = (uint8_t)(*data)[0]; char *hostname = new char[hostsize + 1]; memcpy((void *)hostname, ++(*data), hostsize); hostname[hostsize] = '\0'; - printf("Registering Proxy Host: %s PORT=%d\n", hostname, portno); - ProxyServer::getServer()->registerAddress(hostname, portno); + printf("Registering Proxy Host: %s PULL_PORT=%d PUSH_PORT=%d\n", hostname, + pull, push); + ProxyServer::getServer()->registerAddresses(hostname, pull, push); } -void ProxyServer::registerAddress(char *t_host, int t_port) { +void ProxyServer::registerAddresses(char *_host, int _pull_port, + int _push_port) { if (this->host != nullptr) { this->closeConnections(); free(this->host); } - this->host = t_host; - this->pull_port = t_port; + this->host = _host; + this->pull_port = _pull_port; + this->push_port = _push_port; } void ProxyServer::updateExcpMsg(const char *msg) { diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h index 50de85a5..56676546 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_server.h @@ -22,7 +22,7 @@ class ProxyServer { public: char *exceptionMsg; - void registerAddress(char *t_host, int t_port); + void registerAddresses(char *_host, int _pull_port, int _push_port); void closeConnections(); bool openConnections(); void updateExcpMsg(const char *msg); From 50b815dd72abc12705ecfb6de5cdebe2ba9812d0 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 28 Apr 2022 10:20:00 +0200 Subject: [PATCH 055/249] Add push socket pthread and mutex lock --- documentation/PushDebugging.md | 26 +++++++++ .../Arduino-socket.ino.template | 16 +----- src/Debug/debugger.cpp | 21 ++++++- src/Debug/debugger.h | 10 ++++ src/RFC/proxy_server.cpp | 55 +++++++++++++++---- src/RFC/proxy_server.h | 7 ++- src/WARDuino/WARDuino.cpp | 2 + 7 files changed, 105 insertions(+), 32 deletions(-) create mode 100644 documentation/PushDebugging.md diff --git a/documentation/PushDebugging.md b/documentation/PushDebugging.md new file mode 100644 index 00000000..b9be97aa --- /dev/null +++ b/documentation/PushDebugging.md @@ -0,0 +1,26 @@ +# Pull-Push Debugging + +Aside from traditional remote debugging, the WARDuino virtual machine also supports pull-push debugging. + +## Pull Debugging + +With pull debugging the current application is debugged in a local emulated WARDuino instance, but with live actuator and sensor values from a drone device. +To get current values, the emulated debugger initiates proxy calls to the drone device. +The debugger will wait until this call has completed and the result is returned by the drone. + +Communication happens through a minimal byte format. + +## Push Debugging + +A drone device can also push live values to the emulated debugger. +These will typically be asynchronous events such as hardware interrupts, exceptions, ... + +Those are represented by `Events` in WARDuino and send by the drone device as simple json: + +```json +{ + "topic":"topic string", + "payload":"payload as a string" +} +``` + diff --git a/platforms/Arduino-socket/Arduino-socket.ino.template b/platforms/Arduino-socket/Arduino-socket.ino.template index 464967fd..d637ee69 100644 --- a/platforms/Arduino-socket/Arduino-socket.ino.template +++ b/platforms/Arduino-socket/Arduino-socket.ino.template @@ -55,17 +55,7 @@ void setup(void) { Serial.begin(115200); // attachInterrupt(UART_PIN, handleInput, CHANGE); - Serial.println(ESP.getFreeHeap()); - Serial.println("Total heap:"); - Serial.println(ESP.getHeapSize()); - Serial.println("\nFree heap:"); - Serial.println(ESP.getFreeHeap()); - Serial.println("\nTotal PSRAM:"); - Serial.println(ESP.getPsramSize()); - Serial.println("\nFree PSRAM: "); - Serial.println(ESP.getFreePsram()); - - // create & connect SocketServer + // Create & connect SocketServer SocketServer::createServer(portno, &handleInterrupt); server = SocketServer::getServer(); server->connect2Wifi(&serverCredentials); @@ -82,10 +72,8 @@ void loop() { xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); - Serial.println("\nFree heap:"); - Serial.println(ESP.getFreeHeap()); - wac.run_module(m); + printf("END\n\n"); wac.unload_module(m); } diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 6dbea237..5ad41460 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -884,12 +884,27 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, } #else void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { + this->connected_to_drone = true; + pthread_mutex_init(&this->push_mutex, nullptr); + pthread_mutex_lock(&this->push_mutex); + RFC::registerRFCs(m, &interruptData); ProxyServer::registerMCUHost(&interruptData); ProxyServer *mcuhost = ProxyServer::getServer(); - if (!mcuhost->openConnections()) { - FATAL("problem opening socket to MCU: %s\n", mcuhost->exceptionMsg); - } + this->push_debugging_threadid = mcuhost->openConnections(&this->push_mutex); dprintf(this->socket, "done!\n"); } + +bool Debugger::drone_connected() const { + return this->connected_to_drone; +} + +void Debugger::disconnect_drone() { + if (this->drone_connected()) { + return; + } + int *ptr; + pthread_mutex_unlock(&this->push_mutex); + pthread_join(this->push_debugging_threadid, (void **)&ptr); +} #endif diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 63db09d1..2c3aacff 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -47,6 +47,12 @@ class Debugger { std::vector interruptBuffer; long interruptSize{}; +#ifndef ARDUINO + bool connected_to_drone = false; + pthread_mutex_t push_mutex; + pthread_t push_debugging_threadid; +#endif + // Private methods void printValue(StackValue *v, uint32_t idx, bool end) const; @@ -119,5 +125,9 @@ class Debugger { uint8_t *interruptData); #else void handleMonitorProxies(Module *m, uint8_t *interruptData); + + bool drone_connected() const; + + void disconnect_drone(); #endif }; diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index f7f42a14..f059a938 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -12,6 +12,7 @@ #include "../Utils/sockets.h" #include "../Utils/util.h" +#include "../Utils/macros.h" // TODO exception msg const char SUCCESS[] = ""; // Empty denotes success @@ -27,6 +28,12 @@ struct Address { struct hostent *aServer; }; +struct Socket { + int port; + int fileDescriptor; + pthread_mutex_t *mutex; +}; + bool is_success(const char *msg) { return (msg != nullptr) && (msg[0] == '\0'); // check if string is empty } @@ -53,6 +60,25 @@ const char *createConnection(int socketfd, char *host, int port, return SUCCESS; } +bool continuing(pthread_mutex_t *mutex) +{ + switch(pthread_mutex_trylock(mutex)) { + case 0: /* if we got the lock, unlock and return true */ + pthread_mutex_unlock(mutex); + return true; + case EBUSY: /* return false if the mutex was locked */ + return false; + default: + return true; + } +} + +void *readSocket(void *input) { + // Print value received as argument: + dbg_info("\n=== LISTENING TO SOCKET (in separate thread) ===\n"); + ProxyServer::startPushDebuggerSocket(*((struct Socket*)input)); +} + ProxyServer *ProxyServer::proxyServer = nullptr; ProxyServer *ProxyServer::getServer() { @@ -100,15 +126,15 @@ ProxyServer::ProxyServer() { address = (struct Address *)malloc(sizeof(struct Address)); } -void ProxyServer::startPushDebuggerSocket() const { - struct sockaddr_in _address = createAddress(this->push_port); - bindSocketToAddress(this->push_socket, _address); - startListening(this->push_socket); +void ProxyServer::startPushDebuggerSocket(struct Socket arg) { + struct sockaddr_in _address = createAddress(arg.port); + bindSocketToAddress(arg.fileDescriptor, _address); + startListening(arg.fileDescriptor); int valread; uint8_t buffer[1024] = {0}; - while (true) { - int socket = listenForIncomingConnection(this->push_socket, _address); + while (continuing(arg.mutex)) { + int socket = listenForIncomingConnection(arg.fileDescriptor, _address); while ((valread = read(socket, buffer, 1024)) != -1) { write(socket, "got a push message ... \n", 19); // TODO process push message @@ -116,7 +142,7 @@ void ProxyServer::startPushDebuggerSocket() const { } } -bool ProxyServer::openConnections() { +pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { printf("connecting"); if (this->host == nullptr) { this->updateExcpMsg(NO_HOST_ERR); @@ -128,7 +154,7 @@ bool ProxyServer::openConnections() { this->push_socket = socket(AF_INET, SOCK_STREAM, 0); if (this->pull_socket < 0 || this->push_socket < 0) { this->updateExcpMsg(CREATE_SOCK_ERR); - return false; + FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); } // Connect to pull socket @@ -136,7 +162,7 @@ bool ProxyServer::openConnections() { this->address); if (!is_success(msg)) { this->updateExcpMsg(msg); - return false; + FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); } // Connect to push socket @@ -144,14 +170,19 @@ bool ProxyServer::openConnections() { this->address); if (!is_success(msg)) { this->updateExcpMsg(msg); // TODO differentiate between ports - return false; + FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); } // Listen to push socket on new thread - // TODO + pthread_t id; + auto *args = (struct Socket *)malloc(sizeof(struct Socket)); + args->port = this->push_port; + args->fileDescriptor = this->push_socket; + args->mutex = mutex; + pthread_create(&id, nullptr, readSocket, &args); printf("connected"); - return true; + return id; } void ProxyServer::closeConnections() { diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h index 56676546..febb8664 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_server.h @@ -1,6 +1,7 @@ #pragma once #include +#include struct Address; @@ -17,14 +18,14 @@ class ProxyServer { // private constructor for singleton ProxyServer(); - void startPushDebuggerSocket() const; - public: char *exceptionMsg; + static void startPushDebuggerSocket(struct Socket arg); + void registerAddresses(char *_host, int _pull_port, int _push_port); void closeConnections(); - bool openConnections(); + pthread_t openConnections(pthread_mutex_t *mutex); void updateExcpMsg(const char *msg); bool send(void *t_buffer, int t_size); char *readReply(short int amount = 1024); diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index d159cc24..8f720964 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -862,6 +862,8 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, } void WARDuino::unload_module(Module *m) { + this->debugger->disconnect_drone(); // TODO should this be in unload module? + auto it = std::find(this->modules.begin(), this->modules.end(), m); if (it != this->modules.end()) this->modules.erase(it); From e96e2cbedf6aacf2b9b70613d408cc52c435e74d Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 28 Apr 2022 10:40:58 +0200 Subject: [PATCH 056/249] Fix print + add empty parseJSON function --- src/Debug/debugger.cpp | 4 +--- src/RFC/proxy_server.cpp | 18 +++++++++++------- src/WARDuino/WARDuino.cpp | 3 ++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 5ad41460..0ad7f61d 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -895,9 +895,7 @@ void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { dprintf(this->socket, "done!\n"); } -bool Debugger::drone_connected() const { - return this->connected_to_drone; -} +bool Debugger::drone_connected() const { return this->connected_to_drone; } void Debugger::disconnect_drone() { if (this->drone_connected()) { diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index f059a938..898f8ee6 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -10,9 +10,9 @@ #include #include +#include "../Utils/macros.h" #include "../Utils/sockets.h" #include "../Utils/util.h" -#include "../Utils/macros.h" // TODO exception msg const char SUCCESS[] = ""; // Empty denotes success @@ -60,9 +60,8 @@ const char *createConnection(int socketfd, char *host, int port, return SUCCESS; } -bool continuing(pthread_mutex_t *mutex) -{ - switch(pthread_mutex_trylock(mutex)) { +bool continuing(pthread_mutex_t *mutex) { + switch (pthread_mutex_trylock(mutex)) { case 0: /* if we got the lock, unlock and return true */ pthread_mutex_unlock(mutex); return true; @@ -76,7 +75,11 @@ bool continuing(pthread_mutex_t *mutex) void *readSocket(void *input) { // Print value received as argument: dbg_info("\n=== LISTENING TO SOCKET (in separate thread) ===\n"); - ProxyServer::startPushDebuggerSocket(*((struct Socket*)input)); + ProxyServer::startPushDebuggerSocket(*((struct Socket *)input)); +} + +Event parseJSON(size_t len, uint8_t *buff) { + // TODO parse JSON message } ProxyServer *ProxyServer::proxyServer = nullptr; @@ -136,8 +139,9 @@ void ProxyServer::startPushDebuggerSocket(struct Socket arg) { while (continuing(arg.mutex)) { int socket = listenForIncomingConnection(arg.fileDescriptor, _address); while ((valread = read(socket, buffer, 1024)) != -1) { - write(socket, "got a push message ... \n", 19); - // TODO process push message + write(socket, "got a push message ... \n", 24); + Event event = parseJSON(valread - 1, buffer); + // TODO sent event to CallbackHandler } } } diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index 8f720964..7cbcd165 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -862,7 +862,8 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, } void WARDuino::unload_module(Module *m) { - this->debugger->disconnect_drone(); // TODO should this be in unload module? + this->debugger + ->disconnect_drone(); // TODO should this be in unload module? auto it = std::find(this->modules.begin(), this->modules.end(), m); if (it != this->modules.end()) this->modules.erase(it); From 3ef6b8b0e30dc212cd4b05b47b7da4674bc115d6 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 28 Apr 2022 10:47:43 +0200 Subject: [PATCH 057/249] Fix macos compilation errors --- src/RFC/proxy_server.cpp | 2 +- src/RFC/proxy_server.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 898f8ee6..895187d5 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -150,7 +150,7 @@ pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { printf("connecting"); if (this->host == nullptr) { this->updateExcpMsg(NO_HOST_ERR); - return false; + FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); } // Create sockets diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h index febb8664..1cff1b11 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_server.h @@ -3,6 +3,9 @@ #include #include +#include "pthread.h" +#include "sys/types.h" + struct Address; class ProxyServer { From c18e26c684beb3a1259b6965fe179f13c92cb73c Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 28 Apr 2022 11:16:52 +0200 Subject: [PATCH 058/249] Fix Arduino compilation --- src/RFC/proxy_server.cpp | 2 ++ src/WARDuino/WARDuino.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 895187d5..25fbca24 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -1,3 +1,4 @@ +#ifndef ARDUINO #include "proxy_server.h" /* #include */ // Might be needed #include @@ -226,3 +227,4 @@ char *ProxyServer::readReply(short int amount) { this->updateExcpMsg(READ_ERR); return nullptr; } +#endif \ No newline at end of file diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index 7cbcd165..d0863a71 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -862,9 +862,10 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, } void WARDuino::unload_module(Module *m) { +#ifndef ARDUINO this->debugger ->disconnect_drone(); // TODO should this be in unload module? - +#endif auto it = std::find(this->modules.begin(), this->modules.end(), m); if (it != this->modules.end()) this->modules.erase(it); From 70b0b6c94e54f94c87b32edca214335a09d9eb62 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 11:17:44 +0200 Subject: [PATCH 059/249] fix merge conflict --- .../Arduino-socket.ino.template | 29 +++++-- platforms/Arduino-socket/upload.h | 87 +++++++++++++------ 2 files changed, 82 insertions(+), 34 deletions(-) diff --git a/platforms/Arduino-socket/Arduino-socket.ino.template b/platforms/Arduino-socket/Arduino-socket.ino.template index d637ee69..39d31d9d 100644 --- a/platforms/Arduino-socket/Arduino-socket.ino.template +++ b/platforms/Arduino-socket/Arduino-socket.ino.template @@ -17,7 +17,8 @@ Module* m; SocketServer* server; ServerCredentials serverCredentials = {"{{SSID}}", "{{Password}}"}; -uint16_t portno = 8080; +uint16_t pullportno = 8080; +uint16_t pushportno = 8081; #define UART_PIN 3 @@ -55,21 +56,31 @@ void setup(void) { Serial.begin(115200); // attachInterrupt(UART_PIN, handleInput, CHANGE); - // Create & connect SocketServer - SocketServer::createServer(portno, &handleInterrupt); - server = SocketServer::getServer(); - server->connect2Wifi(&serverCredentials); + Serial.println(ESP.getFreeHeap()); + Serial.println("Total heap:"); + Serial.println(ESP.getHeapSize()); + Serial.println("\nFree heap:"); + Serial.println(ESP.getFreeHeap()); + Serial.println("\nTotal PSRAM:"); + Serial.println(ESP.getPsramSize()); + Serial.println("\nFree PSRAM: "); + Serial.println(ESP.getFreePsram()); + + // create & connect SocketServer + //SocketServer::createServer(pullportno, pushportno, &handleInterrupt); + //server = SocketServer::getServer(); + //server->connect2Wifi(&serverCredentials); } void loop() { disableCore0WDT(); m = wac.load_module(wasm, wasm_len, {}); - server->begin(); + //server->begin(); printf("LOADED \n\n"); - uint8_t command[] = {'0', '3', '\n'}; - wac.handleInterrupt(3, command); - xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); +// uint8_t command[] = {'0', '3', '\n'}; +// wac.handleInterrupt(3, command); + // xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); wac.run_module(m); diff --git a/platforms/Arduino-socket/upload.h b/platforms/Arduino-socket/upload.h index efac27f4..4fc0c199 100644 --- a/platforms/Arduino-socket/upload.h +++ b/platforms/Arduino-socket/upload.h @@ -1,26 +1,63 @@ +// unsigned char upload_wasm[] = { +// 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, +// 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, +// 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, +// 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, +// 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, +// 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, +// 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, +// 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, +// 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, +// 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, +// 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, +// 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, +// 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, +// 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, +// 0x0b, 0x0b, 0x00, 0x6e, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x49, 0x05, +// 0x00, 0x0e, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, +// 0x65, 0x6c, 0x61, 0x79, 0x01, 0x11, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, +// 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x02, +// 0x16, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, 0x69, +// 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x03, +// 0x04, 0x69, 0x6e, 0x69, 0x74, 0x04, 0x05, 0x62, 0x6c, 0x69, 0x6e, 0x6b, +// 0x02, 0x1c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, +// 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, +// 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; +// unsigned int upload_wasm_len = 282; +// +// +// +// + unsigned char upload_wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, - 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, - 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, - 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, - 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, - 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, - 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, - 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, - 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, - 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, - 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, - 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, - 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, - 0x0b, 0x0b, 0x00, 0x6e, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x49, 0x05, - 0x00, 0x0e, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, - 0x65, 0x6c, 0x61, 0x79, 0x01, 0x11, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, - 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x02, - 0x16, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, 0x69, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x03, - 0x04, 0x69, 0x6e, 0x69, 0x74, 0x04, 0x05, 0x62, 0x6c, 0x69, 0x6e, 0x6b, - 0x02, 0x1c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, - 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, - 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; -unsigned int upload_wasm_len = 282; + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x05, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, + 0x7f, 0x7f, 0x00, 0x60, 0x05, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x60, + 0x00, 0x00, 0x02, 0x60, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0d, 0x63, 0x68, + 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x00, + 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, + 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x11, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x64, + 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x13, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, + 0x70, 0x74, 0x00, 0x02, 0x03, 0x07, 0x06, 0x03, 0x04, 0x00, 0x00, 0x01, + 0x02, 0x04, 0x05, 0x01, 0x70, 0x01, 0x02, 0x02, 0x05, 0x03, 0x01, 0x00, + 0x01, 0x06, 0x13, 0x03, 0x7f, 0x01, 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, + 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, 0x41, 0x80, 0x10, 0x0b, 0x07, 0x2c, + 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x04, 0x6d, + 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x5f, 0x65, 0x6e, 0x64, 0x03, 0x01, 0x0b, 0x5f, 0x5f, 0x68, 0x65, 0x61, + 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x09, 0x07, 0x01, 0x00, + 0x41, 0x01, 0x0b, 0x01, 0x04, 0x0a, 0x4f, 0x06, 0x0d, 0x00, 0x41, 0x1a, + 0x41, 0x1a, 0x10, 0x08, 0x41, 0x01, 0x47, 0x10, 0x07, 0x0b, 0x1b, 0x00, + 0x41, 0x25, 0x41, 0x00, 0x10, 0x06, 0x41, 0x1a, 0x41, 0x02, 0x10, 0x06, + 0x41, 0x25, 0x41, 0x01, 0x41, 0x02, 0x10, 0x09, 0x03, 0x40, 0x0c, 0x00, + 0x0b, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0b, 0x08, + 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x01, 0x0b, 0x06, 0x00, 0x20, 0x00, + 0x10, 0x02, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, + 0x03, 0x0b +}; +unsigned int upload_wasm_len = 314; +/* +*/ From 6caed716ddf6e704e755fd7c0f4c462911b78118 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 10:41:26 +0200 Subject: [PATCH 060/249] add temporary button example pin 37 --- .../Arduino-socket/button_37_example/button.c | 32 +++++++++++ .../button_37_example/button.wast | 57 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 platforms/Arduino-socket/button_37_example/button.c create mode 100644 platforms/Arduino-socket/button_37_example/button.wast diff --git a/platforms/Arduino-socket/button_37_example/button.c b/platforms/Arduino-socket/button_37_example/button.c new file mode 100644 index 00000000..f02045d5 --- /dev/null +++ b/platforms/Arduino-socket/button_37_example/button.c @@ -0,0 +1,32 @@ +unsigned char button_wasm[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x05, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, + 0x7f, 0x7f, 0x00, 0x60, 0x05, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x60, + 0x00, 0x00, 0x02, 0x60, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0d, 0x63, 0x68, + 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x00, + 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, + 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x11, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x64, + 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x13, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, + 0x70, 0x74, 0x00, 0x02, 0x03, 0x07, 0x06, 0x03, 0x04, 0x00, 0x00, 0x01, + 0x02, 0x04, 0x05, 0x01, 0x70, 0x01, 0x02, 0x02, 0x05, 0x03, 0x01, 0x00, + 0x01, 0x06, 0x13, 0x03, 0x7f, 0x01, 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, + 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, 0x41, 0x80, 0x10, 0x0b, 0x07, 0x2c, + 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x04, 0x6d, + 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x5f, 0x65, 0x6e, 0x64, 0x03, 0x01, 0x0b, 0x5f, 0x5f, 0x68, 0x65, 0x61, + 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x09, 0x07, 0x01, 0x00, + 0x41, 0x01, 0x0b, 0x01, 0x04, 0x0a, 0x4f, 0x06, 0x0d, 0x00, 0x41, 0x1a, + 0x41, 0x1a, 0x10, 0x08, 0x41, 0x01, 0x47, 0x10, 0x07, 0x0b, 0x1b, 0x00, + 0x41, 0x25, 0x41, 0x00, 0x10, 0x06, 0x41, 0x1a, 0x41, 0x02, 0x10, 0x06, + 0x41, 0x25, 0x41, 0x01, 0x41, 0x02, 0x10, 0x09, 0x03, 0x40, 0x0c, 0x00, + 0x0b, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0b, 0x08, + 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x01, 0x0b, 0x06, 0x00, 0x20, 0x00, + 0x10, 0x02, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, + 0x03, 0x0b +}; +unsigned int button_wasm_len = 314; +/* +*/ diff --git a/platforms/Arduino-socket/button_37_example/button.wast b/platforms/Arduino-socket/button_37_example/button.wast new file mode 100644 index 00000000..507d00ed --- /dev/null +++ b/platforms/Arduino-socket/button_37_example/button.wast @@ -0,0 +1,57 @@ +(module + (type $t0 (func (param i32 i32))) + (type $t1 (func (param i32) (result i32))) + (type $t2 (func (param i32 i32 i32))) + (type $t3 (func (param i32 i32 i32 i32 i32))) + (type $t4 (func)) + (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $t0))) + (import "env" "chip_digital_write" (func $env.chip_digital_write (type $t0))) + (import "env" "chip_digital_read" (func $env.chip_digital_read (type $t1))) + (import "env" "subscribe_interrupt" (func $env.subscribe_interrupt (type $t2))) + (func $f4 (type $t3) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (param $p4 i32) + i32.const 26 + i32.const 26 + call $f8 + i32.const 1 + i32.ne + call $f7) + (func $main (type $t4) + i32.const 37 + i32.const 0 + call $f6 + i32.const 26 + i32.const 2 + call $f6 + i32.const 37 + i32.const 1 + i32.const 2 + call $f9 + loop $L0 + br $L0 + end) + (func $f6 (type $t0) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + call $env.chip_pin_mode) + (func $f7 (type $t0) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + call $env.chip_digital_write) + (func $f8 (type $t1) (param $p0 i32) (result i32) + local.get $p0 + call $env.chip_digital_read) + (func $f9 (type $t2) (param $p0 i32) (param $p1 i32) (param $p2 i32) + local.get $p0 + local.get $p1 + local.get $p2 + call $env.subscribe_interrupt) + (table $T0 2 2 funcref) + (memory $memory 1) + (global $g0 (mut i32) (i32.const 2048)) + (global $__data_end i32 (i32.const 2048)) + (global $__heap_base i32 (i32.const 2048)) + (export "memory" (memory $memory)) + (export "main" (func $main)) + (export "__data_end" (global $__data_end)) + (export "__heap_base" (global $__heap_base)) + (elem $e0 (i32.const 1) func $f4)) From cfbd7ac0580a1017ee40ccf8b8b000bb22701c55 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 10:42:50 +0200 Subject: [PATCH 061/249] add printf + push event as comment --- src/Primitives/arduino.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index 7d0b5d36..306ccdaa 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -20,6 +20,7 @@ #include #include "../Memory/mem.h" +//#include "../RFC/SocketServer.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "primitives.h" @@ -512,6 +513,16 @@ void Interrupt::handleInterrupt() { topic += String(pin); auto *empty = reinterpret_cast(""); CallbackHandler::push_event(topic.c_str(), empty, 0); + bool recording = true; + printf("reached handleInterrupt\n"); + // if (recording) { + // SocketServer *server = SocketServer::getServer(); + // printf(R"({"topic":"%s","payload":"%s"})", topic.c_str(), "empty"); + // // server->printf2Client(server->pushClient, + // // R"({"topic":"%s","payload":"%s"})", topic.c_str(), + // // empty); + // } else { + // } } std::vector handlers; From b293df84bb3c970070de57b1ec17f8ccdc66bae5 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 10:44:51 +0200 Subject: [PATCH 062/249] use 2th socketserver + commented functionality --- src/RFC/rfc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index 4de42a7b..f1e7cf46 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -106,6 +106,8 @@ void RFC::returnResult(Module *m) { const char *data = (const char *)rfc_result->raw; size_t data_size = (size_t)rfc_result->size; SocketServer::getServer()->write2Client(data, data_size); + // SocketServer *server = SocketServer::getServer(); + // server->write2Client(server->pullClient, data, data_size); // FATAL("writing into socketdf\n"); // write(m->warduino->debugger->socket, rfc_result->raw, rfc_result->size); } From fd2a9b25bfb47967fdfeddf37c487fe507d78da5 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 10:45:25 +0200 Subject: [PATCH 063/249] temporariy printf --- src/WARDuino/CallbackHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 724bd34b..8cb22c5a 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -57,8 +57,8 @@ bool CallbackHandler::resolve_event() { Event event = CallbackHandler::events->front(); CallbackHandler::events->pop(); - dbg_info("Resolving an event. (%lu remaining)\n", - CallbackHandler::events->size()); + printf("Resolving an event. (%lu remaining)\n", + CallbackHandler::events->size()); auto iterator = CallbackHandler::callbacks->find(event.topic); if (iterator != CallbackHandler::callbacks->end()) { From b67a30e717aa13b4e72548fe020fbcf97b45be45 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 10:46:05 +0200 Subject: [PATCH 064/249] define 2th socketserver + commented functionality --- src/RFC/SocketServer.cpp | 96 ++++++++++++++++++++++++++++------------ src/RFC/SocketServer.h | 19 +++++--- 2 files changed, 80 insertions(+), 35 deletions(-) diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp index 121d5aba..aadef46c 100644 --- a/src/RFC/SocketServer.cpp +++ b/src/RFC/SocketServer.cpp @@ -7,20 +7,26 @@ SocketServer *SocketServer::socketServer = nullptr; -SocketServer::SocketServer(uint16_t t_port, +SocketServer::SocketServer(uint16_t t_pullport, uint16_t t_pushport, void (*t_handler)(size_t, uint8_t *)) - : portno(t_port) { - this->asyncServer = new AsyncServer(t_port); + : pull_portno(t_pullport), push_portno(t_pushport) { + this->pullServer = new AsyncServer(t_pullport); + this->pushServer = nullptr; // new AsyncServer(t_pushport); this->handler = t_handler; } -void SocketServer::createServer(uint16_t t_port, +void SocketServer::createServer(uint16_t t_pullport, uint16_t t_pushport, void (*t_handler)(size_t, uint8_t *)) { if (socketServer == nullptr) - socketServer = new SocketServer(t_port, t_handler); + socketServer = new SocketServer(t_pullport, t_pushport, t_handler); } -SocketServer *SocketServer::getServer() { return socketServer; } +SocketServer *SocketServer::getServer() { + // if (socketServer == nullptr) { + // FATAL("SocketServer::getServer is nullptr\n"); + // } + return socketServer; +} void SocketServer::connect2Wifi(ServerCredentials *t_credentials) { printf("Connecting to WiFi...\n"); @@ -34,70 +40,102 @@ void SocketServer::connect2Wifi(ServerCredentials *t_credentials) { } void SocketServer::begin() { - this->asyncServer->begin(); - this->asyncServer->onClient( - [this](void *s, AsyncClient *c) { - debug("A new client connected!\n"); - this->registerClient(c); - }, - NULL); + printf("starting PullSever\n"); + SocketServer *thisServer = this; + // this->pullServer->begin(); + // this->pullServer->onClient( + // [thisServer](void *s, AsyncClient *c) { + // debug("A new client connected!\n"); + // thisServer->registerClient(c, &thisServer->pullClient); + // }, + // NULL); + + printf("starting PushSever\n"); + // this->pushServer->begin(); + // this->pushServer->onClient( + // [thisServer](void *s, AsyncClient *c) { + // debug("A new client connected!\n"); + // thisServer->registerClient(c, &thisServer->pushClient); + // }, + // NULL); } -void SocketServer::registerClient(AsyncClient *t_client) { - if (t_client == NULL) { +void SocketServer::registerClient(AsyncClient *new_client, + AsyncClient **current_client) { + if (new_client == NULL) { debug("a new Client is NULL\n"); return; } - if (this->client == nullptr) { - this->client = t_client; + if (*current_client == nullptr) { + *current_client = new_client; } else { debug("Only one socket client allowed.\n"); - t_client->close(true); - t_client->free(); - delete t_client; + new_client->close(true); + new_client->free(); + delete new_client; return; } void (*handler)(size_t, uint8_t *) = this->handler; SocketServer *thisServer = this; - t_client->onError( + new_client->onError( [thisServer](void *r, AsyncClient *t_client, int8_t error) { debug("ClientSocket Error %" PRIu8 "\n", error); }, NULL); - t_client->onDisconnect( + new_client->onDisconnect( [thisServer](void *r, AsyncClient *t_client) { debug("Client Disconnected\n"); thisServer->unregisterClient(t_client); }, NULL); - t_client->onTimeout( + new_client->onTimeout( [thisServer](void *r, AsyncClient *t_client, uint32_t time) { debug("Client timeouted\n"); thisServer->unregisterClient(t_client); }, NULL); - t_client->onData([handler](void *r, AsyncClient *t_client, void *buf, - size_t len) { handler(len, (uint8_t *)buf); }, - NULL); + new_client->onData([handler](void *r, AsyncClient *t_client, void *buf, + size_t len) { handler(len, (uint8_t *)buf); }, + NULL); } void SocketServer::unregisterClient(AsyncClient *t_client) { - if (this->client == t_client) { - this->client = nullptr; + if (this->pullClient == t_client) { + this->pullClient = nullptr; + } else if (this->pushClient == t_client) { + this->pushClient = nullptr; } t_client->close(true); // TODO potential issue: close twice same client t_client->free(); delete t_client; } +// void SocketServer::write2Client(AsyncClient *client, const char *buf, +// size_t size_buf) { void SocketServer::write2Client(const char *buf, size_t size_buf) { - if (this->client == nullptr) return; + AsyncClient *client = this->pullClient; + if (client == nullptr) return; size_t space_left = client->space(); client->add(buf, size_buf > space_left ? space_left : size_buf); client->send(); if (size_buf <= space_left) return; + // write2Client(client, buf + space_left, size_buf - space_left); write2Client(buf + space_left, size_buf - space_left); } + +// void SocketServer::printf2Client(AsyncClient *client, const char *format, ...) { +// va_list args; +// va_start(args, format); + +// if (client == nullptr) return; + +// uint32_t BUFF_SIZE = 300; +// char buffer[BUFF_SIZE]; +// int l = vsnprintf(buffer, BUFF_SIZE, format, args); +// if (l == BUFF_SIZE) FATAL("TOO MUCH got %d\n", l); +// this->write2Client(client, buffer, l); +// va_end(args); +// } #endif diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h index 12710642..db0d153e 100644 --- a/src/RFC/SocketServer.h +++ b/src/RFC/SocketServer.h @@ -17,29 +17,36 @@ typedef struct { class SocketServer { private: // SocketServer configuration - const uint16_t portno; + const uint16_t pull_portno, push_portno; + ServerCredentials *credentials; - AsyncServer *asyncServer; - AsyncClient *client; + AsyncServer *pullServer; + AsyncServer *pushServer; // handler for client's received data void (*handler)(size_t, uint8_t *); // singleton static SocketServer *socketServer; - SocketServer(uint16_t t_port, void (*t_handler)(size_t, uint8_t *)); + SocketServer(uint16_t t_pullport, uint16_t t_pushport, + void (*t_handler)(size_t, uint8_t *)); - void registerClient(AsyncClient *t_client); + void registerClient(AsyncClient *new_client, AsyncClient **current_client); void unregisterClient(AsyncClient *t_client); public: + AsyncClient *pullClient; + AsyncClient *pushClient; + void begin(); void connect2Wifi(ServerCredentials *t_credentials); void write2Client(const char *buf, size_t size_buf); + // void write2Client(AsyncClient *client, const char *buf, size_t size_buf); + // void printf2Client(AsyncClient *client, const char *format, ...); static SocketServer *getServer(void); - static void createServer(uint16_t t_port, + static void createServer(uint16_t t_pullport, uint16_t t_pushport, void (*t_handler)(size_t, uint8_t *)); }; #endif From e0ab3352e29930efd269506eae1c44e44347ab09 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 19:51:12 +0200 Subject: [PATCH 065/249] activate use of push server --- src/RFC/SocketServer.cpp | 72 +++++++++++++++++++--------------------- src/RFC/SocketServer.h | 6 ++-- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp index aadef46c..2dfbf0fd 100644 --- a/src/RFC/SocketServer.cpp +++ b/src/RFC/SocketServer.cpp @@ -11,7 +11,9 @@ SocketServer::SocketServer(uint16_t t_pullport, uint16_t t_pushport, void (*t_handler)(size_t, uint8_t *)) : pull_portno(t_pullport), push_portno(t_pushport) { this->pullServer = new AsyncServer(t_pullport); - this->pushServer = nullptr; // new AsyncServer(t_pushport); + this->pushServer = new AsyncServer(t_pushport); + this->pullClient = nullptr; + this->pushClient = nullptr; this->handler = t_handler; } @@ -21,12 +23,7 @@ void SocketServer::createServer(uint16_t t_pullport, uint16_t t_pushport, socketServer = new SocketServer(t_pullport, t_pushport, t_handler); } -SocketServer *SocketServer::getServer() { - // if (socketServer == nullptr) { - // FATAL("SocketServer::getServer is nullptr\n"); - // } - return socketServer; -} +SocketServer *SocketServer::getServer() { return socketServer; } void SocketServer::connect2Wifi(ServerCredentials *t_credentials) { printf("Connecting to WiFi...\n"); @@ -42,22 +39,22 @@ void SocketServer::connect2Wifi(ServerCredentials *t_credentials) { void SocketServer::begin() { printf("starting PullSever\n"); SocketServer *thisServer = this; - // this->pullServer->begin(); - // this->pullServer->onClient( - // [thisServer](void *s, AsyncClient *c) { - // debug("A new client connected!\n"); - // thisServer->registerClient(c, &thisServer->pullClient); - // }, - // NULL); + this->pullServer->begin(); + this->pullServer->onClient( + [thisServer](void *s, AsyncClient *c) { + printf("A new PullClient connected!\n"); + thisServer->registerClient(c, &thisServer->pullClient); + }, + NULL); printf("starting PushSever\n"); - // this->pushServer->begin(); - // this->pushServer->onClient( - // [thisServer](void *s, AsyncClient *c) { - // debug("A new client connected!\n"); - // thisServer->registerClient(c, &thisServer->pushClient); - // }, - // NULL); + this->pushServer->begin(); + this->pushServer->onClient( + [thisServer](void *s, AsyncClient *c) { + printf("A new PushClient connected!\n"); + thisServer->registerClient(c, &thisServer->pushClient); + }, + NULL); } void SocketServer::registerClient(AsyncClient *new_client, @@ -112,30 +109,29 @@ void SocketServer::unregisterClient(AsyncClient *t_client) { delete t_client; } -// void SocketServer::write2Client(AsyncClient *client, const char *buf, -// size_t size_buf) { -void SocketServer::write2Client(const char *buf, size_t size_buf) { - AsyncClient *client = this->pullClient; +void SocketServer::write2Client(AsyncClient *client, const char *buf, + size_t size_buf) { if (client == nullptr) return; size_t space_left = client->space(); client->add(buf, size_buf > space_left ? space_left : size_buf); client->send(); if (size_buf <= space_left) return; - // write2Client(client, buf + space_left, size_buf - space_left); - write2Client(buf + space_left, size_buf - space_left); + write2Client(client, buf + space_left, size_buf - space_left); } -// void SocketServer::printf2Client(AsyncClient *client, const char *format, ...) { -// va_list args; -// va_start(args, format); +void SocketServer::printf2Client(AsyncClient *client, const char *format, ...) { + va_list args; + va_start(args, format); + + if (client == nullptr) return; -// if (client == nullptr) return; + uint32_t BUFF_SIZE = 300; + char buffer[BUFF_SIZE]; + int l = vsnprintf(buffer, BUFF_SIZE, format, args); + if (l == BUFF_SIZE) FATAL("Buffer not big enough: %d\n", l); + this->write2Client(client, buffer, l); + va_end(args); +} -// uint32_t BUFF_SIZE = 300; -// char buffer[BUFF_SIZE]; -// int l = vsnprintf(buffer, BUFF_SIZE, format, args); -// if (l == BUFF_SIZE) FATAL("TOO MUCH got %d\n", l); -// this->write2Client(client, buffer, l); -// va_end(args); -// } +bool SocketServer::hasPushClient() { return this->pushClient != nullptr; } #endif diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h index db0d153e..47f44bd0 100644 --- a/src/RFC/SocketServer.h +++ b/src/RFC/SocketServer.h @@ -41,9 +41,9 @@ class SocketServer { void begin(); void connect2Wifi(ServerCredentials *t_credentials); - void write2Client(const char *buf, size_t size_buf); - // void write2Client(AsyncClient *client, const char *buf, size_t size_buf); - // void printf2Client(AsyncClient *client, const char *format, ...); + void write2Client(AsyncClient *client, const char *buf, size_t size_buf); + void printf2Client(AsyncClient *client, const char *format, ...); + bool hasPushClient(); static SocketServer *getServer(void); static void createServer(uint16_t t_pullport, uint16_t t_pushport, From 70b3d7db3d7225645058d696b322675a58e91103 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 19:51:47 +0200 Subject: [PATCH 066/249] remove the use of printf --- src/Primitives/arduino.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index 306ccdaa..2edf9f70 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -513,16 +513,6 @@ void Interrupt::handleInterrupt() { topic += String(pin); auto *empty = reinterpret_cast(""); CallbackHandler::push_event(topic.c_str(), empty, 0); - bool recording = true; - printf("reached handleInterrupt\n"); - // if (recording) { - // SocketServer *server = SocketServer::getServer(); - // printf(R"({"topic":"%s","payload":"%s"})", topic.c_str(), "empty"); - // // server->printf2Client(server->pushClient, - // // R"({"topic":"%s","payload":"%s"})", topic.c_str(), - // // empty); - // } else { - // } } std::vector handlers; From f67b598f36355070598266a6b4440b4bbc24debb Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 19:52:33 +0200 Subject: [PATCH 067/249] use updated write2Client --- src/RFC/rfc.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index f1e7cf46..40706109 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -105,11 +105,8 @@ void RFC::returnResult(Module *m) { struct SerializeData *rfc_result = this->serializeRFCallee(); const char *data = (const char *)rfc_result->raw; size_t data_size = (size_t)rfc_result->size; - SocketServer::getServer()->write2Client(data, data_size); - // SocketServer *server = SocketServer::getServer(); - // server->write2Client(server->pullClient, data, data_size); - // FATAL("writing into socketdf\n"); - // write(m->warduino->debugger->socket, rfc_result->raw, rfc_result->size); + SocketServer *server = SocketServer::getServer(); + server->write2Client(server->pullClient, data, data_size); } #endif From 1ef31489c867c45a23190d7a55b112eb7106dcf5 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 19:53:15 +0200 Subject: [PATCH 068/249] push events when pushmode activated --- src/WARDuino/CallbackHandler.cpp | 19 +++++++++++++++++++ src/WARDuino/CallbackHandler.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 8cb22c5a..968ec94b 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -2,11 +2,14 @@ #include +#include "../Debug/debugger.h" #include "../Interpreter/instructions.h" #include "../Utils/macros.h" // CallbackHandler class +bool CallbackHandler::pushingMode = false; + // bool CallbackHandler::resolving_event = false; std::unordered_map *> *CallbackHandler::callbacks = @@ -55,6 +58,12 @@ bool CallbackHandler::resolve_event() { // CallbackHandler::resolving_event = true; Event event = CallbackHandler::events->front(); + // check if we need to push events + SocketServer *server = SocketServer::getServer(); + if (CallbackHandler::pushingMode && !server->hasPushClient()) { + printf("recording and no push client\n"); + return true; + } CallbackHandler::events->pop(); printf("Resolving an event. (%lu remaining)\n", @@ -85,6 +94,16 @@ void Callback::resolve_event(const Event &e) { dbg_trace("Callback(%s, %i): resolving Event(%s, \"%s\")\n", topic.c_str(), table_index, e.topic.c_str(), e.payload); + if (CallbackHandler::pushingMode) { + SocketServer *server = SocketServer::getServer(); + printf(R"({"topic":"%s","payload":"%s"})", e.topic.c_str(), + e.payload); // TODO remove + server->printf2Client(server->pushClient, + R"({"topic":"%s","payload":"%s"})", + e.topic.c_str(), e.payload); + return; + } + // Copy topic and payload to linear memory uint32_t start = 10000; // TODO use reserved area in linear memory std::string topic = e.topic; diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index 06d2f827..e06aa762 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -26,6 +26,9 @@ class CallbackHandler { static void push_event(std::string topic, const unsigned char *payload, unsigned int length); static bool resolve_event(); + + // WOOD needed to know when to push events + static bool pushingMode; }; class Event { From eea1f1d89dfad6db08cbc48b84cdb169efa0f892 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 19:53:36 +0200 Subject: [PATCH 069/249] activate push mode when dumping --- src/Debug/debugger.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 0ad7f61d..fd072443 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -173,6 +173,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptWOODDUMP: *program_state = WARDUINOpause; + CallbackHandler::pushingMode = true; free(interruptData); woodDump(m); break; From a5bd57a4e48227039bb4d439c38b8e7fd6fd5242 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 19:56:07 +0200 Subject: [PATCH 070/249] update template --- .../Arduino-socket/Arduino-socket.ino.template | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platforms/Arduino-socket/Arduino-socket.ino.template b/platforms/Arduino-socket/Arduino-socket.ino.template index 39d31d9d..391ce6dc 100644 --- a/platforms/Arduino-socket/Arduino-socket.ino.template +++ b/platforms/Arduino-socket/Arduino-socket.ino.template @@ -67,20 +67,20 @@ void setup(void) { Serial.println(ESP.getFreePsram()); // create & connect SocketServer - //SocketServer::createServer(pullportno, pushportno, &handleInterrupt); - //server = SocketServer::getServer(); - //server->connect2Wifi(&serverCredentials); + SocketServer::createServer(pullportno, pushportno, &handleInterrupt); + server = SocketServer::getServer(); + server->connect2Wifi(&serverCredentials); } void loop() { disableCore0WDT(); m = wac.load_module(wasm, wasm_len, {}); - //server->begin(); + server->begin(); printf("LOADED \n\n"); -// uint8_t command[] = {'0', '3', '\n'}; -// wac.handleInterrupt(3, command); - // xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); + uint8_t command[] = {'0', '3', '\n'}; + wac.handleInterrupt(3, command); + xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); wac.run_module(m); From a3e4d99c0cbbee99944cb54adb52d11712a186e6 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 19:57:14 +0200 Subject: [PATCH 071/249] delete unneeded files --- .../Arduino-socket/button_37_example/button.c | 32 ----------- .../button_37_example/button.wast | 57 ------------------- 2 files changed, 89 deletions(-) delete mode 100644 platforms/Arduino-socket/button_37_example/button.c delete mode 100644 platforms/Arduino-socket/button_37_example/button.wast diff --git a/platforms/Arduino-socket/button_37_example/button.c b/platforms/Arduino-socket/button_37_example/button.c deleted file mode 100644 index f02045d5..00000000 --- a/platforms/Arduino-socket/button_37_example/button.c +++ /dev/null @@ -1,32 +0,0 @@ -unsigned char button_wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x05, 0x60, - 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, - 0x7f, 0x7f, 0x00, 0x60, 0x05, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x60, - 0x00, 0x00, 0x02, 0x60, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0d, 0x63, 0x68, - 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x00, - 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, - 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x11, 0x63, 0x68, 0x69, 0x70, 0x5f, - 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x64, - 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x13, 0x73, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, - 0x70, 0x74, 0x00, 0x02, 0x03, 0x07, 0x06, 0x03, 0x04, 0x00, 0x00, 0x01, - 0x02, 0x04, 0x05, 0x01, 0x70, 0x01, 0x02, 0x02, 0x05, 0x03, 0x01, 0x00, - 0x01, 0x06, 0x13, 0x03, 0x7f, 0x01, 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, - 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, 0x41, 0x80, 0x10, 0x0b, 0x07, 0x2c, - 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x04, 0x6d, - 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, - 0x5f, 0x65, 0x6e, 0x64, 0x03, 0x01, 0x0b, 0x5f, 0x5f, 0x68, 0x65, 0x61, - 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x09, 0x07, 0x01, 0x00, - 0x41, 0x01, 0x0b, 0x01, 0x04, 0x0a, 0x4f, 0x06, 0x0d, 0x00, 0x41, 0x1a, - 0x41, 0x1a, 0x10, 0x08, 0x41, 0x01, 0x47, 0x10, 0x07, 0x0b, 0x1b, 0x00, - 0x41, 0x25, 0x41, 0x00, 0x10, 0x06, 0x41, 0x1a, 0x41, 0x02, 0x10, 0x06, - 0x41, 0x25, 0x41, 0x01, 0x41, 0x02, 0x10, 0x09, 0x03, 0x40, 0x0c, 0x00, - 0x0b, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0b, 0x08, - 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x01, 0x0b, 0x06, 0x00, 0x20, 0x00, - 0x10, 0x02, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, - 0x03, 0x0b -}; -unsigned int button_wasm_len = 314; -/* -*/ diff --git a/platforms/Arduino-socket/button_37_example/button.wast b/platforms/Arduino-socket/button_37_example/button.wast deleted file mode 100644 index 507d00ed..00000000 --- a/platforms/Arduino-socket/button_37_example/button.wast +++ /dev/null @@ -1,57 +0,0 @@ -(module - (type $t0 (func (param i32 i32))) - (type $t1 (func (param i32) (result i32))) - (type $t2 (func (param i32 i32 i32))) - (type $t3 (func (param i32 i32 i32 i32 i32))) - (type $t4 (func)) - (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $t0))) - (import "env" "chip_digital_write" (func $env.chip_digital_write (type $t0))) - (import "env" "chip_digital_read" (func $env.chip_digital_read (type $t1))) - (import "env" "subscribe_interrupt" (func $env.subscribe_interrupt (type $t2))) - (func $f4 (type $t3) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (param $p4 i32) - i32.const 26 - i32.const 26 - call $f8 - i32.const 1 - i32.ne - call $f7) - (func $main (type $t4) - i32.const 37 - i32.const 0 - call $f6 - i32.const 26 - i32.const 2 - call $f6 - i32.const 37 - i32.const 1 - i32.const 2 - call $f9 - loop $L0 - br $L0 - end) - (func $f6 (type $t0) (param $p0 i32) (param $p1 i32) - local.get $p0 - local.get $p1 - call $env.chip_pin_mode) - (func $f7 (type $t0) (param $p0 i32) (param $p1 i32) - local.get $p0 - local.get $p1 - call $env.chip_digital_write) - (func $f8 (type $t1) (param $p0 i32) (result i32) - local.get $p0 - call $env.chip_digital_read) - (func $f9 (type $t2) (param $p0 i32) (param $p1 i32) (param $p2 i32) - local.get $p0 - local.get $p1 - local.get $p2 - call $env.subscribe_interrupt) - (table $T0 2 2 funcref) - (memory $memory 1) - (global $g0 (mut i32) (i32.const 2048)) - (global $__data_end i32 (i32.const 2048)) - (global $__heap_base i32 (i32.const 2048)) - (export "memory" (memory $memory)) - (export "main" (func $main)) - (export "__data_end" (global $__data_end)) - (export "__heap_base" (global $__heap_base)) - (elem $e0 (i32.const 1) func $f4)) From ab63df0df515ead2c6c3fa28c4de8bad9a2bb53d Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 20:05:44 +0200 Subject: [PATCH 072/249] format --- platforms/Arduino-socket/upload.h | 57 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/platforms/Arduino-socket/upload.h b/platforms/Arduino-socket/upload.h index 4fc0c199..c62c9fa3 100644 --- a/platforms/Arduino-socket/upload.h +++ b/platforms/Arduino-socket/upload.h @@ -30,34 +30,33 @@ // unsigned char upload_wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x05, 0x60, - 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, - 0x7f, 0x7f, 0x00, 0x60, 0x05, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x60, - 0x00, 0x00, 0x02, 0x60, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0d, 0x63, 0x68, - 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x00, - 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, - 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x11, 0x63, 0x68, 0x69, 0x70, 0x5f, - 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x64, - 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x13, 0x73, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, - 0x70, 0x74, 0x00, 0x02, 0x03, 0x07, 0x06, 0x03, 0x04, 0x00, 0x00, 0x01, - 0x02, 0x04, 0x05, 0x01, 0x70, 0x01, 0x02, 0x02, 0x05, 0x03, 0x01, 0x00, - 0x01, 0x06, 0x13, 0x03, 0x7f, 0x01, 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, - 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, 0x41, 0x80, 0x10, 0x0b, 0x07, 0x2c, - 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x04, 0x6d, - 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, - 0x5f, 0x65, 0x6e, 0x64, 0x03, 0x01, 0x0b, 0x5f, 0x5f, 0x68, 0x65, 0x61, - 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x09, 0x07, 0x01, 0x00, - 0x41, 0x01, 0x0b, 0x01, 0x04, 0x0a, 0x4f, 0x06, 0x0d, 0x00, 0x41, 0x1a, - 0x41, 0x1a, 0x10, 0x08, 0x41, 0x01, 0x47, 0x10, 0x07, 0x0b, 0x1b, 0x00, - 0x41, 0x25, 0x41, 0x00, 0x10, 0x06, 0x41, 0x1a, 0x41, 0x02, 0x10, 0x06, - 0x41, 0x25, 0x41, 0x01, 0x41, 0x02, 0x10, 0x09, 0x03, 0x40, 0x0c, 0x00, - 0x0b, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0b, 0x08, - 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x01, 0x0b, 0x06, 0x00, 0x20, 0x00, - 0x10, 0x02, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, - 0x03, 0x0b -}; + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x05, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, + 0x7f, 0x7f, 0x00, 0x60, 0x05, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x60, + 0x00, 0x00, 0x02, 0x60, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0d, 0x63, 0x68, + 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x00, + 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, + 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x11, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x64, + 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x13, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, + 0x70, 0x74, 0x00, 0x02, 0x03, 0x07, 0x06, 0x03, 0x04, 0x00, 0x00, 0x01, + 0x02, 0x04, 0x05, 0x01, 0x70, 0x01, 0x02, 0x02, 0x05, 0x03, 0x01, 0x00, + 0x01, 0x06, 0x13, 0x03, 0x7f, 0x01, 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, + 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, 0x41, 0x80, 0x10, 0x0b, 0x07, 0x2c, + 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x04, 0x6d, + 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x5f, 0x65, 0x6e, 0x64, 0x03, 0x01, 0x0b, 0x5f, 0x5f, 0x68, 0x65, 0x61, + 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x09, 0x07, 0x01, 0x00, + 0x41, 0x01, 0x0b, 0x01, 0x04, 0x0a, 0x4f, 0x06, 0x0d, 0x00, 0x41, 0x1a, + 0x41, 0x1a, 0x10, 0x08, 0x41, 0x01, 0x47, 0x10, 0x07, 0x0b, 0x1b, 0x00, + 0x41, 0x25, 0x41, 0x00, 0x10, 0x06, 0x41, 0x1a, 0x41, 0x02, 0x10, 0x06, + 0x41, 0x25, 0x41, 0x01, 0x41, 0x02, 0x10, 0x09, 0x03, 0x40, 0x0c, 0x00, + 0x0b, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0b, 0x08, + 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x01, 0x0b, 0x06, 0x00, 0x20, 0x00, + 0x10, 0x02, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, + 0x03, 0x0b}; unsigned int upload_wasm_len = 314; /* -*/ + */ From 0b2b3060f7dca32422064972abf558022970e029 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 20:08:39 +0200 Subject: [PATCH 073/249] bug fix: add missing header --- src/WARDuino/CallbackHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 968ec94b..1eb786e2 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -4,6 +4,7 @@ #include "../Debug/debugger.h" #include "../Interpreter/instructions.h" +#include "../RFC/SocketServer.h" #include "../Utils/macros.h" // CallbackHandler class From b74e065f4308e5e4cc2dbcc7e9628a328f5612a2 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 28 Apr 2022 20:14:27 +0200 Subject: [PATCH 074/249] bug fix: pushmode only for MCU --- src/Debug/debugger.cpp | 2 ++ src/WARDuino/CallbackHandler.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index fd072443..3d9e5227 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -173,7 +173,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptWOODDUMP: *program_state = WARDUINOpause; +#ifdef ARDUINO CallbackHandler::pushingMode = true; +#endif free(interruptData); woodDump(m); break; diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 1eb786e2..61246b9a 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -4,7 +4,9 @@ #include "../Debug/debugger.h" #include "../Interpreter/instructions.h" +#ifdef ARDUINO #include "../RFC/SocketServer.h" +#endif #include "../Utils/macros.h" // CallbackHandler class @@ -59,12 +61,15 @@ bool CallbackHandler::resolve_event() { // CallbackHandler::resolving_event = true; Event event = CallbackHandler::events->front(); + +#ifdef ARDUINO // check if we need to push events SocketServer *server = SocketServer::getServer(); if (CallbackHandler::pushingMode && !server->hasPushClient()) { - printf("recording and no push client\n"); + printf("pushingMode activated but client to push to\n"); return true; } +#endif CallbackHandler::events->pop(); printf("Resolving an event. (%lu remaining)\n", @@ -95,6 +100,7 @@ void Callback::resolve_event(const Event &e) { dbg_trace("Callback(%s, %i): resolving Event(%s, \"%s\")\n", topic.c_str(), table_index, e.topic.c_str(), e.payload); +#ifdef ARDUINO if (CallbackHandler::pushingMode) { SocketServer *server = SocketServer::getServer(); printf(R"({"topic":"%s","payload":"%s"})", e.topic.c_str(), @@ -104,6 +110,7 @@ void Callback::resolve_event(const Event &e) { e.topic.c_str(), e.payload); return; } +#endif // Copy topic and payload to linear memory uint32_t start = 10000; // TODO use reserved area in linear memory From 23d7ffc36e1819d49ef62b5aee6476149b75e4be Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 29 Apr 2022 10:23:20 +0200 Subject: [PATCH 075/249] Fix template cache --- .github/workflows/compile.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index c2604fd7..901cadf2 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -55,7 +55,7 @@ jobs: - name: Retrieve version id: version run: | - echo "::set-output name=COMMIT::$(sha1sum Arduino-socket.ino.template | grep '^[^ ]*' -o)" + echo "::set-output name=HASH::$(sha1sum Arduino-socket.ino.template | grep '^[^ ]*' -o)" working-directory: platforms/Arduino-socket - name: Cache filled out templates @@ -64,7 +64,7 @@ jobs: with: path: | platforms/Arduino-socket - key: ${{ env.INO_SOCKET_CACHE }}-${{ steps.version.outputs.COMMIT }} + key: ${{ env.INO_SOCKET_CACHE }}-${{ steps.version.outputs.HASH }} - name: Fill out Arduino-socket.ino.template if: steps.cache-ino.outputs.cache-hit != 'true' @@ -109,13 +109,19 @@ jobs: with: submodules: 'recursive' + - name: Retrieve version + id: version + run: | + echo "::set-output name=HASH::$(sha1sum Arduino-socket.ino.template | grep '^[^ ]*' -o)" + working-directory: platforms/Arduino-socket + - name: Get Template Cache id: cache-ino uses: actions/cache@v2 with: path: | platforms/Arduino-socket - key: ${{ env.INO_SOCKET_CACHE }}-${{ steps.version.outputs.COMMIT }} + key: ${{ env.INO_SOCKET_CACHE }}-${{ steps.version.outputs.HASH }} - name: Compile sketches uses: arduino/compile-sketches@v1 From 2a093be3344661536cc60032ce17fc14b970cebb Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Fri, 29 Apr 2022 10:52:56 +0200 Subject: [PATCH 076/249] bug fix: push event one single time --- src/WARDuino/CallbackHandler.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 61246b9a..a6226ff9 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -65,9 +65,20 @@ bool CallbackHandler::resolve_event() { #ifdef ARDUINO // check if we need to push events SocketServer *server = SocketServer::getServer(); - if (CallbackHandler::pushingMode && !server->hasPushClient()) { - printf("pushingMode activated but client to push to\n"); - return true; + if (CallbackHandler::pushingMode) { + if (!server->hasPushClient()) { + printf("pushingMode activated but no PushClient to push to\n"); + return true; + } else { + CallbackHandler::events->pop(); + SocketServer *server = SocketServer::getServer(); + printf(R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), + event.payload); + server->printf2Client(server->pushClient, + R"({"topic":"%s","payload":"%s"})", + event.topic.c_str(), event.payload); + return CallbackHandler::resolve_event(); + } } #endif CallbackHandler::events->pop(); @@ -100,18 +111,6 @@ void Callback::resolve_event(const Event &e) { dbg_trace("Callback(%s, %i): resolving Event(%s, \"%s\")\n", topic.c_str(), table_index, e.topic.c_str(), e.payload); -#ifdef ARDUINO - if (CallbackHandler::pushingMode) { - SocketServer *server = SocketServer::getServer(); - printf(R"({"topic":"%s","payload":"%s"})", e.topic.c_str(), - e.payload); // TODO remove - server->printf2Client(server->pushClient, - R"({"topic":"%s","payload":"%s"})", - e.topic.c_str(), e.payload); - return; - } -#endif - // Copy topic and payload to linear memory uint32_t start = 10000; // TODO use reserved area in linear memory std::string topic = e.topic; From 7fae5c977436757987fd361a5e6b6e3ce8a969a3 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Fri, 29 Apr 2022 10:53:22 +0200 Subject: [PATCH 077/249] disable starting in pause mode --- platforms/Arduino-socket/Arduino-socket.ino.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/Arduino-socket/Arduino-socket.ino.template b/platforms/Arduino-socket/Arduino-socket.ino.template index 391ce6dc..3bbbc522 100644 --- a/platforms/Arduino-socket/Arduino-socket.ino.template +++ b/platforms/Arduino-socket/Arduino-socket.ino.template @@ -78,8 +78,8 @@ void loop() { server->begin(); printf("LOADED \n\n"); - uint8_t command[] = {'0', '3', '\n'}; - wac.handleInterrupt(3, command); + // uint8_t command[] = {'0', '3', '\n'}; + // wac.handleInterrupt(3, command); xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); From d4e6e88f92e49f6926fad04ad20569b0d0b28e84 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 29 Apr 2022 11:12:34 +0200 Subject: [PATCH 078/249] Add event debug interrupts to enum --- src/Debug/debugger.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 2c3aacff..f0031141 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -17,6 +17,7 @@ enum RunningState { }; enum InterruptTypes { + // Remote Debugging interruptRUN = 0x01, interruptHALT = 0x02, interruptPAUSE = 0x03, @@ -28,11 +29,18 @@ enum InterruptTypes { interruptDUMPFull = 0x12, interruptUPDATEFun = 0x20, interruptUPDATELocal = 0x21, + + // WOOD Pull Debugging interruptWOODDUMP = 0x60, interruptOffset = 0x61, interruptRecvState = 0x62, interruptMonitorProxies = 0x63, - interruptProxyCall = 0x64 + interruptProxyCall = 0x64, + + // Push Debugging + interruptDUMPEvent = 0x65, + interruptPOPEvent = 0x66, + interruptPUSHEvent = 0x67 }; class Debugger { From b1a12879168ff5bfdcc2c2fa74ee43ad920e2c95 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 29 Apr 2022 15:53:29 +0200 Subject: [PATCH 079/249] Fix Makefile --- platforms/Arduino/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platforms/Arduino/Makefile b/platforms/Arduino/Makefile index d2003eef..bb35f086 100644 --- a/platforms/Arduino/Makefile +++ b/platforms/Arduino/Makefile @@ -4,11 +4,11 @@ PORT = /dev/ttyUSB0 FQBN = esp32:esp32:esp32wrover flash: - arduino-cli upload -p $(PORT) --fqbn $(FQBN) Arduino-socket.ino + arduino-cli upload -p $(PORT) --fqbn $(FQBN) Arduino.ino compile: - arduino-cli -v compile --fqbn $(FQBN) Arduino-socket.ino + arduino-cli -v compile --fqbn $(FQBN) Arduino.ino monitor: - arduino-cli monitor -p $(PORT) -c baudrate=115200 + arduino-cli monitor -p $(PORT) -c baudrate=115200 From b5eeeec1f5466384be685550169ba10b74232545 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 29 Apr 2022 17:57:17 +0200 Subject: [PATCH 080/249] Update Arduino ESP install instructions Increase version number CLI to 0.1.1 --- README.md | 2 +- documentation/InstallArduinoESP32.md | 45 ++++++++++++++++++++++++++++ platforms/CLI-Emulator/main.cpp | 3 +- src/Debug/debugger.h | 2 +- 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 documentation/InstallArduinoESP32.md diff --git a/README.md b/README.md index e8b5d9f9..cb8411b4 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ Second, create the config file: arduino-cli config init ``` -If you need additional boards, such as the esp32 boards, you can add them in the generated config file. More information [here](https://arduino.github.io/arduino-cli/0.21/getting-started/). +If you need additional boards, such as the esp32 boards, you can add them in the generated config file. More information on how to install the esp32 boards can be found here. Thirdly, make sure you install the `PubSubClient` and `Adafruit NeoPixel` library. (used for MQTT and pixel primitives) diff --git a/documentation/InstallArduinoESP32.md b/documentation/InstallArduinoESP32.md new file mode 100644 index 00000000..f0e15272 --- /dev/null +++ b/documentation/InstallArduinoESP32.md @@ -0,0 +1,45 @@ +# Install instructions for Arduino ESP32 + +To use ESP32 boards with the WARDuino project you need to install the correct board manager for ESP32. + +## Installing the board manager for ESP32 + +To use the ESP32 boards with `arduino-cli` perform the following steps: + +1. Init the config file, if you have not done so yet. + +``` +arduino-cli config init +``` + +2. To find the location of your config file you can run: + +``` +arduino-cli config dump --verbose +``` + +3. Add the ESP32 board manager URL to the config file: + +``` +board_manager: + additional_urls: + - https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json +``` + +4. Install the ESP32 platform: + +``` +arduino-cli core install esp32:esp32 +``` + +To use ESP32 boards with the WARDuino Project you need at least version 2.0.2 of the board manager. +you can check your version with: + +``` +arduino-cli core list +``` + +## Additional information + +More information on how to use `arduino-cli` can be found [here](https://arduino.github.io/arduino-cli/0.21/getting-started/). + diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index c4118d21..495cf7ca 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -3,7 +3,6 @@ // #include #include -#include #include #include @@ -32,7 +31,7 @@ } void print_help() { - fprintf(stdout, "WARDuino WebAssembly Runtime - 0.1.0\n\n"); + fprintf(stdout, "WARDuino WebAssembly Runtime - 0.1.1\n\n"); fprintf(stdout, "Usage:\n"); fprintf(stdout, " warduino [options] \n"); fprintf(stdout, "Options:\n"); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index f0031141..187b4f0c 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -94,7 +94,7 @@ class Debugger { // WOOD Private Methods - // receiving and dumping State + // Receiving and dumping State bool receivingData = false; void freeState(Module *m, uint8_t *interruptData); static uint8_t *findOpcode(Module *m, Block *block); From 8526a407590aa8e40ccede02a18133988ea73109 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 3 May 2022 14:51:23 +0200 Subject: [PATCH 081/249] Add nlohmann/json library --- .gitmodules | 3 +++ CMakeLists.txt | 18 +++++++++++------- lib/json | 1 + src/RFC/proxy_server.cpp | 4 +++- 4 files changed, 18 insertions(+), 8 deletions(-) create mode 160000 lib/json diff --git a/.gitmodules b/.gitmodules index db420bdd..c81691f9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "tests/sexpr-parser"] path = tests/integration/sexpr-parser url = git@github.com:benthepoet/c-sexpr-parser.git +[submodule "lib/json"] + path = lib/json + url = https://github.com/nlohmann/json diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dd8bb4f..aa2cea30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ if (BUILD_ESP) if (NOT EXISTS $ENV{IDF_PATH}/tools/cmake/project.cmake) message(FATAL_ERROR "Can't find $IDF_PATH/tools/cmake/project.cmake. Make sure ESP-IDF is installed and $IDF_PATH is set.") endif () - + message(VERBOSE "Using ESP-IDF toolchain") set(EXTRA_COMPONENT_DIRS "platforms/ESP-IDF") @@ -25,7 +25,10 @@ project(WARDuino) # Build the emulator version of WARDuino if (BUILD_EMULATOR) + set(EXTERNAL_LIB_HEADERS lib/json/single_include) + find_package(Threads REQUIRED) + set(SOURCE_FILES src/Memory/mem.cpp src/Utils/util.cpp @@ -40,11 +43,11 @@ if (BUILD_EMULATOR) src/RFC/proxy_server.cpp src/RFC/SocketServer.cpp src/Utils/sockets.cpp) + set(TEST_FRAMEWORK - tests/integration/wasm_tests.cpp - tests/integration/assertion.cpp - tests/integration/sexpr-parser/src/sexpr.c - ) + tests/integration/wasm_tests.cpp + tests/integration/assertion.cpp + tests/integration/sexpr-parser/src/sexpr.c) add_definitions(-DINFO=0) add_definitions(-DDEBUG=0) @@ -55,11 +58,12 @@ if (BUILD_EMULATOR) set(CMAKE_CXX_STANDARD 11) # Set default compile flags for GCC - if(CMAKE_COMPILER_IS_GNUCXX) + if (CMAKE_COMPILER_IS_GNUCXX) add_compile_options(-g -v -Wall -Wextra -Wunused) - endif(CMAKE_COMPILER_IS_GNUCXX) + endif (CMAKE_COMPILER_IS_GNUCXX) # WARDuino CLI add_executable(wdcli platforms/CLI-Emulator/main.cpp ${SOURCE_FILES} ${TEST_FRAMEWORK}) target_link_libraries(wdcli PRIVATE Threads::Threads) + target_include_directories(wdcli PRIVATE ${EXTERNAL_LIB_HEADERS}) endif (BUILD_EMULATOR) diff --git a/lib/json b/lib/json new file mode 160000 index 00000000..b205361d --- /dev/null +++ b/lib/json @@ -0,0 +1 @@ +Subproject commit b205361d8652759b6d850a37b227c8d57ee19005 diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 25fbca24..ca5e17d8 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "../Utils/macros.h" #include "../Utils/sockets.h" @@ -81,6 +82,7 @@ void *readSocket(void *input) { Event parseJSON(size_t len, uint8_t *buff) { // TODO parse JSON message + nlohmann::json parsed; } ProxyServer *ProxyServer::proxyServer = nullptr; @@ -227,4 +229,4 @@ char *ProxyServer::readReply(short int amount) { this->updateExcpMsg(READ_ERR); return nullptr; } -#endif \ No newline at end of file +#endif From 419dd23551fd34d7d4738041f2b1cf93df504f3e Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 3 May 2022 15:25:31 +0200 Subject: [PATCH 082/249] Make WARDuino a singleton --- .../Arduino-socket.ino.template | 14 +++++------ platforms/Arduino/Arduino.ino | 14 +++++------ platforms/CLI-Emulator/main.cpp | 16 ++++++------ platforms/ESP-IDF/main.cpp | 25 ++++++------------- src/WARDuino.h | 5 +++- src/WARDuino/WARDuino.cpp | 7 ++++++ 6 files changed, 40 insertions(+), 41 deletions(-) diff --git a/platforms/Arduino-socket/Arduino-socket.ino.template b/platforms/Arduino-socket/Arduino-socket.ino.template index 3bbbc522..290fb165 100644 --- a/platforms/Arduino-socket/Arduino-socket.ino.template +++ b/platforms/Arduino-socket/Arduino-socket.ino.template @@ -12,7 +12,7 @@ unsigned int wasm_len = upload_wasm_len; unsigned char* wasm = upload_wasm; -WARDuino wac; +WARDuino* wac = WARDuino::instance(); Module* m; SocketServer* server; @@ -25,7 +25,7 @@ uint16_t pushportno = 8081; void startDebuggerStd(void* pvParameter) { int valread; uint8_t buffer[1024] = {0}; - wac.debugger->socket = fileno(stdout); + wac->debugger->socket = fileno(stdout); write(fileno(stdout), "Got a message ... \n", 19); while (true) { // taskYIELD(); @@ -40,7 +40,7 @@ void startDebuggerStd(void* pvParameter) { if (buff_len) { write(fileno(stdout), "Reading message ..... \n", 19); fflush(stdout); - wac.handleInterrupt(valread - 1, buffer); + wac->handleInterrupt(valread - 1, buffer); write(fileno(stdout), buffer, valread); fflush(stdout); } @@ -49,7 +49,7 @@ void startDebuggerStd(void* pvParameter) { } void handleInterrupt(size_t len, uint8_t* buff) { - wac.handleInterrupt(len, buff); + wac->handleInterrupt(len, buff); } void setup(void) { @@ -74,7 +74,7 @@ void setup(void) { void loop() { disableCore0WDT(); - m = wac.load_module(wasm, wasm_len, {}); + m = wac->load_module(wasm, wasm_len, {}); server->begin(); printf("LOADED \n\n"); @@ -83,8 +83,8 @@ void loop() { xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); - wac.run_module(m); + wac->run_module(m); printf("END\n\n"); - wac.unload_module(m); + wac->unload_module(m); } diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index 919bee00..3dbcc474 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -15,7 +15,7 @@ unsigned int wasm_len = upload_wasm_len; unsigned char* wasm = upload_wasm; -WARDuino wac; +WARDuino* wac = WARDuino::instance(); Module* m; #define UART_PIN 3 @@ -23,7 +23,7 @@ Module* m; void startDebuggerStd(void* pvParameter) { int valread; uint8_t buffer[1024] = {0}; - wac.debugger->socket = fileno(stdout); + wac->debugger->socket = fileno(stdout); write(fileno(stdout), "Got a message ... \n", 19); while (true) { // taskYIELD(); @@ -38,7 +38,7 @@ void startDebuggerStd(void* pvParameter) { if (buff_len) { write(fileno(stdout), "Reading message ..... \n", 19); fflush(stdout); - wac.handleInterrupt(valread - 1, buffer); + wac->handleInterrupt(valread - 1, buffer); write(fileno(stdout), buffer, valread); fflush(stdout); } @@ -63,18 +63,18 @@ void setup(void) { void loop() { disableCore0WDT(); - m = wac.load_module(wasm, wasm_len, {}); + m = wac->load_module(wasm, wasm_len, {}); printf("LOADED \n\n"); uint8_t command[] = {'0', '3', '\n'}; - wac.handleInterrupt(3, command); + wac->handleInterrupt(3, command); xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); Serial.println("\nFree heap:"); Serial.println(ESP.getFreeHeap()); - wac.run_module(m); + wac->run_module(m); printf("END\n\n"); - wac.unload_module(m); + wac->unload_module(m); } diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 495cf7ca..7a21b0aa 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -131,14 +131,14 @@ void startDebuggerSocket(WARDuino *wac, Module *m) { } } -WARDuino wac; +WARDuino *wac = WARDuino::instance(); Module *m; void *runWAC(void *p) { // Print value received as argument: dbg_info("\n=== STARTED INTERPRETATION (in separate thread) ===\n"); - wac.run_module(m); - wac.unload_module(m); + wac->run_module(m); + wac->unload_module(m); } int main(int argc, const char *argv[]) { @@ -185,10 +185,10 @@ int main(int argc, const char *argv[]) { if (argc == 0 && file_name != nullptr) { if (run_tests) { dbg_info("=== STARTING SPEC TESTS ===\n"); - return run_wasm_test(wac, file_name, asserts_file, watcompiler); + return run_wasm_test(*wac, file_name, asserts_file, watcompiler); } dbg_info("=== LOAD MODULE INTO WARDUINO ===\n"); - m = load(wac, file_name, + m = load(*wac, file_name, {.disable_memory_bounds = false, .mangle_table_index = false, .dlsym_trim_underscore = false, @@ -202,12 +202,12 @@ int main(int argc, const char *argv[]) { pthread_t id; uint8_t command[] = {'0', '3', '\n'}; // wac.handleInterrupt(3, command); - m->warduino = &wac; + m->warduino = wac; pthread_create(&id, nullptr, runWAC, nullptr); if (no_socket) { - startDebuggerStd(&wac, m); + startDebuggerStd(wac, m); } else { - startDebuggerSocket(&wac, m); + startDebuggerSocket(wac, m); } int *ptr; pthread_join(id, (void **)&ptr); diff --git a/platforms/ESP-IDF/main.cpp b/platforms/ESP-IDF/main.cpp index bbbed898..999d1156 100644 --- a/platforms/ESP-IDF/main.cpp +++ b/platforms/ESP-IDF/main.cpp @@ -2,8 +2,6 @@ // WARDuino - WebAssembly interpreter for embedded devices. // // -//#include - #include #include "../../src/WARDuino.h" @@ -45,20 +43,20 @@ extern "C" { extern void app_main(void); } -WARDuino wac; +WARDuino* wac = WARDuino::instance(); Module* m; void startDebuggerStd(void* pvParameter) { int valread; uint8_t buffer[1024] = {0}; - wac.debugger->socket = fileno(stdout); + wac->debugger->socket = fileno(stdout); while (true) { taskYIELD(); vTaskDelay(1000 / portTICK_PERIOD_MS); while ((valread = read(fileno(stdin), buffer, 1024)) != -1) { write(fileno(stdout), "got a message ... \n", 19); - wac.handleInterrupt(valread - 1, buffer); + wac->handleInterrupt(valread - 1, buffer); write(fileno(stdout), buffer, valread); fflush(stdout); } @@ -66,21 +64,12 @@ void startDebuggerStd(void* pvParameter) { } void app_main(void) { - m = wac.load_module(wasm, wasm_len, {}); + m = wac->load_module(wasm, wasm_len, {}); uint8_t command[] = {'0', '3', '\n'}; - wac.handleInterrupt(3, command); + wac->handleInterrupt(3, command); xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); - wac.run_module(m); + wac->run_module(m); printf("END\n\n"); - wac.unload_module(m); + wac->unload_module(m); } - -/*void app_main(void) { - m = wac.load_module(wasm, wasm_len, {}); - printf("START\n\n"); - //wac.run_module(m); - //printf("END\n\n"); - //wac.unload_module(m); - while(true); -}*/ diff --git a/src/WARDuino.h b/src/WARDuino.h index 3f0b39dc..81604439 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -180,12 +180,15 @@ typedef struct PrimitiveEntry { class WARDuino { private: + static WARDuino *singleton; std::vector modules = {}; + WARDuino(); + public: Debugger *debugger; - WARDuino(); + static WARDuino *instance(); int run_module(Module *m); diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index d0863a71..f5f10a53 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -941,3 +941,10 @@ int WARDuino::run_module(Module *m) { void WARDuino::handleInterrupt(size_t len, uint8_t *buff) { this->debugger->addDebugMessage(len, buff); } + +WARDuino *WARDuino::singleton = nullptr; + +WARDuino *WARDuino::instance() { + if (singleton == nullptr) singleton = new WARDuino(); + return singleton; +} From 745f301b35d51d63f5f61055089c9dc53a4e06e2 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 3 May 2022 15:33:23 +0200 Subject: [PATCH 083/249] Parse event json --- src/RFC/proxy_server.cpp | 14 ++++++++------ src/WARDuino/CallbackHandler.cpp | 7 +++++++ src/WARDuino/CallbackHandler.h | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index ca5e17d8..0d873658 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -80,9 +80,11 @@ void *readSocket(void *input) { ProxyServer::startPushDebuggerSocket(*((struct Socket *)input)); } -Event parseJSON(size_t len, uint8_t *buff) { - // TODO parse JSON message - nlohmann::json parsed; +Event *parseJSON(size_t len, char *buff) { + auto parsed = nlohmann::json::parse(buff); + dbg_info("%s\n", parsed.dump()); + std::string payload = parsed["payload"]; + return new Event(parsed["topic"], payload.c_str()); } ProxyServer *ProxyServer::proxyServer = nullptr; @@ -138,13 +140,13 @@ void ProxyServer::startPushDebuggerSocket(struct Socket arg) { startListening(arg.fileDescriptor); int valread; - uint8_t buffer[1024] = {0}; + char buffer[1024] = {0}; while (continuing(arg.mutex)) { int socket = listenForIncomingConnection(arg.fileDescriptor, _address); while ((valread = read(socket, buffer, 1024)) != -1) { write(socket, "got a push message ... \n", 24); - Event event = parseJSON(valread - 1, buffer); - // TODO sent event to CallbackHandler + Event *event = parseJSON(valread - 1, buffer); + CallbackHandler::push_event(event); } } } diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index a6226ff9..c263fddf 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -54,6 +54,13 @@ void CallbackHandler::push_event(std::string topic, } } +void CallbackHandler::push_event(Event *event) { + if (events->size() < EVENTS_SIZE) { + dbg_info("Push Event(%s, %s)\n", event->topic.c_str(), event->payload); + events->push(*event); + } +} + bool CallbackHandler::resolve_event() { if (CallbackHandler::events->empty()) { return false; diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index e06aa762..d557ae24 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -25,6 +25,7 @@ class CallbackHandler { static void remove_callback(const Callback &c); static void push_event(std::string topic, const unsigned char *payload, unsigned int length); + static void push_event(Event *event); static bool resolve_event(); // WOOD needed to know when to push events From 2da13e10015d14859572282efd955a9f1b790c8c Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 4 May 2022 11:51:33 +0200 Subject: [PATCH 084/249] Add interruptDronify to enum --- src/Debug/debugger.cpp | 3 +++ src/Debug/debugger.h | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 3d9e5227..9d265f70 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -215,6 +215,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { free(interruptData); } break; #endif + case interruptDronify: + // TODO Dronify + break; default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 187b4f0c..a1da1ecb 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -36,11 +36,12 @@ enum InterruptTypes { interruptRecvState = 0x62, interruptMonitorProxies = 0x63, interruptProxyCall = 0x64, + interruptDronify = 0x65, // Push Debugging - interruptDUMPEvent = 0x65, - interruptPOPEvent = 0x66, - interruptPUSHEvent = 0x67 + interruptDUMPEvent = 0x70, + interruptPOPEvent = 0x71, + interruptPUSHEvent = 0x72 }; class Debugger { From 4cab2a8d16f42182e9b9dfe2473c23f1038eefdf Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 4 May 2022 13:54:07 +0200 Subject: [PATCH 085/249] bug fix: push client uses push port --- src/RFC/proxy_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 0d873658..90b8a380 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -175,7 +175,7 @@ pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { } // Connect to push socket - msg = createConnection(push_socket, this->host, this->pull_port, + msg = createConnection(push_socket, this->host, this->push_port, this->address); if (!is_success(msg)) { this->updateExcpMsg(msg); // TODO differentiate between ports From 9e9e84c2823c016f4d47351e54b5f3417ad17697 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 4 May 2022 14:32:59 +0200 Subject: [PATCH 086/249] use seperate adress struct for pushclient --- src/RFC/proxy_server.cpp | 3 ++- src/RFC/proxy_server.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 90b8a380..cb317125 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -132,6 +132,7 @@ ProxyServer::ProxyServer() { pull_socket = -1; push_socket = -1; address = (struct Address *)malloc(sizeof(struct Address)); + addressPush = (struct Address *)malloc(sizeof(struct Address)); } void ProxyServer::startPushDebuggerSocket(struct Socket arg) { @@ -176,7 +177,7 @@ pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { // Connect to push socket msg = createConnection(push_socket, this->host, this->push_port, - this->address); + this->addressPush); if (!is_success(msg)) { this->updateExcpMsg(msg); // TODO differentiate between ports FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h index 1cff1b11..ea677563 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_server.h @@ -17,6 +17,7 @@ class ProxyServer { int pull_port, push_port, pull_socket, push_socket; struct Address *address; + struct Address *addressPush; // private constructor for singleton ProxyServer(); From 52d640e6f7bf695237f211a4490f829394e2b28d Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 4 May 2022 14:43:36 +0200 Subject: [PATCH 087/249] Add Event interrupts Restore CallbackHandler::resolving_event Bump EVENTS_SIZE to 10 --- documentation/PushDebugging.md | 22 +++++++++----- src/Debug/debugger.cpp | 49 ++++++++++++++++++++++++++++++++ src/Debug/debugger.h | 11 +++++-- src/Interpreter/instructions.cpp | 9 +++--- src/WARDuino.h | 4 +-- src/WARDuino/CallbackHandler.cpp | 26 ++++++++++++----- src/WARDuino/CallbackHandler.h | 8 ++++-- src/WARDuino/WARDuino.cpp | 4 +-- 8 files changed, 105 insertions(+), 28 deletions(-) diff --git a/documentation/PushDebugging.md b/documentation/PushDebugging.md index b9be97aa..38a1d998 100644 --- a/documentation/PushDebugging.md +++ b/documentation/PushDebugging.md @@ -4,23 +4,31 @@ Aside from traditional remote debugging, the WARDuino virtual machine also suppo ## Pull Debugging -With pull debugging the current application is debugged in a local emulated WARDuino instance, but with live actuator and sensor values from a drone device. -To get current values, the emulated debugger initiates proxy calls to the drone device. -The debugger will wait until this call has completed and the result is returned by the drone. +With pull debugging the current application is debugged in a local emulated WARDuino instance, but with live actuator +and sensor values from a drone device. To get current values, the emulated debugger initiates proxy calls to the drone +device. The debugger will wait until this call has completed and the result is returned by the drone. Communication happens through a minimal byte format. ## Push Debugging -A drone device can also push live values to the emulated debugger. -These will typically be asynchronous events such as hardware interrupts, exceptions, ... +A drone device can also push live values to the emulated debugger. These will typically be asynchronous events such as +hardware interrupts, exceptions, ... Those are represented by `Events` in WARDuino and send by the drone device as simple json: ```json { - "topic":"topic string", - "payload":"payload as a string" + "topic": "topic string", + "payload": "payload as a string" } ``` +The supported interrupt messages: + +1. `interruptDUMPAllEvents (0x70)` dumps all events. +2. `interruptDUMPEvents (0x71)` this message' code is followed by two bytes, `a` and `b`. The command dumps at most `b` + events, starting in the event queue from index `a`. +3. `interruptPOPEvent (0x72)` tells the VM to remove the event at the front of the queue and process it. +4. `interruptPUSHEvent (0x73)` this messages' code is followed by a json representation of an event to be pushed on the + stack. diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 9d265f70..0cd1c8f1 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -9,6 +9,7 @@ #include "../RFC/rfc.h" #include "../Utils//util.h" #include "../Utils/macros.h" +#include "nlohmann/json.hpp" // Debugger @@ -119,6 +120,8 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } dprintf(this->socket, "Interrupt: %x\n", *interruptData); + + long start = 0, size = 0; switch (*interruptData) { case interruptRUN: this->handleInterruptRUN(m, program_state); @@ -218,6 +221,19 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { case interruptDronify: // TODO Dronify break; + case interruptDUMPAllEvents: + printf("InterruptDUMPEvents\n"); + size = (long)CallbackHandler::event_count(); + case interruptDUMPEvents: + // TODO get start and size from message + this->dumpEvents(start, size); + break; + case interruptPOPEvent: + CallbackHandler::resolve_event(); + break; + case interruptPUSHEvent: + this->handlePushedEvent(m, interruptData); + break; default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); @@ -408,6 +424,30 @@ void Debugger::dumpLocals(Module *m) const { // fflush(stdout); } +void Debugger::dumpEvents(long start, long size) { + CallbackHandler::resolving_event = true; + if (size > EVENTS_SIZE) { + size = EVENTS_SIZE; + } + dbg_info("Printing event queue (%lu, %lu) ...\n", start, size); + + dprintf(this->socket, R"({"events": [)"); + long index = start, end = start + size; + std::for_each(CallbackHandler::event_begin() + start, + CallbackHandler::event_begin() + end, + [this, &index, &end](const Event &e) { + dprintf(this->socket, + R"({"topic": "%s", "payload": "%s"})", + e.topic.c_str(), e.payload); + if (++index < end) { + dprintf(this->socket, ", "); + } + }); + dprintf(this->socket, "]}"); + + CallbackHandler::resolving_event = false; +} + /** * Read the change in bytes array. * @@ -499,6 +539,15 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { dprintf(this->socket, "Local %u changed to %u\n", localId, v->value.uint32); return true; } + +bool Debugger::handlePushedEvent(Module *m, uint8_t *bytes) const { + if (*bytes != interruptPUSHEvent) return false; + auto parsed = nlohmann::json::parse(bytes); + std::string payload = parsed["payload"]; + CallbackHandler::push_event(new Event(parsed["topic"], payload.c_str())); + return true; +} + void Debugger::woodDump(Module *m) { debug("asked for doDump\n"); printf("asked for woodDump\n"); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index a1da1ecb..f547069e 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -39,9 +39,10 @@ enum InterruptTypes { interruptDronify = 0x65, // Push Debugging - interruptDUMPEvent = 0x70, - interruptPOPEvent = 0x71, - interruptPUSHEvent = 0x72 + interruptDUMPAllEvents = 0x70, + interruptDUMPEvents = 0x71, + interruptPOPEvent = 0x72, + interruptPUSHEvent = 0x73 }; class Debugger { @@ -87,12 +88,16 @@ class Debugger { void dumpCallstack(Module *m) const; + void dumpEvents(long start, long size); + //// Handle live code update static bool handleChangedFunction(Module *m, uint8_t *bytes); bool handleChangedLocal(Module *m, uint8_t *bytes) const; + bool handlePushedEvent(Module *m, uint8_t *bytes) const; + // WOOD Private Methods // Receiving and dumping State diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index dcda415a..e2eb3507 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1550,9 +1550,9 @@ bool interpret(Module *m) { // Resolve 1 callback event if queue is not empty and no event // currently resolving - // if (!CallbackHandler::resolving_event) { - CallbackHandler::resolve_event(); - // } + if (!CallbackHandler::resolving_event) { + CallbackHandler::resolve_event(); + } // if BP and not the one we just unpaused if (m->warduino->debugger->isBreakpoint(m->pc_ptr) && @@ -1765,8 +1765,7 @@ bool interpret(Module *m) { } // Resolve all unhandled callback events - while (/*!CallbackHandler::resolving_event &&*/ - CallbackHandler::resolve_event()) + while (CallbackHandler::resolving_event && CallbackHandler::resolve_event()) ; dbg_trace("Interpretation ended %s with status %s\n", diff --git a/src/WARDuino.h b/src/WARDuino.h index 81604439..ed0de89f 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -32,7 +32,7 @@ #define FUNC 0x60 // -0x20 #define BLOCK 0x40 // -0x40 -#define EVENTS_SIZE 1 +#define EVENTS_SIZE 10 #define KIND_FUNCTION 0 #define KIND_TABLE 1 @@ -200,5 +200,5 @@ class WARDuino { uint32_t get_export_fidx(Module *m, const char *name); - void handleInterrupt(size_t len, uint8_t *buff); + void handleInterrupt(size_t len, uint8_t *buff) const; }; diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index c263fddf..f9abdbe9 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -12,12 +12,12 @@ // CallbackHandler class bool CallbackHandler::pushingMode = false; +bool CallbackHandler::resolving_event = false; -// bool CallbackHandler::resolving_event = false; std::unordered_map *> *CallbackHandler::callbacks = new std::unordered_map *>(); -std::queue *CallbackHandler::events = new std::queue(); +std::deque *CallbackHandler::events = new std::deque(); void CallbackHandler::add_callback(const Callback &c) { auto item = callbacks->find(c.topic); @@ -50,14 +50,14 @@ void CallbackHandler::push_event(std::string topic, auto e = new Event(std::move(topic), reinterpret_cast(message)); dbg_info("Push Event(%s, %s)\n", e->topic.c_str(), e->payload); - events->push(*e); + events->push_back(*e); } } void CallbackHandler::push_event(Event *event) { if (events->size() < EVENTS_SIZE) { dbg_info("Push Event(%s, %s)\n", event->topic.c_str(), event->payload); - events->push(*event); + events->push_back(*event); } } @@ -65,7 +65,7 @@ bool CallbackHandler::resolve_event() { if (CallbackHandler::events->empty()) { return false; } - // CallbackHandler::resolving_event = true; + CallbackHandler::resolving_event = true; Event event = CallbackHandler::events->front(); @@ -88,7 +88,7 @@ bool CallbackHandler::resolve_event() { } } #endif - CallbackHandler::events->pop(); + CallbackHandler::events->pop_front(); printf("Resolving an event. (%lu remaining)\n", CallbackHandler::events->size()); @@ -102,10 +102,22 @@ bool CallbackHandler::resolve_event() { } else { // TODO handle error: event for non-existing iterator } - // CallbackHandler::resolving_event = false; + CallbackHandler::resolving_event = false; return !CallbackHandler::events->empty(); } +size_t CallbackHandler::event_count() { + return CallbackHandler::events->size(); +} + +std::deque::const_iterator CallbackHandler::event_begin() { + return CallbackHandler::events->cbegin(); +} + +std::deque::const_iterator CallbackHandler::event_end() { + return CallbackHandler::events->cend(); +} + // Callback class Callback::Callback(Module *m, std::string id, uint32_t tidx) { diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index d557ae24..c075a299 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -14,12 +14,16 @@ class Event; class CallbackHandler { private: static std::unordered_map *> *callbacks; - static std::queue *events; + static std::deque *events; CallbackHandler() = default; // Disallow creation public: - // static bool resolving_event; + static size_t event_count(); + static std::deque::const_iterator event_begin(); + static std::deque::const_iterator event_end(); + + static bool resolving_event; static void add_callback(const Callback &c); static void remove_callback(const Callback &c); diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index f5f10a53..1a4a1f2c 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -507,7 +507,7 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, { ASSERT(!m->table.entries, "More than 1 table not supported\n"); - Table *tval = (Table *)val; + auto *tval = (Table *)val; m->table.entries = (uint32_t *)val; ASSERT(m->table.initial <= tval->maximum, "Imported table is not large enough\n"); @@ -938,7 +938,7 @@ int WARDuino::run_module(Module *m) { // ntly the same function) // parse numer per 2 chars (HEX) (stop if non-hex) // Don't use print in interrupt handlers -void WARDuino::handleInterrupt(size_t len, uint8_t *buff) { +void WARDuino::handleInterrupt(size_t len, uint8_t *buff) const { this->debugger->addDebugMessage(len, buff); } From 21b5708ff91968f7c46cc1690d9c2017547fdaa7 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Wed, 4 May 2022 15:44:53 +0200 Subject: [PATCH 088/249] Quickfix Arduino compilation Disables `interruptPUSHEvent` on Arduino --- src/Debug/debugger.cpp | 8 +++++++- src/RFC/proxy_server.cpp | 1 + src/WARDuino/CallbackHandler.cpp | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 0cd1c8f1..dbd2f651 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -3,13 +3,15 @@ #include #include #include +#ifndef ARDUINO +#include +#endif #include "../Memory/mem.h" #include "../RFC/proxy_server.h" #include "../RFC/rfc.h" #include "../Utils//util.h" #include "../Utils/macros.h" -#include "nlohmann/json.hpp" // Debugger @@ -231,9 +233,11 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { case interruptPOPEvent: CallbackHandler::resolve_event(); break; +#ifndef ARDUINO case interruptPUSHEvent: this->handlePushedEvent(m, interruptData); break; +#endif default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); @@ -540,6 +544,7 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { return true; } +#ifndef ARDUINO bool Debugger::handlePushedEvent(Module *m, uint8_t *bytes) const { if (*bytes != interruptPUSHEvent) return false; auto parsed = nlohmann::json::parse(bytes); @@ -547,6 +552,7 @@ bool Debugger::handlePushedEvent(Module *m, uint8_t *bytes) const { CallbackHandler::push_event(new Event(parsed["topic"], payload.c_str())); return true; } +#endif void Debugger::woodDump(Module *m) { debug("asked for doDump\n"); diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index cb317125..4df759dc 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -81,6 +81,7 @@ void *readSocket(void *input) { } Event *parseJSON(size_t len, char *buff) { + // TODO duplicate code in Debugger::handlePushedEvent auto parsed = nlohmann::json::parse(buff); dbg_info("%s\n", parsed.dump()); std::string payload = parsed["payload"]; diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index f9abdbe9..ed07f1a7 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -77,7 +77,7 @@ bool CallbackHandler::resolve_event() { printf("pushingMode activated but no PushClient to push to\n"); return true; } else { - CallbackHandler::events->pop(); + CallbackHandler::events->pop_front(); SocketServer *server = SocketServer::getServer(); printf(R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), event.payload); From a127c08c82604512acf24b1d5106c60fa6fb5774 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 4 May 2022 17:00:19 +0200 Subject: [PATCH 089/249] bug fix: no longer starts a socketserver --- src/RFC/proxy_server.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 4df759dc..a3a9b730 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -33,6 +33,7 @@ struct Address { struct Socket { int port; int fileDescriptor; + struct sockaddr_in adress; pthread_mutex_t *mutex; }; @@ -137,16 +138,11 @@ ProxyServer::ProxyServer() { } void ProxyServer::startPushDebuggerSocket(struct Socket arg) { - struct sockaddr_in _address = createAddress(arg.port); - bindSocketToAddress(arg.fileDescriptor, _address); - startListening(arg.fileDescriptor); - + int socket = arg.fileDescriptor; int valread; char buffer[1024] = {0}; while (continuing(arg.mutex)) { - int socket = listenForIncomingConnection(arg.fileDescriptor, _address); while ((valread = read(socket, buffer, 1024)) != -1) { - write(socket, "got a push message ... \n", 24); Event *event = parseJSON(valread - 1, buffer); CallbackHandler::push_event(event); } @@ -190,9 +186,10 @@ pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { args->port = this->push_port; args->fileDescriptor = this->push_socket; args->mutex = mutex; + args->adress = this->addressPush->aserv_addr; + pthread_create(&id, nullptr, readSocket, &args); - printf("connected"); return id; } From 3bb3b1fe23457e0856384b942926e8497b8f3fd6 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 4 May 2022 17:38:01 +0200 Subject: [PATCH 090/249] OSX compilation issue fix: removed Event forward reference --- src/WARDuino/CallbackHandler.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index c075a299..4255a1e2 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -9,7 +9,13 @@ struct Module; class Callback; -class Event; +class Event { + public: + std::string topic; + const char *payload; + + Event(std::string topic, const char *payload); +}; class CallbackHandler { private: @@ -36,14 +42,6 @@ class CallbackHandler { static bool pushingMode; }; -class Event { - public: - std::string topic; - const char *payload; - - Event(std::string topic, const char *payload); -}; - class Callback { private: Module *module; // reference to module From 3b34faed5e3c4b5e4f9f29711a906a9e2a345ede Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 4 May 2022 19:04:58 +0200 Subject: [PATCH 091/249] changed parameter to be a pointer --- src/RFC/proxy_server.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h index ea677563..5dd372d8 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_server.h @@ -25,7 +25,7 @@ class ProxyServer { public: char *exceptionMsg; - static void startPushDebuggerSocket(struct Socket arg); + static void startPushDebuggerSocket(struct Socket *arg); void registerAddresses(char *_host, int _pull_port, int _push_port); void closeConnections(); From 38ebdfbedb132e55058c19a8e863392821feeb40 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 4 May 2022 19:10:26 +0200 Subject: [PATCH 092/249] bug fix: disable mutex + remove & --- src/RFC/proxy_server.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index a3a9b730..51679f3a 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -78,7 +78,7 @@ bool continuing(pthread_mutex_t *mutex) { void *readSocket(void *input) { // Print value received as argument: dbg_info("\n=== LISTENING TO SOCKET (in separate thread) ===\n"); - ProxyServer::startPushDebuggerSocket(*((struct Socket *)input)); + ProxyServer::startPushDebuggerSocket((struct Socket *)input); } Event *parseJSON(size_t len, char *buff) { @@ -137,12 +137,14 @@ ProxyServer::ProxyServer() { addressPush = (struct Address *)malloc(sizeof(struct Address)); } -void ProxyServer::startPushDebuggerSocket(struct Socket arg) { - int socket = arg.fileDescriptor; +void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { + int socket = arg->fileDescriptor; int valread; char buffer[1024] = {0}; - while (continuing(arg.mutex)) { - while ((valread = read(socket, buffer, 1024)) != -1) { + // TODO add continuing(arg.mutex) + while (true) { + valread = read(6, buffer, 1024); + if (valread != -1) { Event *event = parseJSON(valread - 1, buffer); CallbackHandler::push_event(event); } @@ -150,7 +152,6 @@ void ProxyServer::startPushDebuggerSocket(struct Socket arg) { } pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { - printf("connecting"); if (this->host == nullptr) { this->updateExcpMsg(NO_HOST_ERR); FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); @@ -188,7 +189,7 @@ pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { args->mutex = mutex; args->adress = this->addressPush->aserv_addr; - pthread_create(&id, nullptr, readSocket, &args); + pthread_create(&id, nullptr, readSocket, args); return id; } From 61eadbda24b626a1a4d23a6b176b84575e28bc7f Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 4 May 2022 20:03:07 +0200 Subject: [PATCH 093/249] bug fix: removed hardcoded socket descriptor --- src/RFC/proxy_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 51679f3a..c039561c 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -143,7 +143,7 @@ void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { char buffer[1024] = {0}; // TODO add continuing(arg.mutex) while (true) { - valread = read(6, buffer, 1024); + valread = read(socket, buffer, 1024); if (valread != -1) { Event *event = parseJSON(valread - 1, buffer); CallbackHandler::push_event(event); From 61e9dc8c0558fb084a4c0b33b8c595d81fd2a44b Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 5 May 2022 08:57:28 +0200 Subject: [PATCH 094/249] Restore mutex --- src/RFC/proxy_server.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index c039561c..dc13633d 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -141,8 +141,7 @@ void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { int socket = arg->fileDescriptor; int valread; char buffer[1024] = {0}; - // TODO add continuing(arg.mutex) - while (true) { + while (continuing(arg->mutex)) { valread = read(socket, buffer, 1024); if (valread != -1) { Event *event = parseJSON(valread - 1, buffer); From a874ef1277d0c9843efa20a6f6285ded9e0a7ea1 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Thu, 5 May 2022 10:47:59 +0200 Subject: [PATCH 095/249] Fix `continuing` function for mutex lock --- src/RFC/proxy_server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index dc13633d..d5af038f 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -67,9 +67,9 @@ bool continuing(pthread_mutex_t *mutex) { switch (pthread_mutex_trylock(mutex)) { case 0: /* if we got the lock, unlock and return true */ pthread_mutex_unlock(mutex); - return true; - case EBUSY: /* return false if the mutex was locked */ return false; + case EBUSY: /* return false if the mutex was locked */ + return true; default: return true; } From ed07248e6307ed161b04ea0971ec317b1318570c Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 11:52:32 +0200 Subject: [PATCH 096/249] bug fix: resolving_event set to false once done --- src/WARDuino/CallbackHandler.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index ed07f1a7..8187cebb 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -58,6 +58,7 @@ void CallbackHandler::push_event(Event *event) { if (events->size() < EVENTS_SIZE) { dbg_info("Push Event(%s, %s)\n", event->topic.c_str(), event->payload); events->push_back(*event); + printf("new events size %lu\n", events->size()); // TODO remove } } @@ -79,12 +80,13 @@ bool CallbackHandler::resolve_event() { } else { CallbackHandler::events->pop_front(); SocketServer *server = SocketServer::getServer(); - printf(R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), - event.payload); + printf(R"({"topic":"%s","payload":"%s"}\n)", event.topic.c_str(), + event.payload); // TODO remove server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), event.payload); - return CallbackHandler::resolve_event(); + CallbackHandler::resolving_event = false; + return !CallbackHandler::events->empty(); } } #endif From e18f3af2a6f5539d30bee8a93d93401d7d72dfda Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 15:21:09 +0200 Subject: [PATCH 097/249] bug fix: resolving_event disabled for pushmode --- src/WARDuino/CallbackHandler.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 8187cebb..71fcd804 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -66,8 +66,6 @@ bool CallbackHandler::resolve_event() { if (CallbackHandler::events->empty()) { return false; } - CallbackHandler::resolving_event = true; - Event event = CallbackHandler::events->front(); #ifdef ARDUINO @@ -85,11 +83,12 @@ bool CallbackHandler::resolve_event() { server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), event.payload); - CallbackHandler::resolving_event = false; return !CallbackHandler::events->empty(); } } #endif + + CallbackHandler::resolving_event = true; CallbackHandler::events->pop_front(); printf("Resolving an event. (%lu remaining)\n", From 6860bb9b9383f885b6c04e21034d1ae2d5288254 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 15:22:02 +0200 Subject: [PATCH 098/249] bug fix: pushing events despite of paused VM --- src/Interpreter/instructions.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index e2eb3507..2368ddb4 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1543,6 +1543,9 @@ bool interpret(Module *m) { #endif if (program_state == WARDUINOpause) { + if (CallbackHandler::pushingMode) { + CallbackHandler::resolve_event(); + } continue; } From 7191fe928a2fe69ba75aad85a944bd1094c6fb94 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 16:05:27 +0200 Subject: [PATCH 099/249] delete unneeded printf --- src/WARDuino/CallbackHandler.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 71fcd804..b43a3c13 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -73,12 +73,11 @@ bool CallbackHandler::resolve_event() { SocketServer *server = SocketServer::getServer(); if (CallbackHandler::pushingMode) { if (!server->hasPushClient()) { - printf("pushingMode activated but no PushClient to push to\n"); return true; } else { CallbackHandler::events->pop_front(); SocketServer *server = SocketServer::getServer(); - printf(R"({"topic":"%s","payload":"%s"}\n)", event.topic.c_str(), + printf(R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), event.payload); // TODO remove server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", From 6c3f47493e49c8c20eff49d1be4c3cb0a14f5da0 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 16:06:38 +0200 Subject: [PATCH 100/249] add interrupt to toggle event push mode --- src/Debug/debugger.cpp | 8 +++++++- src/Debug/debugger.h | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index dbd2f651..298e4bea 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -233,7 +233,13 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { case interruptPOPEvent: CallbackHandler::resolve_event(); break; -#ifndef ARDUINO +#ifdef ARDUINO + case interruptTOGGLEPushingMode: + CallbackHandler::pushingMode = !CallbackHandler::pushingMode; + printf(R"({"pushingMode": %s})", + CallbackHandler::pushingMode ? "true" : "false"); + break; +#else case interruptPUSHEvent: this->handlePushedEvent(m, interruptData); break; diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index f547069e..0af3f3db 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -42,7 +42,8 @@ enum InterruptTypes { interruptDUMPAllEvents = 0x70, interruptDUMPEvents = 0x71, interruptPOPEvent = 0x72, - interruptPUSHEvent = 0x73 + interruptPUSHEvent = 0x73, + interruptTOGGLEPushingMode = 0x74 }; class Debugger { From b6544d1de3d151f9a1b661430941e29773799883 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 16:09:33 +0200 Subject: [PATCH 101/249] increase emulator's event buffer size --- src/WARDuino.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/WARDuino.h b/src/WARDuino.h index ed0de89f..e5156bbe 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -32,8 +32,11 @@ #define FUNC 0x60 // -0x20 #define BLOCK 0x40 // -0x40 +#ifdef ARDUINO #define EVENTS_SIZE 10 - +#else +#define EVENTS_SIZE 50 +#endif #define KIND_FUNCTION 0 #define KIND_TABLE 1 #define KIND_MEMORY 2 From 82ded9d68fe05f7015e1fc480766f3f8e2fa81c4 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 17:04:47 +0200 Subject: [PATCH 102/249] Enalbe the update of the proxy list more than once The `interruptMonitorProxies` can now be called more than once for the same MCU host and this solely to update the proxy list. No new connection to the host is triggered. Triggering the same interrupt with a different host and/or port will cause the emulator to first close the existing socket connections. --- src/Debug/debugger.cpp | 15 ++++++++------- src/RFC/proxy_server.cpp | 14 +++++++++----- src/RFC/proxy_server.h | 4 ++-- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 298e4bea..adc5749e 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -951,14 +951,15 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, } #else void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { - this->connected_to_drone = true; - pthread_mutex_init(&this->push_mutex, nullptr); - pthread_mutex_lock(&this->push_mutex); - RFC::registerRFCs(m, &interruptData); - ProxyServer::registerMCUHost(&interruptData); - ProxyServer *mcuhost = ProxyServer::getServer(); - this->push_debugging_threadid = mcuhost->openConnections(&this->push_mutex); + if (ProxyServer::registerMCUHost(&interruptData)) { + this->connected_to_drone = true; + pthread_mutex_init(&this->push_mutex, nullptr); + pthread_mutex_lock(&this->push_mutex); + ProxyServer *mcuhost = ProxyServer::getServer(); + this->push_debugging_threadid = + mcuhost->openConnections(&this->push_mutex); + } dprintf(this->socket, "done!\n"); } diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index d5af038f..3b6ea837 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -96,27 +96,31 @@ ProxyServer *ProxyServer::getServer() { return proxyServer; } -void ProxyServer::registerMCUHost(uint8_t **data) { +bool ProxyServer::registerMCUHost(uint8_t **data) { int pull = (int)read_B32(data); int push = pull + 1; auto hostsize = (uint8_t)(*data)[0]; char *hostname = new char[hostsize + 1]; memcpy((void *)hostname, ++(*data), hostsize); hostname[hostsize] = '\0'; - printf("Registering Proxy Host: %s PULL_PORT=%d PUSH_PORT=%d\n", hostname, - pull, push); - ProxyServer::getServer()->registerAddresses(hostname, pull, push); + return ProxyServer::getServer()->registerAddresses(hostname, pull, push); } -void ProxyServer::registerAddresses(char *_host, int _pull_port, +bool ProxyServer::registerAddresses(char *_host, int _pull_port, int _push_port) { if (this->host != nullptr) { + if (this->pull_port == _pull_port && strcmp(_host, this->host) == 0) { + return false; + } this->closeConnections(); free(this->host); } + printf("Registering Proxy Host: %s PULL_PORT=%d PUSH_PORT=%d\n", _host, + _pull_port, _push_port); this->host = _host; this->pull_port = _pull_port; this->push_port = _push_port; + return true; } void ProxyServer::updateExcpMsg(const char *msg) { diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_server.h index 5dd372d8..f1a5025c 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_server.h @@ -27,13 +27,13 @@ class ProxyServer { static void startPushDebuggerSocket(struct Socket *arg); - void registerAddresses(char *_host, int _pull_port, int _push_port); + bool registerAddresses(char *_host, int _pull_port, int _push_port); void closeConnections(); pthread_t openConnections(pthread_mutex_t *mutex); void updateExcpMsg(const char *msg); bool send(void *t_buffer, int t_size); char *readReply(short int amount = 1024); - static void registerMCUHost(uint8_t **data); + static bool registerMCUHost(uint8_t **data); static ProxyServer *getServer(); }; From 0b90a8e780e3d89a3360341291c0397d9c6d5a89 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 18:18:17 +0200 Subject: [PATCH 103/249] bug fix: json parse error --- src/RFC/proxy_server.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 3b6ea837..e6843b1d 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -143,13 +143,22 @@ ProxyServer::ProxyServer() { void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { int socket = arg->fileDescriptor; - int valread; + + char _char; + int buf_idx = 0; char buffer[1024] = {0}; + while (continuing(arg->mutex)) { - valread = read(socket, buffer, 1024); - if (valread != -1) { - Event *event = parseJSON(valread - 1, buffer); - CallbackHandler::push_event(event); + if (read(socket, &_char, 1) != -1) { + // TODO FIX if buffer becomes too small + buffer[buf_idx++] = _char; + buffer[buf_idx] = '\0'; + try { + Event *event = parseJSON(buf_idx - 1, buffer); + CallbackHandler::push_event(event); + buf_idx = 0; + } catch (const nlohmann::detail::parse_error &e) { + } } } } From 0dfa0c7ae89616abff8ba5ee4cace14c52ee6cb4 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 5 May 2022 18:23:47 +0200 Subject: [PATCH 104/249] add comment --- src/RFC/proxy_server.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index e6843b1d..c8bec008 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -152,7 +152,8 @@ void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { if (read(socket, &_char, 1) != -1) { // TODO FIX if buffer becomes too small buffer[buf_idx++] = _char; - buffer[buf_idx] = '\0'; + buffer[buf_idx] = '\0'; // needed because parseJSON does not use + // first len argument try { Event *event = parseJSON(buf_idx - 1, buffer); CallbackHandler::push_event(event); From aa7bfaec138a635a23e184de617e580fba6d4495 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Fri, 6 May 2022 08:55:24 +0200 Subject: [PATCH 105/249] increase pushbuffer socket size if needed --- src/RFC/proxy_server.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index c8bec008..1f268bf7 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -145,15 +145,27 @@ void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { int socket = arg->fileDescriptor; char _char; - int buf_idx = 0; - char buffer[1024] = {0}; + uint32_t buf_idx = 0; + const uint32_t start_size = 1024; + uint32_t current_size = start_size; + char *buffer = (char *)malloc(start_size); while (continuing(arg->mutex)) { if (read(socket, &_char, 1) != -1) { - // TODO FIX if buffer becomes too small + // increase buffer size if needed + if (current_size <= (buf_idx + 1)) { + char *new_buff = (char *)malloc(current_size + start_size); + memcpy((void *)new_buff, (void *)buffer, current_size); + free(buffer); + buffer = new_buff; + current_size += start_size; + printf("increasing PushClient's buffer size to %d\n", + current_size); + } buffer[buf_idx++] = _char; - buffer[buf_idx] = '\0'; // needed because parseJSON does not use - // first len argument + // manual nulltermination is needed because parseJSON does not use + // first len argument + buffer[buf_idx] = '\0'; try { Event *event = parseJSON(buf_idx - 1, buffer); CallbackHandler::push_event(event); From e82c316e8c34dcfb370c5452788d615e5debf5ea Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 6 May 2022 13:25:35 +0200 Subject: [PATCH 106/249] Add events to full dump --- documentation/DumpFormat.md | 276 ++++++++++++++++++------------------ src/Debug/debugger.cpp | 10 +- src/Debug/debugger.h | 2 +- 3 files changed, 146 insertions(+), 142 deletions(-) diff --git a/documentation/DumpFormat.md b/documentation/DumpFormat.md index cfa74fc2..2b09b7db 100644 --- a/documentation/DumpFormat.md +++ b/documentation/DumpFormat.md @@ -2,7 +2,7 @@ WARDuino sends its information dumps as json. -## Full dump (0x12) +## Full dump (0x12) Lists the following items: @@ -11,11 +11,13 @@ Lists the following items: - breakpoints (list of pointers to instrs in program buffer) - functions (all declared functions) - callstack (the current callstack, bottom to top) +- locals +- events (async events currently in CallbackHandler queue) ### Callstack -The callstack is printed as a list of objects, with the first object the bottom of the stack. -Each object represents a block with a type: +The callstack is printed as a list of objects, with the first object the bottom of the stack. Each object represents a +block with a type: - Function 0x00 - Init expression 0x01 @@ -29,46 +31,45 @@ When the block is a function it also holds the function index in the `fidx` fiel ```json { - "pc":"0x3ffbdc00", - "start":[ - "0x3ffbdb70" - ], - "breakpoints":[ - - ], - "functions":[ + "pc": "0x3ffbdc00", + "start": [ + "0x3ffbdb70" + ], + "breakpoints": [ + ], + "functions": [ + { + "fidx": "0x3", + "from": "0x3ffbdbee", + "to": "0x3ffbdbf4" + }, + { + "fidx": "0x4", + "from": "0x3ffbdbf9", + "to": "0x3ffbdc19" + } + ], + "callstack": [ + { + "type": 0, + "fidx": "0x4", + "sp": -1, + "fp": -1, + "start": "0x3ffbdbf9", + "ra": "0x3ffbdbdf", + "callsite": "0x3ffbdbdd" + } + ], + "locals": { + "count": 1, + "locals": [ { - "fidx":"0x3", - "from":"0x3ffbdbee", - "to":"0x3ffbdbf4" - }, - { - "fidx":"0x4", - "from":"0x3ffbdbf9", - "to":"0x3ffbdc19" - } - ], - "callstack":[ - { - "type":0, - "fidx":"0x4", - "sp":-1, - "fp":-1, - "start":"0x3ffbdbf9", - "ra":"0x3ffbdbdf", - "callsite":"0x3ffbdbdd" + "type": "i32", + "value": 1000, + "index": 0 } - ], - "locals":{ - "count":1, - "locals":[ - { - "type":"i32", - "value":1000, - "index":0 - } - ] - } + ] + } } ``` @@ -80,14 +81,14 @@ The locals can also be retreived on their own with the 0x11 byte. ```json { - "count":1, - "locals":[ - { - "type":"i32", - "value":1000, - "index":0 - } - ] + "count": 1, + "locals": [ + { + "type": "i32", + "value": 1000, + "index": 0 + } + ] } ``` @@ -95,94 +96,93 @@ The locals can also be retreived on their own with the 0x11 byte. ```json { - "pc":"0x60000272806e", - "start":[ - "0x600002728000" - ], - "breakpoints":[ - - ], - "stack":[ - { - "idx":0, - "type":"i32", - "value":5 - }, - { - "idx":1, - "type":"i32", - "value":5 - }, - { - "idx":2, - "type":"i32", - "value":5 - } - ], - "callstack":[ - { - "type":0, - "fidx":"0x3", - "sp":-1, - "fp":-1, - "block_key":"0x0", - "ra":"0x60000272805a", - "idx":0 - }, - { - "type":3, - "fidx":"0x0", - "sp":0, - "fp":0, - "block_key":"0x600002728083", - "ra":"0x600002728085", - "idx":1 - }, - { - "type":0, - "fidx":"0x2", - "sp":0, - "fp":0, - "block_key":"0x0", - "ra":"0x600002728089", - "idx":2 - }, - { - "type":4, - "fidx":"0x0", - "sp":2, - "fp":1, - "block_key":"0x60000272806a", - "ra":"0x60000272806c", - "idx":3 - } - ], - "globals":[ - { - "idx":0, - "type":"i32", - "value":0 - }, - { - "idx":1, - "type":"i32", - "value":0 - } - ], - "table":{ - "max":2, - "init":2, - "elements":"" - }, - "memory":{ - "pages":2, - "max":32768, - "init":2, - "bytes":"" - }, - "br_table":{ - "size":"0x100", - "labels":"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00" - } + "pc": "0x60000272806e", + "start": [ + "0x600002728000" + ], + "breakpoints": [ + ], + "stack": [ + { + "idx": 0, + "type": "i32", + "value": 5 + }, + { + "idx": 1, + "type": "i32", + "value": 5 + }, + { + "idx": 2, + "type": "i32", + "value": 5 + } + ], + "callstack": [ + { + "type": 0, + "fidx": "0x3", + "sp": -1, + "fp": -1, + "block_key": "0x0", + "ra": "0x60000272805a", + "idx": 0 + }, + { + "type": 3, + "fidx": "0x0", + "sp": 0, + "fp": 0, + "block_key": "0x600002728083", + "ra": "0x600002728085", + "idx": 1 + }, + { + "type": 0, + "fidx": "0x2", + "sp": 0, + "fp": 0, + "block_key": "0x0", + "ra": "0x600002728089", + "idx": 2 + }, + { + "type": 4, + "fidx": "0x0", + "sp": 2, + "fp": 1, + "block_key": "0x60000272806a", + "ra": "0x60000272806c", + "idx": 3 + } + ], + "globals": [ + { + "idx": 0, + "type": "i32", + "value": 0 + }, + { + "idx": 1, + "type": "i32", + "value": 0 + } + ], + "table": { + "max": 2, + "init": 2, + "elements": "" + }, + "memory": { + "pages": 2, + "max": 32768, + "init": 2, + "bytes": "" + }, + "br_table": { + "size": "0x100", + "labels": "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00" + } } ``` diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index adc5749e..c38ad312 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -228,7 +228,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { size = (long)CallbackHandler::event_count(); case interruptDUMPEvents: // TODO get start and size from message + dprintf(this->socket, "{"); this->dumpEvents(start, size); + dprintf(this->socket, "}"); break; case interruptPOPEvent: CallbackHandler::resolve_event(); @@ -341,6 +343,8 @@ void Debugger::dump(Module *m, bool full) const { if (full) { dprintf(this->socket, R"(, "locals": )"); this->dumpLocals(m); + dprintf(this->socket, ", "); + this->dumpEvents(0, CallbackHandler::event_count()); } dprintf(this->socket, "}\n\n"); @@ -434,14 +438,14 @@ void Debugger::dumpLocals(Module *m) const { // fflush(stdout); } -void Debugger::dumpEvents(long start, long size) { +void Debugger::dumpEvents(long start, long size) const { CallbackHandler::resolving_event = true; if (size > EVENTS_SIZE) { size = EVENTS_SIZE; } dbg_info("Printing event queue (%lu, %lu) ...\n", start, size); - dprintf(this->socket, R"({"events": [)"); + dprintf(this->socket, R"("events": [)"); long index = start, end = start + size; std::for_each(CallbackHandler::event_begin() + start, CallbackHandler::event_begin() + end, @@ -453,7 +457,7 @@ void Debugger::dumpEvents(long start, long size) { dprintf(this->socket, ", "); } }); - dprintf(this->socket, "]}"); + dprintf(this->socket, "]"); CallbackHandler::resolving_event = false; } diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 0af3f3db..58b84b0b 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -89,7 +89,7 @@ class Debugger { void dumpCallstack(Module *m) const; - void dumpEvents(long start, long size); + void dumpEvents(long start, long size) const; //// Handle live code update From 2cb6f54f1200dea389408687af86dcfe5f25f911 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 6 May 2022 14:47:07 +0200 Subject: [PATCH 107/249] Add subscribe_interrupt EMU --- src/Primitives/emulated.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 2d81a42b..7cef117d 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -25,7 +25,7 @@ #include "primitives.h" #define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 23 +#define NUM_PRIMITIVES_ARDUINO 24 #define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) @@ -419,6 +419,15 @@ def_prim(write_spi_bytes_16, twoToNoneU32) { return true; } +def_prim(subscribe_interrupt, threeToNoneU32) { + uint8_t pin = arg2.uint32; // GPIOPin + uint8_t fidx = arg1.uint32; // Callback function + uint8_t mode = arg0.uint32; + + debug("EMU: subscribe_interrupt(%u, %u, %u) \n", pin, fidx, mode); + pop_args(3); + return true; +} //------------------------------------------------------ // Installing all the primitives //------------------------------------------------------ @@ -444,6 +453,7 @@ void install_primitives() { install_primitive(spi_begin); install_primitive(write_spi_byte); install_primitive(write_spi_bytes_16); + install_primitive(subscribe_interrupt); install_primitive(init_pixels); install_primitive(set_pixel_color); @@ -489,4 +499,4 @@ bool resolve_external_memory(char *symbol, Memory **val) { return false; } -#endif // ARDUINO \ No newline at end of file +#endif // ARDUINO From 0a8d95658eb2e608e3b76c020ba7beb2a8c7bac2 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 6 May 2022 14:47:20 +0200 Subject: [PATCH 108/249] Make `pushingMode` default true --- src/WARDuino/CallbackHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 5ca6ebc9..e5e9fdf8 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -11,7 +11,7 @@ // CallbackHandler class -bool CallbackHandler::pushingMode = false; +bool CallbackHandler::pushingMode = true; bool CallbackHandler::resolving_event = false; std::unordered_map *> From 72ea40b971c8024bd5239b3ad356d549675f78e0 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 6 May 2022 19:55:37 +0200 Subject: [PATCH 109/249] Fix push code in `CallbackHandler::resolve_event` Fixes: resolve event code was unreachable on `ARDUINO` Fixes: in `server->hasPushClient()`, the server could be a `nullptr` --- src/WARDuino/CallbackHandler.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index e5e9fdf8..17bab61d 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -75,19 +75,15 @@ bool CallbackHandler::resolve_event() { #ifdef ARDUINO // check if we need to push events SocketServer *server = SocketServer::getServer(); - if (CallbackHandler::pushingMode) { - if (!server->hasPushClient()) { - return true; - } else { - CallbackHandler::events->pop_front(); - SocketServer *server = SocketServer::getServer(); - printf(R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), - event.payload); // TODO remove - server->printf2Client(server->pushClient, - R"({"topic":"%s","payload":"%s"})", - event.topic.c_str(), event.payload); - return !CallbackHandler::events->empty(); - } + if (CallbackHandler::pushingMode && server != nullptr && + server->hasPushClient()) { + CallbackHandler::events->pop_front(); + printf(R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), + event.payload); // TODO remove + server->printf2Client(server->pushClient, + R"({"topic":"%s","payload":"%s"})", + event.topic.c_str(), event.payload); + return !CallbackHandler::events->empty(); } #endif From 3b3de274955a10a7448f01d5c037332b8542c0fd Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Fri, 6 May 2022 22:38:11 +0200 Subject: [PATCH 110/249] Remove `pushingMode` + add `manual_event_resolution` Fixes: events were still processed in emulator during out-of-place debugging --- src/Debug/debugger.cpp | 12 +----------- src/Debug/debugger.h | 3 +-- src/Interpreter/instructions.cpp | 17 +++++++---------- src/WARDuino/CallbackHandler.cpp | 13 +++++++------ src/WARDuino/CallbackHandler.h | 2 +- 5 files changed, 17 insertions(+), 30 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 5df04c3f..a677cd98 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -182,9 +182,6 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptWOODDUMP: *program_state = WARDUINOpause; -#ifdef ARDUINO - CallbackHandler::pushingMode = true; -#endif free(interruptData); woodDump(m); break; @@ -196,6 +193,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { if (!this->receivingData) { debug("paused program execution\n"); *program_state = WARDUINOpause; + CallbackHandler::manual_event_resolution = true; this->receivingData = true; this->freeState(m, interruptData); free(interruptData); @@ -239,17 +237,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { case interruptPOPEvent: CallbackHandler::resolve_event(); break; -#ifdef ARDUINO - case interruptTOGGLEPushingMode: - CallbackHandler::pushingMode = !CallbackHandler::pushingMode; - printf(R"({"pushingMode": %s})", - CallbackHandler::pushingMode ? "true" : "false"); - break; -#else case interruptPUSHEvent: this->handlePushedEvent(m, interruptData); break; -#endif default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index bfbb1ad2..4fc63c83 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -42,8 +42,7 @@ enum InterruptTypes { interruptDUMPAllEvents = 0x70, interruptDUMPEvents = 0x71, interruptPOPEvent = 0x72, - interruptPUSHEvent = 0x73, - interruptTOGGLEPushingMode = 0x74 + interruptPUSHEvent = 0x73 }; class Debugger { diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index a2be36cd..7db14149 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1542,22 +1542,19 @@ bool interpret(Module *m) { } #endif + if (CallbackHandler::manual_event_resolution || program_state != WARDUINOpause) { + // Resolve 1 callback event if queue is not empty and no event + // currently resolving + CallbackHandler::resolve_event(); + } + if (program_state == WARDUINOpause) { - if (CallbackHandler::pushingMode) { - CallbackHandler::resolve_event(); - } continue; } // Program state is not paused - // Resolve 1 callback event if queue is not empty and no event - // currently resolving - if (!CallbackHandler::resolving_event) { - CallbackHandler::resolve_event(); - } - - // if BP and not the one we just unpaused + // If BP and not the one we just unpaused if (m->warduino->debugger->isBreakpoint(m->pc_ptr) && m->warduino->debugger->skipBreakpoint != m->pc_ptr && program_state != WARDuinoProxyRun) { diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 17bab61d..048668dd 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -11,7 +11,7 @@ // CallbackHandler class -bool CallbackHandler::pushingMode = true; +bool CallbackHandler::manual_event_resolution = false; bool CallbackHandler::resolving_event = false; std::unordered_map *> @@ -67,7 +67,7 @@ void CallbackHandler::push_event(Event *event) { } bool CallbackHandler::resolve_event() { - if (CallbackHandler::events->empty()) { + if (CallbackHandler::resolving_event || CallbackHandler::events->empty()) { return false; } Event event = CallbackHandler::events->front(); @@ -75,18 +75,19 @@ bool CallbackHandler::resolve_event() { #ifdef ARDUINO // check if we need to push events SocketServer *server = SocketServer::getServer(); - if (CallbackHandler::pushingMode && server != nullptr && - server->hasPushClient()) { - CallbackHandler::events->pop_front(); + if (server != nullptr && server->hasPushClient()) { printf(R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), event.payload); // TODO remove server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), event.payload); - return !CallbackHandler::events->empty(); } #endif + if (CallbackHandler::manual_event_resolution) { + return true; + } + CallbackHandler::resolving_event = true; CallbackHandler::events->pop_front(); diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index a1de5c5e..1f4618eb 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -40,7 +40,7 @@ class CallbackHandler { static bool resolve_event(); // WOOD needed to know when to push events - static bool pushingMode; + static bool manual_event_resolution; }; class Callback { From a40ecc3a9897c3ac9fc333a5d523733980cb45cb Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Sat, 7 May 2022 00:20:39 +0200 Subject: [PATCH 111/249] Fix json parse + compilation --- src/Debug/debugger.cpp | 14 +++++++++----- src/Debug/debugger.h | 28 ++++++++++++++++++++-------- src/Interpreter/instructions.cpp | 3 ++- src/RFC/proxy_server.cpp | 10 +++++----- src/WARDuino/CallbackHandler.cpp | 4 ++-- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index a677cd98..503b9ead 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -217,6 +217,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } break; #else case interruptMonitorProxies: { + CallbackHandler::manual_event_resolution = true; printf("receiving functions list to proxy\n"); this->handleMonitorProxies(m, interruptData + 1); free(interruptData); @@ -232,14 +233,16 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { // TODO get start and size from message dprintf(this->socket, "{"); this->dumpEvents(start, size); - dprintf(this->socket, "}"); + dprintf(this->socket, "}\n"); break; case interruptPOPEvent: CallbackHandler::resolve_event(); break; +#ifndef ARDUINO case interruptPUSHEvent: - this->handlePushedEvent(m, interruptData); + this->handlePushedEvent(m, reinterpret_cast(interruptData)); break; +#endif default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); @@ -549,11 +552,12 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { } #ifndef ARDUINO -bool Debugger::handlePushedEvent(Module *m, uint8_t *bytes) const { +bool Debugger::handlePushedEvent(Module *m, char *bytes) const { if (*bytes != interruptPUSHEvent) return false; auto parsed = nlohmann::json::parse(bytes); - std::string payload = parsed["payload"]; - CallbackHandler::push_event(new Event(parsed["topic"], payload.c_str())); + std::string payload = *parsed.find("payload"); + CallbackHandler::push_event( + new Event(*parsed.find("topic"), payload.c_str())); return true; } #endif diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 4fc63c83..b65e3609 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -50,12 +50,14 @@ class Debugger { std::deque debugMessages = {}; // Help variables + volatile bool interruptWrite{}; volatile bool interruptRead{}; bool interruptEven = true; uint8_t interruptLastChar{}; std::vector interruptBuffer; long interruptSize{}; + bool receivingData = false; #ifndef ARDUINO bool connected_to_drone = false; @@ -96,24 +98,26 @@ class Debugger { bool handleChangedLocal(Module *m, uint8_t *bytes) const; - bool handlePushedEvent(Module *m, uint8_t *bytes) const; - - // WOOD Private Methods + //// Handle out-of-place debugging - // Receiving and dumping State - bool receivingData = false; void freeState(Module *m, uint8_t *interruptData); + static uint8_t *findOpcode(Module *m, Block *block); + bool saveState(Module *m, uint8_t *interruptData); + static uintptr_t readPointer(uint8_t **data); public: + // Public fields + int socket; std::set breakpoints = {}; // Vector, we expect few breakpoints uint8_t *skipBreakpoint = nullptr; // Breakpoint to skip in the next interpretation step + // Constructor explicit Debugger(int socket); // Interrupts @@ -134,16 +138,24 @@ class Debugger { void notifyBreakpoint(uint8_t *pc_ptr); - // WOOD + // Out-of-place debugging + void woodDump(Module *m); + #ifdef ARDUINO void handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData); #else - void handleMonitorProxies(Module *m, uint8_t *interruptData); - bool drone_connected() const; void disconnect_drone(); + + // Pull-based + + void handleMonitorProxies(Module *m, uint8_t *interruptData); + + // Push-based + + bool handlePushedEvent(Module *m, char *bytes) const; #endif }; diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 7db14149..0d0a5451 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1542,7 +1542,8 @@ bool interpret(Module *m) { } #endif - if (CallbackHandler::manual_event_resolution || program_state != WARDUINOpause) { + if (CallbackHandler::manual_event_resolution || + program_state != WARDUINOpause) { // Resolve 1 callback event if queue is not empty and no event // currently resolving CallbackHandler::resolve_event(); diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 1f268bf7..028fdfcf 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -81,12 +81,12 @@ void *readSocket(void *input) { ProxyServer::startPushDebuggerSocket((struct Socket *)input); } -Event *parseJSON(size_t len, char *buff) { +Event *parseJSON(char *buff) { // TODO duplicate code in Debugger::handlePushedEvent - auto parsed = nlohmann::json::parse(buff); + nlohmann::basic_json<> parsed = nlohmann::json::parse(buff); dbg_info("%s\n", parsed.dump()); - std::string payload = parsed["payload"]; - return new Event(parsed["topic"], payload.c_str()); + std::string payload = *parsed.find("payload"); + return new Event(*parsed.find("topic"), payload.c_str()); } ProxyServer *ProxyServer::proxyServer = nullptr; @@ -167,7 +167,7 @@ void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { // first len argument buffer[buf_idx] = '\0'; try { - Event *event = parseJSON(buf_idx - 1, buffer); + Event *event = parseJSON(buffer); CallbackHandler::push_event(event); buf_idx = 0; } catch (const nlohmann::detail::parse_error &e) { diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 048668dd..65f82451 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -91,8 +91,8 @@ bool CallbackHandler::resolve_event() { CallbackHandler::resolving_event = true; CallbackHandler::events->pop_front(); - printf("Resolving an event. (%lu remaining)\n", - CallbackHandler::events->size()); + debug("Resolving an event. (%lu remaining)\n", + CallbackHandler::events->size()); auto iterator = CallbackHandler::callbacks->find(event.topic); if (iterator != CallbackHandler::callbacks->end()) { From 86314303ba62c5872eaf7e2753238b36c43ccf9c Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Sat, 7 May 2022 10:32:29 +0200 Subject: [PATCH 112/249] Update documentation --- documentation/Interrupts.md | 2 +- documentation/{PushDebugging.md => OutOfPlaceDebugging.md} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename documentation/{PushDebugging.md => OutOfPlaceDebugging.md} (94%) diff --git a/documentation/Interrupts.md b/documentation/Interrupts.md index 477e9649..0f2766b4 100644 --- a/documentation/Interrupts.md +++ b/documentation/Interrupts.md @@ -13,4 +13,4 @@ character, it should match `([0-9A-F][0-9A-F])+` The first two character of the HEX sequence (that is the first byte of the translated binary data) differentiates between the various interrup types. -See: [interrupt_operations.cpp](../interrupt_operations.cpp) \ No newline at end of file +See: [src/Debug/Debugger.cpp](../src/Debug/Debugger.cpp) diff --git a/documentation/PushDebugging.md b/documentation/OutOfPlaceDebugging.md similarity index 94% rename from documentation/PushDebugging.md rename to documentation/OutOfPlaceDebugging.md index 38a1d998..b1b98985 100644 --- a/documentation/PushDebugging.md +++ b/documentation/OutOfPlaceDebugging.md @@ -1,8 +1,8 @@ -# Pull-Push Debugging +# Out-of-place debugging Aside from traditional remote debugging, the WARDuino virtual machine also supports pull-push debugging. -## Pull Debugging +## Pull-based OOP Debugging With pull debugging the current application is debugged in a local emulated WARDuino instance, but with live actuator and sensor values from a drone device. To get current values, the emulated debugger initiates proxy calls to the drone @@ -10,7 +10,7 @@ device. The debugger will wait until this call has completed and the result is r Communication happens through a minimal byte format. -## Push Debugging +## Push-based OOP Debugging A drone device can also push live values to the emulated debugger. These will typically be asynchronous events such as hardware interrupts, exceptions, ... From 5ca94b2a7333b50f045e3fea77122a7a1e5fc909 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Sat, 7 May 2022 12:05:37 +0200 Subject: [PATCH 113/249] Remove extra `manual_event_resolution = true` --- src/Debug/debugger.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 503b9ead..f492315a 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -217,7 +217,6 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } break; #else case interruptMonitorProxies: { - CallbackHandler::manual_event_resolution = true; printf("receiving functions list to proxy\n"); this->handleMonitorProxies(m, interruptData + 1); free(interruptData); From 9cc9859c9868154e9297610aa7d656ecf457d5b2 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Sat, 7 May 2022 15:31:41 +0200 Subject: [PATCH 114/249] Add new pushed event notification + remove breaking print --- src/Debug/debugger.cpp | 10 ++++++++-- src/Debug/debugger.h | 4 ++++ src/WARDuino/CallbackHandler.cpp | 14 +++++++++++--- src/WARDuino/CallbackHandler.h | 2 ++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index f492315a..b5f6e9da 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -551,12 +551,18 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { } #ifndef ARDUINO +void Debugger::notifyPushedEvent(const std::string &serialized) const { + dprintf(this->socket, "new pushed event"); + // dprintf(this->socket, "%s", serialized.c_str()); +} + bool Debugger::handlePushedEvent(Module *m, char *bytes) const { if (*bytes != interruptPUSHEvent) return false; auto parsed = nlohmann::json::parse(bytes); std::string payload = *parsed.find("payload"); - CallbackHandler::push_event( - new Event(*parsed.find("topic"), payload.c_str())); + auto *event = new Event(*parsed.find("topic"), payload.c_str()); + CallbackHandler::push_event(event); + this->notifyPushedEvent(event->serialized()); return true; } #endif diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index b65e3609..e1322eac 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -156,6 +156,10 @@ class Debugger { // Push-based +#ifndef ARDUINO + void notifyPushedEvent(const std::string &serialized) const; +#endif + bool handlePushedEvent(Module *m, char *bytes) const; #endif }; diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 65f82451..0e627bb5 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -55,6 +55,9 @@ void CallbackHandler::push_event(std::string topic, reinterpret_cast(message)); dbg_info("Push Event(%s, %s)\n", e->topic.c_str(), e->payload); events->push_back(*e); +#ifndef ARDUINO + WARDuino::instance()->debugger->notifyPushedEvent(e->serialized()); +#endif } } @@ -62,7 +65,9 @@ void CallbackHandler::push_event(Event *event) { if (events->size() < EVENTS_SIZE) { dbg_info("Push Event(%s, %s)\n", event->topic.c_str(), event->payload); events->push_back(*event); - printf("new events size %lu\n", events->size()); // TODO remove +#ifndef ARDUINO + WARDuino::instance()->debugger->notifyPushedEvent(event->serialized()); +#endif } } @@ -76,8 +81,6 @@ bool CallbackHandler::resolve_event() { // check if we need to push events SocketServer *server = SocketServer::getServer(); if (server != nullptr && server->hasPushClient()) { - printf(R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), - event.payload); // TODO remove server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", event.topic.c_str(), event.payload); @@ -171,3 +174,8 @@ Event::Event(std::string topic, const char *payload) { this->topic = topic; this->payload = payload; } + +std::string Event::serialized() const { + return R"({"topic": ")" + this->topic + R"(", "payload": ")" + + this->payload + R"("})"; +} diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index 1f4618eb..98c2c031 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -15,6 +15,8 @@ class Event { const char *payload; Event(std::string topic, const char *payload); + + std::string serialized() const; }; class CallbackHandler { From f5001d6b1cecf96e8852ac15abccc9252620c4f1 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Sat, 7 May 2022 19:05:46 +0200 Subject: [PATCH 115/249] Fix events --- src/Debug/debugger.cpp | 11 +++++------ src/Debug/debugger.h | 2 +- src/RFC/proxy_server.cpp | 2 +- src/WARDuino/CallbackHandler.cpp | 8 ++++---- src/WARDuino/CallbackHandler.h | 4 ++-- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index b5f6e9da..bada7230 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -448,7 +448,7 @@ void Debugger::dumpEvents(long start, long size) const { [this, &index, &end](const Event &e) { dprintf(this->socket, R"({"topic": "%s", "payload": "%s"})", - e.topic.c_str(), e.payload); + e.topic.c_str(), e.payload.c_str()); if (++index < end) { dprintf(this->socket, ", "); } @@ -551,18 +551,17 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { } #ifndef ARDUINO -void Debugger::notifyPushedEvent(const std::string &serialized) const { +void Debugger::notifyPushedEvent() const { dprintf(this->socket, "new pushed event"); - // dprintf(this->socket, "%s", serialized.c_str()); } bool Debugger::handlePushedEvent(Module *m, char *bytes) const { if (*bytes != interruptPUSHEvent) return false; auto parsed = nlohmann::json::parse(bytes); - std::string payload = *parsed.find("payload"); - auto *event = new Event(*parsed.find("topic"), payload.c_str()); + printf("handle pushed event: %s", bytes); + auto *event = new Event(*parsed.find("topic"), *parsed.find("payload")); CallbackHandler::push_event(event); - this->notifyPushedEvent(event->serialized()); + this->notifyPushedEvent(); return true; } #endif diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index e1322eac..14e4abd3 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -157,7 +157,7 @@ class Debugger { // Push-based #ifndef ARDUINO - void notifyPushedEvent(const std::string &serialized) const; + void notifyPushedEvent() const; #endif bool handlePushedEvent(Module *m, char *bytes) const; diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index 028fdfcf..a6881401 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -84,7 +84,7 @@ void *readSocket(void *input) { Event *parseJSON(char *buff) { // TODO duplicate code in Debugger::handlePushedEvent nlohmann::basic_json<> parsed = nlohmann::json::parse(buff); - dbg_info("%s\n", parsed.dump()); + printf("parseJSON: %s\n", parsed.dump().c_str()); std::string payload = *parsed.find("payload"); return new Event(*parsed.find("topic"), payload.c_str()); } diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 0e627bb5..c6e14fe1 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -56,7 +56,7 @@ void CallbackHandler::push_event(std::string topic, dbg_info("Push Event(%s, %s)\n", e->topic.c_str(), e->payload); events->push_back(*e); #ifndef ARDUINO - WARDuino::instance()->debugger->notifyPushedEvent(e->serialized()); + WARDuino::instance()->debugger->notifyPushedEvent(); #endif } } @@ -66,7 +66,7 @@ void CallbackHandler::push_event(Event *event) { dbg_info("Push Event(%s, %s)\n", event->topic.c_str(), event->payload); events->push_back(*event); #ifndef ARDUINO - WARDuino::instance()->debugger->notifyPushedEvent(event->serialized()); + WARDuino::instance()->debugger->notifyPushedEvent(); #endif } } @@ -83,7 +83,7 @@ bool CallbackHandler::resolve_event() { if (server != nullptr && server->hasPushClient()) { server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", - event.topic.c_str(), event.payload); + event.topic.c_str(), event.payload.c_str()); } #endif @@ -170,7 +170,7 @@ Callback::Callback(const Callback &c) { // Event class -Event::Event(std::string topic, const char *payload) { +Event::Event(std::string topic, std::string payload) { this->topic = topic; this->payload = payload; } diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index 98c2c031..0db35346 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -12,9 +12,9 @@ class Callback; class Event { public: std::string topic; - const char *payload; + std::string payload; - Event(std::string topic, const char *payload); + Event(std::string topic, std::string payload); std::string serialized() const; }; From bd087c39d7e681ac7b96a342fda19f59ee158cad Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Mon, 9 May 2022 12:39:42 +0200 Subject: [PATCH 116/249] Fix `notifyPushedEvent` + support paused drone Move RunningState to WARDuino object --- src/Interpreter/instructions.cpp | 34 +++++++++++++------------- src/RFC/proxy_server.cpp | 1 + src/WARDuino.h | 1 + src/WARDuino/CallbackHandler.cpp | 42 +++++++++++++++++--------------- src/WARDuino/CallbackHandler.h | 4 +++ 5 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 0d0a5451..0c2c8ec1 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1498,23 +1498,24 @@ bool interpret(Module *m) { bool program_done = false; // TODO: this is actually a property of warduino - RunningState program_state = WARDUINOrun; + m->warduino->program_state = WARDUINOrun; // needed for RFC RFC *callee = nullptr; while (!program_done && success) { - if (program_state == WARDUINOstep) { - program_state = WARDUINOpause; + if (m->warduino->program_state == WARDUINOstep) { + m->warduino->program_state = WARDUINOpause; } - while (m->warduino->debugger->checkDebugMessages(m, &program_state)) { + while (m->warduino->debugger->checkDebugMessages( + m, &m->warduino->program_state)) { }; fflush(stdout); reset_wdt(); #ifdef ARDUINO // handle RFC requested by emulator - if (program_state == WARDuinoProxyRun) { + if (m->warduino->program_state == WARDuinoProxyRun) { if (callee == nullptr) { // TODO maybe use RFC::hasRFCallee() // call happens for the first time callee = RFC::currentCallee(); @@ -1525,7 +1526,8 @@ bool interpret(Module *m) { callee->succes = ((Primitive)m->functions[callee->fid].func_ptr)(m); callee->returnResult(m); - callee->restoreExecutionState(m, &program_state); + callee->restoreExecutionState(m, + &m->warduino->program_state); RFC::removeRFCallee(); callee = nullptr; } else @@ -1534,7 +1536,8 @@ bool interpret(Module *m) { // check if call completes if (callee->callCompleted(m)) { callee->returnResult(m); - callee->restoreExecutionState(m, &program_state); + callee->restoreExecutionState(m, + &m->warduino->program_state); RFC::removeRFCallee(); callee = nullptr; } @@ -1542,14 +1545,11 @@ bool interpret(Module *m) { } #endif - if (CallbackHandler::manual_event_resolution || - program_state != WARDUINOpause) { - // Resolve 1 callback event if queue is not empty and no event - // currently resolving - CallbackHandler::resolve_event(); - } + // Resolve 1 callback event if queue is not empty and VM not paused, and + // no event currently resolving + CallbackHandler::resolve_event(); - if (program_state == WARDUINOpause) { + if (m->warduino->program_state == WARDUINOpause) { continue; } @@ -1558,8 +1558,8 @@ bool interpret(Module *m) { // If BP and not the one we just unpaused if (m->warduino->debugger->isBreakpoint(m->pc_ptr) && m->warduino->debugger->skipBreakpoint != m->pc_ptr && - program_state != WARDuinoProxyRun) { - program_state = WARDUINOpause; + m->warduino->program_state != WARDuinoProxyRun) { + m->warduino->program_state = WARDUINOpause; m->warduino->debugger->notifyBreakpoint(m->pc_ptr); continue; } @@ -1757,7 +1757,7 @@ bool interpret(Module *m) { } return false; } - if (program_state == WARDuinoProxyRun && !success) { + if (m->warduino->program_state == WARDuinoProxyRun && !success) { // RFC was unsuccesful RFC::currentCallee()->succes = false; // TODO copy exceptionMsg diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index a6881401..a31a6432 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -169,6 +169,7 @@ void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { try { Event *event = parseJSON(buffer); CallbackHandler::push_event(event); + WARDuino::instance()->debugger->notifyPushedEvent(); buf_idx = 0; } catch (const nlohmann::detail::parse_error &e) { } diff --git a/src/WARDuino.h b/src/WARDuino.h index e5156bbe..cec0cd3a 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -190,6 +190,7 @@ class WARDuino { public: Debugger *debugger; + RunningState program_state; static WARDuino *instance(); diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index c6e14fe1..52c46e37 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -13,6 +13,14 @@ bool CallbackHandler::manual_event_resolution = false; bool CallbackHandler::resolving_event = false; +#ifdef ARDUINO +size_t CallbackHandler::pushed_cursor = 0; + +bool should_push_event(SocketServer *server) { + return server != nullptr && server->hasPushClient() && + CallbackHandler::pushed_cursor < CallbackHandler::event_count(); +} +#endif std::unordered_map *> *CallbackHandler::callbacks = @@ -45,29 +53,21 @@ size_t CallbackHandler::callback_count(const std::string &topic) { return callbacks->find(topic)->second->size(); } +// WARNING: Push event functions should not use IO functions, since they can be +// called from ISR callbacks void CallbackHandler::push_event(std::string topic, const unsigned char *payload, unsigned int length) { - if (events->size() < EVENTS_SIZE) { - char *message = (char *)(malloc(sizeof(char) * length + 1)); - snprintf(message, length + 1, "%s", payload); - auto e = new Event(std::move(topic), - reinterpret_cast(message)); - dbg_info("Push Event(%s, %s)\n", e->topic.c_str(), e->payload); - events->push_back(*e); -#ifndef ARDUINO - WARDuino::instance()->debugger->notifyPushedEvent(); -#endif - } + char *message = (char *)(malloc(sizeof(char) * length + 1)); + snprintf(message, length + 1, "%s", payload); + auto event = + new Event(std::move(topic), reinterpret_cast(message)); + CallbackHandler::push_event(event); } void CallbackHandler::push_event(Event *event) { if (events->size() < EVENTS_SIZE) { - dbg_info("Push Event(%s, %s)\n", event->topic.c_str(), event->payload); events->push_back(*event); -#ifndef ARDUINO - WARDuino::instance()->debugger->notifyPushedEvent(); -#endif } } @@ -78,21 +78,25 @@ bool CallbackHandler::resolve_event() { Event event = CallbackHandler::events->front(); #ifdef ARDUINO - // check if we need to push events SocketServer *server = SocketServer::getServer(); - if (server != nullptr && server->hasPushClient()) { + if (should_push_event(server)) { + Event e = CallbackHandler::events->at(CallbackHandler::pushed_cursor++); server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", - event.topic.c_str(), event.payload.c_str()); + e.topic.c_str(), e.payload.c_str()); } #endif - if (CallbackHandler::manual_event_resolution) { + if (CallbackHandler::manual_event_resolution || + WARDuino::instance()->program_state == WARDUINOpause) { return true; } CallbackHandler::resolving_event = true; CallbackHandler::events->pop_front(); +#ifdef ARDUINO + CallbackHandler::pushed_cursor--; +#endif debug("Resolving an event. (%lu remaining)\n", CallbackHandler::events->size()); diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index 0db35346..e1a9dde4 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -27,6 +27,10 @@ class CallbackHandler { CallbackHandler() = default; // Disallow creation public: +#ifdef ARDUINO + static size_t pushed_cursor; +#endif + static size_t event_count(); static std::deque::const_iterator event_begin(); static std::deque::const_iterator event_end(); From 84be87ff9bf8a1784e4492993e537c4dde35c9a1 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Mon, 9 May 2022 13:34:50 +0200 Subject: [PATCH 117/249] Clang format + update README --- README.md | 5 +++-- src/WARDuino/CallbackHandler.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cb8411b4..47cb66f8 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@

-This project is released under the Mozilla Public License 2.0, and is being developed as part of an active research project at the University of Ghent's [TOPL](https://github.com/TOPLLab) lab. +This project is released under the Mozilla Public License 2.0, and is being developed as part of an active research project at the University of Ghent's [TOPL Lab](https://github.com/TOPLLab). The WARDuino virtual machine is a WebAssembly runtime for microcontrollers, which runs both under the Arduino and ESP-IDF toolchains. -The WARDuino project also includes a [VS Code extension](https://github.com/TOPLLab/WARDuino-VSCode) to use the remote debugging facilities offered by the virtual machine. +The WARDuino project also includes a [VS Code extension](https://github.com/TOPLLab/WARDuino-VSCode) to use both the remote debugging and the out-of-place debugging facilities offered by the virtual machine.

Installation | Examples | Run Specification tests | Documentation @@ -70,6 +70,7 @@ arduino-cli config init ``` If you need additional boards, such as the esp32 boards, you can add them in the generated config file. More information on how to install the esp32 boards can be found here. +(_note: WARDuino requires at least version 2.0.2 of the esp32 board manager when using esp32 devices)_ Thirdly, make sure you install the `PubSubClient` and `Adafruit NeoPixel` library. (used for MQTT and pixel primitives) diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index e1a9dde4..39b5eee6 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -30,7 +30,7 @@ class CallbackHandler { #ifdef ARDUINO static size_t pushed_cursor; #endif - + static size_t event_count(); static std::deque::const_iterator event_begin(); static std::deque::const_iterator event_end(); From 96585bfa4062c4d02e246ee4b1c252db7f725cc4 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Mon, 9 May 2022 13:53:30 +0200 Subject: [PATCH 118/249] Add force arg to `resolve_event` Fixes `interruptPOPEvent` --- src/Debug/debugger.cpp | 2 +- src/WARDuino/CallbackHandler.cpp | 6 +++--- src/WARDuino/CallbackHandler.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index bada7230..b9dababf 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -235,7 +235,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { dprintf(this->socket, "}\n"); break; case interruptPOPEvent: - CallbackHandler::resolve_event(); + CallbackHandler::resolve_event(true); break; #ifndef ARDUINO case interruptPUSHEvent: diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 52c46e37..39dc3bbd 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -71,7 +71,7 @@ void CallbackHandler::push_event(Event *event) { } } -bool CallbackHandler::resolve_event() { +bool CallbackHandler::resolve_event(bool force) { if (CallbackHandler::resolving_event || CallbackHandler::events->empty()) { return false; } @@ -87,8 +87,8 @@ bool CallbackHandler::resolve_event() { } #endif - if (CallbackHandler::manual_event_resolution || - WARDuino::instance()->program_state == WARDUINOpause) { + if (!force && (CallbackHandler::manual_event_resolution || + WARDuino::instance()->program_state == WARDUINOpause)) { return true; } diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index 39b5eee6..f7f27a5d 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -43,7 +43,7 @@ class CallbackHandler { static void push_event(std::string topic, const unsigned char *payload, unsigned int length); static void push_event(Event *event); - static bool resolve_event(); + static bool resolve_event(bool force = false); // WOOD needed to know when to push events static bool manual_event_resolution; From 24f48985d566991a86fb37e24719b422c037bff9 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Mon, 9 May 2022 15:22:50 +0200 Subject: [PATCH 119/249] Add callback interrupts + implement dump --- src/Debug/debugger.cpp | 17 +++++++++++++++++ src/Debug/debugger.h | 8 +++++++- src/WARDuino/CallbackHandler.cpp | 21 +++++++++++++++++++++ src/WARDuino/CallbackHandler.h | 2 ++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index b9dababf..9b6ef1c3 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -242,6 +242,12 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { this->handlePushedEvent(m, reinterpret_cast(interruptData)); break; #endif + case interruptDUMPCallbackmapping: + this->dumpCallbackmapping(); + break; + case interruptRecvCallbackmapping: + this->updateCallbackmapping( + m, reinterpret_cast(interruptData + 1)); default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); @@ -458,6 +464,10 @@ void Debugger::dumpEvents(long start, long size) const { CallbackHandler::resolving_event = false; } +void Debugger::dumpCallbackmapping() const { + dprintf(this->socket, "%s", CallbackHandler::dump_callbacks().c_str()); +} + /** * Read the change in bytes array. * @@ -979,4 +989,11 @@ void Debugger::disconnect_drone() { pthread_mutex_unlock(&this->push_mutex); pthread_join(this->push_debugging_threadid, (void **)&ptr); } + +void Debugger::updateCallbackmapping(Module *m, const char *data) const { + nlohmann::basic_json<> parsed = nlohmann::json::parse(data); + printf("updateCallbackmapping: %s\n", parsed.dump().c_str()); + CallbackHandler::clear_callbacks(); + // TODO for each callback in json: CallbackHandler::add_callback(); +} #endif diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 14e4abd3..93563fa6 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -42,7 +42,9 @@ enum InterruptTypes { interruptDUMPAllEvents = 0x70, interruptDUMPEvents = 0x71, interruptPOPEvent = 0x72, - interruptPUSHEvent = 0x73 + interruptPUSHEvent = 0x73, + interruptDUMPCallbackmapping = 0x74, + interruptRecvCallbackmapping = 0x75 }; class Debugger { @@ -92,6 +94,8 @@ class Debugger { void dumpEvents(long start, long size) const; + void dumpCallbackmapping() const; + //// Handle live code update static bool handleChangedFunction(Module *m, uint8_t *bytes); @@ -108,6 +112,8 @@ class Debugger { static uintptr_t readPointer(uint8_t **data); + void updateCallbackmapping(Module *m, const char *interruptData) const; + public: // Public fields diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 39dc3bbd..b04bb7e0 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -126,6 +126,27 @@ std::deque::const_iterator CallbackHandler::event_end() { return CallbackHandler::events->cend(); } +void CallbackHandler::clear_callbacks() { CallbackHandler::callbacks->clear(); } + +std::string CallbackHandler::dump_callbacks() { + std::string repr = R"({"callbacks": [)"; + auto iterator = CallbackHandler::callbacks->begin(); + while (iterator != CallbackHandler::callbacks->end()) { + repr += R"({")" + iterator->first + R"(": [)"; + for (const auto &value : *iterator->second) { + auto callback = std::begin(*iterator->second); + while (callback != std::end(*iterator->second)) { + repr += std::to_string(callback->table_index); + repr += (++callback != iterator->second->end()) ? ", " : ""; + } + } + repr += "]}"; + repr += (++iterator != CallbackHandler::callbacks->end()) ? ", " : ""; + } + repr += "]}"; + return repr; +} + // Callback class Callback::Callback(Module *m, std::string id, uint32_t tidx) { diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index f7f27a5d..0287cb7b 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -39,6 +39,8 @@ class CallbackHandler { static void add_callback(const Callback &c); static void remove_callback(const Callback &c); + static void clear_callbacks(); + static std::string dump_callbacks(); static size_t callback_count(const std::string &topic); static void push_event(std::string topic, const unsigned char *payload, unsigned int length); From 7d91618d58c4117ac5c2777f36089bbc8f6caaa6 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Mon, 9 May 2022 16:31:30 +0200 Subject: [PATCH 120/249] Fix compile error + fix infinite loop --- src/Debug/debugger.cpp | 9 +++++---- src/Debug/debugger.h | 3 ++- src/WARDuino/CallbackHandler.cpp | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 9b6ef1c3..3ba1d2d5 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -241,13 +241,14 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { case interruptPUSHEvent: this->handlePushedEvent(m, reinterpret_cast(interruptData)); break; + case interruptRecvCallbackmapping: + this->updateCallbackmapping( + m, reinterpret_cast(interruptData + 1)); + break; #endif case interruptDUMPCallbackmapping: this->dumpCallbackmapping(); break; - case interruptRecvCallbackmapping: - this->updateCallbackmapping( - m, reinterpret_cast(interruptData + 1)); default: // handle later dprintf(this->socket, "COULD not parse interrupt data!\n"); @@ -465,7 +466,7 @@ void Debugger::dumpEvents(long start, long size) const { } void Debugger::dumpCallbackmapping() const { - dprintf(this->socket, "%s", CallbackHandler::dump_callbacks().c_str()); + dprintf(this->socket, "%s\n", CallbackHandler::dump_callbacks().c_str()); } /** diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 93563fa6..8da8ff96 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -112,8 +112,9 @@ class Debugger { static uintptr_t readPointer(uint8_t **data); +#ifndef ARDUINO void updateCallbackmapping(Module *m, const char *interruptData) const; - +#endif public: // Public fields diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index b04bb7e0..851493ee 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -140,8 +140,9 @@ std::string CallbackHandler::dump_callbacks() { repr += (++callback != iterator->second->end()) ? ", " : ""; } } + iterator++; repr += "]}"; - repr += (++iterator != CallbackHandler::callbacks->end()) ? ", " : ""; + repr += (iterator != CallbackHandler::callbacks->end()) ? ", " : ""; } repr += "]}"; return repr; From 0978acdf8ce5a8d2f3781de6c37e326f3793a9a9 Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Mon, 9 May 2022 17:23:59 +0200 Subject: [PATCH 121/249] Quickfix no binary payload for `0x75` --- src/Debug/debugger.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 3ba1d2d5..74839e21 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -21,7 +21,14 @@ Debugger::Debugger(int socket) { this->socket = socket; } void Debugger::addDebugMessage(size_t len, const uint8_t *buff) { uint8_t *data = this->parseDebugBuffer(len, buff); - if (data != nullptr) { + if (*data == interruptRecvCallbackmapping) { + std::string text = (char *)buff; + auto *msg = + (uint8_t *)acalloc(sizeof(uint8_t), len, "interrupt buffer"); + memcpy(msg, buff, len * sizeof(uint8_t)); + *msg = *data; + this->debugMessages.push_back(msg); + } else if (data != nullptr) { this->debugMessages.push_back(data); } } @@ -243,7 +250,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptRecvCallbackmapping: this->updateCallbackmapping( - m, reinterpret_cast(interruptData + 1)); + m, reinterpret_cast(interruptData + 2)); break; #endif case interruptDUMPCallbackmapping: From 7ab5c9748af016afc9af1dd2aa16d994a3427c1c Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 10 May 2022 08:08:44 +0200 Subject: [PATCH 122/249] Add import callbackmapping Closes #62 --- src/Debug/debugger.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 74839e21..e2ee18ba 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -1000,8 +1000,14 @@ void Debugger::disconnect_drone() { void Debugger::updateCallbackmapping(Module *m, const char *data) const { nlohmann::basic_json<> parsed = nlohmann::json::parse(data); - printf("updateCallbackmapping: %s\n", parsed.dump().c_str()); CallbackHandler::clear_callbacks(); - // TODO for each callback in json: CallbackHandler::add_callback(); + nlohmann::basic_json<> callbacks = *parsed.find("callbacks"); + for (auto &array : callbacks.items()) { + auto callback = array.value().begin(); + for (auto &functions : callback.value().items()) { + CallbackHandler::add_callback( + Callback(m, callback.key(), functions.value())); + } + } } #endif From 8832ccad8f5f087e14857ecc619f15915ac26a9d Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 10 May 2022 09:17:40 +0200 Subject: [PATCH 123/249] Update docs + small fix for ci --- .github/workflows/compile.yml | 1 + documentation/OutOfPlaceDebugging.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 901cadf2..af52b71a 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -46,6 +46,7 @@ jobs: fill-out-template: name: Fill out template files runs-on: ubuntu-latest + if: github.event.pull_request.draft == false steps: - name: Checkout uses: actions/checkout@v2 diff --git a/documentation/OutOfPlaceDebugging.md b/documentation/OutOfPlaceDebugging.md index b1b98985..1259c5c6 100644 --- a/documentation/OutOfPlaceDebugging.md +++ b/documentation/OutOfPlaceDebugging.md @@ -32,3 +32,6 @@ The supported interrupt messages: 3. `interruptPOPEvent (0x72)` tells the VM to remove the event at the front of the queue and process it. 4. `interruptPUSHEvent (0x73)` this messages' code is followed by a json representation of an event to be pushed on the stack. +5. `interruptDUMPCallbackmapping (0x74)` requests a dump of the current callback mapping as json. +6. `interruptRecvCallbackmapping (0x75)` sends a callback mapping as json to replace the current callback mapping. + From d97ee71c7c10c14c822349e7e144647b7de9b81c Mon Sep 17 00:00:00 2001 From: Tom Lauwaerts Date: Tue, 10 May 2022 15:43:22 +0200 Subject: [PATCH 124/249] Fix nullptr exception --- src/Debug/debugger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index e2ee18ba..251757a9 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -21,7 +21,7 @@ Debugger::Debugger(int socket) { this->socket = socket; } void Debugger::addDebugMessage(size_t len, const uint8_t *buff) { uint8_t *data = this->parseDebugBuffer(len, buff); - if (*data == interruptRecvCallbackmapping) { + if (data != nullptr && *data == interruptRecvCallbackmapping) { std::string text = (char *)buff; auto *msg = (uint8_t *)acalloc(sizeof(uint8_t), len, "interrupt buffer"); From fd4c18e9372be11daa8b051b7765ef16b20e3c2c Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Wed, 11 May 2022 08:24:59 +0200 Subject: [PATCH 125/249] added primitives for ESP32 analogwrite --- src/Primitives/arduino.cpp | 41 ++++++++++++++++++++++++++++++++++++- src/Primitives/emulated.cpp | 35 ++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index c3c62bd3..12490709 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -54,7 +54,7 @@ void write_spi_bytes_16_prim(int times, uint32_t color) { } #define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 33 +#define NUM_PRIMITIVES_ARDUINO 36 #define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) @@ -487,6 +487,40 @@ def_prim(clear_pixels, NoneToNoneU32) { return true; } +// Temporary Primitives needed for analogWrite in ESP32 +def_prim(chip_ledc_analog_write, threeToNoneU32) { + uint8_t channel = arg2.uint32; + uint32_t value = arg1.uint32; + uint32_t maxValue = arg0.uint32; + + // printf("chip_ledc_analog_write(%u, %u, %u)\n", channel, value, maxValue); + // calculate duty, 4095 from 2 ^ 12 - 1 + uint32_t duty = (4095 / maxValue) * min(value, maxValue); + + ledcWrite(channel, duty); + pop_args(3); + return true; +} + +def_prim(chip_ledc_setup, threeToNoneU32) { + uint32_t channel = arg2.uint32; + uint32_t freq = arg1.uint32; + uint32_t ledc_timer = arg0.uint32; + // printf("chip_ledc_setup(%u, %u, %u)\n", channel, freq, ledc_timer); + ledcSetup(channel, freq, ledc_timer); + pop_args(3); + return true; +} + +def_prim(chip_ledc_attach_pin, twoToNoneU32) { + uint32_t pin = arg1.uint32; + uint32_t channel = arg0.uint32; + // printf("chip_ledc_attach_pin(%u,%u)\n", pin, channel); + ledcAttachPin(pin, channel); + pop_args(2); + return true; +} + // INTERRUPTS class Interrupt { @@ -857,6 +891,11 @@ void install_primitives() { install_primitive(set_pixel_color); install_primitive(clear_pixels); install_primitive(show_pixels); + + // temporary primitives needed for analogWrite in ESP32 + install_primitive(chip_ledc_analog_write); + install_primitive(chip_ledc_setup); + install_primitive(chip_ledc_attach_pin); } //------------------------------------------------------ diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 7cef117d..edcea8aa 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -25,7 +25,7 @@ #include "primitives.h" #define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 24 +#define NUM_PRIMITIVES_ARDUINO 27 #define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) @@ -428,6 +428,34 @@ def_prim(subscribe_interrupt, threeToNoneU32) { pop_args(3); return true; } + +// Temporary Primitives needed for analogWrite in ESP32 +def_prim(chip_ledc_analog_write, threeToNoneU32) { + uint8_t channel = arg2.uint32; + uint32_t value = arg1.uint32; + uint32_t maxValue = arg0.uint32; + // calculate duty, 4095 from 2 ^ 12 - 1 + printf("chip_ledc_analog_write(%u, %u, %u)\n", channel, value, maxValue); + pop_args(3); + return true; +} + +def_prim(chip_ledc_setup, threeToNoneU32) { + uint32_t channel = arg2.uint32; + uint32_t freq = arg1.uint32; + uint32_t ledc_timer = arg0.uint32; + printf("chip_ledc_setup(%u, %u, %u)\n", channel, freq, ledc_timer); + pop_args(3); + return true; +} + +def_prim(chip_ledc_attach_pin, twoToNoneU32) { + uint32_t pin = arg1.uint32; + uint32_t channel = arg0.uint32; + printf("chip_ledc_attach_pin(%u,%u)\n", pin, channel); + pop_args(2); + return true; +} //------------------------------------------------------ // Installing all the primitives //------------------------------------------------------ @@ -459,6 +487,11 @@ void install_primitives() { install_primitive(set_pixel_color); install_primitive(clear_pixels); install_primitive(show_pixels); + + // temporary mock primitives needed for analogWrite in ESP32 + install_primitive(chip_ledc_analog_write); + install_primitive(chip_ledc_setup); + install_primitive(chip_ledc_attach_pin); } //------------------------------------------------------ From 546d9800ea3e8cfe4057db07ebbf6929eb38e468 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 10:30:32 +0200 Subject: [PATCH 126/249] Fix compilation error --- src/Debug/debugger.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 8da8ff96..715b8a68 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -1,10 +1,13 @@ #pragma once +#include #include // std::queue #include #include #include - +#ifndef ARDUINO +#include +#endif struct Module; struct Block; struct StackValue; From a766d50efd486d057b7b350e992c40a94a4f2ac5 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 10:42:34 +0200 Subject: [PATCH 127/249] Add socket server to warduino template in benchmarks --- benchmarks/.gitignore | 2 ++ benchmarks/tasks/makefile | 12 +++++++ benchmarks/warduino.ino.template | 56 ++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore index c4f050ed..f027464a 100644 --- a/benchmarks/.gitignore +++ b/benchmarks/.gitignore @@ -3,3 +3,5 @@ bin/ output *.csv + +.config diff --git a/benchmarks/tasks/makefile b/benchmarks/tasks/makefile index 53f9096b..35ef926b 100644 --- a/benchmarks/tasks/makefile +++ b/benchmarks/tasks/makefile @@ -1,5 +1,16 @@ TASKS=$(patsubst %/.,%,$(wildcard */.)) +CONFIG = .config +include ${CONFIG} + +ifndef SSID +$(error SSID is not set. Use a .config file.) +endif + +ifndef PASSWORD +$(error PASSWORD is not set. Use a .config file.) +endif + all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/wasm3/wasm3.ino,$(TASKS)) $(addsuffix /wast/impl.wast,$(TASKS)) $(addsuffix /wast/impl.wasm,$(TASKS)) $(addsuffix /c/arduino.ino,$(TASKS)) echo $(TASKS) @@ -9,6 +20,7 @@ all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/wasm3/w -mkdir $(@D) xxd -i $< $@ sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ + sed -i 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' $@ cat ../warduino.ino.template >> $@ %/wast/wasm3/wasm3.ino: %/wast/impl.wasm diff --git a/benchmarks/warduino.ino.template b/benchmarks/warduino.ino.template index f07a8a3c..cb303d07 100644 --- a/benchmarks/warduino.ino.template +++ b/benchmarks/warduino.ino.template @@ -1,40 +1,62 @@ #include "Arduino.h" #include "WARDuino.h" -WARDuino wac; +WARDuino* wac = WARDuino::instance(); +SocketServer* server; +ServerCredentials serverCredentials = {"{{SSID}}", "{{Password}}"}; +uint16_t pullportno = 8080; +uint16_t pushportno = 8081; #define D1 5 -volatile bool handelingInterrupt = false; -uint8_t buff[100] = {0}; -uint8_t buff_len = 0; +void startDebuggerStd(void* pvParameter) { + int valread; + uint8_t buffer[1024] = {0}; + wac->debugger->socket = fileno(stdout); + write(fileno(stdout), "Got a message ... \n", 19); + while (true) { + // taskYIELD(); + // vTaskDelay(100 / portTICK_PERIOD_MS); + yield(); -void ICACHE_RAM_ATTR handleInput() { - if (handelingInterrupt) return; - handelingInterrupt = true; - interrupts(); - - while (Serial.available()) { - size_t buff_len = 0; while (Serial.available()) { - buff[buff_len++] = (int8_t) Serial.read(); - } - if (buff_len) { - wac.handleInterrupt(buff_len, buff); + size_t buff_len = 0; + while (Serial.available()) { + buffer[buff_len++] = (int8_t)Serial.read(); + } + if (buff_len) { + write(fileno(stdout), "Reading message ..... \n", 19); + fflush(stdout); + wac->handleInterrupt(valread - 1, buffer); + write(fileno(stdout), buffer, valread); + fflush(stdout); + } } } - handelingInterrupt = false; +} + +void handleInterrupt(size_t len, uint8_t* buff) { + wac->handleInterrupt(len, buff); } void setup() { Serial.begin(115200); attachInterrupt(D1, handleInput, CHANGE); + + // create & connect SocketServer + SocketServer::createServer(pullportno, pushportno, &handleInterrupt); + server = SocketServer::getServer(); + server->connect2Wifi(&serverCredentials); } void loop() { + disableCore0WDT(); Module *m = wac.load_module(impl_wasm, impl_wasm_len, {}); - delay(1000); + server->begin(); + + printf("LOADED \n\n"); + xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); for (int i = 0; i < 10; i++) { wac.run_module(m); From 505d1bbba015dcc7e614cbd4487b67c42f79ec12 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 11:10:19 +0200 Subject: [PATCH 128/249] Update boardmanager install instructions --- documentation/InstallArduinoESP32.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/documentation/InstallArduinoESP32.md b/documentation/InstallArduinoESP32.md index f0e15272..fe2c662f 100644 --- a/documentation/InstallArduinoESP32.md +++ b/documentation/InstallArduinoESP32.md @@ -26,7 +26,13 @@ board_manager: - https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json ``` -4. Install the ESP32 platform: +4. Update index + +``` +arduino-cli core update-index +``` + +5. Install the ESP32 platform: ``` arduino-cli core install esp32:esp32 From 789602221c46aa300f6dd554c6238bbca2cef5fb Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 11:10:37 +0200 Subject: [PATCH 129/249] Fix some compile errors in benchmarks Remaining error: json lib not found --- benchmarks/benchmarks.cpp | 4 ++-- benchmarks/makefile | 22 +++++++++++++--------- benchmarks/tasks/makefile | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/benchmarks/benchmarks.cpp b/benchmarks/benchmarks.cpp index a3f145a9..50e39dd9 100644 --- a/benchmarks/benchmarks.cpp +++ b/benchmarks/benchmarks.cpp @@ -2,7 +2,7 @@ #include -#include "../debug.h" +#include "../src/Utils/macros.h" #include "../src/WARDuino.h" #include "timer.h" @@ -48,7 +48,7 @@ int run_benchmarks(size_t num_benchmarks, string benchmarks[], char path[MAX_PATH]; unsigned char bytes[MAX_BYTE_CODE_SIZE]; unsigned int bytes_length; - auto *w = new WARDuino(); + auto *w = WARDuino::instance(); size_t correct = 0; for (size_t i = 0; i < num_benchmarks; i++) { string name = benchmarks[i]; diff --git a/benchmarks/makefile b/benchmarks/makefile index 3ae306e9..5b762243 100644 --- a/benchmarks/makefile +++ b/benchmarks/makefile @@ -26,15 +26,19 @@ TARGET = warduino_benchmark TASKS = $(notdir $(patsubst %/.,%,$(wildcard tasks/*/.))) CXXSOURCES = \ - ../mem.cpp \ - ../util.cpp \ - ../util_arduino.cpp \ - ../interrupt_operations.cpp \ - ../debug.cpp \ - ../WARDuino.cpp \ - ../primitives.cpp \ - ../instructions.cpp \ - ../glue.cpp \ + ../src/Memory/mem.cpp \ + ../src/Utils/util.cpp \ + ../src/Utils/util_arduino.cpp \ + ../src/Debug/debugger.cpp \ + ../src/Utils/macros.cpp \ + ../src/WARDuino/WARDuino.cpp \ + ../src/WARDuino/CallbackHandler.cpp \ + ../src/Primitives/emulated.cpp \ + ../src/Interpreter/instructions.cpp \ + ../src/RFC/rfc.cpp \ + ../src/RFC/proxy_server.cpp \ + ../src/RFC/SocketServer.cpp \ + ../src/Utils/sockets.cpp \ benchmarks.cpp all: $(OUTPUTDIR)$(TARGET) $(addprefix tasks/,$(addsuffix /wast/impl.wasm, $(TASKS))) diff --git a/benchmarks/tasks/makefile b/benchmarks/tasks/makefile index 35ef926b..364b3faa 100644 --- a/benchmarks/tasks/makefile +++ b/benchmarks/tasks/makefile @@ -16,7 +16,7 @@ all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/wasm3/w echo $(TASKS) -%/wast/warduino/warduino.ino: %/wast/impl.wasm +%/wast/warduino/warduino.ino: .config %/wast/impl.wasm -mkdir $(@D) xxd -i $< $@ sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ From 0bd2e7b60182273e95da668fe37775b208adaa05 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 11:18:25 +0200 Subject: [PATCH 130/249] Use arduino-cli in scripts/upload --- scripts/upload | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/upload b/scripts/upload index 9f3e5059..500f024a 100755 --- a/scripts/upload +++ b/scripts/upload @@ -20,13 +20,13 @@ fi case "$device" in "ESP32") - exec arduino --upload "$file" --board "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$@" + arduino-cli -v compile --fqbn "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" ;; "ESP32WROVER") - exec arduino --upload "$file" --board "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$@" + arduino-cli -v compile --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" ;; "ESP8266") - exec arduino --upload "$file" --board "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$@" + arduino-cli -v compile --fqbn "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$file" "$@" ;; *) echo "Unknown device: $device" From 5a00e34088305023782ccb9da56bf7731046760b Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 11:22:33 +0200 Subject: [PATCH 131/249] Fix ino template benchmarks --- benchmarks/warduino.ino.template | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/benchmarks/warduino.ino.template b/benchmarks/warduino.ino.template index cb303d07..3263da23 100644 --- a/benchmarks/warduino.ino.template +++ b/benchmarks/warduino.ino.template @@ -10,6 +10,27 @@ uint16_t pushportno = 8081; #define D1 5 +volatile bool handelingInterrupt = false; +uint8_t buff[100] = {0}; +uint8_t buff_len = 0; + +void ICACHE_RAM_ATTR handleInput() { + if (handelingInterrupt) return; + handelingInterrupt = true; + interrupts(); + + while (Serial.available()) { + size_t buff_len = 0; + while (Serial.available()) { + buff[buff_len++] = (int8_t) Serial.read(); + } + if (buff_len) { + wac->handleInterrupt(buff_len, buff); + } + } + handelingInterrupt = false; +} + void startDebuggerStd(void* pvParameter) { int valread; uint8_t buffer[1024] = {0}; @@ -52,16 +73,16 @@ void setup() { void loop() { disableCore0WDT(); - Module *m = wac.load_module(impl_wasm, impl_wasm_len, {}); + Module *m = wac->load_module(impl_wasm, impl_wasm_len, {}); server->begin(); printf("LOADED \n\n"); xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); for (int i = 0; i < 10; i++) { - wac.run_module(m); + wac->run_module(m); printf("%d: %u\n", i, m->stack->value.uint32); } - wac.unload_module(m); + wac->unload_module(m); printf("DONE\n\n"); } \ No newline at end of file From e9741a81b944ea7522b5e65885963b6d821b514b Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 11:27:56 +0200 Subject: [PATCH 132/249] Fix makefile --- benchmarks/tasks/makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/benchmarks/tasks/makefile b/benchmarks/tasks/makefile index 364b3faa..55288269 100644 --- a/benchmarks/tasks/makefile +++ b/benchmarks/tasks/makefile @@ -16,12 +16,12 @@ all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/wasm3/w echo $(TASKS) -%/wast/warduino/warduino.ino: .config %/wast/impl.wasm +%/wast/warduino/warduino.ino: %/wast/impl.wasm .config -mkdir $(@D) xxd -i $< $@ - sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ - sed -i 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' $@ + sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ cat ../warduino.ino.template >> $@ + sed -i 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' $@ %/wast/wasm3/wasm3.ino: %/wast/impl.wasm -mkdir $(@D) From ab21f50c4f84ebc488446382c5e736390b3914e0 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 13:22:04 +0200 Subject: [PATCH 133/249] Fix bench upload --- benchmarks/warduino_bench.sh | 4 ++-- scripts/upload | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/benchmarks/warduino_bench.sh b/benchmarks/warduino_bench.sh index 6ebf364f..ebdd0e3c 100755 --- a/benchmarks/warduino_bench.sh +++ b/benchmarks/warduino_bench.sh @@ -11,10 +11,10 @@ make -C tasks all cat bench.list | while read l; do echo $l | tee -a $1 - ../scripts/upload ${BOARD:-ESP32WROVER} ./tasks/$l/wast/warduino/warduino.ino 2>&1 >"$tmpfile" + ../scripts/upload ${BOARD:-ESP32WROVER} ./tasks/$l/wast/warduino/warduino.ino -p /dev/ttyUSB0 2>&1 >"$tmpfile" if [ "$?" -eq "0" ]; then echo "flashed" - python flash_and_check.py | tee -a $1 + python3 flash_and_check.py | tee -a $1 else cat $tmpfile echo "FAILED!" diff --git a/scripts/upload b/scripts/upload index 500f024a..80f827ee 100755 --- a/scripts/upload +++ b/scripts/upload @@ -20,13 +20,13 @@ fi case "$device" in "ESP32") - arduino-cli -v compile --fqbn "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" + arduino-cli upload --fqbn "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" ;; "ESP32WROVER") - arduino-cli -v compile --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" + arduino-cli upload --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" ;; "ESP8266") - arduino-cli -v compile --fqbn "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$file" "$@" + arduino-cli upload --fqbn "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$file" "$@" ;; *) echo "Unknown device: $device" From 99ca305ef35603fb52b80b0856e62fafc406276d Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 13:41:48 +0200 Subject: [PATCH 134/249] Fix upload script --- scripts/upload | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/upload b/scripts/upload index 80f827ee..c27ff9f7 100755 --- a/scripts/upload +++ b/scripts/upload @@ -20,12 +20,15 @@ fi case "$device" in "ESP32") + arduino-cli compile --fqbn "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" arduino-cli upload --fqbn "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" ;; "ESP32WROVER") + arduino-cli compile --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" arduino-cli upload --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" ;; "ESP8266") + arduino-cli compile --fqbn "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$file" arduino-cli upload --fqbn "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$file" "$@" ;; *) From 6e7a5ffe49c57a1ff4320a40f8f350a5da19b9c6 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 13:47:40 +0200 Subject: [PATCH 135/249] Move socket bench to seperate edward.ino Restores previous warduino.ino Adds edward as seperate platform to bench scripts and makefile --- benchmarks/all_bench.sh | 6 +++ benchmarks/edward.ino.template | 88 ++++++++++++++++++++++++++++++++ benchmarks/edward_bench.sh | 23 +++++++++ benchmarks/tasks/makefile | 12 +++-- benchmarks/warduino.ino.template | 60 +++------------------- 5 files changed, 134 insertions(+), 55 deletions(-) create mode 100644 benchmarks/edward.ino.template create mode 100755 benchmarks/edward_bench.sh diff --git a/benchmarks/all_bench.sh b/benchmarks/all_bench.sh index 9ed673bf..f754fc69 100755 --- a/benchmarks/all_bench.sh +++ b/benchmarks/all_bench.sh @@ -26,6 +26,10 @@ sleep 5 ./warduino_bench.sh $tmpdir/warduino to_csv $tmpdir/warduino +sleep 5 +./edward_bench.sh $tmpdir/edward +to_csv $tmpdir/edward + sleep 5 ./wasm3_bench.sh $tmpdir/wasm3 to_csv $tmpdir/wasm3 @@ -38,6 +42,8 @@ echo "# Espruino" cat $tmpdir/espruino echo "# Warduino" cat $tmpdir/warduino +echo "# Edward" +cat $tmpdir/edward echo "# Wasm3" cat $tmpdir/wasm3 echo "# Native" diff --git a/benchmarks/edward.ino.template b/benchmarks/edward.ino.template new file mode 100644 index 00000000..721cfe94 --- /dev/null +++ b/benchmarks/edward.ino.template @@ -0,0 +1,88 @@ +#include "Arduino.h" +#include "WARDuino.h" + +WARDuino* wac = WARDuino::instance(); + +SocketServer* server; +ServerCredentials serverCredentials = {"{{SSID}}", "{{Password}}"}; +uint16_t pullportno = 8080; +uint16_t pushportno = 8081; + +#define D1 5 + +volatile bool handelingInterrupt = false; +uint8_t buff[100] = {0}; +uint8_t buff_len = 0; + +void ICACHE_RAM_ATTR handleInput() { + if (handelingInterrupt) return; + handelingInterrupt = true; + interrupts(); + + while (Serial.available()) { + size_t buff_len = 0; + while (Serial.available()) { + buff[buff_len++] = (int8_t)Serial.read(); + } + if (buff_len) { + wac->handleInterrupt(buff_len, buff); + } + } + handelingInterrupt = false; +} + +void startDebuggerStd(void* pvParameter) { + int valread; + uint8_t buffer[1024] = {0}; + wac->debugger->socket = fileno(stdout); + write(fileno(stdout), "Got a message ... \n", 19); + while (true) { + // taskYIELD(); + // vTaskDelay(100 / portTICK_PERIOD_MS); + yield(); + + while (Serial.available()) { + size_t buff_len = 0; + while (Serial.available()) { + buffer[buff_len++] = (int8_t)Serial.read(); + } + if (buff_len) { + write(fileno(stdout), "Reading message ..... \n", 19); + fflush(stdout); + wac->handleInterrupt(valread - 1, buffer); + write(fileno(stdout), buffer, valread); + fflush(stdout); + } + } + } +} + +void handleInterrupt(size_t len, uint8_t* buff) { + wac->handleInterrupt(len, buff); +} + +void setup() { + Serial.begin(115200); + attachInterrupt(D1, handleInput, CHANGE); + + // create & connect SocketServer + SocketServer::createServer(pullportno, pushportno, &handleInterrupt); + server = SocketServer::getServer(); + server->connect2Wifi(&serverCredentials); +} + +void loop() { + disableCore0WDT(); + Module* m = wac->load_module(impl_wasm, impl_wasm_len, {}); + server->begin(); + + printf("LOADED \n\n"); + xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); + printf("START\n\n"); + for (int i = 0; i < 10; i++) { + wac->run_module(m); + printf("%d: %u\n", i, m->stack->value.uint32); + } + wac->unload_module(m); + printf("DONE\n\n"); +} \ No newline at end of file diff --git a/benchmarks/edward_bench.sh b/benchmarks/edward_bench.sh new file mode 100755 index 00000000..7efea3c9 --- /dev/null +++ b/benchmarks/edward_bench.sh @@ -0,0 +1,23 @@ +#!/usr/bin/sh +# Name: Upload all programs in bench.list to arduino (WARDuino) and time +# By Robbert Gurdeep Singh +################################################################################ +tmpfile="$(mktemp --tmpdir)" +trap "rm '$tmpfile'" EXIT +cd "$(dirname "$0")" +date >$1 +make clean all +make -C tasks all + +cat bench.list | while read l; do + echo $l | tee -a $1 + ../scripts/upload ${BOARD:-ESP32WROVER} ./tasks/$l/wast/edward/edward.ino -p /dev/ttyUSB0 2>&1 >"$tmpfile" + if [ "$?" -eq "0" ]; then + echo "flashed" + python3 flash_and_check.py | tee -a $1 + else + cat $tmpfile + echo "FAILED!" + exit 1 + fi +done diff --git a/benchmarks/tasks/makefile b/benchmarks/tasks/makefile index 55288269..39570e31 100644 --- a/benchmarks/tasks/makefile +++ b/benchmarks/tasks/makefile @@ -11,16 +11,22 @@ ifndef PASSWORD $(error PASSWORD is not set. Use a .config file.) endif -all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/wasm3/wasm3.ino,$(TASKS)) $(addsuffix /wast/impl.wast,$(TASKS)) $(addsuffix /wast/impl.wasm,$(TASKS)) $(addsuffix /c/arduino.ino,$(TASKS)) +all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/edward/edward.ino,$(TASKS)) $(addsuffix /wast/wasm3/wasm3.ino,$(TASKS)) $(addsuffix /wast/impl.wast,$(TASKS)) $(addsuffix /wast/impl.wasm,$(TASKS)) $(addsuffix /c/arduino.ino,$(TASKS)) echo $(TASKS) -%/wast/warduino/warduino.ino: %/wast/impl.wasm .config +%/wast/warduino/warduino.ino: %/wast/impl.wasm -mkdir $(@D) xxd -i $< $@ sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ cat ../warduino.ino.template >> $@ + +%/wast/edward/edward.ino: %/wast/impl.wasm .config + -mkdir $(@D) + xxd -i $< $@ + sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ + cat ../edward.ino.template >> $@ sed -i 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' $@ %/wast/wasm3/wasm3.ino: %/wast/impl.wasm @@ -55,5 +61,5 @@ all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/wasm3/w wasm2wat -f $< > $@ clean: - -find -iname "impl.wast" -o -iname "impl.wasm" -o -iname "arduino.ino" -o -iname "warduino.ino" -o -iname "wasm3.ino" | xargs rm + -find -iname "impl.wast" -o -iname "impl.wasm" -o -iname "arduino.ino" -o -iname "warduino.ino" -o -iname "edward.ino" -o -iname "wasm3.ino" | xargs rm diff --git a/benchmarks/warduino.ino.template b/benchmarks/warduino.ino.template index 3263da23..a101b76e 100644 --- a/benchmarks/warduino.ino.template +++ b/benchmarks/warduino.ino.template @@ -1,12 +1,7 @@ #include "Arduino.h" #include "WARDuino.h" -WARDuino* wac = WARDuino::instance(); - -SocketServer* server; -ServerCredentials serverCredentials = {"{{SSID}}", "{{Password}}"}; -uint16_t pullportno = 8080; -uint16_t pushportno = 8081; +WARDuino wac; #define D1 5 @@ -22,67 +17,28 @@ void ICACHE_RAM_ATTR handleInput() { while (Serial.available()) { size_t buff_len = 0; while (Serial.available()) { - buff[buff_len++] = (int8_t) Serial.read(); + buff[buff_len++] = (int8_t)Serial.read(); } if (buff_len) { - wac->handleInterrupt(buff_len, buff); + wac.handleInterrupt(buff_len, buff); } } handelingInterrupt = false; } -void startDebuggerStd(void* pvParameter) { - int valread; - uint8_t buffer[1024] = {0}; - wac->debugger->socket = fileno(stdout); - write(fileno(stdout), "Got a message ... \n", 19); - while (true) { - // taskYIELD(); - // vTaskDelay(100 / portTICK_PERIOD_MS); - yield(); - - while (Serial.available()) { - size_t buff_len = 0; - while (Serial.available()) { - buffer[buff_len++] = (int8_t)Serial.read(); - } - if (buff_len) { - write(fileno(stdout), "Reading message ..... \n", 19); - fflush(stdout); - wac->handleInterrupt(valread - 1, buffer); - write(fileno(stdout), buffer, valread); - fflush(stdout); - } - } - } -} - -void handleInterrupt(size_t len, uint8_t* buff) { - wac->handleInterrupt(len, buff); -} - void setup() { Serial.begin(115200); attachInterrupt(D1, handleInput, CHANGE); - - // create & connect SocketServer - SocketServer::createServer(pullportno, pushportno, &handleInterrupt); - server = SocketServer::getServer(); - server->connect2Wifi(&serverCredentials); } void loop() { - disableCore0WDT(); - Module *m = wac->load_module(impl_wasm, impl_wasm_len, {}); - server->begin(); - - printf("LOADED \n\n"); - xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); + Module *m = wac.load_module(impl_wasm, impl_wasm_len, {}); + delay(1000); printf("START\n\n"); for (int i = 0; i < 10; i++) { - wac->run_module(m); + wac.run_module(m); printf("%d: %u\n", i, m->stack->value.uint32); } - wac->unload_module(m); + wac.unload_module(m); printf("DONE\n\n"); -} \ No newline at end of file +} From 2d09e9a085642fa0191d2a3df689d34470c00c91 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 13:52:08 +0200 Subject: [PATCH 136/249] Use singleton WD in warduino.ino.template --- benchmarks/warduino.ino.template | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/benchmarks/warduino.ino.template b/benchmarks/warduino.ino.template index a101b76e..d682df8d 100644 --- a/benchmarks/warduino.ino.template +++ b/benchmarks/warduino.ino.template @@ -1,7 +1,7 @@ #include "Arduino.h" #include "WARDuino.h" -WARDuino wac; +WARDuino* wac = WARDuino::instance(); #define D1 5 @@ -20,7 +20,7 @@ void ICACHE_RAM_ATTR handleInput() { buff[buff_len++] = (int8_t)Serial.read(); } if (buff_len) { - wac.handleInterrupt(buff_len, buff); + wac->handleInterrupt(buff_len, buff); } } handelingInterrupt = false; @@ -32,13 +32,13 @@ void setup() { } void loop() { - Module *m = wac.load_module(impl_wasm, impl_wasm_len, {}); + Module *m = wac->load_module(impl_wasm, impl_wasm_len, {}); delay(1000); printf("START\n\n"); for (int i = 0; i < 10; i++) { - wac.run_module(m); + wac->run_module(m); printf("%d: %u\n", i, m->stack->value.uint32); } - wac.unload_module(m); + wac->unload_module(m); printf("DONE\n\n"); } From c85bc8ee76e71e7ec05ed13fe9b4463ff0c1aa8c Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 25 May 2022 13:52:48 +0200 Subject: [PATCH 137/249] Add edward to tasks/.gitignore --- benchmarks/tasks/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/benchmarks/tasks/.gitignore b/benchmarks/tasks/.gitignore index 60b2a44a..f97f5809 100644 --- a/benchmarks/tasks/.gitignore +++ b/benchmarks/tasks/.gitignore @@ -1,4 +1,5 @@ */wast/warduino/ +*/wast/edward/ */wast/wasm3/ */wast/*.wasm */wast/*.wast From 2824cb08189b10cecd70906f68d295d6d7432efb Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 30 May 2022 15:38:18 +0200 Subject: [PATCH 138/249] Make example more stable --- examples/assemblyscript/lib/warduino.ts | 4 ++-- examples/assemblyscript/main/smartlamp.ts | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/assemblyscript/lib/warduino.ts b/examples/assemblyscript/lib/warduino.ts index d827eff5..4d712a07 100644 --- a/examples/assemblyscript/lib/warduino.ts +++ b/examples/assemblyscript/lib/warduino.ts @@ -11,7 +11,7 @@ @external("env", "wifi_connect") declare function _wifi_connect(ssid: ArrayBuffer, length: i32, password: ArrayBuffer, size: i32): void; @external("env", "wifi_status") export declare function wifi_status(): i32; -@external("env", "wifi_connected") declare function _wifi_status(): i32; +@external("env", "wifi_connected") declare function _wifi_connected(): i32; @external("env", "wifi_localip") declare function _wifi_localip(buff: ArrayBuffer, buffer_size: u32): i32; @external("env", "http_get") declare function _http_get(url: ArrayBuffer, url_len: u32, buffer: ArrayBuffer, buffer_size: u32): i32; @@ -56,7 +56,7 @@ export function print(text: string): void { export function wifi_connected(): bool { - return _wifi_status() == 1; + return _wifi_connected() === 1; } export function wifi_connect(ssid: string, password: string): void { diff --git a/examples/assemblyscript/main/smartlamp.ts b/examples/assemblyscript/main/smartlamp.ts index 67bf90fa..3b8bcfa9 100644 --- a/examples/assemblyscript/main/smartlamp.ts +++ b/examples/assemblyscript/main/smartlamp.ts @@ -7,10 +7,12 @@ const PASSWORD = "network-password"; const CLIENT_ID = "random-mqtt-client-id"; function until_connected(connect: () => void, - connected: () => boolean): void { + connected: () => boolean, + retry: boolean = false): void { + connect(); while (!connected()) { wd.delay(1000); - connect(); + if (retry) connect(); } } @@ -48,7 +50,8 @@ export function main(): void { wd.mqtt_init("192.168.0.24", 1883); until_connected( () => { wd.mqtt_connect(CLIENT_ID); wd.mqtt_loop(); }, - () => { return wd.mqtt_connected(); }); + () => { return wd.mqtt_connected(); }, + true); // Subscribe to MQTT topic and turn on LED wd.mqtt_subscribe("LED", callback); From 85a4cc8d4f07476b86011421177558c957d59123 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 30 May 2022 15:40:48 +0200 Subject: [PATCH 139/249] Clean examples --- examples/assemblyscript/package-lock.json | 55 ++++++++++++++++++++++- examples/blinkm5stickc/blink.wast | 54 ---------------------- examples/factorial/fac.wast | 42 ----------------- 3 files changed, 53 insertions(+), 98 deletions(-) delete mode 100644 examples/blinkm5stickc/blink.wast delete mode 100644 examples/factorial/fac.wast diff --git a/examples/assemblyscript/package-lock.json b/examples/assemblyscript/package-lock.json index 7d6be6f1..4cfe17db 100644 --- a/examples/assemblyscript/package-lock.json +++ b/examples/assemblyscript/package-lock.json @@ -1,8 +1,59 @@ { "name": "smartlamp", - "version": "1.0.0", - "lockfileVersion": 1, + "version": "0.1.0", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "smartlamp", + "version": "0.1.0", + "license": "ISC", + "dependencies": { + "@assemblyscript/loader": "^0.17.1" + }, + "devDependencies": { + "assemblyscript": "^0.17.14" + } + }, + "node_modules/@assemblyscript/loader": { + "version": "0.17.14", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.17.14.tgz", + "integrity": "sha512-+PVTOfla/0XMLRTQLJFPg4u40XcdTfon6GGea70hBGi8Pd7ZymIXyVUR+vK8wt5Jb4MVKTKPIz43Myyebw5mZA==" + }, + "node_modules/assemblyscript": { + "version": "0.17.14", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.17.14.tgz", + "integrity": "sha512-TLuwNvZAIH26wu2puKpAJokzLp10kJkVXxbgDjFFmbW9VF/qg7rkmi0hjsiu41bjoH1UaVgY4vYvbbUeOHtKyg==", + "dev": true, + "dependencies": { + "binaryen": "98.0.0-nightly.20201109", + "long": "^4.0.0" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/binaryen": { + "version": "98.0.0-nightly.20201109", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-98.0.0-nightly.20201109.tgz", + "integrity": "sha512-iRarAqdH5lMWlMBzrDuJgLYJR2g4QXk93iYE2zpr6gEZkb/jCgDpPUXdhuN11Ge1zZ/6By4DwA1mmifcx7FWaw==", + "dev": true, + "bin": { + "wasm-opt": "bin/wasm-opt" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "dev": true + } + }, "dependencies": { "@assemblyscript/loader": { "version": "0.17.14", diff --git a/examples/blinkm5stickc/blink.wast b/examples/blinkm5stickc/blink.wast deleted file mode 100644 index 0e0ed2df..00000000 --- a/examples/blinkm5stickc/blink.wast +++ /dev/null @@ -1,54 +0,0 @@ -(module - ;; Type declarations - (type $int32->int32->void (func (param i32 i32))) - (type $int32->void (func (param i32))) - (type $void->void (func)) - - ;; Imports from the WARDuino VM - (import "env" "chip_delay" (func $env.chip_delay (type $int32->void))) - (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $int32->int32->void))) - (import "env" "chip_digital_write" (func $env.chip_digital_write (type $int32->int32->void))) - (import "env" "print_int" (func $env.print_int (type $int32->void))) - - - ;; Non-mutable globals - (global $led i32 (i32.const 10)) - (global $on i32 (i32.const 1)) - (global $off i32 (i32.const 0)) - - ;; Initialise function (private) - (func $init (type $void->void) - ;; Set pin mode - global.get $led - i32.const 2 - call $env.chip_pin_mode) - - ;; Blink function (public) - (func $blink (type $void->void) - ;; Declare local $delay - (local $delay i32) - i32.const 1000 - local.set $delay - - ;; Initialise - call $init - - ;; Blink in infinite loop - loop $infinite - global.get $led - global.get $led - call $env.print_int ;;print led nr - global.get $on - call $env.chip_digital_write ;; turn led on - local.get $delay - call $env.chip_delay ;; wait - global.get $led - global.get $off - call $env.chip_digital_write ;; turn led off - local.get $delay - call $env.chip_delay ;; wait - br $infinite ;; jump back to start of loop - end) - - ;; Export blink as function - (export "main" (func $blink))) diff --git a/examples/factorial/fac.wast b/examples/factorial/fac.wast deleted file mode 100644 index 3e153e3d..00000000 --- a/examples/factorial/fac.wast +++ /dev/null @@ -1,42 +0,0 @@ -(module - (import "env" "print_int" (func $print (type $i2v))) - - (; Type declarations ;) - (type $i2v (func (param i32) (result))) - (type $i32toi32 (func (param i32) (result i32))) - (type $v2v (func (param) (result))) - - (; Define one function ;) - (export "main" (func $main)) - (memory 2) - (table funcref (elem $fac $dummy)) - - (global $g1 i32 (i32.const 0)) - (global $g2 (mut i32) (i32.const 0)) - - (func $dummy (type $i2v)) - (func $fac (type $i32toi32) - (i32.gt_s - (local.get 0) - (i32.const 1)) - (if (result i32) - (then - (i32.sub - (local.get 0) - (i32.const 1)) - (call $fac) - (local.get 0) - i32.mul) - (else - (i32.const 1)))) - - (func $main (type $v2v) - (local $arg i32) - (local.set $arg (i32.const 5)) - (loop - (local.get $arg) - (call $fac) - (call $print) - (br 0))) -) - From d139b0bd608708903cfa60290b6d25d0df13406a Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 30 May 2022 17:22:46 +0200 Subject: [PATCH 140/249] Start ESP-IDF primitive implementations --- platforms/ESP-IDF/CMakeLists.txt | 2 +- src/Primitives/idf.cpp | 262 +++++++++++++++++++++++++++++++ 2 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 src/Primitives/idf.cpp diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index 845b0f2c..88bd7212 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -5,7 +5,7 @@ set(SOURCE_FILES ../../src/Debug/debugger.cpp ../../src/Utils/macros.cpp ../../src/WARDuino/WARDuino.cpp - ../../src/Primitives/emulated.cpp + ../../src/Primitives/idf.cpp ../../src/Interpreter/instructions.cpp ../../src/WARDuino/CallbackHandler.cpp ) diff --git a/src/Primitives/idf.cpp b/src/Primitives/idf.cpp new file mode 100644 index 00000000..ae755d44 --- /dev/null +++ b/src/Primitives/idf.cpp @@ -0,0 +1,262 @@ +#ifndef ARDUINO + +/** + * This file lists the primitives of the language and stores them in the + * primitives + * + * Adding a primitive: + * 1) Bump up the NUM_PRIMITIVES constant + * 2) Define _type + * 3) Define a function void primitive(Module* m) + * 4) Extend the install_primitives function + * + */ +#include + +#include +#include +#include +#include +#include + +#include "../Memory/mem.h" +#include "../Utils/macros.h" +#include "../Utils/util.h" +#include "driver/gpio.h" +#include "primitives.h" + +#define NUM_PRIMITIVES 0 +#define NUM_PRIMITIVES_ARDUINO 2 + +#define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) + +// Global index for installing primitives +int prim_index = 0; + +double sensor_emu = 0; + +/* + Private macros to install a primitive +*/ +#define install_primitive(prim_name) \ + { \ + dbg_info("installing primitive number: %d of %d with name: %s\n", \ + prim_index + 1, ALL_PRIMITIVES, #prim_name); \ + if (prim_index < ALL_PRIMITIVES) { \ + PrimitiveEntry *p = &primitives[prim_index++]; \ + p->name = #prim_name; \ + p->f = &(prim_name); \ + } else { \ + FATAL("pim_index out of bounds"); \ + } \ + } + +#define def_prim(function_name, type) \ + Type function_name##_type = type; \ + bool function_name(Module *m) + +// TODO: use fp +#define pop_args(n) m->sp -= n +#define get_arg(m, arg) m->stack[(m)->sp - (arg)].value +#define pushUInt32(arg) m->stack[++m->sp].value.uint32 = arg +#define pushInt32(arg) m->stack[++m->sp].value.int32 = arg +#define pushUInt64(arg) \ + m->stack[++m->sp].value_type = I64; \ + m->stack[m->sp].value.uint64 = arg +#define arg0 get_arg(m, 0) +#define arg1 get_arg(m, 1) +#define arg2 get_arg(m, 2) +#define arg3 get_arg(m, 3) +#define arg4 get_arg(m, 4) +#define arg5 get_arg(m, 5) +#define arg6 get_arg(m, 6) +#define arg7 get_arg(m, 7) +#define arg8 get_arg(m, 8) +#define arg9 get_arg(m, 9) + +// The primitive table +PrimitiveEntry primitives[ALL_PRIMITIVES]; + +// +uint32_t param_arr_len0[0] = {}; +uint32_t param_I32_arr_len1[1] = {I32}; +uint32_t param_I32_arr_len2[2] = {I32, I32}; +uint32_t param_I32_arr_len3[3] = {I32, I32, I32}; +uint32_t param_I32_arr_len4[4] = {I32, I32, I32, I32}; +uint32_t param_I32_arr_len10[10] = {I32, I32, I32, I32, I32, + I32, I32, I32, I32, I32}; + +uint32_t param_I64_arr_len1[1] = {I64}; + +Type oneToNoneU32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 0, + .results = nullptr, + .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ +}; + +Type twoToNoneU32 = { + .form = FUNC, + .param_count = 2, + .params = param_I32_arr_len2, + .result_count = 0, + .results = nullptr, + .mask = 0x80011 /* 0x800 = no return ; 1 = I32; 1 = I32*/ +}; + +Type threeToNoneU32 = { + .form = FUNC, + .param_count = 3, + .params = param_I32_arr_len3, + .result_count = 0, + .results = nullptr, + .mask = 0x800111 /* 0x800 = no return ; 1=I32; 1=I32; 1=I32*/ +}; + +Type fourToNoneU32 = { + .form = FUNC, + .param_count = 4, + .params = param_I32_arr_len4, + .result_count = 0, + .results = nullptr, + .mask = + 0x8001111 /* 0x800 = no return ; 1 = I32; 1 = I32; 1 = I32; 1 = I32*/ +}; + +Type oneToOneU32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +Type oneToOneI32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +Type twoToOneU32 = { + .form = FUNC, + .param_count = 2, + .params = param_I32_arr_len2, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x81011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +Type threeToOneU32 = { + .form = FUNC, + .param_count = 3, + .params = param_I32_arr_len3, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x810111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32*/ +}; + +Type fourToOneU32 = { + .form = FUNC, + .param_count = 4, + .params = param_I32_arr_len4, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x8101111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32; 1=I32*/ +}; + +Type tenToOneU32 = { + .form = FUNC, + .param_count = 10, + .params = param_I32_arr_len10, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x8101111111111 /* 0x8 1=I32 0=endRet ; 10 params 1=I32*/ +}; + +Type NoneToNoneU32 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 0, + .results = nullptr, + .mask = 0x80000}; + +Type NoneToOneU32 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x81000}; + +Type NoneToOneU64 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 1, + .results = param_I64_arr_len1, + .mask = 0x82000}; + +def_prim(chip_pin_mode, twoToNoneU32) { + gpio_set_direction(arg1.uint32, arg0.uint32); + pop_args(2); + return true; +} + +def_prim(chip_digital_write, twoToNoneU32) { + gpio_set_level(arg1.uint32, arg0.uint32); + pop_args(2); + return true; +} + +//------------------------------------------------------ +// Installing all the primitives +//------------------------------------------------------ +void install_primitives() { + dbg_info("INSTALLING PRIMITIVES\n"); + install_primitive(chip_pin_mode); + install_primitive(chip_digital_write); +} + +//------------------------------------------------------ +// resolving the primitives +//------------------------------------------------------ +bool resolve_primitive(char *symbol, Primitive *val) { + debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); + + for (auto &primitive : primitives) { + // printf("Checking %s = %s \n", symbol, primitive.name); + if (!strcmp(symbol, primitive.name)) { + debug("FOUND PRIMITIVE\n"); + *val = primitive.f; + return true; + } + } + FATAL("Could not find primitive %s \n", symbol); + return false; +} + +Memory external_mem = {0, 0, 0, nullptr}; + +bool resolve_external_memory(char *symbol, Memory **val) { + if (!strcmp(symbol, "memory")) { + if (external_mem.bytes == nullptr) { + external_mem.initial = 256; + external_mem.maximum = 256; + external_mem.pages = 256; + external_mem.bytes = (uint8_t *)acalloc( + external_mem.pages * PAGE_SIZE, sizeof(uint32_t), + "Module->memory.bytes primitive"); + } + *val = &external_mem; + return true; + } + + FATAL("Could not find memory %s \n", symbol); + return false; +} + +#endif // ARDUINO From 16db31768a887292a0df9fab3e736d3439e6f716 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 31 May 2022 09:49:47 +0200 Subject: [PATCH 141/249] Fix ESP-IDF compilation --- platforms/ESP-IDF/CMakeLists.txt | 5 +- sdkconfig | 286 ++++++++++++++++++------------- src/RFC/proxy_server.cpp | 1 + 3 files changed, 175 insertions(+), 117 deletions(-) diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index 88bd7212..cc0d95ee 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -7,10 +7,13 @@ set(SOURCE_FILES ../../src/WARDuino/WARDuino.cpp ../../src/Primitives/idf.cpp ../../src/Interpreter/instructions.cpp + ../../src/RFC/rfc.cpp + ../../src/RFC/proxy_server.cpp + ../../src/RFC/SocketServer.cpp ../../src/WARDuino/CallbackHandler.cpp ) -idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS "" REQUIRES driver) +idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS ../../lib/json/single_include/ REQUIRES driver) add_definitions(-DINFO=0) add_definitions(-DDEBUG=0) diff --git a/sdkconfig b/sdkconfig index 88079570..ab55b50a 100644 --- a/sdkconfig +++ b/sdkconfig @@ -10,6 +10,7 @@ CONFIG_SOC_DAC_SUPPORTED=y CONFIG_SOC_MCPWM_SUPPORTED=y CONFIG_SOC_SDMMC_HOST_SUPPORTED=y CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_BLUEDROID_SUPPORTED=y CONFIG_SOC_CLASSIC_BT_SUPPORTED=y CONFIG_SOC_PCNT_SUPPORTED=y CONFIG_SOC_WIFI_SUPPORTED=y @@ -19,23 +20,32 @@ CONFIG_SOC_EMAC_SUPPORTED=y CONFIG_SOC_CPU_CORES_NUM=2 CONFIG_SOC_ULP_SUPPORTED=y CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y -CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y CONFIG_SOC_I2S_SUPPORTED=y CONFIG_SOC_RMT_SUPPORTED=y CONFIG_SOC_SIGMADELTA_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y CONFIG_SOC_ADC_PERIPH_NUM=2 CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 CONFIG_SOC_ADC_PATT_LEN_MAX=16 CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=2000 -CONFIG_SOC_ADC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 CONFIG_SOC_CPU_WATCHPOINT_SIZE=64 @@ -56,17 +66,22 @@ CONFIG_SOC_APLL_MULTIPLIER_OUT_MAX_HZ=500000000 CONFIG_SOC_APLL_MIN_HZ=5303031 CONFIG_SOC_APLL_MAX_HZ=125000000 CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y CONFIG_SOC_I2S_SUPPORTS_ADC=y CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y CONFIG_SOC_I2S_LCD_I80_VARIANT=y CONFIG_SOC_LCD_I80_SUPPORTED=y -CONFIG_SOC_LCD_I80_BUSES=y +CONFIG_SOC_LCD_I80_BUSES=2 CONFIG_SOC_LCD_I80_BUS_WIDTH=24 CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y CONFIG_SOC_LEDC_CHANNEL_NUM=8 @@ -94,6 +109,7 @@ CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y CONFIG_SOC_RTCIO_PIN_COUNT=18 CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y @@ -107,10 +123,15 @@ CONFIG_SOC_SPI_PERIPH_NUM=3 CONFIG_SOC_SPI_DMA_CHAN_NUM=2 CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y CONFIG_SOC_TIMER_GROUPS=2 CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y CONFIG_SOC_TOUCH_VERSION_1=y CONFIG_SOC_TOUCH_SENSOR_NUM=10 CONFIG_SOC_TOUCH_PAD_MEASURE_WAIT_MAX=0xFF @@ -130,10 +151,13 @@ CONFIG_SOC_RSA_MAX_BIT_LEN=4096 CONFIG_SOC_AES_SUPPORT_AES_128=y CONFIG_SOC_AES_SUPPORT_AES_192=y CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y CONFIG_SOC_SDMMC_USE_IOMUX=y CONFIG_SOC_SDMMC_NUM_SLOTS=2 CONFIG_SOC_BLE_DONT_UPDATE_OWN_RPA=y @@ -154,6 +178,8 @@ CONFIG_APP_BUILD_BOOTLOADER=y CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y # CONFIG_APP_REPRODUCIBLE_BUILD is not set # CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # end of Build type # @@ -185,6 +211,7 @@ CONFIG_BOOTLOADER_LOG_LEVEL=3 CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y # CONFIG_BOOTLOADER_FACTORY_RESET is not set # CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 @@ -200,6 +227,7 @@ CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y # # Security features # +CONFIG_SECURE_BOOT_V1_SUPPORTED=y # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set # CONFIG_SECURE_BOOT is not set # CONFIG_SECURE_FLASH_ENC_ENABLED is not set @@ -267,10 +295,12 @@ CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +CONFIG_COMPILER_CXX_EXCEPTIONS=y +CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set @@ -290,6 +320,10 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # # CONFIG_APPTRACE_DEST_JTAG is not set CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 CONFIG_APPTRACE_LOCK_ENABLE=y # end of Application Level Tracing @@ -351,6 +385,7 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # GPIO Configuration # # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set # end of GPIO Configuration # @@ -370,6 +405,14 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set # end of PCNT Configuration + +# +# RMT Configuration +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of RMT Configuration # end of Driver configurations # @@ -388,50 +431,12 @@ CONFIG_EFUSE_MAX_BLK_LEN=192 # CONFIG_ESP_TLS_USING_MBEDTLS=y # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set -# CONFIG_ESP_TLS_SERVER is not set # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER is not set # CONFIG_ESP_TLS_PSK_VERIFICATION is not set # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS -# -# ESP32-specific -# -CONFIG_ESP32_REV_MIN_0=y -# CONFIG_ESP32_REV_MIN_1 is not set -# CONFIG_ESP32_REV_MIN_2 is not set -# CONFIG_ESP32_REV_MIN_3 is not set -CONFIG_ESP32_REV_MIN=0 -CONFIG_ESP32_DPORT_WORKAROUND=y -# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y -# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 -# CONFIG_ESP32_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_TRAX is not set -CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y -# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y -# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 -CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP32_XTAL_FREQ_40=y -# CONFIG_ESP32_XTAL_FREQ_26 is not set -# CONFIG_ESP32_XTAL_FREQ_AUTO is not set -CONFIG_ESP32_XTAL_FREQ=40 -# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -# CONFIG_ESP32_NO_BLOBS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set -# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set -CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5 -# end of ESP32-specific - # # ADC-Calibration # @@ -463,6 +468,7 @@ CONFIG_ETH_USE_SPI_ETHERNET=y # CONFIG_ETH_SPI_ETHERNET_W5500 is not set # CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set # CONFIG_ETH_USE_OPENETH is not set +# CONFIG_ETH_TRANSMIT_MUTEX is not set # end of Ethernet # @@ -495,6 +501,7 @@ CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 # CONFIG_HTTPD_LOG_PURGE_DATA is not set # CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set # end of HTTP Server # @@ -513,6 +520,7 @@ CONFIG_HTTPD_PURGE_BUF_LEN=32 # # Hardware Settings # +# CONFIG_SPIRAM is not set # # MAC Config @@ -533,12 +541,36 @@ CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set # CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 # end of Sleep Config # # RTC Clock Config # +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 # end of RTC Clock Config + +# +# Peripheral Control +# +# CONFIG_PERIPH_CTRL_FUNC_IN_IRAM is not set +# end of Peripheral Control + +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_DPORT_WORKAROUND=y +CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5 +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_26 is not set +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 # end of Hardware Settings # @@ -549,6 +581,7 @@ CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y # LCD Peripheral Configuration # CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set # end of LCD Peripheral Configuration # end of LCD and Touch Panel @@ -558,7 +591,6 @@ CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 CONFIG_ESP_NETIF_TCPIP_LWIP=y # CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y # CONFIG_ESP_NETIF_L2_TAP is not set # end of ESP NETIF Adapter @@ -581,6 +613,24 @@ CONFIG_ESP_PHY_REDUCE_TX_POWER=y # # ESP System Settings # +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + # CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set @@ -629,6 +679,8 @@ CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_ESP_BROWNOUT_DET_LVL=0 # end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set # end of ESP System Settings # @@ -740,75 +792,56 @@ CONFIG_FATFS_PER_FILE_CACHE=y # end of FAT Filesystem support # -# Modbus configuration -# -CONFIG_FMB_COMM_MODE_TCP_EN=y -CONFIG_FMB_TCP_PORT_DEFAULT=502 -CONFIG_FMB_TCP_PORT_MAX_CONN=5 -CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 -CONFIG_FMB_COMM_MODE_RTU_EN=y -CONFIG_FMB_COMM_MODE_ASCII_EN=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 -CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 -CONFIG_FMB_PORT_TASK_PRIO=10 -# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y -# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set -CONFIG_FMB_PORT_TASK_AFFINITY=0x0 -CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_FMB_TIMER_PORT_ENABLED is not set -# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set -# end of Modbus configuration +# FreeRTOS +# # -# FreeRTOS +# Kernel # +# CONFIG_FREERTOS_SMP is not set # CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y -CONFIG_FREERTOS_CORETIMER_0=y -# CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y CONFIG_FREERTOS_HZ=100 -CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -CONFIG_FREERTOS_ISR_STACKSIZE=1536 # CONFIG_FREERTOS_USE_IDLE_HOOK is not set # CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set -CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y -# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# end of Kernel + +# +# Port +# CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y # CONFIG_FREERTOS_FPU_IN_ISR is not set -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set # CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +# end of Port + +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y # end of FreeRTOS # @@ -1025,6 +1058,7 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 # end of Certificate Bundle # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set @@ -1036,6 +1070,7 @@ CONFIG_MBEDTLS_ROM_MD5=y # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_SHA512_C=y @@ -1123,6 +1158,7 @@ CONFIG_MBEDTLS_ECP_NIST_OPTIM=y # # mDNS # +CONFIG_MDNS_MAX_INTERFACES=3 CONFIG_MDNS_MAX_SERVICES=10 CONFIG_MDNS_TASK_PRIORITY=1 CONFIG_MDNS_TASK_STACK_SIZE=4096 @@ -1135,6 +1171,14 @@ CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 CONFIG_MDNS_TIMER_PERIOD_MS=100 # CONFIG_MDNS_NETWORKING_SOCKET is not set CONFIG_MDNS_MULTIPLE_INSTANCE=y + +# +# MDNS Predefined interfaces +# +CONFIG_MDNS_PREDEF_NETIF_STA=y +CONFIG_MDNS_PREDEF_NETIF_AP=y +CONFIG_MDNS_PREDEF_NETIF_ETH=y +# end of MDNS Predefined interfaces # end of mDNS # @@ -1162,6 +1206,10 @@ CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y # CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set # end of Newlib # @@ -1301,7 +1349,6 @@ CONFIG_VFS_SUPPORT_TERMIOS=y # Host File System I/O (Semihosting) # CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 # end of Host File System I/O (Semihosting) # end of Virtual file system @@ -1324,6 +1371,7 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 # Supplicant # CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y # CONFIG_WPA_WAPI_PSK is not set # CONFIG_WPA_SUITE_B_192 is not set # CONFIG_WPA_DEBUG_PRINT is not set @@ -1332,11 +1380,16 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y # CONFIG_WPA_11KV_SUPPORT is not set # CONFIG_WPA_MBO_SUPPORT is not set # CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set # end of Supplicant # end of Component config # Deprecated options for backward compatibility # CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set # CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set @@ -1359,7 +1412,8 @@ CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_CXX_EXCEPTIONS=y +CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set @@ -1370,30 +1424,37 @@ CONFIG_STACK_CHECK_NONE=y CONFIG_ESP32_APPTRACE_DEST_NONE=y CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y CONFIG_ADC2_DISABLE_DAC=y -# CONFIG_SPIRAM_SUPPORT is not set -CONFIG_TRACEMEM_RESERVE_DRAM=0x0 -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set -CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set -# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set -# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set # CONFIG_EVENT_LOOP_PROFILING is not set CONFIG_POST_EVENTS_FROM_ISR=y CONFIG_POST_EVENTS_FROM_IRAM_ISR=y # CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 CONFIG_ESP_SYSTEM_PD_FLASH=y +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 CONFIG_REDUCE_PHY_TX_POWER=y CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 # CONFIG_ESP32_PANIC_PRINT_HALT is not set CONFIG_ESP32_PANIC_PRINT_REBOOT=y # CONFIG_ESP32_PANIC_SILENT_REBOOT is not set @@ -1432,28 +1493,16 @@ CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y -CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_MB_QUEUE_LENGTH=20 -CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 -CONFIG_MB_SERIAL_BUF_SIZE=256 -CONFIG_MB_SERIAL_TASK_PRIO=10 -CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_MB_CONTROLLER_STACK_SIZE=4096 -CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_MB_TIMER_PORT_ENABLED is not set -# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set # CONFIG_L2_TO_L3_COPY is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 @@ -1476,6 +1525,12 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF # CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 CONFIG_ESP32_PTHREAD_STACK_MIN=768 @@ -1491,5 +1546,4 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 # End of deprecated options diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index a31a6432..ba7641c1 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -79,6 +79,7 @@ void *readSocket(void *input) { // Print value received as argument: dbg_info("\n=== LISTENING TO SOCKET (in separate thread) ===\n"); ProxyServer::startPushDebuggerSocket((struct Socket *)input); + pthread_exit(nullptr); } Event *parseJSON(char *buff) { From c4db33d57d93db4de201f824195feb9923251e4d Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 31 May 2022 10:12:42 +0200 Subject: [PATCH 142/249] Re-enabled TWDT init on startup --- sdkconfig | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sdkconfig b/sdkconfig index ab55b50a..2d5dd7d3 100644 --- a/sdkconfig +++ b/sdkconfig @@ -658,7 +658,11 @@ CONFIG_ESP_CONSOLE_MULTIPLE_UART=y CONFIG_ESP_CONSOLE_UART_NUM=0 CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 # CONFIG_ESP_INT_WDT is not set -# CONFIG_ESP_TASK_WDT is not set +CONFIG_ESP_TASK_WDT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_PANIC_HANDLER_IRAM is not set # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set CONFIG_ESP_DEBUG_OCDAWARE=y @@ -1470,7 +1474,11 @@ CONFIG_CONSOLE_UART=y CONFIG_CONSOLE_UART_NUM=0 CONFIG_CONSOLE_UART_BAUDRATE=115200 # CONFIG_INT_WDT is not set -# CONFIG_TASK_WDT is not set +CONFIG_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_BROWNOUT_DET=y From edeccdcff7b2f2f91f8523c3d6260ec0524e8aef Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 31 May 2022 10:13:48 +0200 Subject: [PATCH 143/249] Fix blink example for ESP IDF --- examples/blink/build.sh | 2 +- examples/blink/main/CMakeLists.txt | 23 +++++++++++++---------- platforms/ESP-IDF/main.cpp | 29 +++++------------------------ src/Primitives/idf.cpp | 24 +++++++++++++++++++++--- 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/examples/blink/build.sh b/examples/blink/build.sh index 05a05915..fb7e1ae3 100755 --- a/examples/blink/build.sh +++ b/examples/blink/build.sh @@ -17,7 +17,7 @@ if [[ $src == *.wat ]] || [[ $extension == *.wast ]]; then fi # Optimize (optional) -wasm-opt -O3 "${src}.wasm" -o "src.wasm" +#wasm-opt -O3 "${src}.wasm" -o "src.wasm" wasm-strip "src.wasm" echo -e "> optimized src.wasm" diff --git a/examples/blink/main/CMakeLists.txt b/examples/blink/main/CMakeLists.txt index 3fdb8c1d..7ddf2d42 100644 --- a/examples/blink/main/CMakeLists.txt +++ b/examples/blink/main/CMakeLists.txt @@ -1,16 +1,19 @@ set(SOURCE_FILES - ../../../src/Memory/mem.cpp - ../../../src/Utils/util.cpp - ../../../src/Utils/util_arduino.cpp - ../../../src/Debug/debugger.cpp - ../../../src/Utils/macros.cpp - ../../../src/WARDuino/WARDuino.cpp - ../../../src/Primitives/emulated.cpp - ../../../src/Interpreter/instructions.cpp - ../../../src/WARDuino/CallbackHandler.cpp + ../../src/Memory/mem.cpp + ../../src/Utils/util.cpp + ../../src/Utils/util_arduino.cpp + ../../src/Debug/debugger.cpp + ../../src/Utils/macros.cpp + ../../src/WARDuino/WARDuino.cpp + ../../src/Primitives/idf.cpp + ../../src/Interpreter/instructions.cpp + ../../src/RFC/rfc.cpp + ../../src/RFC/proxy_server.cpp + ../../src/RFC/SocketServer.cpp + ../../src/WARDuino/CallbackHandler.cpp ) -idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS "" REQUIRES driver) +idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS ../../lib/json/single_include/ REQUIRES driver) add_definitions(-DESP=1) diff --git a/platforms/ESP-IDF/main.cpp b/platforms/ESP-IDF/main.cpp index 999d1156..81544f1c 100644 --- a/platforms/ESP-IDF/main.cpp +++ b/platforms/ESP-IDF/main.cpp @@ -13,31 +13,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "sdkconfig.h" +#include "upload.h" volatile bool handelingInterrupt = false; -unsigned char wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x03, 0x60, - 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7e, 0x7f, 0x01, 0x7f, - 0x03, 0x04, 0x03, 0x00, 0x02, 0x01, 0x04, 0x04, 0x01, 0x70, 0x00, 0x03, - 0x05, 0x03, 0x01, 0x00, 0x01, 0x06, 0x23, 0x04, 0x7f, 0x01, 0x41, 0x00, - 0x0b, 0x7f, 0x01, 0x41, 0x00, 0x0b, 0x7c, 0x01, 0x44, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x7c, 0x01, 0x44, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, - 0x69, 0x6e, 0x00, 0x02, 0x09, 0x09, 0x01, 0x00, 0x41, 0x00, 0x0b, 0x03, - 0x02, 0x01, 0x00, 0x0a, 0x54, 0x03, 0x02, 0x00, 0x0b, 0x39, 0x00, 0x20, - 0x01, 0x41, 0x01, 0x4a, 0x04, 0x7f, 0x20, 0x00, 0x42, 0x01, 0x7c, 0x20, - 0x01, 0x41, 0x01, 0x6b, 0x10, 0x01, 0x20, 0x01, 0x6c, 0x05, 0x41, 0x20, - 0x24, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40, 0x24, - 0x02, 0x23, 0x00, 0x23, 0x00, 0x6a, 0x24, 0x01, 0x23, 0x02, 0x23, 0x02, - 0xa0, 0x24, 0x03, 0x41, 0x01, 0x0b, 0x0b, 0x15, 0x01, 0x01, 0x7f, 0x41, - 0x06, 0x21, 0x00, 0x03, 0x40, 0x42, 0x0d, 0x20, 0x00, 0x10, 0x01, 0x10, - 0x00, 0x0c, 0x00, 0x0b, 0x0b, 0x00, 0x31, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x01, 0x13, 0x03, 0x00, 0x05, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x01, 0x03, - 0x66, 0x61, 0x63, 0x02, 0x04, 0x66, 0x61, 0x63, 0x35, 0x02, 0x15, 0x03, - 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x00, 0x02, 0x01, - 0x00, 0x06, 0x69, 0x6e, 0x74, 0x5f, 0x33, 0x32}; -unsigned int wasm_len = 236; +unsigned int wasm_len = upload_wasm_len; +unsigned char* wasm = upload_wasm; extern "C" { extern void app_main(void); @@ -65,8 +46,8 @@ void startDebuggerStd(void* pvParameter) { void app_main(void) { m = wac->load_module(wasm, wasm_len, {}); - uint8_t command[] = {'0', '3', '\n'}; - wac->handleInterrupt(3, command); + // uint8_t command[] = {'0', '3', '\n'}; + // wac->handleInterrupt(3, command); xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); printf("START\n\n"); wac->run_module(m); diff --git a/src/Primitives/idf.cpp b/src/Primitives/idf.cpp index ae755d44..883a6b18 100644 --- a/src/Primitives/idf.cpp +++ b/src/Primitives/idf.cpp @@ -11,6 +11,8 @@ * 4) Extend the install_primitives function * */ +#include +#include #include #include @@ -26,7 +28,7 @@ #include "primitives.h" #define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 2 +#define NUM_PRIMITIVES_ARDUINO 4 #define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) @@ -200,25 +202,41 @@ Type NoneToOneU64 = {.form = FUNC, .results = param_I64_arr_len1, .mask = 0x82000}; +def_prim(chip_delay, oneToNoneU32) { + vTaskDelay(arg0.uint32 / portTICK_PERIOD_MS); + pop_args(1); + return true; +} + def_prim(chip_pin_mode, twoToNoneU32) { - gpio_set_direction(arg1.uint32, arg0.uint32); + gpio_set_direction(gpio_num_t(arg1.uint32), gpio_mode_t(arg0.uint32)); pop_args(2); return true; } def_prim(chip_digital_write, twoToNoneU32) { - gpio_set_level(arg1.uint32, arg0.uint32); + gpio_set_level(gpio_num_t(arg1.uint32), gpio_mode_t(arg0.uint32)); pop_args(2); return true; } +def_prim(chip_digital_read, oneToOneU32) { + gpio_num_t pin = gpio_num_t(arg0.uint32); + uint8_t res = (uint8_t)gpio_get_level(pin); + pop_args(1); + pushUInt32(res); + return true; +} + //------------------------------------------------------ // Installing all the primitives //------------------------------------------------------ void install_primitives() { dbg_info("INSTALLING PRIMITIVES\n"); + install_primitive(chip_delay); install_primitive(chip_pin_mode); install_primitive(chip_digital_write); + install_primitive(chip_digital_read); } //------------------------------------------------------ From 8b6fd3598bb0f7e0a15f17f42af7e663c4b01947 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 31 May 2022 10:37:39 +0200 Subject: [PATCH 144/249] Add missing upload.h + update .gitignore --- .gitignore | 2 ++ platforms/ESP-IDF/upload.h | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 platforms/ESP-IDF/upload.h diff --git a/.gitignore b/.gitignore index ab0901f5..78858d21 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ _deps .AppleDouble .LSOverride +*.old + diff --git a/platforms/ESP-IDF/upload.h b/platforms/ESP-IDF/upload.h new file mode 100644 index 00000000..753e37df --- /dev/null +++ b/platforms/ESP-IDF/upload.h @@ -0,0 +1,17 @@ +unsigned char upload_wasm[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, + 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, + 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, + 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, + 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, + 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, + 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, + 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, + 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, + 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, + 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x0b, 0x0b}; +unsigned int upload_wasm_len = 170; From 67e3a483581ebfda9fe98a0d794dab28fc2ce7e3 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 31 May 2022 10:40:25 +0200 Subject: [PATCH 145/249] Update IDF CI action --- .github/workflows/compile.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index af52b71a..51d7b7b3 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -158,10 +158,19 @@ jobs: with: submodules: 'recursive' + - name: Create build folder + run: mkdir build + + - name: Test + run: ls -l .. + working-directory: build + - name: Build WARDuino for ESP-IDF uses: espressif/esp-idf-ci-action@main + working-directory: build with: esp_idf_version: latest target: esp32 + command: cmake .. -D BUILD_ESP=ON & make path: . From 9b8157ba314419c57cb14c887d84ba55a2d7838d Mon Sep 17 00:00:00 2001 From: tolauwae Date: Thu, 2 Jun 2022 09:11:45 +0200 Subject: [PATCH 146/249] Fix ESP compile CI action --- .github/workflows/compile.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 51d7b7b3..a9d721e1 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -158,19 +158,11 @@ jobs: with: submodules: 'recursive' - - name: Create build folder - run: mkdir build - - - name: Test - run: ls -l .. - working-directory: build - - name: Build WARDuino for ESP-IDF uses: espressif/esp-idf-ci-action@main - working-directory: build with: esp_idf_version: latest target: esp32 - command: cmake .. -D BUILD_ESP=ON & make + command: idf.py build -DBUILD_ESP=ON path: . From 662ce391658d4788f05895fe48b0d5264c3781be Mon Sep 17 00:00:00 2001 From: tolauwae Date: Thu, 2 Jun 2022 17:41:15 +0200 Subject: [PATCH 147/249] Allow `updateCallbackmapping` on Arduino --- src/Debug/debugger.cpp | 6 ++++-- src/Debug/debugger.h | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 251757a9..01c11bb3 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -5,6 +5,8 @@ #include #ifndef ARDUINO #include +#else +#include "../../lib/json/single_include/nlohmann/json.hpp" #endif #include "../Memory/mem.h" @@ -997,8 +999,9 @@ void Debugger::disconnect_drone() { pthread_mutex_unlock(&this->push_mutex); pthread_join(this->push_debugging_threadid, (void **)&ptr); } +#endif -void Debugger::updateCallbackmapping(Module *m, const char *data) const { +void Debugger::updateCallbackmapping(Module *m, const char *data) { nlohmann::basic_json<> parsed = nlohmann::json::parse(data); CallbackHandler::clear_callbacks(); nlohmann::basic_json<> callbacks = *parsed.find("callbacks"); @@ -1010,4 +1013,3 @@ void Debugger::updateCallbackmapping(Module *m, const char *data) const { } } } -#endif diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 715b8a68..4f36eee3 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -115,9 +115,7 @@ class Debugger { static uintptr_t readPointer(uint8_t **data); -#ifndef ARDUINO - void updateCallbackmapping(Module *m, const char *interruptData) const; -#endif + static void updateCallbackmapping(Module *m, const char *interruptData); public: // Public fields From 1ba1568fc3d17ebf30e724b58e21d0ce1cf8429c Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Fri, 3 Jun 2022 09:12:16 +0200 Subject: [PATCH 148/249] Add dependencies to README --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 47cb66f8..ba2b38cb 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Or simply run `idf.py flash`. ### Build for Arduino First, install the [arduino-cli](https://arduino.github.io/arduino-cli/0.21/installation/). +You will also need python3 with the pyserial pacakge. Second, create the config file: @@ -75,17 +76,21 @@ If you need additional boards, such as the esp32 boards, you can add them in the Thirdly, make sure you install the `PubSubClient` and `Adafruit NeoPixel` library. (used for MQTT and pixel primitives) ```bash -arduino-cli lib install "PubSubClient" -arduino-cli lib install "Adafruit NeoPixel" +arduino-cli lib install "PubSubClient" # for MQTT +arduino-cli lib install "Adafruit NeoPixel" # for some primitives ``` -To build for Arduino with WIFI support you need to also install the following third-party libraries +To build for Arduino with WIFI support you need to also install the following third-party libraries. +(Wou might need to set `enable_unsafe_install` to `true` in your arduino config ) ```bash arduino-cli lib install FreeRTOS arduino-cli lib install --git-url https://github.com/me-no-dev/AsyncTCP.git ``` +If you haven't done so already, clone (or symlink) this repository to `~/Arduino/libraries` to make WARDuino availible to Arduino. + + After this initial installation steps you can start using WARDuino with the Arduino toolchain. You can upload the example file as follows, starting from the project root: From 8ff733ceeccf51d17a9b4f87ba453797fc0f3955 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 3 Jun 2022 08:24:46 +0200 Subject: [PATCH 149/249] Clang Tidy and Format `src/Debug/` --- src/Debug/debugger.cpp | 18 ++++++------------ src/Debug/debugger.h | 3 ++- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 01c11bb3..61d5a9dd 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -102,7 +102,7 @@ bool Debugger::isBreakpoint(uint8_t *loc) { return this->breakpoints.find(loc) != this->breakpoints.end(); } -void Debugger::notifyBreakpoint(uint8_t *pc_ptr) { +void Debugger::notifyBreakpoint(uint8_t *pc_ptr) const { dprintf(this->socket, "AT %p!\n", (void *)pc_ptr); } @@ -200,9 +200,10 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptRecvState: if (!this->receivingData) { - debug("paused program execution\n"); *program_state = WARDUINOpause; + debug("paused program execution\n"); CallbackHandler::manual_event_resolution = true; + dbg_info("Manual event resolution is on."); this->receivingData = true; this->freeState(m, interruptData); free(interruptData); @@ -251,7 +252,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { this->handlePushedEvent(m, reinterpret_cast(interruptData)); break; case interruptRecvCallbackmapping: - this->updateCallbackmapping( + Debugger::updateCallbackmapping( m, reinterpret_cast(interruptData + 2)); break; #endif @@ -415,7 +416,7 @@ void Debugger::dumpLocals(Module *m) const { } Frame *f = &m->callstack[firstFunFramePtr]; dprintf(this->socket, R"({"count":%u,"locals":[)", 0); - // fflush(stdout); // FIXME: this is needed for ESP to propery print + // fflush(stdout); // FIXME: this is needed for ESP to properly print char _value_str[256]; for (uint32_t i = 0; i < f->block->local_count; i++) { auto v = &m->stack[m->fp + i]; @@ -592,13 +593,11 @@ void Debugger::woodDump(Module *m) { dprintf(this->socket, "DUMP!\n"); dprintf(this->socket, "{"); - // printf("asked for pc\n"); // current PC dprintf(this->socket, R"("pc":"%p",)", (void *)m->pc_ptr); // start of bytes dprintf(this->socket, R"("start":["%p"],)", (void *)m->bytes); - // printf("asked for bps\n"); dprintf(this->socket, "\"breakpoints\":["); size_t i = 0; @@ -608,7 +607,6 @@ void Debugger::woodDump(Module *m) { } dprintf(this->socket, "],"); - // printf("asked for stack\n"); // stack dprintf(this->socket, "\"stack\":["); for (int j = 0; j <= m->sp; j++) { @@ -630,8 +628,7 @@ void Debugger::woodDump(Module *m) { static_cast(f->ra_ptr), j, (j < m->csp) ? "," : ""); } - // printf("asked for globals\n"); - // GLobals + // Globals dprintf(this->socket, "],\"globals\":["); for (uint32_t j = 0; j < m->global_count; j++) { auto v = m->globals + j; @@ -639,7 +636,6 @@ void Debugger::woodDump(Module *m) { } dprintf(this->socket, "]"); // closing globals - // printf("asked for table\n"); dprintf(this->socket, R"(,"table":{"max":%d, "init":%d, "elements":[)", m->table.maximum, m->table.initial); @@ -649,7 +645,6 @@ void Debugger::woodDump(Module *m) { } dprintf(this->socket, "]}"); // closing table - // printf("asked for mem\n"); // memory uint32_t total_elems = m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE @@ -662,7 +657,6 @@ void Debugger::woodDump(Module *m) { } dprintf(this->socket, "]}"); // closing memory - // printf("asked for br_table\n"); dprintf(this->socket, R"(,"br_table":{"size":"0x%x","labels":[)", BR_TABLE_SIZE); for (uint32_t j = 0; j < BR_TABLE_SIZE; j++) { diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 4f36eee3..c1dd375c 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include // std::queue #include @@ -144,7 +145,7 @@ class Debugger { bool isBreakpoint(uint8_t *loc); - void notifyBreakpoint(uint8_t *pc_ptr); + void notifyBreakpoint(uint8_t *pc_ptr) const; // Out-of-place debugging From 959410c9b72aefc3251ddb1aee8e7d70c0b286ea Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 3 Jun 2022 10:34:50 +0200 Subject: [PATCH 150/249] Allow `interruptRecvCallbackmapping` on Arduino --- src/Debug/debugger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 61d5a9dd..c643738f 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -251,11 +251,11 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { case interruptPUSHEvent: this->handlePushedEvent(m, reinterpret_cast(interruptData)); break; +#endif case interruptRecvCallbackmapping: Debugger::updateCallbackmapping( m, reinterpret_cast(interruptData + 2)); break; -#endif case interruptDUMPCallbackmapping: this->dumpCallbackmapping(); break; From a59000d0838e7ea9c135ca808c75a11783047f6e Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 3 Jun 2022 11:03:00 +0200 Subject: [PATCH 151/249] Ask for cbkmapping dump after Proxy Call --- src/Debug/debugger.h | 1 + src/RFC/rfc.cpp | 4 ++++ src/WARDuino/CallbackHandler.cpp | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index c1dd375c..7e3032d1 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -117,6 +117,7 @@ class Debugger { static uintptr_t readPointer(uint8_t **data); static void updateCallbackmapping(Module *m, const char *interruptData); + public: // Public fields diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index 40706109..b13adcf6 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -293,6 +293,10 @@ void RFC::deserializeRFCResult() { FATAL("Deserialization RFCResult\n"); } delete[] call_result; + + // Retreive new callbackmapping + std::string message = std::to_string(interruptDUMPCallbackmapping) + "\n"; + ProxyServer::getServer()->send((char *) message.c_str(), (int) message.length()); } void RFC::call(StackValue *arguments) { diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 851493ee..7a91838a 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -16,7 +16,7 @@ bool CallbackHandler::resolving_event = false; #ifdef ARDUINO size_t CallbackHandler::pushed_cursor = 0; -bool should_push_event(SocketServer *server) { +bool should_push_event(SocketServer *server) { // TODO replace with WARDuinoDrone RunningState check return server != nullptr && server->hasPushClient() && CallbackHandler::pushed_cursor < CallbackHandler::event_count(); } From f2b938f49c88487cd5b1d366d47bb1e358bfd9c8 Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Fri, 3 Jun 2022 11:13:39 +0200 Subject: [PATCH 152/249] Add dronify instruction --- src/Debug/debugger.cpp | 17 ++++++++++++++++- src/Debug/debugger.h | 9 +++++++-- src/Interpreter/instructions.cpp | 7 ++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index c643738f..c6c09132 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -10,6 +10,7 @@ #endif #include "../Memory/mem.h" +#include "../RFC/SocketServer.h" #include "../RFC/proxy_server.h" #include "../RFC/rfc.h" #include "../Utils//util.h" @@ -232,9 +233,23 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { free(interruptData); } break; #endif +#ifdef ARDUINO case interruptDronify: - // TODO Dronify + // 0x65 the wifi ssid \0 wifipass \0 + // 1 |____len_____| 1 + char *ssid = (char *)(interruptData + 1); + size_t ssid_len = strlen(ssid); + char *pass = (char *)(interruptData + 1 + ssid_len + 1); + ServerCredentials serverCredentials = {ssid, pass}; + SocketServer::createServer( + 8080, 8081, [m](size_t len, uint8_t *buff) { + m->warduino->handleInterrupt(len, buff); + }); + auto server = SocketServer::getServer(); + server->connect2Wifi(&serverCredentials); + *program_state = WARDUINOdrone; break; +#endif case interruptDUMPAllEvents: printf("InterruptDUMPEvents\n"); size = (long)CallbackHandler::event_count(); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 7e3032d1..3bec1f3c 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -17,7 +17,12 @@ enum RunningState { WARDUINOrun, WARDUINOpause, WARDUINOstep, - WARDuinoProxyRun + WARDuinoProxyRun, // Running state used when executing a proxy call. During + // this state the call is set up and executed by the main + // loop. After execution, the state is restored to + // WARDUINODrone + WARDUINODrone // Do not run the program (program runs on computer, which + // sends messages for primitives, do forward interupts) }; enum InterruptTypes { @@ -40,7 +45,7 @@ enum InterruptTypes { interruptRecvState = 0x62, interruptMonitorProxies = 0x63, interruptProxyCall = 0x64, - interruptDronify = 0x65, + interruptDronify = 0x65, // wifi SSID \0 wifi PASS \0 // Push Debugging interruptDUMPAllEvents = 0x70, diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 0c2c8ec1..b68b4c1a 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1536,10 +1536,13 @@ bool interpret(Module *m) { // check if call completes if (callee->callCompleted(m)) { callee->returnResult(m); + + // TODO: this is likley no longer needed callee->restoreExecutionState(m, &m->warduino->program_state); RFC::removeRFCallee(); callee = nullptr; + m->warduino->program_state = WARDUINODrone; } } } @@ -1549,7 +1552,9 @@ bool interpret(Module *m) { // no event currently resolving CallbackHandler::resolve_event(); - if (m->warduino->program_state == WARDUINOpause) { + // Skip the main loop if paused or drone + if (m->warduino->program_state == WARDUINOpause || + m->warduino->program_state == WARDUINODrone) { continue; } From b8cf8ed0efbbc45473e3c935af7a8a9f1059db29 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 3 Jun 2022 13:16:01 +0200 Subject: [PATCH 153/249] Clang format --- src/RFC/rfc.cpp | 3 ++- src/WARDuino/CallbackHandler.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index b13adcf6..d78c26b7 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -296,7 +296,8 @@ void RFC::deserializeRFCResult() { // Retreive new callbackmapping std::string message = std::to_string(interruptDUMPCallbackmapping) + "\n"; - ProxyServer::getServer()->send((char *) message.c_str(), (int) message.length()); + ProxyServer::getServer()->send((char *)message.c_str(), + (int)message.length()); } void RFC::call(StackValue *arguments) { diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 7a91838a..851493ee 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -16,7 +16,7 @@ bool CallbackHandler::resolving_event = false; #ifdef ARDUINO size_t CallbackHandler::pushed_cursor = 0; -bool should_push_event(SocketServer *server) { // TODO replace with WARDuinoDrone RunningState check +bool should_push_event(SocketServer *server) { return server != nullptr && server->hasPushClient() && CallbackHandler::pushed_cursor < CallbackHandler::event_count(); } From f1bbc1a20456ca8a4fa27f83a14c451a7c17579c Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 3 Jun 2022 13:38:39 +0200 Subject: [PATCH 154/249] Fix Arduino compilation Use `std::function` for handler in SocketServer --- src/Debug/debugger.cpp | 5 +++-- src/RFC/SocketServer.cpp | 17 ++++++++++------- src/RFC/SocketServer.h | 6 +++--- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index c6c09132..03b2149b 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -234,7 +234,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } break; #endif #ifdef ARDUINO - case interruptDronify: + case interruptDronify: { // 0x65 the wifi ssid \0 wifipass \0 // 1 |____len_____| 1 char *ssid = (char *)(interruptData + 1); @@ -247,8 +247,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { }); auto server = SocketServer::getServer(); server->connect2Wifi(&serverCredentials); - *program_state = WARDUINOdrone; + *program_state = WARDUINODrone; break; + } #endif case interruptDUMPAllEvents: printf("InterruptDUMPEvents\n"); diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp index 2dfbf0fd..293fece9 100644 --- a/src/RFC/SocketServer.cpp +++ b/src/RFC/SocketServer.cpp @@ -8,7 +8,7 @@ SocketServer *SocketServer::socketServer = nullptr; SocketServer::SocketServer(uint16_t t_pullport, uint16_t t_pushport, - void (*t_handler)(size_t, uint8_t *)) + std::function t_handler) : pull_portno(t_pullport), push_portno(t_pushport) { this->pullServer = new AsyncServer(t_pullport); this->pushServer = new AsyncServer(t_pushport); @@ -17,8 +17,9 @@ SocketServer::SocketServer(uint16_t t_pullport, uint16_t t_pushport, this->handler = t_handler; } -void SocketServer::createServer(uint16_t t_pullport, uint16_t t_pushport, - void (*t_handler)(size_t, uint8_t *)) { +void SocketServer::createServer( + uint16_t t_pullport, uint16_t t_pushport, + std::function t_handler) { if (socketServer == nullptr) socketServer = new SocketServer(t_pullport, t_pushport, t_handler); } @@ -74,7 +75,7 @@ void SocketServer::registerClient(AsyncClient *new_client, return; } - void (*handler)(size_t, uint8_t *) = this->handler; + std::function _handler = this->handler; SocketServer *thisServer = this; new_client->onError( [thisServer](void *r, AsyncClient *t_client, int8_t error) { @@ -93,9 +94,11 @@ void SocketServer::registerClient(AsyncClient *new_client, thisServer->unregisterClient(t_client); }, NULL); - new_client->onData([handler](void *r, AsyncClient *t_client, void *buf, - size_t len) { handler(len, (uint8_t *)buf); }, - NULL); + new_client->onData( + [_handler](void *r, AsyncClient *t_client, void *buf, size_t len) { + _handler(len, (uint8_t *)buf); + }, + NULL); } void SocketServer::unregisterClient(AsyncClient *t_client) { diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h index 47f44bd0..42590a78 100644 --- a/src/RFC/SocketServer.h +++ b/src/RFC/SocketServer.h @@ -25,12 +25,12 @@ class SocketServer { AsyncServer *pushServer; // handler for client's received data - void (*handler)(size_t, uint8_t *); + std::function handler; // singleton static SocketServer *socketServer; SocketServer(uint16_t t_pullport, uint16_t t_pushport, - void (*t_handler)(size_t, uint8_t *)); + std::function t_handler); void registerClient(AsyncClient *new_client, AsyncClient **current_client); void unregisterClient(AsyncClient *t_client); @@ -47,6 +47,6 @@ class SocketServer { static SocketServer *getServer(void); static void createServer(uint16_t t_pullport, uint16_t t_pushport, - void (*t_handler)(size_t, uint8_t *)); + std::function t_handler); }; #endif From ddece628c48300b8438c87b70bdac6ce9db898b8 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 3 Jun 2022 14:24:03 +0200 Subject: [PATCH 155/249] Allow lowercase in debug messages --- src/Debug/debugger.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 03b2149b..9c8fbbdf 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -49,6 +49,9 @@ uint8_t *Debugger::parseDebugBuffer(size_t len, const uint8_t *buff) { case 'A' ... 'F': r = buff[i] - 'A' + 10; break; + case 'a' ... 'f': + r = buff[i] - 'a' + 10; + break; default: success = false; } From fed773755f73871a634a282da178c1ae2de50028 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 3 Jun 2022 15:02:18 +0200 Subject: [PATCH 156/249] Start SocketServer on interruptDronify --- src/Debug/debugger.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 9c8fbbdf..9185f0a4 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -250,6 +250,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { }); auto server = SocketServer::getServer(); server->connect2Wifi(&serverCredentials); + server->begin(); *program_state = WARDUINODrone; break; } From 9cb7d26bd988e07f01f1b6f72d91c4f444b2b723 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 3 Jun 2022 17:21:58 +0200 Subject: [PATCH 157/249] Clean up. Closes #70 --- benchmarks/all_bench.sh | 6 +- benchmarks/warduino_bench.sh | 3 +- do_build.sh | 8 -- platforms/Arduino-socket/.gitignore | 2 - .../Arduino-socket.ino.template | 90 ------------------- platforms/Arduino-socket/Makefile | 28 ------ platforms/Arduino-socket/README.md | 3 - platforms/Arduino-socket/upload | 1 - platforms/Arduino-socket/upload.h | 62 ------------- platforms/Arduino/upload | 1 - scripts/upload | 39 -------- 11 files changed, 5 insertions(+), 238 deletions(-) delete mode 100755 do_build.sh delete mode 100644 platforms/Arduino-socket/.gitignore delete mode 100644 platforms/Arduino-socket/Arduino-socket.ino.template delete mode 100644 platforms/Arduino-socket/Makefile delete mode 100644 platforms/Arduino-socket/README.md delete mode 100644 platforms/Arduino-socket/upload delete mode 100644 platforms/Arduino-socket/upload.h delete mode 100644 platforms/Arduino/upload delete mode 100755 scripts/upload diff --git a/benchmarks/all_bench.sh b/benchmarks/all_bench.sh index f754fc69..ce4dcd88 100755 --- a/benchmarks/all_bench.sh +++ b/benchmarks/all_bench.sh @@ -18,9 +18,9 @@ to_csv() { sed -i -n '0~2{N;s/\n/,/p}' $1 } -sleep 5 -./espruino_bench.sh $tmpdir/espruino -to_csv $tmpdir/espruino +#sleep 5 +#./espruino_bench.sh $tmpdir/espruino +#to_csv $tmpdir/espruino sleep 5 ./warduino_bench.sh $tmpdir/warduino diff --git a/benchmarks/warduino_bench.sh b/benchmarks/warduino_bench.sh index ebdd0e3c..48c588ec 100755 --- a/benchmarks/warduino_bench.sh +++ b/benchmarks/warduino_bench.sh @@ -11,7 +11,8 @@ make -C tasks all cat bench.list | while read l; do echo $l | tee -a $1 - ../scripts/upload ${BOARD:-ESP32WROVER} ./tasks/$l/wast/warduino/warduino.ino -p /dev/ttyUSB0 2>&1 >"$tmpfile" + arduino-cli compile --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" ./tasks/$l/wast/warduino/warduino.ino 2>&1 >"$tmpfile" + arduino-cli upload --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" ./tasks/$l/wast/warduino/warduino.ino -p /dev/ttyUSB0 2>&1 >"$tmpfile" if [ "$?" -eq "0" ]; then echo "flashed" python3 flash_and_check.py | tee -a $1 diff --git a/do_build.sh b/do_build.sh deleted file mode 100755 index 8b73aa04..00000000 --- a/do_build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -cd build/ -make && cd .. - -echo Starting CLI - -./build/wdcli --file examples/blinkm5stickc/blink.wasm diff --git a/platforms/Arduino-socket/.gitignore b/platforms/Arduino-socket/.gitignore deleted file mode 100644 index a71162b0..00000000 --- a/platforms/Arduino-socket/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.config -Arduino-socket.ino diff --git a/platforms/Arduino-socket/Arduino-socket.ino.template b/platforms/Arduino-socket/Arduino-socket.ino.template deleted file mode 100644 index 290fb165..00000000 --- a/platforms/Arduino-socket/Arduino-socket.ino.template +++ /dev/null @@ -1,90 +0,0 @@ -// -// WARDuino - WebAssembly interpreter for embedded devices. -// -// -//#include - -#include - -#include "Arduino.h" -#include "upload.h" - -unsigned int wasm_len = upload_wasm_len; -unsigned char* wasm = upload_wasm; - -WARDuino* wac = WARDuino::instance(); -Module* m; - -SocketServer* server; -ServerCredentials serverCredentials = {"{{SSID}}", "{{Password}}"}; -uint16_t pullportno = 8080; -uint16_t pushportno = 8081; - -#define UART_PIN 3 - -void startDebuggerStd(void* pvParameter) { - int valread; - uint8_t buffer[1024] = {0}; - wac->debugger->socket = fileno(stdout); - write(fileno(stdout), "Got a message ... \n", 19); - while (true) { - // taskYIELD(); - // vTaskDelay(100 / portTICK_PERIOD_MS); - yield(); - - while (Serial.available()) { - size_t buff_len = 0; - while (Serial.available()) { - buffer[buff_len++] = (int8_t)Serial.read(); - } - if (buff_len) { - write(fileno(stdout), "Reading message ..... \n", 19); - fflush(stdout); - wac->handleInterrupt(valread - 1, buffer); - write(fileno(stdout), buffer, valread); - fflush(stdout); - } - } - } -} - -void handleInterrupt(size_t len, uint8_t* buff) { - wac->handleInterrupt(len, buff); -} - -void setup(void) { - Serial.begin(115200); - // attachInterrupt(UART_PIN, handleInput, CHANGE); - - Serial.println(ESP.getFreeHeap()); - Serial.println("Total heap:"); - Serial.println(ESP.getHeapSize()); - Serial.println("\nFree heap:"); - Serial.println(ESP.getFreeHeap()); - Serial.println("\nTotal PSRAM:"); - Serial.println(ESP.getPsramSize()); - Serial.println("\nFree PSRAM: "); - Serial.println(ESP.getFreePsram()); - - // create & connect SocketServer - SocketServer::createServer(pullportno, pushportno, &handleInterrupt); - server = SocketServer::getServer(); - server->connect2Wifi(&serverCredentials); -} - -void loop() { - disableCore0WDT(); - m = wac->load_module(wasm, wasm_len, {}); - server->begin(); - - printf("LOADED \n\n"); - // uint8_t command[] = {'0', '3', '\n'}; - // wac.handleInterrupt(3, command); - xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); - printf("START\n\n"); - - wac->run_module(m); - - printf("END\n\n"); - wac->unload_module(m); -} diff --git a/platforms/Arduino-socket/Makefile b/platforms/Arduino-socket/Makefile deleted file mode 100644 index 27abe906..00000000 --- a/platforms/Arduino-socket/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# Arduino Socket Platform - -PORT = /dev/ttyUSB0 -FQBN = esp32:esp32:esp32wrover - -CONFIG = .config -include ${CONFIG} - -ifndef SSID -$(error SSID is not set. Use a .config file.) -endif - -ifndef PASSWORD -$(error PASSWORD is not set. Use a .config file.) -endif - -Arduino-socket.ino: .config Arduino-socket.ino.template - sed 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' Arduino-socket.ino.template > $@ - -compile: Arduino-socket.ino - arduino-cli -v compile --fqbn $(FQBN) Arduino-socket.ino - -flash: - arduino-cli upload -p $(PORT) --fqbn $(FQBN) Arduino-socket.ino - -monitor: - arduino-cli monitor -p $(PORT) -c baudrate=115200 - diff --git a/platforms/Arduino-socket/README.md b/platforms/Arduino-socket/README.md deleted file mode 100644 index a77e5361..00000000 --- a/platforms/Arduino-socket/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Arduino Socket Platform - -The code in this folder sets up the WARDuino for the Arduino socket platform, where the device creates a socket server to communicate with other WARDuino instances over Wi-Fi. diff --git a/platforms/Arduino-socket/upload b/platforms/Arduino-socket/upload deleted file mode 100644 index ae837a40..00000000 --- a/platforms/Arduino-socket/upload +++ /dev/null @@ -1 +0,0 @@ -arduino-cli upload -p $1 --fqbn esp32:esp32:esp32wrover Arduino-socket.ino diff --git a/platforms/Arduino-socket/upload.h b/platforms/Arduino-socket/upload.h deleted file mode 100644 index c62c9fa3..00000000 --- a/platforms/Arduino-socket/upload.h +++ /dev/null @@ -1,62 +0,0 @@ -// unsigned char upload_wasm[] = { -// 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, -// 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, -// 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, -// 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, -// 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, -// 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, -// 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, -// 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, -// 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, -// 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, -// 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, -// 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, -// 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, -// 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, -// 0x0b, 0x0b, 0x00, 0x6e, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x01, 0x49, 0x05, -// 0x00, 0x0e, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, -// 0x65, 0x6c, 0x61, 0x79, 0x01, 0x11, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, -// 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x02, -// 0x16, 0x65, 0x6e, 0x76, 0x2e, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, 0x69, -// 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x03, -// 0x04, 0x69, 0x6e, 0x69, 0x74, 0x04, 0x05, 0x62, 0x6c, 0x69, 0x6e, 0x6b, -// 0x02, 0x1c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, -// 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, -// 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79}; -// unsigned int upload_wasm_len = 282; -// -// -// -// - -unsigned char upload_wasm[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x05, 0x60, - 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, - 0x7f, 0x7f, 0x00, 0x60, 0x05, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x60, - 0x00, 0x00, 0x02, 0x60, 0x04, 0x03, 0x65, 0x6e, 0x76, 0x0d, 0x63, 0x68, - 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x00, - 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, 0x5f, 0x64, - 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x11, 0x63, 0x68, 0x69, 0x70, 0x5f, - 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x64, - 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x13, 0x73, 0x75, 0x62, 0x73, 0x63, - 0x72, 0x69, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, - 0x70, 0x74, 0x00, 0x02, 0x03, 0x07, 0x06, 0x03, 0x04, 0x00, 0x00, 0x01, - 0x02, 0x04, 0x05, 0x01, 0x70, 0x01, 0x02, 0x02, 0x05, 0x03, 0x01, 0x00, - 0x01, 0x06, 0x13, 0x03, 0x7f, 0x01, 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, - 0x41, 0x80, 0x10, 0x0b, 0x7f, 0x00, 0x41, 0x80, 0x10, 0x0b, 0x07, 0x2c, - 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x04, 0x6d, - 0x61, 0x69, 0x6e, 0x00, 0x05, 0x0a, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, - 0x5f, 0x65, 0x6e, 0x64, 0x03, 0x01, 0x0b, 0x5f, 0x5f, 0x68, 0x65, 0x61, - 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x09, 0x07, 0x01, 0x00, - 0x41, 0x01, 0x0b, 0x01, 0x04, 0x0a, 0x4f, 0x06, 0x0d, 0x00, 0x41, 0x1a, - 0x41, 0x1a, 0x10, 0x08, 0x41, 0x01, 0x47, 0x10, 0x07, 0x0b, 0x1b, 0x00, - 0x41, 0x25, 0x41, 0x00, 0x10, 0x06, 0x41, 0x1a, 0x41, 0x02, 0x10, 0x06, - 0x41, 0x25, 0x41, 0x01, 0x41, 0x02, 0x10, 0x09, 0x03, 0x40, 0x0c, 0x00, - 0x0b, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0b, 0x08, - 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x01, 0x0b, 0x06, 0x00, 0x20, 0x00, - 0x10, 0x02, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, - 0x03, 0x0b}; -unsigned int upload_wasm_len = 314; -/* - */ diff --git a/platforms/Arduino/upload b/platforms/Arduino/upload deleted file mode 100644 index abef5100..00000000 --- a/platforms/Arduino/upload +++ /dev/null @@ -1 +0,0 @@ -arduino-cli upload -p $1 --fqbn esp32:esp32:esp32wrover Arduino.ino diff --git a/scripts/upload b/scripts/upload deleted file mode 100755 index c27ff9f7..00000000 --- a/scripts/upload +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -# Name: -# By Robbert Gurdeep Singh -# --pref build.path=/tmp/build -# The above extra arguments allows specifying a build loc -################################################################################ -set -x -e - -device="$(echo "${1?-Please specify a device type}" | tr '[:lower:]' '[:upper:]')" -file=${2?-No file to upload} -shift 2 - -if [ -n "$USE_TMPDIR" ]; then - tmpfile="$(mktemp -d --tmpdir)" - trap "rm -rf '$tmpfile'" EXIT - cp "$file" "$tmpfile/prog.c" - cd "$tmpfile" - file="prog.c" -fi - -case "$device" in -"ESP32") - arduino-cli compile --fqbn "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" - arduino-cli upload --fqbn "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" - ;; -"ESP32WROVER") - arduino-cli compile --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" - arduino-cli upload --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$file" "$@" - ;; -"ESP8266") - arduino-cli compile --fqbn "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$file" - arduino-cli upload --fqbn "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$file" "$@" - ;; -*) - echo "Unknown device: $device" - exit 1 -esac - -echo "done" From 74b8466874695c7b1e65d773ceec91fd0d846564 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Sat, 4 Jun 2022 11:08:06 +0200 Subject: [PATCH 158/249] Remove scripts/signal --- scripts/signal | 100 ------------------------------------------------- 1 file changed, 100 deletions(-) delete mode 100755 scripts/signal diff --git a/scripts/signal b/scripts/signal deleted file mode 100755 index 4138bed4..00000000 --- a/scripts/signal +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/sh - -if test -n "$WARDUINO_DEV"; then - echo "USING: $WARDUINO_DEV" - target="$WARDUINO_DEV" - write() { - ( - tr -d '\n\t ' - echo"" - ) | tr '[:lower:]' '[:upper:]' | tee $WARDUINO_DEV - echo "Written to $WARDUINO_DEV" - } -else - write() { - # xxd -r -p > /tmp/change - ( - tr -d '\n\t ' - echo"" - ) | tr '[:lower:]' '[:upper:]' | tee /tmp/change - kill -USR1 "$(pgrep -i warduino)" - } -fi - -#echo "AAcAQeQAEAIL" | base64 -d > /tmp/change -case "$1" in -"REPLACE") - cat </dev/null | sort | uniq | sed 's/^/ export WARDUINO_DEV=/') - - Communication via /tmp/change and kill -USR1 - export WARDUINO_DEV="" -HELP - - ;; -esac From ca1bcdd1a3942705f369739e44627b95783200e0 Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Sat, 4 Jun 2022 17:41:21 +0200 Subject: [PATCH 159/249] Make write2client iterative istead of recursive --- src/RFC/SocketServer.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp index 293fece9..d28ca621 100644 --- a/src/RFC/SocketServer.cpp +++ b/src/RFC/SocketServer.cpp @@ -116,10 +116,14 @@ void SocketServer::write2Client(AsyncClient *client, const char *buf, size_t size_buf) { if (client == nullptr) return; size_t space_left = client->space(); - client->add(buf, size_buf > space_left ? space_left : size_buf); - client->send(); - if (size_buf <= space_left) return; - write2Client(client, buf + space_left, size_buf - space_left); + // Send upto limit + do { + size_t send_size = size_buf > space_left ? space_left : size_buf; + client->add(buf, send_size); + client->send(); + buf += send_size; + size_buf -= send_size; + } while (size_buf > 0); } void SocketServer::printf2Client(AsyncClient *client, const char *format, ...) { From cdeb15d68a3d819f49c435d9848387516c81c4cc Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Sat, 4 Jun 2022 17:45:25 +0200 Subject: [PATCH 160/249] Reformulate shoud_push event in terms of WARDuino We shoud use should_push_event in the future to determine what to do with an added handler --- src/WARDuino/CallbackHandler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 851493ee..f491b5bd 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -16,9 +16,9 @@ bool CallbackHandler::resolving_event = false; #ifdef ARDUINO size_t CallbackHandler::pushed_cursor = 0; -bool should_push_event(SocketServer *server) { - return server != nullptr && server->hasPushClient() && - CallbackHandler::pushed_cursor < CallbackHandler::event_count(); +bool should_push_event() { + return WARDuino::instance()->program_state == WARDuinoProxyRun || + WARDuino::instance()->program_state == WARDUINODrone; } #endif @@ -79,7 +79,7 @@ bool CallbackHandler::resolve_event(bool force) { #ifdef ARDUINO SocketServer *server = SocketServer::getServer(); - if (should_push_event(server)) { + if (should_push_event()) { Event e = CallbackHandler::events->at(CallbackHandler::pushed_cursor++); server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", From c6eed6b19c6bcb34039b2c399f2e1a68b7b9cdc7 Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Sat, 4 Jun 2022 17:46:44 +0200 Subject: [PATCH 161/249] Remove debug print in the middle of capturing events This breaks the JSON when DEBUG is 1 --- src/Debug/debugger.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 9185f0a4..f9bf0015 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -476,7 +476,6 @@ void Debugger::dumpEvents(long start, long size) const { if (size > EVENTS_SIZE) { size = EVENTS_SIZE; } - dbg_info("Printing event queue (%lu, %lu) ...\n", start, size); dprintf(this->socket, R"("events": [)"); long index = start, end = start + size; From 000a8e369efe8f5afc7044fd206054b5579ead1d Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Sat, 4 Jun 2022 17:54:08 +0200 Subject: [PATCH 162/249] Fix wrong buffer length used TODO: remove valread completely --- platforms/Arduino/Arduino.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index 3dbcc474..052f5bf0 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -36,9 +36,10 @@ void startDebuggerStd(void* pvParameter) { buffer[buff_len++] = (int8_t)Serial.read(); } if (buff_len) { + buffer[buff_len] = '\0'; write(fileno(stdout), "Reading message ..... \n", 19); fflush(stdout); - wac->handleInterrupt(valread - 1, buffer); + wac->handleInterrupt(buff_len, buffer); write(fileno(stdout), buffer, valread); fflush(stdout); } From 4603ace2d61ec4b4e16f142a1a870727226c20d0 Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Sat, 4 Jun 2022 17:55:50 +0200 Subject: [PATCH 163/249] Fix request for callback mappting DEC->HEX --- src/RFC/rfc.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index d78c26b7..4d6cfc18 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -294,10 +294,6 @@ void RFC::deserializeRFCResult() { } delete[] call_result; - // Retreive new callbackmapping - std::string message = std::to_string(interruptDUMPCallbackmapping) + "\n"; - ProxyServer::getServer()->send((char *)message.c_str(), - (int)message.length()); } void RFC::call(StackValue *arguments) { @@ -313,8 +309,15 @@ void RFC::call(StackValue *arguments) { delete[] rfc_request->raw; delete rfc_request; + printf("sent FAILED \n"); return; } + // Fetch new callback mapping + // convert message to hex TODO: move to proxyserver + char cmdBuffer[10] = ""; + int cmdBufferLen = 0; + sprintf(cmdBuffer, "%x\n%n", interruptDUMPCallbackmapping, &cmdBufferLen); + ProxyServer::getServer()->send(cmdBuffer, cmdBufferLen); this->deserializeRFCResult(); } From fca41c901b8457fb6ecad4c4282682bc9535502f Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Sat, 4 Jun 2022 17:57:10 +0200 Subject: [PATCH 164/249] Add notification for missing handlers --- src/WARDuino/CallbackHandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index f491b5bd..398c1bdb 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -109,6 +109,8 @@ bool CallbackHandler::resolve_event(bool force) { } } else { // TODO handle error: event for non-existing iterator + printf("No handler found for %s (in %lu items)!\n", event.topic.c_str(), + CallbackHandler::callbacks->size()); } CallbackHandler::resolving_event = false; return !CallbackHandler::events->empty(); From 7433590a743bdfa2858b9ea3867f490706a29d88 Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Sat, 4 Jun 2022 17:59:16 +0200 Subject: [PATCH 165/249] Improve callback handeling logic --- src/WARDuino/CallbackHandler.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 398c1bdb..cbdadf06 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -72,18 +72,34 @@ void CallbackHandler::push_event(Event *event) { } bool CallbackHandler::resolve_event(bool force) { - if (CallbackHandler::resolving_event || CallbackHandler::events->empty()) { +#ifdef ARDUINO + SocketServer *server = SocketServer::getServer(); +#endif + if ((!force && CallbackHandler::resolving_event) || + CallbackHandler::events->empty()) { + if (force) { + printf("No events to be processed!\n"); +#ifdef ARDUINO + server->printf2Client(server->pushClient, + "no events to be processed"); +#endif + } return false; } Event event = CallbackHandler::events->front(); #ifdef ARDUINO - SocketServer *server = SocketServer::getServer(); if (should_push_event()) { Event e = CallbackHandler::events->at(CallbackHandler::pushed_cursor++); server->printf2Client(server->pushClient, R"({"topic":"%s","payload":"%s"})", e.topic.c_str(), e.payload.c_str()); + + CallbackHandler::events->pop_front(); + CallbackHandler::pushed_cursor--; + CallbackHandler::resolving_event = false; + return !CallbackHandler::events->empty(); + // no further execution if drone } #endif From 13cc7f2989b1ff5d1f195d8294997bc61fd471c0 Mon Sep 17 00:00:00 2001 From: Robbert Gurdeep Singh Date: Sat, 4 Jun 2022 18:04:43 +0200 Subject: [PATCH 166/249] CI: remove fill template --- .github/workflows/compile.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index a9d721e1..54a8642a 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -43,37 +43,6 @@ jobs: run: cmake .. -D BUILD_EMULATOR=ON ; cmake --build . working-directory: build-emu - fill-out-template: - name: Fill out template files - runs-on: ubuntu-latest - if: github.event.pull_request.draft == false - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - submodules: 'recursive' - - - name: Retrieve version - id: version - run: | - echo "::set-output name=HASH::$(sha1sum Arduino-socket.ino.template | grep '^[^ ]*' -o)" - working-directory: platforms/Arduino-socket - - - name: Cache filled out templates - id: cache-ino - uses: actions/cache@v2 - with: - path: | - platforms/Arduino-socket - key: ${{ env.INO_SOCKET_CACHE }}-${{ steps.version.outputs.HASH }} - - - name: Fill out Arduino-socket.ino.template - if: steps.cache-ino.outputs.cache-hit != 'true' - run: | - echo -e "SSID=ssid\nPASSWORD=password" > .config - make Arduino-socket.ino - working-directory: platforms/Arduino-socket - compile-with-arduino: name: (Arduino) Compile on ${{matrix.board.platform-name}} needs: [formatting-check, fill-out-template] From b146ee313ec981d82acd5fea736d3517c53074c8 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 6 Jun 2022 17:46:17 +0200 Subject: [PATCH 167/249] Fix compile CI --- .github/workflows/compile.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 54a8642a..705c2bea 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -45,7 +45,7 @@ jobs: compile-with-arduino: name: (Arduino) Compile on ${{matrix.board.platform-name}} - needs: [formatting-check, fill-out-template] + needs: [formatting-check] runs-on: ubuntu-latest env: SKETCHES_REPORTS_PATH: sketches-reports From 66d68653bd17fba1cc4f68537743026e80df3ce7 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 7 Jun 2022 16:17:02 +0200 Subject: [PATCH 168/249] Fix: don't change `resolving_event` in debugger thread --- src/Debug/debugger.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index f9bf0015..14f3b901 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -472,6 +472,7 @@ void Debugger::dumpLocals(Module *m) const { } void Debugger::dumpEvents(long start, long size) const { + bool previous = CallbackHandler::resolving_event; CallbackHandler::resolving_event = true; if (size > EVENTS_SIZE) { size = EVENTS_SIZE; @@ -491,7 +492,7 @@ void Debugger::dumpEvents(long start, long size) const { }); dprintf(this->socket, "]"); - CallbackHandler::resolving_event = false; + CallbackHandler::resolving_event = previous; } void Debugger::dumpCallbackmapping() const { From ced41f230f85b56afbf4e55c71c1b3a2da587f49 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 7 Jun 2022 16:18:35 +0200 Subject: [PATCH 169/249] Add callback guard --- src/Interpreter/instructions.cpp | 6 ++++++ src/WARDuino.h | 2 +- src/WARDuino/CallbackHandler.cpp | 22 +++++++++++++++++++++- src/WARDuino/CallbackHandler.h | 3 +-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index b68b4c1a..b4bc64ad 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -34,6 +34,12 @@ Block *pop_block(Module *m) { Frame *frame = &m->callstack[m->csp--]; Type *t = frame->block->type; + if (frame->block->block_type == 0xff) { + CallbackHandler::resolving_event = false; + frame = &m->callstack[m->csp--]; + t = frame->block->type; + } + // TODO: validate return value if there is one m->fp = frame->fp; // Restore frame pointer diff --git a/src/WARDuino.h b/src/WARDuino.h index cec0cd3a..2426f8d7 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -71,7 +71,7 @@ typedef union FuncPtr { // A block or function typedef struct Block { uint8_t block_type; // 0x00: function, 0x01: init_exp - // 0x02: block, 0x03: loop, 0x04: if + // 0x02: block, 0x03: loop, 0x04: if, 0xff: cbk guard uint32_t fidx; // function only (index) Type *type; // params/results type uint32_t local_count; // function only diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index cbdadf06..bf4da3da 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -9,6 +9,24 @@ #endif #include "../Utils/macros.h" +void push_guard(Module *m) { + if (m == nullptr) { + return; + } + auto *guard = (Block *)malloc(sizeof(struct Block)); + guard->block_type = 255; + guard->type = nullptr; + guard->local_value_type = nullptr; + guard->start_ptr = nullptr; + guard->end_ptr = nullptr; + guard->else_ptr = nullptr; + guard->export_name = nullptr; + guard->import_field = nullptr; + guard->import_module = nullptr; + guard->func_ptr = nullptr; + push_block(m, guard, m->sp); +} + // CallbackHandler class bool CallbackHandler::manual_event_resolution = false; @@ -119,16 +137,18 @@ bool CallbackHandler::resolve_event(bool force) { auto iterator = CallbackHandler::callbacks->find(event.topic); if (iterator != CallbackHandler::callbacks->end()) { + Module *module = nullptr; std::string key = iterator->first; for (Callback cbs : *iterator->second) { cbs.resolve_event(event); + module = cbs.module; } + push_guard(module); } else { // TODO handle error: event for non-existing iterator printf("No handler found for %s (in %lu items)!\n", event.topic.c_str(), CallbackHandler::callbacks->size()); } - CallbackHandler::resolving_event = false; return !CallbackHandler::events->empty(); } diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index 0287cb7b..8ffa33e7 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -52,9 +52,8 @@ class CallbackHandler { }; class Callback { - private: - Module *module; // reference to module public: + Module *module; // reference to module std::string topic; uint32_t table_index{}; From 6b2fbabf47e2213b9456352e15ea59b0a953cbbc Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 7 Jun 2022 19:26:08 +0200 Subject: [PATCH 170/249] Clang format --- src/RFC/rfc.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index 4d6cfc18..1a5e8fdf 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -293,7 +293,6 @@ void RFC::deserializeRFCResult() { FATAL("Deserialization RFCResult\n"); } delete[] call_result; - } void RFC::call(StackValue *arguments) { From 107a4d8167cdb74321ee7d719edf29b134884564 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 7 Jun 2022 20:15:50 +0200 Subject: [PATCH 171/249] Remove socket ino from compile.yml --- .github/workflows/compile.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 705c2bea..a62783ea 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -5,9 +5,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true # Cancel in-flight jobs for the same branch or PR -env: - INO_SOCKET_CACHE: "template-socket" - jobs: formatting-check: name: Formatting Check @@ -72,27 +69,12 @@ jobs: source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json sketches: | - platforms/Arduino - - platforms/Arduino-socket steps: - name: Checkout uses: actions/checkout@v2 with: submodules: 'recursive' - - name: Retrieve version - id: version - run: | - echo "::set-output name=HASH::$(sha1sum Arduino-socket.ino.template | grep '^[^ ]*' -o)" - working-directory: platforms/Arduino-socket - - - name: Get Template Cache - id: cache-ino - uses: actions/cache@v2 - with: - path: | - platforms/Arduino-socket - key: ${{ env.INO_SOCKET_CACHE }}-${{ steps.version.outputs.HASH }} - - name: Compile sketches uses: arduino/compile-sketches@v1 with: From 396facf4ad0a187d8f8ec69b34e1264637bb94dd Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 7 Jun 2022 20:18:29 +0200 Subject: [PATCH 172/249] Fix ESP IDF compilation --- src/WARDuino/CallbackHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index bf4da3da..015dfad5 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -146,7 +146,7 @@ bool CallbackHandler::resolve_event(bool force) { push_guard(module); } else { // TODO handle error: event for non-existing iterator - printf("No handler found for %s (in %lu items)!\n", event.topic.c_str(), + printf("No handler found for %s (in %u items)!\n", event.topic.c_str(), CallbackHandler::callbacks->size()); } return !CallbackHandler::events->empty(); From fb76fffb811726ba481b0011a98b1845f4c90191 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 7 Jun 2022 20:35:57 +0200 Subject: [PATCH 173/249] Add retry to assemblyscript examples --- examples/assemblyscript/main/smartlamp.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/assemblyscript/main/smartlamp.ts b/examples/assemblyscript/main/smartlamp.ts index 3b8bcfa9..b46e3431 100644 --- a/examples/assemblyscript/main/smartlamp.ts +++ b/examples/assemblyscript/main/smartlamp.ts @@ -8,7 +8,7 @@ const CLIENT_ID = "random-mqtt-client-id"; function until_connected(connect: () => void, connected: () => boolean, - retry: boolean = false): void { + retry: () => boolean): void { connect(); while (!connected()) { wd.delay(1000); @@ -42,7 +42,8 @@ export function main(): void { // Connect to Wi-Fi until_connected( () => { wd.wifi_connect(SSID, PASSWORD); }, - wd.wifi_connected); + wd.wifi_connected, + () => { return wd.wifi_status() === 6; }); let message = "Connected to wifi network with ip: "; wd.print(message.concat(wd.wifi_localip())); @@ -51,7 +52,7 @@ export function main(): void { until_connected( () => { wd.mqtt_connect(CLIENT_ID); wd.mqtt_loop(); }, () => { return wd.mqtt_connected(); }, - true); + () => { return true; }); // Subscribe to MQTT topic and turn on LED wd.mqtt_subscribe("LED", callback); @@ -63,7 +64,8 @@ export function main(): void { while (true) { until_connected( () => { wd.mqtt_connect(CLIENT_ID); wd.mqtt_loop(); }, - () => { return wd.mqtt_connected(); }); + () => { return wd.mqtt_connected(); }, + () => { return true; }); wd.sleep(5); // Sleep for 5 seconds } From 174f36f194310b55045c1fb4b6b8a83e7ec37767 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 15 Jun 2022 16:12:47 +0200 Subject: [PATCH 174/249] Fix typos and clang warnings --- src/Interpreter/instructions.cpp | 210 +++++++++++++++---------------- src/RFC/proxy_server.cpp | 15 ++- src/Utils/macros.cpp | 1 - 3 files changed, 110 insertions(+), 116 deletions(-) diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index b4bc64ad..8f546f4e 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -3,17 +3,12 @@ #include #include -#include "../Debug/debugger.h" #include "../Memory/mem.h" #include "../RFC/rfc.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "../Utils/util_arduino.h" -#ifndef ARDUINO -// performs proxy calls to an MCU -bool proxy_call(uint32_t fidx, Module *m); -#endif // Size of memory load. // This starts with the first memory load operator at opcode 0x28 uint32_t LOAD_SIZE[] = {4, 8, 4, 8, 1, 1, 2, 2, 1, 1, 2, 2, 4, 4, // loads @@ -80,15 +75,16 @@ void setup_call(Module *m, uint32_t fidx) { // Push current frame on the call stack push_block(m, func, m->sp - type->param_count); - if (TRACE) { - dbg_warn(" >> fn0x%x(%d) %s(", fidx, fidx, - func->export_name ? func->export_name : ""); - for (int p = ((int)type->param_count) - 1; p >= 0; p--) { - dbg_warn("%s%s", value_repr(&m->stack[m->sp - p]), p ? " " : ""); - } - dbg_warn("), %d locals, %d results\n", func->local_count, - type->result_count); +#if TRACE + dbg_warn(" >> fn0x%x(%d) %s(", fidx, fidx, + func->export_name + ? func->export_name + : "") for (int p = ((int)type->param_count) - 1; p >= 0; p--) { + dbg_warn("%s%s", value_repr(&m->stack[m->sp - p]), p ? " " : ""); } + dbg_warn("), %d locals, %d results\n", func->local_count, + type->result_count); +#endif // Push locals (dropping extras) m->fp = m->sp - ((int)type->param_count) + 1; @@ -105,6 +101,28 @@ void setup_call(Module *m, uint32_t fidx) { m->pc_ptr = func->start_ptr; } +#ifndef ARDUINO +// performs proxy calls to an MCU +bool proxy_call(uint32_t fidx, Module *m) { + printf("Remote Function Call %d\n", fidx); + RFC *rf = RFC::getRFC(fidx); + StackValue *args = nullptr; + if (rf->type->param_count > 0) { + m->sp -= rf->type->param_count; + args = &m->stack[m->sp + 1]; + } + + rf->call(args); + if (!rf->succes) { + // TODO exception bugger might be too small and msg not null terminated? + memcpy(&exception, rf->exceptionMsg, strlen(rf->exceptionMsg)); + return false; + } + if (rf->type->result_count > 0) m->stack[++m->sp] = *rf->result; + return true; +} +#endif + /* * WebAssembly Instructions * @@ -210,10 +228,10 @@ bool i_instr_if(Module *m, uint8_t *block_ptr) { } } // if true, keep going - if (TRACE) { - debug(" - cond: 0x%x jump to 0x%x, block: %s\n", cond, - (uint32_t)(m->pc_ptr - m->bytes), block_repr(block)); - } +#if TRACE + debug(" - cond: 0x%x jump to 0x%x, block: %s\n", cond, + (uint32_t)(m->pc_ptr - m->bytes), block_repr(block)); +#endif return true; } @@ -223,9 +241,9 @@ bool i_instr_if(Module *m, uint8_t *block_ptr) { bool i_instr_else(Module *m) { Block *block = m->callstack[m->csp].block; m->pc_ptr = block->br_ptr; - if (TRACE) { - debug(" - of %s jump to 0x%p\n", block_repr(block), m->pc_ptr); - } +#if TRACE + debug(" - of %s jump to 0x%p\n", block_repr(block), m->pc_ptr); +#endif return true; } @@ -237,17 +255,16 @@ bool i_instr_end(Module *m, bool *prog_done) { if (block == nullptr) { return false; // an exception (set by pop_block) } - if (TRACE) { - debug(" - of %s\n", block_repr(block)); - } +#if TRACE + debug(" - of %s\n", block_repr(block)); +#endif if (block->block_type == 0x00) { // Function - if (TRACE) { - dbg_warn(" << fn0x%x(%d) %s = %s\n", block->fidx, block->fidx, - block->export_name ? block->export_name : "", - block->type->result_count > 0 - ? value_repr(&m->stack[m->sp]) - : "_"); - } +#if TRACE + dbg_warn( + " << fn0x%x(%d) %s = %s\n", block->fidx, block->fidx, + block->export_name ? block->export_name : "", + block->type->result_count > 0 ? value_repr(&m->stack[m->sp]) : "_"); +#endif if (m->csp == -1) { // Return to top-level *prog_done = true; @@ -272,9 +289,9 @@ bool i_instr_br(Module *m) { m->csp -= depth; // set to end for pop_block m->pc_ptr = m->callstack[m->csp].block->br_ptr; - if (TRACE) { - debug(" - to: 0x%p\n", m->pc_ptr); - } +#if TRACE + debug(" - to: 0x%p\n", m->pc_ptr); +#endif return true; } @@ -290,11 +307,10 @@ bool i_instr_br_if(Module *m) { // set to end for pop_block m->pc_ptr = m->callstack[m->csp].block->br_ptr; } - if (TRACE) { - debug(" - depth: 0x%x, cond: 0x%x, to: 0x%p\n", depth, cond, - m->pc_ptr); - } - +#if TRACE + debug(" - depth: 0x%x, cond: 0x%x, to: 0x%p\n", depth, cond, + m->pc_ptr); +#endif return true; } @@ -322,10 +338,9 @@ bool i_instr_br_table(Module *m) { m->csp -= depth; // set to end for pop_block m->pc_ptr = m->callstack[m->csp].block->br_ptr; - if (TRACE) { - debug(" - count: %d, didx: %d, to: 0x%p\n", count, didx, - m->pc_ptr); - } +#if TRACE + debug(" - count: %d, didx: %d, to: 0x%p\n", count, didx, m->pc_ptr); +#endif return true; } @@ -339,9 +354,9 @@ bool i_instr_return(Module *m) { // Set the program count to the end of the function // The actual pop_block and return is handled by the end opcode. m->pc_ptr = m->callstack[0].block->end_ptr; - if (TRACE) { - debug(" - to: 0x%p\n", m->pc_ptr); - } +#if TRACE + debug(" - to: 0x%p\n", m->pc_ptr); +#endif return true; } @@ -351,7 +366,9 @@ bool i_instr_return(Module *m) { bool i_instr_call(Module *m) { uint32_t fidx = read_LEB_32(&m->pc_ptr); #ifndef ARDUINO - if (RFC::isRFC(fidx)) return proxy_call(fidx, m); + if (RFC::isRFC(fidx)) { + return proxy_call(fidx, m); + } #endif if (fidx < m->import_count) { return ((Primitive)m->functions[fidx].func_ptr)(m); @@ -361,34 +378,12 @@ bool i_instr_call(Module *m) { return false; } setup_call(m, fidx); // regular function call - if (TRACE) { - debug(" - calling function fidx: %d at: 0x%p\n", fidx, - m->pc_ptr); - } - } - return true; -} - -#ifndef ARDUINO -bool proxy_call(uint32_t fidx, Module *m) { - printf("Remote Function Call %d\n", fidx); - RFC *rf = RFC::getRFC(fidx); - StackValue *args = nullptr; - if (rf->type->param_count > 0) { - m->sp -= rf->type->param_count; - args = &m->stack[m->sp + 1]; - } - - rf->call(args); - if (!rf->succes) { - // TODO exception bugger might be too small and msg not null terminated? - memcpy(&exception, rf->exceptionMsg, strlen(rf->exceptionMsg)); - return false; +#if TRACE + debug(" - calling function fidx: %d at: 0x%p\n", fidx, m->pc_ptr); +#endif } - if (rf->type->result_count > 0) m->stack[++m->sp] = *rf->result; return true; } -#endif /** * 0x11 call_indirect @@ -401,11 +396,11 @@ bool i_instr_call_indirect(Module *m) { if (m->options.mangle_table_index) { // val is the table address + the index (not sized for the // pointer size) so get the actual (sized) index - if (TRACE) { - debug(" - entries: %p, original val: 0x%x, new val: 0x%x\n", - m->table.entries, val, - (uint32_t)((uint64_t)m->table.entries) - val); - } +#if TRACE + debug(" - entries: %p, original val: 0x%x, new val: 0x%x\n", + m->table.entries, val, + (uint32_t)((uint64_t)m->table.entries) - val); +#endif // val = val - (uint32_t)((uint64_t)m->table.entries & 0xFFFFFFFF); val = val - (uint32_t)((uint64_t)m->table.entries); } @@ -416,13 +411,15 @@ bool i_instr_call_indirect(Module *m) { } uint32_t fidx = m->table.entries[val]; - if (TRACE) { - debug(" - call_indirect tidx: %d, val: 0x%x, fidx: 0x%x\n", tidx, - val, fidx); - } +#if TRACE + debug(" - call_indirect tidx: %d, val: 0x%x, fidx: 0x%x\n", tidx, val, + fidx); +#endif #ifndef ARDUINO - if (RFC::isRFC(fidx)) return proxy_call(fidx, m); + if (RFC::isRFC(fidx)) { + return proxy_call(fidx, m); + } #endif if (fidx < m->import_count) { @@ -459,12 +456,12 @@ bool i_instr_call_indirect(Module *m) { } } - if (TRACE) { - debug( - " - tidx: %d, table idx: %d, " - "calling function fidx: %d at: 0x%p\n", - tidx, val, fidx, m->pc_ptr); - } +#if TRACE + debug( + " - tidx: %d, table idx: %d, " + "calling function fidx: %d at: 0x%p\n", + tidx, val, fidx, m->pc_ptr); +#endif } return true; } @@ -502,10 +499,10 @@ bool i_instr_select(Module *m) { */ bool i_instr_get_local(Module *m) { int32_t arg = read_LEB_32(&m->pc_ptr); - if (TRACE) { - debug(" - arg: 0x%x, got %s\n", arg, - value_repr(&m->stack[m->fp + arg])); - } +#if TRACE + debug(" - arg: 0x%x, got %s\n", arg, + value_repr(&m->stack[m->fp + arg])); +#endif m->stack[++m->sp] = m->stack[m->fp + arg]; return true; } @@ -516,10 +513,10 @@ bool i_instr_get_local(Module *m) { bool i_instr_set_local(Module *m) { int32_t arg = read_LEB_32(&m->pc_ptr); m->stack[m->fp + arg] = m->stack[m->sp--]; - if (TRACE) { - debug(" - arg: 0x%x, to %s (stack loc: %d)\n", arg, - value_repr(&m->stack[m->sp + 1]), m->fp + arg); - } +#if TRACE + debug(" - arg: 0x%x, to %s (stack loc: %d)\n", arg, + value_repr(&m->stack[m->sp + 1]), m->fp + arg); +#endif return true; } @@ -529,9 +526,9 @@ bool i_instr_set_local(Module *m) { bool i_instr_tee_local(Module *m) { int32_t arg = read_LEB_32(&m->pc_ptr); m->stack[m->fp + arg] = m->stack[m->sp]; - if (TRACE) { - debug(" - arg: 0x%x, to %s\n", arg, value_repr(&m->stack[m->sp])); - } +#if TRACE + debug(" - arg: 0x%x, to %s\n", arg, value_repr(&m->stack[m->sp])); +#endif return true; } @@ -540,9 +537,9 @@ bool i_instr_tee_local(Module *m) { */ bool i_instr_get_global(Module *m) { int32_t arg = read_LEB_32(&m->pc_ptr); - if (TRACE) { - debug(" - arg: 0x%x, got %s\n", arg, value_repr(&m->globals[arg])); - } +#if TRACE + debug(" - arg: 0x%x, got %s\n", arg, value_repr(&m->globals[arg])); +#endif m->stack[++m->sp] = m->globals[arg]; return true; } @@ -553,10 +550,9 @@ bool i_instr_get_global(Module *m) { bool i_instr_set_global(Module *m) { uint32_t arg = read_LEB_32(&m->pc_ptr); m->globals[arg] = m->stack[m->sp--]; - if (TRACE) { - debug(" - arg: 0x%x, got %s\n", arg, - value_repr(&m->stack[m->sp + 1])); - } +#if TRACE + debug(" - arg: 0x%x, got %s\n", arg, value_repr(&m->stack[m->sp + 1])); +#endif return true; } @@ -1515,7 +1511,7 @@ bool interpret(Module *m) { while (m->warduino->debugger->checkDebugMessages( m, &m->warduino->program_state)) { - }; + } fflush(stdout); reset_wdt(); @@ -1769,7 +1765,7 @@ bool interpret(Module *m) { return false; } if (m->warduino->program_state == WARDuinoProxyRun && !success) { - // RFC was unsuccesful + // RFC was unsuccessful RFC::currentCallee()->succes = false; // TODO copy exceptionMsg success = true; diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_server.cpp index ba7641c1..1e8bd09c 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_server.cpp @@ -33,7 +33,7 @@ struct Address { struct Socket { int port; int fileDescriptor; - struct sockaddr_in adress; + struct sockaddr_in address; pthread_mutex_t *mutex; }; @@ -65,11 +65,10 @@ const char *createConnection(int socketfd, char *host, int port, bool continuing(pthread_mutex_t *mutex) { switch (pthread_mutex_trylock(mutex)) { - case 0: /* if we got the lock, unlock and return true */ + case 0: /* if we got the lock, unlock and return false */ pthread_mutex_unlock(mutex); return false; - case EBUSY: /* return false if the mutex was locked */ - return true; + case EBUSY: /* return true if the mutex was locked */ default: return true; } @@ -87,7 +86,7 @@ Event *parseJSON(char *buff) { nlohmann::basic_json<> parsed = nlohmann::json::parse(buff); printf("parseJSON: %s\n", parsed.dump().c_str()); std::string payload = *parsed.find("payload"); - return new Event(*parsed.find("topic"), payload.c_str()); + return new Event(*parsed.find("topic"), payload); } ProxyServer *ProxyServer::proxyServer = nullptr; @@ -125,7 +124,7 @@ bool ProxyServer::registerAddresses(char *_host, int _pull_port, } void ProxyServer::updateExcpMsg(const char *msg) { - if (this->exceptionMsg != nullptr) delete[] this->exceptionMsg; + delete[] this->exceptionMsg; auto msg_len = strlen(msg); this->exceptionMsg = new char[(msg_len + 1) / sizeof(char)]; this->exceptionMsg[msg_len] = '\0'; @@ -164,7 +163,7 @@ void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { current_size); } buffer[buf_idx++] = _char; - // manual nulltermination is needed because parseJSON does not use + // manual null-termination is needed because parseJSON does not use // first len argument buffer[buf_idx] = '\0'; try { @@ -214,7 +213,7 @@ pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { args->port = this->push_port; args->fileDescriptor = this->push_socket; args->mutex = mutex; - args->adress = this->addressPush->aserv_addr; + args->address = this->addressPush->aserv_addr; pthread_create(&id, nullptr, readSocket, args); diff --git a/src/Utils/macros.cpp b/src/Utils/macros.cpp index d6be73e3..9f6a28d9 100644 --- a/src/Utils/macros.cpp +++ b/src/Utils/macros.cpp @@ -1,4 +1,3 @@ - #include "macros.h" #include From 392eecbb3d604e01c582b48008268f4311ca52e7 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 15 Jun 2022 16:35:45 +0200 Subject: [PATCH 175/249] Rename Proxy Server to Proxy Supervisor --- CMakeLists.txt | 2 +- platforms/ESP-IDF/CMakeLists.txt | 2 +- src/Debug/debugger.cpp | 6 ++-- ...{proxy_server.cpp => proxy_supervisor.cpp} | 30 +++++++++---------- .../{proxy_server.h => proxy_supervisor.h} | 8 ++--- src/RFC/rfc.cpp | 8 ++--- 6 files changed, 28 insertions(+), 28 deletions(-) rename src/RFC/{proxy_server.cpp => proxy_supervisor.cpp} (89%) rename src/RFC/{proxy_server.h => proxy_supervisor.h} (85%) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa2cea30..1a04c10e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ if (BUILD_EMULATOR) src/Primitives/emulated.cpp src/Interpreter/instructions.cpp src/RFC/rfc.cpp - src/RFC/proxy_server.cpp + src/RFC/proxy_supervisor.cpp src/RFC/SocketServer.cpp src/Utils/sockets.cpp) diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index cc0d95ee..780d9bec 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -8,7 +8,7 @@ set(SOURCE_FILES ../../src/Primitives/idf.cpp ../../src/Interpreter/instructions.cpp ../../src/RFC/rfc.cpp - ../../src/RFC/proxy_server.cpp + ../../src/RFC/proxy_supervisor.cpp ../../src/RFC/SocketServer.cpp ../../src/WARDuino/CallbackHandler.cpp ) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 14f3b901..567fb78a 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -11,7 +11,7 @@ #include "../Memory/mem.h" #include "../RFC/SocketServer.h" -#include "../RFC/proxy_server.h" +#include "../RFC/proxy_supervisor.h" #include "../RFC/rfc.h" #include "../Utils//util.h" #include "../Utils/macros.h" @@ -992,11 +992,11 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, #else void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { RFC::registerRFCs(m, &interruptData); - if (ProxyServer::registerMCUHost(&interruptData)) { + if (ProxySupervisor::registerMCUHost(&interruptData)) { this->connected_to_drone = true; pthread_mutex_init(&this->push_mutex, nullptr); pthread_mutex_lock(&this->push_mutex); - ProxyServer *mcuhost = ProxyServer::getServer(); + ProxySupervisor *mcuhost = ProxySupervisor::getServer(); this->push_debugging_threadid = mcuhost->openConnections(&this->push_mutex); } diff --git a/src/RFC/proxy_server.cpp b/src/RFC/proxy_supervisor.cpp similarity index 89% rename from src/RFC/proxy_server.cpp rename to src/RFC/proxy_supervisor.cpp index 1e8bd09c..f76e90cd 100644 --- a/src/RFC/proxy_server.cpp +++ b/src/RFC/proxy_supervisor.cpp @@ -1,5 +1,5 @@ #ifndef ARDUINO -#include "proxy_server.h" +#include "proxy_supervisor.h" /* #include */ // Might be needed #include #include @@ -77,7 +77,7 @@ bool continuing(pthread_mutex_t *mutex) { void *readSocket(void *input) { // Print value received as argument: dbg_info("\n=== LISTENING TO SOCKET (in separate thread) ===\n"); - ProxyServer::startPushDebuggerSocket((struct Socket *)input); + ProxySupervisor::startPushDebuggerSocket((struct Socket *)input); pthread_exit(nullptr); } @@ -89,24 +89,24 @@ Event *parseJSON(char *buff) { return new Event(*parsed.find("topic"), payload); } -ProxyServer *ProxyServer::proxyServer = nullptr; +ProxySupervisor *ProxySupervisor::proxyServer = nullptr; -ProxyServer *ProxyServer::getServer() { - if (proxyServer == nullptr) proxyServer = new ProxyServer(); +ProxySupervisor *ProxySupervisor::getServer() { + if (proxyServer == nullptr) proxyServer = new ProxySupervisor(); return proxyServer; } -bool ProxyServer::registerMCUHost(uint8_t **data) { +bool ProxySupervisor::registerMCUHost(uint8_t **data) { int pull = (int)read_B32(data); int push = pull + 1; auto hostsize = (uint8_t)(*data)[0]; char *hostname = new char[hostsize + 1]; memcpy((void *)hostname, ++(*data), hostsize); hostname[hostsize] = '\0'; - return ProxyServer::getServer()->registerAddresses(hostname, pull, push); + return ProxySupervisor::getServer()->registerAddresses(hostname, pull, push); } -bool ProxyServer::registerAddresses(char *_host, int _pull_port, +bool ProxySupervisor::registerAddresses(char *_host, int _pull_port, int _push_port) { if (this->host != nullptr) { if (this->pull_port == _pull_port && strcmp(_host, this->host) == 0) { @@ -123,7 +123,7 @@ bool ProxyServer::registerAddresses(char *_host, int _pull_port, return true; } -void ProxyServer::updateExcpMsg(const char *msg) { +void ProxySupervisor::updateExcpMsg(const char *msg) { delete[] this->exceptionMsg; auto msg_len = strlen(msg); this->exceptionMsg = new char[(msg_len + 1) / sizeof(char)]; @@ -131,7 +131,7 @@ void ProxyServer::updateExcpMsg(const char *msg) { memcpy(this->exceptionMsg, msg, msg_len); } -ProxyServer::ProxyServer() { +ProxySupervisor::ProxySupervisor() { host = exceptionMsg = nullptr; pull_port = 0; push_port = 0; @@ -141,7 +141,7 @@ ProxyServer::ProxyServer() { addressPush = (struct Address *)malloc(sizeof(struct Address)); } -void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { +void ProxySupervisor::startPushDebuggerSocket(struct Socket *arg) { int socket = arg->fileDescriptor; char _char; @@ -177,7 +177,7 @@ void ProxyServer::startPushDebuggerSocket(struct Socket *arg) { } } -pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { +pthread_t ProxySupervisor::openConnections(pthread_mutex_t *mutex) { if (this->host == nullptr) { this->updateExcpMsg(NO_HOST_ERR); FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); @@ -220,7 +220,7 @@ pthread_t ProxyServer::openConnections(pthread_mutex_t *mutex) { return id; } -void ProxyServer::closeConnections() { +void ProxySupervisor::closeConnections() { if (this->pull_socket != -1) { if (close(this->pull_socket) == -1) { if (errno == EINTR) close(this->pull_socket); @@ -229,7 +229,7 @@ void ProxyServer::closeConnections() { } } -bool ProxyServer::send(void *buffer, int size) { +bool ProxySupervisor::send(void *buffer, int size) { int n = write(this->pull_socket, buffer, size); if (n == size) return true; @@ -244,7 +244,7 @@ bool ProxyServer::send(void *buffer, int size) { return this->send((void *)buf, size - n); } -char *ProxyServer::readReply(short int amount) { +char *ProxySupervisor::readReply(short int amount) { char *buffer = new char[amount + 1]; bzero(buffer, amount + 1); int n = read(this->pull_socket, buffer, amount); diff --git a/src/RFC/proxy_server.h b/src/RFC/proxy_supervisor.h similarity index 85% rename from src/RFC/proxy_server.h rename to src/RFC/proxy_supervisor.h index f1a5025c..35b5e04c 100644 --- a/src/RFC/proxy_server.h +++ b/src/RFC/proxy_supervisor.h @@ -8,10 +8,10 @@ struct Address; -class ProxyServer { +class ProxySupervisor { private: // for singleton - static ProxyServer *proxyServer; + static ProxySupervisor *proxyServer; char *host; int pull_port, push_port, pull_socket, push_socket; @@ -20,7 +20,7 @@ class ProxyServer { struct Address *addressPush; // private constructor for singleton - ProxyServer(); + ProxySupervisor(); public: char *exceptionMsg; @@ -35,5 +35,5 @@ class ProxyServer { char *readReply(short int amount = 1024); static bool registerMCUHost(uint8_t **data); - static ProxyServer *getServer(); + static ProxySupervisor *getServer(); }; diff --git a/src/RFC/rfc.cpp b/src/RFC/rfc.cpp index 1a5e8fdf..838c5005 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/rfc.cpp @@ -9,7 +9,7 @@ #include "../Utils/macros.h" #include "../Utils/util.h" -#include "proxy_server.h" +#include "proxy_supervisor.h" #ifdef ARDUINO #include "SocketServer.h" #endif @@ -247,7 +247,7 @@ void arguments_copy(unsigned char *dest, StackValue *args, } void RFC::deserializeRFCResult() { - ProxyServer *host = ProxyServer::getServer(); + ProxySupervisor *host = ProxySupervisor::getServer(); auto *call_result = (uint8_t *)host->readReply(); this->succes = (uint8_t)call_result[0] == 1; @@ -299,7 +299,7 @@ void RFC::call(StackValue *arguments) { this->args = arguments; struct SerializeData *rfc_request = this->serializeRFC(); - ProxyServer *host = ProxyServer::getServer(); + ProxySupervisor *host = ProxySupervisor::getServer(); printf("making the RFC call\n"); bool sent = host->send((void *)rfc_request->raw, rfc_request->size); if (!sent) { @@ -316,7 +316,7 @@ void RFC::call(StackValue *arguments) { char cmdBuffer[10] = ""; int cmdBufferLen = 0; sprintf(cmdBuffer, "%x\n%n", interruptDUMPCallbackmapping, &cmdBufferLen); - ProxyServer::getServer()->send(cmdBuffer, cmdBufferLen); + ProxySupervisor::getServer()->send(cmdBuffer, cmdBufferLen); this->deserializeRFCResult(); } From b70fbbb7f5559dceeb950cf78d8a2035dd57ac00 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Thu, 16 Jun 2022 15:54:32 +0200 Subject: [PATCH 176/249] Clang format --- src/RFC/proxy_supervisor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/RFC/proxy_supervisor.cpp b/src/RFC/proxy_supervisor.cpp index f76e90cd..6b17efbc 100644 --- a/src/RFC/proxy_supervisor.cpp +++ b/src/RFC/proxy_supervisor.cpp @@ -103,11 +103,12 @@ bool ProxySupervisor::registerMCUHost(uint8_t **data) { char *hostname = new char[hostsize + 1]; memcpy((void *)hostname, ++(*data), hostsize); hostname[hostsize] = '\0'; - return ProxySupervisor::getServer()->registerAddresses(hostname, pull, push); + return ProxySupervisor::getServer()->registerAddresses(hostname, pull, + push); } bool ProxySupervisor::registerAddresses(char *_host, int _pull_port, - int _push_port) { + int _push_port) { if (this->host != nullptr) { if (this->pull_port == _pull_port && strcmp(_host, this->host) == 0) { return false; From 52d4eefd5a987ad808bdc763d95daca4fcead680 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 08:52:31 +0200 Subject: [PATCH 177/249] Refactor RFC to Proxy --- CMakeLists.txt | 2 +- platforms/ESP-IDF/CMakeLists.txt | 2 +- src/Debug/debugger.cpp | 8 ++-- src/Interpreter/instructions.cpp | 30 +++++++-------- src/RFC/{rfc.cpp => proxy.cpp} | 66 ++++++++++++++++---------------- src/RFC/{rfc.h => proxy.h} | 14 +++---- src/WARDuino.h | 2 +- src/WARDuino/CallbackHandler.cpp | 2 +- 8 files changed, 63 insertions(+), 63 deletions(-) rename src/RFC/{rfc.cpp => proxy.cpp} (87%) rename src/RFC/{rfc.h => proxy.h} (80%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a04c10e..b3e709fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ if (BUILD_EMULATOR) src/WARDuino/CallbackHandler.cpp src/Primitives/emulated.cpp src/Interpreter/instructions.cpp - src/RFC/rfc.cpp + src/RFC/proxy.cpp src/RFC/proxy_supervisor.cpp src/RFC/SocketServer.cpp src/Utils/sockets.cpp) diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index 780d9bec..41b8b6b7 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -7,7 +7,7 @@ set(SOURCE_FILES ../../src/WARDuino/WARDuino.cpp ../../src/Primitives/idf.cpp ../../src/Interpreter/instructions.cpp - ../../src/RFC/rfc.cpp + ../../src/RFC/proxy.cpp ../../src/RFC/proxy_supervisor.cpp ../../src/RFC/SocketServer.cpp ../../src/WARDuino/CallbackHandler.cpp diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 567fb78a..b4a0e390 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -11,8 +11,8 @@ #include "../Memory/mem.h" #include "../RFC/SocketServer.h" +#include "../RFC/proxy.h" #include "../RFC/proxy_supervisor.h" -#include "../RFC/rfc.h" #include "../Utils//util.h" #include "../Utils/macros.h" @@ -976,7 +976,7 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, printf("Call func %" PRIu32 "\n", fidx); Block *func = &m->functions[fidx]; - StackValue *args = RFC::readRFCArgs(func, data); + StackValue *args = Proxy::readRFCArgs(func, data); printf("Registering %" PRIu32 "as Callee\n", func->fidx); // preserving execution state of call that got interrupted @@ -985,13 +985,13 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, executionState->sp = m->sp; executionState->pc_ptr = m->pc_ptr; executionState->csp = m->csp; - RFC::registerRFCallee(fidx, func->type, args, executionState); + Proxy::registerRFCallee(fidx, func->type, args, executionState); *program_state = WARDuinoProxyRun; } #else void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { - RFC::registerRFCs(m, &interruptData); + Proxy::registerRFCs(m, &interruptData); if (ProxySupervisor::registerMCUHost(&interruptData)) { this->connected_to_drone = true; pthread_mutex_init(&this->push_mutex, nullptr); diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 8f546f4e..4ad19218 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -4,7 +4,7 @@ #include #include "../Memory/mem.h" -#include "../RFC/rfc.h" +#include "../RFC/proxy.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "../Utils/util_arduino.h" @@ -105,7 +105,7 @@ void setup_call(Module *m, uint32_t fidx) { // performs proxy calls to an MCU bool proxy_call(uint32_t fidx, Module *m) { printf("Remote Function Call %d\n", fidx); - RFC *rf = RFC::getRFC(fidx); + Proxy *rf = Proxy::getRFC(fidx); StackValue *args = nullptr; if (rf->type->param_count > 0) { m->sp -= rf->type->param_count; @@ -366,7 +366,7 @@ bool i_instr_return(Module *m) { bool i_instr_call(Module *m) { uint32_t fidx = read_LEB_32(&m->pc_ptr); #ifndef ARDUINO - if (RFC::isRFC(fidx)) { + if (Proxy::isRFC(fidx)) { return proxy_call(fidx, m); } #endif @@ -417,7 +417,7 @@ bool i_instr_call_indirect(Module *m) { #endif #ifndef ARDUINO - if (RFC::isRFC(fidx)) { + if (Proxy::isRFC(fidx)) { return proxy_call(fidx, m); } #endif @@ -1502,8 +1502,8 @@ bool interpret(Module *m) { // TODO: this is actually a property of warduino m->warduino->program_state = WARDUINOrun; - // needed for RFC - RFC *callee = nullptr; + // needed for Proxy + Proxy *callee = nullptr; while (!program_done && success) { if (m->warduino->program_state == WARDUINOstep) { m->warduino->program_state = WARDUINOpause; @@ -1516,21 +1516,21 @@ bool interpret(Module *m) { reset_wdt(); #ifdef ARDUINO - // handle RFC requested by emulator + // handle Proxy requested by emulator if (m->warduino->program_state == WARDuinoProxyRun) { - if (callee == nullptr) { // TODO maybe use RFC::hasRFCallee() + if (callee == nullptr) { // TODO maybe use Proxy::hasRFCallee() // call happens for the first time - callee = RFC::currentCallee(); - RFC::setupCalleeArgs(m, callee); + callee = Proxy::currentCallee(); + Proxy::setupCalleeArgs(m, callee); - // Primitive function RFC happen instantly + // Primitive function proxy call happen instantly if (callee->fid < m->import_count) { callee->succes = ((Primitive)m->functions[callee->fid].func_ptr)(m); callee->returnResult(m); callee->restoreExecutionState(m, &m->warduino->program_state); - RFC::removeRFCallee(); + Proxy::removeRFCallee(); callee = nullptr; } else setup_call(m, callee->fid); @@ -1542,7 +1542,7 @@ bool interpret(Module *m) { // TODO: this is likley no longer needed callee->restoreExecutionState(m, &m->warduino->program_state); - RFC::removeRFCallee(); + Proxy::removeRFCallee(); callee = nullptr; m->warduino->program_state = WARDUINODrone; } @@ -1765,8 +1765,8 @@ bool interpret(Module *m) { return false; } if (m->warduino->program_state == WARDuinoProxyRun && !success) { - // RFC was unsuccessful - RFC::currentCallee()->succes = false; + // Proxy call was unsuccessful + Proxy::currentCallee()->succes = false; // TODO copy exceptionMsg success = true; } diff --git a/src/RFC/rfc.cpp b/src/RFC/proxy.cpp similarity index 87% rename from src/RFC/rfc.cpp rename to src/RFC/proxy.cpp index 838c5005..a0b988dc 100644 --- a/src/RFC/rfc.cpp +++ b/src/RFC/proxy.cpp @@ -1,4 +1,4 @@ -#include "rfc.h" +#include "proxy.h" #include #include @@ -20,39 +20,39 @@ unsigned short int sizeof_valuetype(uint32_t); unsigned short int sizeSerializationRFC(const Type *); -unsigned short int sizeSerializationRFCallee(RFC *); +unsigned short int sizeSerializationRFCallee(Proxy *); void arguments_copy(unsigned char *, StackValue *, uint32_t); -std::map functions; -std::queue callees; +std::map functions; +std::queue callees; /* * Proxy Manager Client Side */ -RFC *RFC::registerRFC(uint32_t t_fid, Type *t_type) { - RFC *rfc = new RFC(t_fid, t_type); +Proxy *Proxy::registerRFC(uint32_t t_fid, Type *t_type) { + Proxy *rfc = new Proxy(t_fid, t_type); functions[t_fid] = rfc; return rfc; } -void RFC::unregisterRFC(uint32_t fid) { +void Proxy::unregisterRFC(uint32_t fid) { auto it = functions.find(fid); if (it != functions.end()) functions.erase(it); } -void RFC::clearRFCs() { - std::map::iterator it; +void Proxy::clearRFCs() { + std::map::iterator it; for (it = functions.begin(); it != functions.end(); it++) delete it->second; functions.clear(); } -bool RFC::isRFC(uint32_t fid) { +bool Proxy::isRFC(uint32_t fid) { auto it = functions.find(fid); return it != functions.end(); } -RFC *RFC::getRFC(uint32_t fid) { +Proxy *Proxy::getRFC(uint32_t fid) { auto it = functions.find(fid); return it->second; } @@ -61,24 +61,24 @@ RFC *RFC::getRFC(uint32_t fid) { * Proxy Manager Server Side */ -RFC *RFC::registerRFCallee(uint32_t t_fid, Type *t_type, StackValue *t_args, +Proxy *Proxy::registerRFCallee(uint32_t t_fid, Type *t_type, StackValue *t_args, ExecutionState *t_executionState) { - RFC *rfc = new RFC(t_fid, t_type, t_args, t_executionState); + Proxy *rfc = new Proxy(t_fid, t_type, t_args, t_executionState); callees.push(rfc); return rfc; } -bool RFC::hasRFCallee() { return !callees.empty(); } +bool Proxy::hasRFCallee() { return !callees.empty(); } -RFC *RFC::currentCallee() { return callees.front(); } +Proxy *Proxy::currentCallee() { return callees.front(); } -void RFC::removeRFCallee() { callees.pop(); } +void Proxy::removeRFCallee() { callees.pop(); } /* - * RFC methods + * Proxy methods */ -RFC::RFC(uint32_t t_fid, Type *t_type, StackValue *t_args, +Proxy::Proxy(uint32_t t_fid, Type *t_type, StackValue *t_args, ExecutionState *t_exState) : fid(t_fid), args(t_args), type(t_type), executionState(t_exState) { this->exceptionMsg = nullptr; @@ -91,7 +91,7 @@ RFC::RFC(uint32_t t_fid, Type *t_type, StackValue *t_args, } } #ifdef ARDUINO -void RFC::returnResult(Module *m) { +void Proxy::returnResult(Module *m) { // reading result from stack if (this->succes && this->type->result_count > 0) { this->result->value_type = m->stack[m->sp].value_type; @@ -110,7 +110,7 @@ void RFC::returnResult(Module *m) { } #endif -void RFC::restoreExecutionState(Module *m, RunningState *program_state) const { +void Proxy::restoreExecutionState(Module *m, RunningState *program_state) const { // restoring the original execution state *program_state = this->executionState->program_state; m->csp = this->executionState->csp; @@ -118,7 +118,7 @@ void RFC::restoreExecutionState(Module *m, RunningState *program_state) const { m->pc_ptr = this->executionState->pc_ptr; } -bool RFC::callCompleted(Module *m) const { +bool Proxy::callCompleted(Module *m) const { return !this->succes || this->executionState->csp == m->csp; } @@ -131,7 +131,7 @@ bool RFC::callCompleted(Module *m) const { * */ -struct RFC::SerializeData *RFC::serializeRFC() { +struct Proxy::SerializeData *Proxy::serializeRFC() { const unsigned short serializationSize = sizeSerializationRFC(this->type); auto *buffer = new unsigned char[serializationSize]; @@ -156,7 +156,7 @@ struct RFC::SerializeData *RFC::serializeRFC() { return ser; } -struct RFC::SerializeData *RFC::serializeRFCallee() { +struct Proxy::SerializeData *Proxy::serializeRFCallee() { const unsigned short serializationSize = sizeSerializationRFCallee(this); auto *raw = new unsigned char[serializationSize]; uint8_t suc = this->succes ? 1 : 0; @@ -181,7 +181,7 @@ struct RFC::SerializeData *RFC::serializeRFCallee() { } /* - * returns the quantity of bytes needed to serialize a RFC. + * returns the quantity of bytes needed to serialize a Proxy. * The size includes: Interrupt + Id of the function + parameters */ unsigned short int sizeSerializationRFC(const Type *type) { @@ -192,7 +192,7 @@ unsigned short int sizeSerializationRFC(const Type *type) { return 1 + sizeof(uint32_t) + paramSize; } -unsigned short int sizeSerializationRFCallee(RFC *callee) { +unsigned short int sizeSerializationRFCallee(Proxy *callee) { if (!callee->succes) return 1 + sizeof(uint16_t) + callee->excpMsgSize; if (callee->type->result_count > 0) @@ -246,7 +246,7 @@ void arguments_copy(unsigned char *dest, StackValue *args, } } -void RFC::deserializeRFCResult() { +void Proxy::deserializeRFCResult() { ProxySupervisor *host = ProxySupervisor::getServer(); auto *call_result = (uint8_t *)host->readReply(); @@ -295,12 +295,12 @@ void RFC::deserializeRFCResult() { delete[] call_result; } -void RFC::call(StackValue *arguments) { +void Proxy::call(StackValue *arguments) { this->args = arguments; struct SerializeData *rfc_request = this->serializeRFC(); ProxySupervisor *host = ProxySupervisor::getServer(); - printf("making the RFC call\n"); + printf("making the Proxy call\n"); bool sent = host->send((void *)rfc_request->raw, rfc_request->size); if (!sent) { this->succes = false; @@ -320,20 +320,20 @@ void RFC::call(StackValue *arguments) { this->deserializeRFCResult(); } -void RFC::registerRFCs(Module *m, uint8_t **data) { +void Proxy::registerRFCs(Module *m, uint8_t **data) { printf("registering_rfc_functions\n"); - RFC::clearRFCs(); + Proxy::clearRFCs(); uint32_t amount_funcs = read_B32(data); printf("funcs_total %" PRIu32 "\n", amount_funcs); for (uint32_t i = 0; i < amount_funcs; i++) { uint32_t fid = read_B32(data); printf("registering fid=%" PRIu32 "\n", fid); Type *type = (m->functions[fid]).type; - RFC::registerRFC(fid, type); + Proxy::registerRFC(fid, type); } } -StackValue *RFC::readRFCArgs(Block *func, uint8_t *data) { +StackValue *Proxy::readRFCArgs(Block *func, uint8_t *data) { if (func->type->param_count == 0) { printf("ProxyFunc %" PRIu32 "takes no arg\n", func->fidx); return nullptr; @@ -381,7 +381,7 @@ StackValue *RFC::readRFCArgs(Block *func, uint8_t *data) { return args; } -void RFC::setupCalleeArgs(Module *m, RFC *callee) { +void Proxy::setupCalleeArgs(Module *m, Proxy *callee) { // adding arguments to the stack StackValue *args = callee->args; for (uint32_t i = 0; i < callee->type->param_count; i++) diff --git a/src/RFC/rfc.h b/src/RFC/proxy.h similarity index 80% rename from src/RFC/rfc.h rename to src/RFC/proxy.h index 20cb74c3..4bf749ba 100644 --- a/src/RFC/rfc.h +++ b/src/RFC/proxy.h @@ -13,7 +13,7 @@ typedef struct { RunningState program_state; } ExecutionState; -class RFC { +class Proxy { private: // short unsigned serializationSize; struct SerializeData { @@ -35,7 +35,7 @@ class RFC { uint16_t excpMsgSize; const ExecutionState *executionState; - RFC(uint32_t t_fid, Type *t_type, StackValue *t_args = nullptr, + Proxy(uint32_t t_fid, Type *t_type, StackValue *t_args = nullptr, ExecutionState *t_exState = nullptr); void call(StackValue *args); #ifdef ARDUINO @@ -45,20 +45,20 @@ class RFC { bool callCompleted(Module *m) const; // Client side - static RFC *registerRFC(uint32_t t_fid, Type *t_type); + static Proxy *registerRFC(uint32_t t_fid, Type *t_type); static void registerRFCs(Module *m, uint8_t **data); static void unregisterRFC(uint32_t fid); static bool isRFC(uint32_t fid); - static RFC *getRFC(uint32_t fid); + static Proxy *getRFC(uint32_t fid); static void clearRFCs(); // Server side - static RFC *registerRFCallee(uint32_t t_fid, Type *t_type, + static Proxy *registerRFCallee(uint32_t t_fid, Type *t_type, StackValue *t_args, ExecutionState *t_executionState); static bool hasRFCallee(); - static RFC *currentCallee(); + static Proxy *currentCallee(); static void removeRFCallee(); static StackValue *readRFCArgs(Block *func, uint8_t *data); - static void setupCalleeArgs(Module *m, RFC *callee); + static void setupCalleeArgs(Module *m, Proxy *callee); }; diff --git a/src/WARDuino.h b/src/WARDuino.h index 2426f8d7..dec4b991 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -11,7 +11,7 @@ #include "Debug/debugger.h" #include "WARDuino/CallbackHandler.h" #ifdef ARDUINO -#include "RFC/SocketServer.h" +#include "Proxy/SocketServer.h" #endif // Constants diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 015dfad5..3da4f7c5 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -5,7 +5,7 @@ #include "../Debug/debugger.h" #include "../Interpreter/instructions.h" #ifdef ARDUINO -#include "../RFC/SocketServer.h" +#include "../Proxy/SocketServer.h" #endif #include "../Utils/macros.h" From d0557a3d2068e4dbb17c78ee3f8c00ccb9a448c5 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 09:49:38 +0200 Subject: [PATCH 178/249] Add `Channel` class to abstract comms socket --- CMakeLists.txt | 14 +-- benchmarks/edward.ino.template | 2 +- platforms/Arduino/Arduino.ino | 2 +- platforms/CLI-Emulator/main.cpp | 4 +- platforms/ESP-IDF/main.cpp | 2 +- src/Debug/debugger.cpp | 169 ++++++++++++++++---------------- src/Debug/debugger.h | 12 ++- src/Utils/sockets.cpp | 12 ++- src/Utils/sockets.h | 9 ++ 9 files changed, 125 insertions(+), 101 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3e709fc..dd9810c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,19 +30,19 @@ if (BUILD_EMULATOR) find_package(Threads REQUIRED) set(SOURCE_FILES - src/Memory/mem.cpp - src/Utils/util.cpp - src/Utils/util_arduino.cpp - src/Debug/debugger.cpp - src/Utils/macros.cpp src/WARDuino/WARDuino.cpp src/WARDuino/CallbackHandler.cpp src/Primitives/emulated.cpp src/Interpreter/instructions.cpp + src/Memory/mem.cpp + src/Utils/util.cpp + src/Utils/util_arduino.cpp + src/Utils/macros.cpp + src/Utils/sockets.cpp + src/Debug/debugger.cpp src/RFC/proxy.cpp src/RFC/proxy_supervisor.cpp - src/RFC/SocketServer.cpp - src/Utils/sockets.cpp) + src/RFC/SocketServer.cpp) set(TEST_FRAMEWORK tests/integration/wasm_tests.cpp diff --git a/benchmarks/edward.ino.template b/benchmarks/edward.ino.template index 721cfe94..e566c6b7 100644 --- a/benchmarks/edward.ino.template +++ b/benchmarks/edward.ino.template @@ -34,7 +34,7 @@ void ICACHE_RAM_ATTR handleInput() { void startDebuggerStd(void* pvParameter) { int valread; uint8_t buffer[1024] = {0}; - wac->debugger->socket = fileno(stdout); + wac->debugger->setChannel(fileno(stdout)); write(fileno(stdout), "Got a message ... \n", 19); while (true) { // taskYIELD(); diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index 052f5bf0..89914927 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -23,7 +23,7 @@ Module* m; void startDebuggerStd(void* pvParameter) { int valread; uint8_t buffer[1024] = {0}; - wac->debugger->socket = fileno(stdout); + wac->debugger->setChannel(fileno(stdout)); write(fileno(stdout), "Got a message ... \n", 19); while (true) { // taskYIELD(); diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 7a21b0aa..2fbeb119 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -94,7 +94,7 @@ Module *load(WARDuino wac, const char *file_name, Options opt) { void startDebuggerStd(WARDuino *wac, Module *m) { int valread; uint8_t buffer[1024] = {0}; - wac->debugger->socket = fileno(stdout); + wac->debugger->setChannel(fileno(stdout)); while (true) { debug("waiting for debug command\n"); while ((valread = read(fileno(stdin), buffer, 1024)) != -1) { @@ -116,7 +116,7 @@ void startDebuggerSocket(WARDuino *wac, Module *m) { uint8_t buffer[1024] = {0}; while (true) { int socket = listenForIncomingConnection(socket_fd, address); - wac->debugger->socket = socket; + wac->debugger->setChannel(socket); // wac->debugger->socket = fileno(stdout); // todo remove while ((valread = read(socket, buffer, 1024)) != -1) { write(socket, "got a message ... \n", 19); diff --git a/platforms/ESP-IDF/main.cpp b/platforms/ESP-IDF/main.cpp index 81544f1c..db803220 100644 --- a/platforms/ESP-IDF/main.cpp +++ b/platforms/ESP-IDF/main.cpp @@ -30,7 +30,7 @@ Module* m; void startDebuggerStd(void* pvParameter) { int valread; uint8_t buffer[1024] = {0}; - wac->debugger->socket = fileno(stdout); + wac->debugger->setChannel(fileno(stdout)); while (true) { taskYIELD(); vTaskDelay(1000 / portTICK_PERIOD_MS); diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index b4a0e390..dbe4597f 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -18,10 +18,15 @@ // Debugger -Debugger::Debugger(int socket) { this->socket = socket; } +Debugger::Debugger(int address) { this->channel = new Channel(address); } // Public methods +void Debugger::setChannel(int address) { + delete this->channel; + this->channel = new Channel(address); +} + void Debugger::addDebugMessage(size_t len, const uint8_t *buff) { uint8_t *data = this->parseDebugBuffer(len, buff); if (data != nullptr && *data == interruptRecvCallbackmapping) { @@ -107,7 +112,7 @@ bool Debugger::isBreakpoint(uint8_t *loc) { } void Debugger::notifyBreakpoint(uint8_t *pc_ptr) const { - dprintf(this->socket, "AT %p!\n", (void *)pc_ptr); + this->channel->write("AT %p!\n", (void *)pc_ptr); } /** @@ -138,7 +143,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { return false; } - dprintf(this->socket, "Interrupt: %x\n", *interruptData); + this->channel->write("Interrupt: %x\n", *interruptData); long start = 0, size = 0; switch (*interruptData) { @@ -147,16 +152,16 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { free(interruptData); break; case interruptHALT: - dprintf(this->socket, "STOP!\n"); + this->channel->write("STOP!\n"); free(interruptData); exit(0); case interruptPAUSE: *program_state = WARDUINOpause; - dprintf(this->socket, "PAUSE!\n"); + this->channel->write("PAUSE!\n"); free(interruptData); break; case interruptSTEP: - dprintf(this->socket, "STEP!\n"); + this->channel->write("STEP!\n"); *program_state = WARDUINOstep; this->skipBreakpoint = m->pc_ptr; free(interruptData); @@ -182,14 +187,14 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { free(interruptData); break; case interruptUPDATEFun: - dprintf(this->socket, "CHANGE function!\n"); + this->channel->write("CHANGE function!\n"); Debugger::handleChangedFunction(m, interruptData); // do not free(interruptData); // we need it to run that code // TODO: free double replacements break; case interruptUPDATELocal: - dprintf(this->socket, "CHANGE local!\n"); + this->channel->write("CHANGE local!\n"); this->handleChangedLocal(m, interruptData); free(interruptData); break; @@ -200,7 +205,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptOffset: free(interruptData); - dprintf(this->socket, "{\"offset\":\"%p\"}\n", (void *)m->bytes); + this->channel->write("{\"offset\":\"%p\"}\n", (void *)m->bytes); break; case interruptRecvState: if (!this->receivingData) { @@ -211,14 +216,14 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { this->receivingData = true; this->freeState(m, interruptData); free(interruptData); - dprintf(this->socket, "ack!\n"); + this->channel->write("ack!\n"); } else { printf("receiving state\n"); debug("receiving state\n"); receivingData = !this->saveState(m, interruptData); free(interruptData); debug("sending %s!\n", receivingData ? "ack" : "done"); - dprintf(this->socket, "%s!\n", receivingData ? "ack" : "done"); + this->channel->write("%s!\n", receivingData ? "ack" : "done"); if (!this->receivingData) { debug("receiving state done\n"); } @@ -260,9 +265,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { size = (long)CallbackHandler::event_count(); case interruptDUMPEvents: // TODO get start and size from message - dprintf(this->socket, "{"); + this->channel->write("{"); this->dumpEvents(start, size); - dprintf(this->socket, "}\n"); + this->channel->write("}\n"); break; case interruptPOPEvent: CallbackHandler::resolve_event(true); @@ -281,7 +286,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; default: // handle later - dprintf(this->socket, "COULD not parse interrupt data!\n"); + this->channel->write("COULD not parse interrupt data!\n"); free(interruptData); break; } @@ -312,7 +317,7 @@ void Debugger::printValue(StackValue *v, uint32_t idx, bool end = false) const { snprintf(buff, 255, R"("type":"%02x","value":"%)" PRIx64 "\"", v->value_type, v->value.uint64); } - dprintf(this->socket, R"({"idx":%d,%s}%s)", idx, buff, end ? "" : ","); + this->channel->write(R"({"idx":%d,%s}%s)", idx, buff, end ? "" : ","); } uint8_t *Debugger::findOpcode(Module *m, Block *block) { @@ -333,7 +338,7 @@ uint8_t *Debugger::findOpcode(Module *m, Block *block) { } void Debugger::handleInterruptRUN(Module *m, RunningState *program_state) { - dprintf(this->socket, "GO!\n"); + this->channel->write("GO!\n"); if (*program_state == WARDUINOpause && this->isBreakpoint(m->pc_ptr)) { this->skipBreakpoint = m->pc_ptr; } @@ -349,7 +354,7 @@ void Debugger::handleInterruptBP(const uint8_t *interruptData) { bp |= interruptData[i + 2]; } auto *bpt = (uint8_t *)bp; - dprintf(this->socket, "BP %p!\n", static_cast(bpt)); + this->channel->write("BP %p!\n", static_cast(bpt)); if (*interruptData == 0x06) { this->addBreakpoint(bpt); @@ -359,13 +364,13 @@ void Debugger::handleInterruptBP(const uint8_t *interruptData) { } void Debugger::dump(Module *m, bool full) const { - dprintf(this->socket, "{"); + this->channel->write("{"); // current PC - dprintf(this->socket, R"("pc":"%p",)", (void *)m->pc_ptr); + this->channel->write(R"("pc":"%p",)", (void *)m->pc_ptr); // start of bytes - dprintf(this->socket, R"("start":["%p"],)", (void *)m->bytes); + this->channel->write(R"("start":["%p"],)", (void *)m->bytes); this->dumpBreakpoints(m); @@ -374,37 +379,37 @@ void Debugger::dump(Module *m, bool full) const { this->dumpCallstack(m); if (full) { - dprintf(this->socket, R"(, "locals": )"); + this->channel->write(R"(, "locals": )"); this->dumpLocals(m); - dprintf(this->socket, ", "); + this->channel->write(", "); this->dumpEvents(0, CallbackHandler::event_count()); } - dprintf(this->socket, "}\n\n"); + this->channel->write("}\n\n"); // fflush(stdout); } void Debugger::dumpBreakpoints(Module *m) const { - dprintf(this->socket, "\"breakpoints\":["); + this->channel->write("\"breakpoints\":["); { size_t i = 0; for (auto bp : this->breakpoints) { - dprintf(this->socket, R"("%p"%s)", bp, - (++i < this->breakpoints.size()) ? "," : ""); + this->channel->write(R"("%p"%s)", bp, + (++i < this->breakpoints.size()) ? "," : ""); } } - dprintf(this->socket, "],"); + this->channel->write("],"); } void Debugger::dumpFunctions(Module *m) const { - dprintf(this->socket, "\"functions\":["); + this->channel->write("\"functions\":["); for (size_t i = m->import_count; i < m->function_count; i++) { - dprintf(this->socket, R"({"fidx":"0x%x","from":"%p","to":"%p"}%s)", - m->functions[i].fidx, - static_cast(m->functions[i].start_ptr), - static_cast(m->functions[i].end_ptr), - (i < m->function_count - 1) ? "," : "],"); + this->channel->write(R"({"fidx":"0x%x","from":"%p","to":"%p"}%s)", + m->functions[i].fidx, + static_cast(m->functions[i].start_ptr), + static_cast(m->functions[i].end_ptr), + (i < m->function_count - 1) ? "," : "],"); } } @@ -412,12 +417,11 @@ void Debugger::dumpFunctions(Module *m) const { * {"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"ra":"%p"}%s */ void Debugger::dumpCallstack(Module *m) const { - dprintf(this->socket, "\"callstack\":["); + this->channel->write("\"callstack\":["); for (int i = 0; i <= m->csp; i++) { Frame *f = &m->callstack[i]; uint8_t *callsite = f->ra_ptr - 2; // callsite of function (if type 0) - dprintf( - this->socket, + this->channel->write( R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"start":"%p","ra":"%p","callsite":"%p"}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, f->block->start_ptr, static_cast(f->ra_ptr), @@ -435,7 +439,7 @@ void Debugger::dumpLocals(Module *m) const { } } Frame *f = &m->callstack[firstFunFramePtr]; - dprintf(this->socket, R"({"count":%u,"locals":[)", 0); + this->channel->write(R"({"count":%u,"locals":[)", 0); // fflush(stdout); // FIXME: this is needed for ESP to properly print char _value_str[256]; for (uint32_t i = 0; i < f->block->local_count; i++) { @@ -463,11 +467,11 @@ void Debugger::dumpLocals(Module *m) const { v->value_type, v->value.uint64); } - dprintf(this->socket, "{%s, \"index\":%u}%s", _value_str, - i + f->block->type->param_count, - (i + 1 < f->block->local_count) ? "," : ""); + this->channel->write("{%s, \"index\":%u}%s", _value_str, + i + f->block->type->param_count, + (i + 1 < f->block->local_count) ? "," : ""); } - dprintf(this->socket, "]}"); + this->channel->write("]}"); // fflush(stdout); } @@ -478,25 +482,24 @@ void Debugger::dumpEvents(long start, long size) const { size = EVENTS_SIZE; } - dprintf(this->socket, R"("events": [)"); + this->channel->write(R"("events": [)"); long index = start, end = start + size; std::for_each(CallbackHandler::event_begin() + start, CallbackHandler::event_begin() + end, [this, &index, &end](const Event &e) { - dprintf(this->socket, - R"({"topic": "%s", "payload": "%s"})", - e.topic.c_str(), e.payload.c_str()); + this->channel->write(R"({"topic": "%s", "payload": "%s"})", + e.topic.c_str(), e.payload.c_str()); if (++index < end) { - dprintf(this->socket, ", "); + this->channel->write(", "); } }); - dprintf(this->socket, "]"); + this->channel->write("]"); CallbackHandler::resolving_event = previous; } void Debugger::dumpCallbackmapping() const { - dprintf(this->socket, "%s\n", CallbackHandler::dump_callbacks().c_str()); + this->channel->write("%s\n", CallbackHandler::dump_callbacks().c_str()); } /** @@ -568,10 +571,10 @@ bool Debugger::handleChangedFunction(Module *m, uint8_t *bytes) { bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { if (*bytes != interruptUPDATELocal) return false; uint8_t *pos = bytes + 1; - dprintf(this->socket, "Local updates: %x\n", *pos); + this->channel->write("Local updates: %x\n", *pos); uint32_t localId = read_LEB_32(&pos); - dprintf(this->socket, "Local %u being changed\n", localId); + this->channel->write("Local %u being changed\n", localId); auto v = &m->stack[m->fp + localId]; switch (v->value_type) { case I32: @@ -587,13 +590,13 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { memcpy(&v->value.uint64, pos, 8); break; } - dprintf(this->socket, "Local %u changed to %u\n", localId, v->value.uint32); + this->channel->write("Local %u changed to %u\n", localId, v->value.uint32); return true; } #ifndef ARDUINO void Debugger::notifyPushedEvent() const { - dprintf(this->socket, "new pushed event"); + this->channel->write("new pushed event"); } bool Debugger::handlePushedEvent(Module *m, char *bytes) const { @@ -610,80 +613,78 @@ bool Debugger::handlePushedEvent(Module *m, char *bytes) const { void Debugger::woodDump(Module *m) { debug("asked for doDump\n"); printf("asked for woodDump\n"); - dprintf(this->socket, "DUMP!\n"); - dprintf(this->socket, "{"); + this->channel->write("DUMP!\n"); + this->channel->write("{"); // current PC - dprintf(this->socket, R"("pc":"%p",)", (void *)m->pc_ptr); + this->channel->write(R"("pc":"%p",)", (void *)m->pc_ptr); // start of bytes - dprintf(this->socket, R"("start":["%p"],)", (void *)m->bytes); + this->channel->write(R"("start":["%p"],)", (void *)m->bytes); - dprintf(this->socket, "\"breakpoints\":["); + this->channel->write("\"breakpoints\":["); size_t i = 0; for (auto bp : this->breakpoints) { - dprintf(this->socket, R"("%p"%s)", bp, - (++i < this->breakpoints.size()) ? "," : ""); + this->channel->write(R"("%p"%s)", bp, + (++i < this->breakpoints.size()) ? "," : ""); } - dprintf(this->socket, "],"); + this->channel->write("],"); // stack - dprintf(this->socket, "\"stack\":["); + this->channel->write("\"stack\":["); for (int j = 0; j <= m->sp; j++) { auto v = &m->stack[j]; printValue(v, j, j == m->sp); } - dprintf(this->socket, "],"); + this->channel->write("],"); // Callstack - dprintf(this->socket, "\"callstack\":["); + this->channel->write("\"callstack\":["); for (int j = 0; j <= m->csp; j++) { Frame *f = &m->callstack[j]; uint8_t *block_key = f->block->block_type == 0 ? nullptr : findOpcode(m, f->block); - dprintf( - this->socket, + this->channel->write( R"({"type":%u,"fidx":"0x%x","sp":%d,"fp":%d,"block_key":"%p", "ra":"%p", "idx":%d}%s)", f->block->block_type, f->block->fidx, f->sp, f->fp, block_key, static_cast(f->ra_ptr), j, (j < m->csp) ? "," : ""); } // Globals - dprintf(this->socket, "],\"globals\":["); + this->channel->write("],\"globals\":["); for (uint32_t j = 0; j < m->global_count; j++) { auto v = m->globals + j; printValue(v, j, j == (m->global_count - 1)); } - dprintf(this->socket, "]"); // closing globals + this->channel->write("]"); // closing globals - dprintf(this->socket, R"(,"table":{"max":%d, "init":%d, "elements":[)", - m->table.maximum, m->table.initial); + this->channel->write(R"(,"table":{"max":%d, "init":%d, "elements":[)", + m->table.maximum, m->table.initial); for (uint32_t j = 0; j < m->table.size; j++) { - dprintf(this->socket, "%" PRIu32 "%s", m->table.entries[j], - (j + 1) == m->table.size ? "" : ","); + this->channel->write("%" PRIu32 "%s", m->table.entries[j], + (j + 1) == m->table.size ? "" : ","); } - dprintf(this->socket, "]}"); // closing table + this->channel->write("]}"); // closing table // memory uint32_t total_elems = m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE - dprintf(this->socket, - R"(,"memory":{"pages":%d,"max":%d,"init":%d,"bytes":[)", - m->memory.pages, m->memory.maximum, m->memory.initial); + this->channel->write(R"(,"memory":{"pages":%d,"max":%d,"init":%d,"bytes":[)", + m->memory.pages, m->memory.maximum, m->memory.initial); for (uint32_t j = 0; j < total_elems; j++) { - dprintf(this->socket, "%" PRIu8 "%s", m->memory.bytes[j], - (j + 1) == total_elems ? "" : ","); + this->channel->write("%" PRIu8 "%s", m->memory.bytes[j], + (j + 1) == total_elems ? "" : ","); } - dprintf(this->socket, "]}"); // closing memory + this->channel->write("]}"); // closing memory - dprintf(this->socket, R"(,"br_table":{"size":"0x%x","labels":[)", - BR_TABLE_SIZE); + this->channel->write(R"(,"br_table":{"size":"0x%x","labels":[)", + BR_TABLE_SIZE); for (uint32_t j = 0; j < BR_TABLE_SIZE; j++) { - dprintf(this->socket, "%" PRIu32 "%s", m->br_table[j], - (j + 1) == BR_TABLE_SIZE ? "" : ","); + this->channel->write("%" PRIu32 "%s", m->br_table[j], + (j + 1) == BR_TABLE_SIZE ? "" : ","); } - dprintf(this->socket, "]}}\n"); + this->channel->write("]}}\n"); } enum ReceiveState { @@ -1000,7 +1001,7 @@ void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { this->push_debugging_threadid = mcuhost->openConnections(&this->push_mutex); } - dprintf(this->socket, "done!\n"); + this->channel->write("done!\n"); } bool Debugger::drone_connected() const { return this->connected_to_drone; } diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 3bec1f3c..ef62c09d 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -8,6 +8,8 @@ #include #ifndef ARDUINO #include + +#include "../Utils/sockets.h" #endif struct Module; struct Block; @@ -39,7 +41,7 @@ enum InterruptTypes { interruptUPDATEFun = 0x20, interruptUPDATELocal = 0x21, - // WOOD Pull Debugging + // Pull Debugging interruptWOODDUMP = 0x60, interruptOffset = 0x61, interruptRecvState = 0x62, @@ -60,6 +62,8 @@ class Debugger { private: std::deque debugMessages = {}; + Channel *channel; + // Help variables volatile bool interruptWrite{}; @@ -126,14 +130,14 @@ class Debugger { public: // Public fields - int socket; - std::set breakpoints = {}; // Vector, we expect few breakpoints uint8_t *skipBreakpoint = nullptr; // Breakpoint to skip in the next interpretation step // Constructor - explicit Debugger(int socket); + explicit Debugger(int address); + + void setChannel(int address); // Interrupts diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index c93a88fb..96836129 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -56,4 +57,13 @@ int listenForIncomingConnection(int socket_fd, struct sockaddr_in address) { exit(EXIT_FAILURE); } return new_socket; -} \ No newline at end of file +} + +Channel::Channel(int socket) { this->socket = socket; } + +void Channel::write(const char *fmt, ...) const { + va_list args; + va_start(args, fmt); + vdprintf(this->socket, fmt, args); + va_end(args); +} diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h index d0908c87..2dece6f1 100644 --- a/src/Utils/sockets.h +++ b/src/Utils/sockets.h @@ -11,3 +11,12 @@ struct sockaddr_in createAddress(int port); void startListening(int socket_fd); int listenForIncomingConnection(int socket_fd, struct sockaddr_in address); + +class Channel { + private: + int socket; + public: + explicit Channel(int socket); + + void write(char const *fmt, ...) const; +}; \ No newline at end of file From b5498640958e03e668a7ad2d549ddf6d15908f72 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 10:46:46 +0200 Subject: [PATCH 179/249] Use debugger channel for oop debugging --- src/Debug/debugger.cpp | 21 ++------------------- src/Debug/debugger.h | 13 +++++-------- src/RFC/proxy.cpp | 13 ++++--------- src/RFC/proxy.h | 8 +++----- src/WARDuino.h | 3 --- src/WARDuino/CallbackHandler.cpp | 24 +++++------------------- src/WARDuino/CallbackHandler.h | 2 -- 7 files changed, 19 insertions(+), 65 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index dbe4597f..6e4bce3b 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -229,37 +229,21 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } } break; -#ifdef ARDUINO case interruptProxyCall: { this->handleProxyCall(m, program_state, interruptData + 1); free(interruptData); } break; -#else +#ifndef ARDUINO case interruptMonitorProxies: { printf("receiving functions list to proxy\n"); this->handleMonitorProxies(m, interruptData + 1); free(interruptData); } break; #endif -#ifdef ARDUINO case interruptDronify: { - // 0x65 the wifi ssid \0 wifipass \0 - // 1 |____len_____| 1 - char *ssid = (char *)(interruptData + 1); - size_t ssid_len = strlen(ssid); - char *pass = (char *)(interruptData + 1 + ssid_len + 1); - ServerCredentials serverCredentials = {ssid, pass}; - SocketServer::createServer( - 8080, 8081, [m](size_t len, uint8_t *buff) { - m->warduino->handleInterrupt(len, buff); - }); - auto server = SocketServer::getServer(); - server->connect2Wifi(&serverCredentials); - server->begin(); *program_state = WARDUINODrone; break; } -#endif case interruptDUMPAllEvents: printf("InterruptDUMPEvents\n"); size = (long)CallbackHandler::event_count(); @@ -969,7 +953,6 @@ uintptr_t Debugger::readPointer(uint8_t **data) { return bp; } -#ifdef ARDUINO void Debugger::handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData) { uint8_t *data = interruptData; @@ -990,7 +973,7 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, *program_state = WARDuinoProxyRun; } -#else +#ifndef ARDUINO void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { Proxy::registerRFCs(m, &interruptData); if (ProxySupervisor::registerMCUHost(&interruptData)) { diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index ef62c09d..0c912324 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -6,10 +6,11 @@ #include #include #include -#ifndef ARDUINO -#include #include "../Utils/sockets.h" + +#ifndef ARDUINO +#include #endif struct Module; struct Block; @@ -62,8 +63,6 @@ class Debugger { private: std::deque debugMessages = {}; - Channel *channel; - // Help variables volatile bool interruptWrite{}; @@ -129,6 +128,7 @@ class Debugger { public: // Public fields + Channel *channel; std::set breakpoints = {}; // Vector, we expect few breakpoints uint8_t *skipBreakpoint = @@ -161,10 +161,9 @@ class Debugger { void woodDump(Module *m); -#ifdef ARDUINO void handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData); -#else +#ifndef ARDUINO bool drone_connected() const; void disconnect_drone(); @@ -175,9 +174,7 @@ class Debugger { // Push-based -#ifndef ARDUINO void notifyPushedEvent() const; -#endif bool handlePushedEvent(Module *m, char *bytes) const; #endif diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index a0b988dc..cb2c850f 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -29,9 +29,8 @@ std::queue callees; /* * Proxy Manager Client Side */ - Proxy *Proxy::registerRFC(uint32_t t_fid, Type *t_type) { - Proxy *rfc = new Proxy(t_fid, t_type); + auto *rfc = new Proxy(t_fid, t_type); functions[t_fid] = rfc; return rfc; } @@ -63,7 +62,7 @@ Proxy *Proxy::getRFC(uint32_t fid) { Proxy *Proxy::registerRFCallee(uint32_t t_fid, Type *t_type, StackValue *t_args, ExecutionState *t_executionState) { - Proxy *rfc = new Proxy(t_fid, t_type, t_args, t_executionState); + auto *rfc = new Proxy(t_fid, t_type, t_args, t_executionState); callees.push(rfc); return rfc; } @@ -90,7 +89,7 @@ Proxy::Proxy(uint32_t t_fid, Type *t_type, StackValue *t_args, this->result->value_type = t_type->results[0]; } } -#ifdef ARDUINO + void Proxy::returnResult(Module *m) { // reading result from stack if (this->succes && this->type->result_count > 0) { @@ -104,11 +103,8 @@ void Proxy::returnResult(Module *m) { // returning the result to the client struct SerializeData *rfc_result = this->serializeRFCallee(); const char *data = (const char *)rfc_result->raw; - size_t data_size = (size_t)rfc_result->size; - SocketServer *server = SocketServer::getServer(); - server->write2Client(server->pullClient, data, data_size); + WARDuino::instance()->debugger->channel->write(data); } -#endif void Proxy::restoreExecutionState(Module *m, RunningState *program_state) const { // restoring the original execution state @@ -130,7 +126,6 @@ bool Proxy::callCompleted(Module *m) const { * Output is also transformed to hexa * */ - struct Proxy::SerializeData *Proxy::serializeRFC() { const unsigned short serializationSize = sizeSerializationRFC(this->type); auto *buffer = new unsigned char[serializationSize]; diff --git a/src/RFC/proxy.h b/src/RFC/proxy.h index 4bf749ba..d4976777 100644 --- a/src/RFC/proxy.h +++ b/src/RFC/proxy.h @@ -36,11 +36,9 @@ class Proxy { const ExecutionState *executionState; Proxy(uint32_t t_fid, Type *t_type, StackValue *t_args = nullptr, - ExecutionState *t_exState = nullptr); + ExecutionState *t_exState = nullptr); void call(StackValue *args); -#ifdef ARDUINO void returnResult(Module *m); -#endif // ARDUINO void restoreExecutionState(Module *m, RunningState *program_state) const; bool callCompleted(Module *m) const; @@ -54,8 +52,8 @@ class Proxy { // Server side static Proxy *registerRFCallee(uint32_t t_fid, Type *t_type, - StackValue *t_args, - ExecutionState *t_executionState); + StackValue *t_args, + ExecutionState *t_executionState); static bool hasRFCallee(); static Proxy *currentCallee(); static void removeRFCallee(); diff --git a/src/WARDuino.h b/src/WARDuino.h index dec4b991..e3617b03 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -10,9 +10,6 @@ #include "Debug/debugger.h" #include "WARDuino/CallbackHandler.h" -#ifdef ARDUINO -#include "Proxy/SocketServer.h" -#endif // Constants #define WA_MAGIC 0x6d736100 diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 3da4f7c5..4425fffc 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -4,9 +4,6 @@ #include "../Debug/debugger.h" #include "../Interpreter/instructions.h" -#ifdef ARDUINO -#include "../Proxy/SocketServer.h" -#endif #include "../Utils/macros.h" void push_guard(Module *m) { @@ -31,14 +28,12 @@ void push_guard(Module *m) { bool CallbackHandler::manual_event_resolution = false; bool CallbackHandler::resolving_event = false; -#ifdef ARDUINO size_t CallbackHandler::pushed_cursor = 0; bool should_push_event() { return WARDuino::instance()->program_state == WARDuinoProxyRun || WARDuino::instance()->program_state == WARDUINODrone; } -#endif std::unordered_map *> *CallbackHandler::callbacks = @@ -90,28 +85,22 @@ void CallbackHandler::push_event(Event *event) { } bool CallbackHandler::resolve_event(bool force) { -#ifdef ARDUINO - SocketServer *server = SocketServer::getServer(); -#endif if ((!force && CallbackHandler::resolving_event) || CallbackHandler::events->empty()) { if (force) { printf("No events to be processed!\n"); -#ifdef ARDUINO - server->printf2Client(server->pushClient, - "no events to be processed"); -#endif + WARDuino::instance()->debugger->channel->write( + "no events to be processed"); } return false; } Event event = CallbackHandler::events->front(); -#ifdef ARDUINO if (should_push_event()) { Event e = CallbackHandler::events->at(CallbackHandler::pushed_cursor++); - server->printf2Client(server->pushClient, - R"({"topic":"%s","payload":"%s"})", - e.topic.c_str(), e.payload.c_str()); + WARDuino::instance()->debugger->channel->write( + R"({"topic":"%s","payload":"%s"})", e.topic.c_str(), + e.payload.c_str()); CallbackHandler::events->pop_front(); CallbackHandler::pushed_cursor--; @@ -119,7 +108,6 @@ bool CallbackHandler::resolve_event(bool force) { return !CallbackHandler::events->empty(); // no further execution if drone } -#endif if (!force && (CallbackHandler::manual_event_resolution || WARDuino::instance()->program_state == WARDUINOpause)) { @@ -128,9 +116,7 @@ bool CallbackHandler::resolve_event(bool force) { CallbackHandler::resolving_event = true; CallbackHandler::events->pop_front(); -#ifdef ARDUINO CallbackHandler::pushed_cursor--; -#endif debug("Resolving an event. (%lu remaining)\n", CallbackHandler::events->size()); diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index 8ffa33e7..c95e5dec 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -27,9 +27,7 @@ class CallbackHandler { CallbackHandler() = default; // Disallow creation public: -#ifdef ARDUINO static size_t pushed_cursor; -#endif static size_t event_count(); static std::deque::const_iterator event_begin(); From 5e149ce36a67c3e97a2e5bad92af291e32b593f7 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 10:48:13 +0200 Subject: [PATCH 180/249] Delete SocketServer --- CMakeLists.txt | 2 +- platforms/ESP-IDF/CMakeLists.txt | 1 - src/Debug/debugger.cpp | 1 - src/Primitives/arduino.cpp | 1 - src/RFC/SocketServer.cpp | 144 ------------------------------- src/RFC/SocketServer.h | 52 ----------- 6 files changed, 1 insertion(+), 200 deletions(-) delete mode 100644 src/RFC/SocketServer.cpp delete mode 100644 src/RFC/SocketServer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dd9810c8..cfce40f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ if (BUILD_EMULATOR) src/Debug/debugger.cpp src/RFC/proxy.cpp src/RFC/proxy_supervisor.cpp - src/RFC/SocketServer.cpp) + ) set(TEST_FRAMEWORK tests/integration/wasm_tests.cpp diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index 41b8b6b7..3f872e2f 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -9,7 +9,6 @@ set(SOURCE_FILES ../../src/Interpreter/instructions.cpp ../../src/RFC/proxy.cpp ../../src/RFC/proxy_supervisor.cpp - ../../src/RFC/SocketServer.cpp ../../src/WARDuino/CallbackHandler.cpp ) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 6e4bce3b..8e881a3e 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -10,7 +10,6 @@ #endif #include "../Memory/mem.h" -#include "../RFC/SocketServer.h" #include "../RFC/proxy.h" #include "../RFC/proxy_supervisor.h" #include "../Utils//util.h" diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index 67d86d0a..39239ba7 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -20,7 +20,6 @@ #include #include "../Memory/mem.h" -//#include "../RFC/SocketServer.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "primitives.h" diff --git a/src/RFC/SocketServer.cpp b/src/RFC/SocketServer.cpp deleted file mode 100644 index d28ca621..00000000 --- a/src/RFC/SocketServer.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#ifdef ARDUINO -#include "SocketServer.h" - -#include - -#include "../Utils/macros.h" - -SocketServer *SocketServer::socketServer = nullptr; - -SocketServer::SocketServer(uint16_t t_pullport, uint16_t t_pushport, - std::function t_handler) - : pull_portno(t_pullport), push_portno(t_pushport) { - this->pullServer = new AsyncServer(t_pullport); - this->pushServer = new AsyncServer(t_pushport); - this->pullClient = nullptr; - this->pushClient = nullptr; - this->handler = t_handler; -} - -void SocketServer::createServer( - uint16_t t_pullport, uint16_t t_pushport, - std::function t_handler) { - if (socketServer == nullptr) - socketServer = new SocketServer(t_pullport, t_pushport, t_handler); -} - -SocketServer *SocketServer::getServer() { return socketServer; } - -void SocketServer::connect2Wifi(ServerCredentials *t_credentials) { - printf("Connecting to WiFi...\n"); - WiFi.begin(t_credentials->ssid, t_credentials->pswd); - while (WiFi.status() != WL_CONNECTED) { - delay(10); - } - - printf("localip: %d.%d.%d.%d\n\n", WiFi.localIP()[0], WiFi.localIP()[1], - WiFi.localIP()[2], WiFi.localIP()[3]); -} - -void SocketServer::begin() { - printf("starting PullSever\n"); - SocketServer *thisServer = this; - this->pullServer->begin(); - this->pullServer->onClient( - [thisServer](void *s, AsyncClient *c) { - printf("A new PullClient connected!\n"); - thisServer->registerClient(c, &thisServer->pullClient); - }, - NULL); - - printf("starting PushSever\n"); - this->pushServer->begin(); - this->pushServer->onClient( - [thisServer](void *s, AsyncClient *c) { - printf("A new PushClient connected!\n"); - thisServer->registerClient(c, &thisServer->pushClient); - }, - NULL); -} - -void SocketServer::registerClient(AsyncClient *new_client, - AsyncClient **current_client) { - if (new_client == NULL) { - debug("a new Client is NULL\n"); - return; - } - - if (*current_client == nullptr) { - *current_client = new_client; - } else { - debug("Only one socket client allowed.\n"); - new_client->close(true); - new_client->free(); - delete new_client; - return; - } - - std::function _handler = this->handler; - SocketServer *thisServer = this; - new_client->onError( - [thisServer](void *r, AsyncClient *t_client, int8_t error) { - debug("ClientSocket Error %" PRIu8 "\n", error); - }, - NULL); - new_client->onDisconnect( - [thisServer](void *r, AsyncClient *t_client) { - debug("Client Disconnected\n"); - thisServer->unregisterClient(t_client); - }, - NULL); - new_client->onTimeout( - [thisServer](void *r, AsyncClient *t_client, uint32_t time) { - debug("Client timeouted\n"); - thisServer->unregisterClient(t_client); - }, - NULL); - new_client->onData( - [_handler](void *r, AsyncClient *t_client, void *buf, size_t len) { - _handler(len, (uint8_t *)buf); - }, - NULL); -} - -void SocketServer::unregisterClient(AsyncClient *t_client) { - if (this->pullClient == t_client) { - this->pullClient = nullptr; - } else if (this->pushClient == t_client) { - this->pushClient = nullptr; - } - t_client->close(true); // TODO potential issue: close twice same client - t_client->free(); - delete t_client; -} - -void SocketServer::write2Client(AsyncClient *client, const char *buf, - size_t size_buf) { - if (client == nullptr) return; - size_t space_left = client->space(); - // Send upto limit - do { - size_t send_size = size_buf > space_left ? space_left : size_buf; - client->add(buf, send_size); - client->send(); - buf += send_size; - size_buf -= send_size; - } while (size_buf > 0); -} - -void SocketServer::printf2Client(AsyncClient *client, const char *format, ...) { - va_list args; - va_start(args, format); - - if (client == nullptr) return; - - uint32_t BUFF_SIZE = 300; - char buffer[BUFF_SIZE]; - int l = vsnprintf(buffer, BUFF_SIZE, format, args); - if (l == BUFF_SIZE) FATAL("Buffer not big enough: %d\n", l); - this->write2Client(client, buffer, l); - va_end(args); -} - -bool SocketServer::hasPushClient() { return this->pushClient != nullptr; } -#endif diff --git a/src/RFC/SocketServer.h b/src/RFC/SocketServer.h deleted file mode 100644 index 42590a78..00000000 --- a/src/RFC/SocketServer.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#ifdef ARDUINO -// clang-format off -// FreeRTOS has to be imported before AsyncTCP.h -#include "freertos/FreeRTOS.h" -#include -// clang-format on -#include - -#include - -typedef struct { - const char *ssid; - const char *pswd; -} ServerCredentials; - -class SocketServer { - private: - // SocketServer configuration - const uint16_t pull_portno, push_portno; - - ServerCredentials *credentials; - - AsyncServer *pullServer; - AsyncServer *pushServer; - - // handler for client's received data - std::function handler; - - // singleton - static SocketServer *socketServer; - SocketServer(uint16_t t_pullport, uint16_t t_pushport, - std::function t_handler); - - void registerClient(AsyncClient *new_client, AsyncClient **current_client); - void unregisterClient(AsyncClient *t_client); - - public: - AsyncClient *pullClient; - AsyncClient *pushClient; - - void begin(); - void connect2Wifi(ServerCredentials *t_credentials); - void write2Client(AsyncClient *client, const char *buf, size_t size_buf); - void printf2Client(AsyncClient *client, const char *format, ...); - bool hasPushClient(); - - static SocketServer *getServer(void); - static void createServer(uint16_t t_pullport, uint16_t t_pushport, - std::function t_handler); -}; -#endif From e2501d3d02cca226293ac8cdebf757fe6b834476 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 10:54:37 +0200 Subject: [PATCH 181/249] Clang-format --- src/Debug/debugger.cpp | 36 +++++++++++++++++++----------------- src/RFC/proxy.cpp | 7 ++++--- src/Utils/sockets.h | 1 + 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 8e881a3e..a3fb4780 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -378,7 +378,7 @@ void Debugger::dumpBreakpoints(Module *m) const { size_t i = 0; for (auto bp : this->breakpoints) { this->channel->write(R"("%p"%s)", bp, - (++i < this->breakpoints.size()) ? "," : ""); + (++i < this->breakpoints.size()) ? "," : ""); } } this->channel->write("],"); @@ -389,10 +389,10 @@ void Debugger::dumpFunctions(Module *m) const { for (size_t i = m->import_count; i < m->function_count; i++) { this->channel->write(R"({"fidx":"0x%x","from":"%p","to":"%p"}%s)", - m->functions[i].fidx, - static_cast(m->functions[i].start_ptr), - static_cast(m->functions[i].end_ptr), - (i < m->function_count - 1) ? "," : "],"); + m->functions[i].fidx, + static_cast(m->functions[i].start_ptr), + static_cast(m->functions[i].end_ptr), + (i < m->function_count - 1) ? "," : "],"); } } @@ -451,8 +451,8 @@ void Debugger::dumpLocals(Module *m) const { } this->channel->write("{%s, \"index\":%u}%s", _value_str, - i + f->block->type->param_count, - (i + 1 < f->block->local_count) ? "," : ""); + i + f->block->type->param_count, + (i + 1 < f->block->local_count) ? "," : ""); } this->channel->write("]}"); // fflush(stdout); @@ -470,8 +470,9 @@ void Debugger::dumpEvents(long start, long size) const { std::for_each(CallbackHandler::event_begin() + start, CallbackHandler::event_begin() + end, [this, &index, &end](const Event &e) { - this->channel->write(R"({"topic": "%s", "payload": "%s"})", - e.topic.c_str(), e.payload.c_str()); + this->channel->write( + R"({"topic": "%s", "payload": "%s"})", + e.topic.c_str(), e.payload.c_str()); if (++index < end) { this->channel->write(", "); } @@ -609,7 +610,7 @@ void Debugger::woodDump(Module *m) { size_t i = 0; for (auto bp : this->breakpoints) { this->channel->write(R"("%p"%s)", bp, - (++i < this->breakpoints.size()) ? "," : ""); + (++i < this->breakpoints.size()) ? "," : ""); } this->channel->write("],"); @@ -642,30 +643,31 @@ void Debugger::woodDump(Module *m) { this->channel->write("]"); // closing globals this->channel->write(R"(,"table":{"max":%d, "init":%d, "elements":[)", - m->table.maximum, m->table.initial); + m->table.maximum, m->table.initial); for (uint32_t j = 0; j < m->table.size; j++) { this->channel->write("%" PRIu32 "%s", m->table.entries[j], - (j + 1) == m->table.size ? "" : ","); + (j + 1) == m->table.size ? "" : ","); } this->channel->write("]}"); // closing table // memory uint32_t total_elems = m->memory.pages * (uint32_t)PAGE_SIZE; // TODO debug PAGE_SIZE - this->channel->write(R"(,"memory":{"pages":%d,"max":%d,"init":%d,"bytes":[)", - m->memory.pages, m->memory.maximum, m->memory.initial); + this->channel->write( + R"(,"memory":{"pages":%d,"max":%d,"init":%d,"bytes":[)", + m->memory.pages, m->memory.maximum, m->memory.initial); for (uint32_t j = 0; j < total_elems; j++) { this->channel->write("%" PRIu8 "%s", m->memory.bytes[j], - (j + 1) == total_elems ? "" : ","); + (j + 1) == total_elems ? "" : ","); } this->channel->write("]}"); // closing memory this->channel->write(R"(,"br_table":{"size":"0x%x","labels":[)", - BR_TABLE_SIZE); + BR_TABLE_SIZE); for (uint32_t j = 0; j < BR_TABLE_SIZE; j++) { this->channel->write("%" PRIu32 "%s", m->br_table[j], - (j + 1) == BR_TABLE_SIZE ? "" : ","); + (j + 1) == BR_TABLE_SIZE ? "" : ","); } this->channel->write("]}}\n"); } diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index cb2c850f..b22ce1ad 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -61,7 +61,7 @@ Proxy *Proxy::getRFC(uint32_t fid) { */ Proxy *Proxy::registerRFCallee(uint32_t t_fid, Type *t_type, StackValue *t_args, - ExecutionState *t_executionState) { + ExecutionState *t_executionState) { auto *rfc = new Proxy(t_fid, t_type, t_args, t_executionState); callees.push(rfc); return rfc; @@ -78,7 +78,7 @@ void Proxy::removeRFCallee() { callees.pop(); } */ Proxy::Proxy(uint32_t t_fid, Type *t_type, StackValue *t_args, - ExecutionState *t_exState) + ExecutionState *t_exState) : fid(t_fid), args(t_args), type(t_type), executionState(t_exState) { this->exceptionMsg = nullptr; this->excpMsgSize = 0; @@ -106,7 +106,8 @@ void Proxy::returnResult(Module *m) { WARDuino::instance()->debugger->channel->write(data); } -void Proxy::restoreExecutionState(Module *m, RunningState *program_state) const { +void Proxy::restoreExecutionState(Module *m, + RunningState *program_state) const { // restoring the original execution state *program_state = this->executionState->program_state; m->csp = this->executionState->csp; diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h index 2dece6f1..c6e2d1c0 100644 --- a/src/Utils/sockets.h +++ b/src/Utils/sockets.h @@ -15,6 +15,7 @@ int listenForIncomingConnection(int socket_fd, struct sockaddr_in address); class Channel { private: int socket; + public: explicit Channel(int socket); From 1e32d45fbd9db3bad7d6b6b99a0c709104458385 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 10:58:36 +0200 Subject: [PATCH 182/249] Fix Arduino compilation --- src/RFC/proxy.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index b22ce1ad..3a569fb8 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -10,9 +10,6 @@ #include "../Utils/macros.h" #include "../Utils/util.h" #include "proxy_supervisor.h" -#ifdef ARDUINO -#include "SocketServer.h" -#endif // TODO tests with exceptions ////TODO test with many args proxy From c44631fd7e6c7c0f8c0dabb151ecbb13a80fc507 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 11:04:06 +0200 Subject: [PATCH 183/249] Fix IDF compilation --- platforms/ESP-IDF/CMakeLists.txt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index 3f872e2f..ec53608b 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -1,15 +1,16 @@ set(SOURCE_FILES - ../../src/Memory/mem.cpp - ../../src/Utils/util.cpp - ../../src/Utils/util_arduino.cpp ../../src/Debug/debugger.cpp - ../../src/Utils/macros.cpp - ../../src/WARDuino/WARDuino.cpp - ../../src/Primitives/idf.cpp ../../src/Interpreter/instructions.cpp + ../../src/Memory/mem.cpp + ../../src/Primitives/idf.cpp ../../src/RFC/proxy.cpp ../../src/RFC/proxy_supervisor.cpp + ../../src/Utils/macros.cpp + ../../src/Utils/sockets.cpp + ../../src/Utils/util.cpp + ../../src/Utils/util_arduino.cpp ../../src/WARDuino/CallbackHandler.cpp + ../../src/WARDuino/WARDuino.cpp ) idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS ../../lib/json/single_include/ REQUIRES driver) From 9b93fd5ad11c0f2cf078e411d3ab43f9caa554a9 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 12:15:23 +0200 Subject: [PATCH 184/249] Add Carlos to authors --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 2eab09ef..5c717b48 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=WARDuino version=0.9.2 -author=Robbert Gurdeep Singh , Christophe Scholliers , Tom Lauwaerts , Joel Martin +author=Robbert Gurdeep Singh , Christophe Scholliers , Tom Lauwaerts , Carlos Rojas Castillo , Joel Martin maintainer=Robbert Gurdeep Singh , Christophe Scholliers , Tom Lauwaerts sentence=A library that enables the use of WebAssembly on Arduino boards with debugging support paragraph= From fbd5777f74e4ae3a1106c7f42c1e4e9f11ea2a7f Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 16:47:58 +0200 Subject: [PATCH 185/249] Use serial connection to proxy --- platforms/CLI-Emulator/main.cpp | 34 ++++++--- src/Debug/debugger.cpp | 31 ++++---- src/Debug/debugger.h | 14 ++-- src/RFC/proxy.cpp | 6 +- src/RFC/proxy_supervisor.cpp | 127 ++++---------------------------- src/RFC/proxy_supervisor.h | 27 +++---- src/WARDuino.h | 1 + src/WARDuino/WARDuino.cpp | 2 +- 8 files changed, 80 insertions(+), 162 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 2fbeb119..7ded526a 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -35,9 +35,9 @@ void print_help() { fprintf(stdout, "Usage:\n"); fprintf(stdout, " warduino [options] \n"); fprintf(stdout, "Options:\n"); - fprintf( - stdout, - " --loop Let the runtime loop infinitely on exceptions\n"); + fprintf(stdout, + " --loop Let the runtime loop infinitely on exceptions " + "(default: false)\n"); fprintf(stdout, " --asserts Name of file containing asserts to run against " "loaded module\n"); @@ -49,6 +49,9 @@ void print_help() { fprintf(stdout, " --no-socket Run without socket " "(default: false)\n"); + fprintf(stdout, + " --paused Pause program on entry (default: false)\n"); + fprintf(stdout, " --proxy Proxy VM to connect to\n"); } Module *load(WARDuino wac, const char *file_name, Options opt) { @@ -117,16 +120,10 @@ void startDebuggerSocket(WARDuino *wac, Module *m) { while (true) { int socket = listenForIncomingConnection(socket_fd, address); wac->debugger->setChannel(socket); - // wac->debugger->socket = fileno(stdout); // todo remove while ((valread = read(socket, buffer, 1024)) != -1) { write(socket, "got a message ... \n", 19); wac->handleInterrupt(valread - 1, buffer); - // runningstate program_state = warduinorun; write(socket, buffer, valread); - // while (checkdebugmessages(m, &program_state)) { - // printf("checkdebugmessages \n"); - //}; - // fflush(stdout); } } } @@ -147,7 +144,9 @@ int main(int argc, const char *argv[]) { bool return_exception = true; bool run_tests = false; bool no_socket = false; + bool paused = false; const char *file_name = nullptr; + const char *proxy = nullptr; const char *asserts_file = nullptr; const char *watcompiler = "wat2wasm"; @@ -174,6 +173,10 @@ int main(int argc, const char *argv[]) { ARGV_GET(watcompiler); } else if (!strcmp("--no-socket", arg)) { no_socket = true; + } else if (!strcmp("--paused", arg)) { + wac->program_state = WARDUINOpause; + } else if (!strcmp("--proxy", arg)) { + ARGV_GET(proxy); // /dev/ttyUSB0 } } @@ -199,11 +202,18 @@ int main(int argc, const char *argv[]) { } if (m) { - pthread_t id; - uint8_t command[] = {'0', '3', '\n'}; - // wac.handleInterrupt(3, command); m->warduino = wac; + + // Run Wasm module + pthread_t id; pthread_create(&id, nullptr, runWAC, nullptr); + + // Connect to proxy device + if (proxy) { + wac->debugger->startProxySupervisor(proxy); + } + + // Start debugger if (no_socket) { startDebuggerStd(wac, m); } else { diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index a3fb4780..f743c32d 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -241,6 +241,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { #endif case interruptDronify: { *program_state = WARDUINODrone; + printf("Dronified.\n"); break; } case interruptDUMPAllEvents: @@ -977,26 +978,30 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, #ifndef ARDUINO void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { Proxy::registerRFCs(m, &interruptData); - if (ProxySupervisor::registerMCUHost(&interruptData)) { - this->connected_to_drone = true; - pthread_mutex_init(&this->push_mutex, nullptr); - pthread_mutex_lock(&this->push_mutex); - ProxySupervisor *mcuhost = ProxySupervisor::getServer(); - this->push_debugging_threadid = - mcuhost->openConnections(&this->push_mutex); - } this->channel->write("done!\n"); } -bool Debugger::drone_connected() const { return this->connected_to_drone; } +void Debugger::startProxySupervisor(const char *proxy) { + this->connected_to_proxy = true; + pthread_mutex_init(&this->supervisor_mutex, nullptr); + pthread_mutex_lock(&this->supervisor_mutex); + + FILE *serial = fopen(proxy, "rw+"); + int proxy_address = fileno(serial); + this->supervisor = new ProxySupervisor(proxy_address, &this->supervisor_mutex); + printf("Connected to proxy.\n"); +} + +bool Debugger::proxy_connected() const { return this->connected_to_proxy; } -void Debugger::disconnect_drone() { - if (this->drone_connected()) { +void Debugger::disconnect_proxy() { + if (this->proxy_connected()) { return; } int *ptr; - pthread_mutex_unlock(&this->push_mutex); - pthread_join(this->push_debugging_threadid, (void **)&ptr); + // TODO close file + pthread_mutex_unlock(&this->supervisor_mutex); + pthread_join(this->supervisor->getThreadID(), (void **)&ptr); } #endif diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 0c912324..6593b92e 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -7,6 +7,7 @@ #include #include +#include "../RFC/proxy_supervisor.h" #include "../Utils/sockets.h" #ifndef ARDUINO @@ -74,9 +75,8 @@ class Debugger { bool receivingData = false; #ifndef ARDUINO - bool connected_to_drone = false; - pthread_mutex_t push_mutex; - pthread_t push_debugging_threadid; + bool connected_to_proxy = false; + pthread_mutex_t supervisor_mutex; #endif // Private methods @@ -129,6 +129,7 @@ class Debugger { public: // Public fields Channel *channel; + ProxySupervisor *supervisor; std::set breakpoints = {}; // Vector, we expect few breakpoints uint8_t *skipBreakpoint = @@ -163,10 +164,13 @@ class Debugger { void handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData); + #ifndef ARDUINO - bool drone_connected() const; + void startProxySupervisor(const char *proxy); + + bool proxy_connected() const; - void disconnect_drone(); + void disconnect_proxy(); // Pull-based diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index 3a569fb8..cc4a0b6e 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -240,7 +240,7 @@ void arguments_copy(unsigned char *dest, StackValue *args, } void Proxy::deserializeRFCResult() { - ProxySupervisor *host = ProxySupervisor::getServer(); + ProxySupervisor *host = WARDuino::instance()->debugger->supervisor; auto *call_result = (uint8_t *)host->readReply(); this->succes = (uint8_t)call_result[0] == 1; @@ -292,7 +292,7 @@ void Proxy::call(StackValue *arguments) { this->args = arguments; struct SerializeData *rfc_request = this->serializeRFC(); - ProxySupervisor *host = ProxySupervisor::getServer(); + ProxySupervisor *host = WARDuino::instance()->debugger->supervisor; printf("making the Proxy call\n"); bool sent = host->send((void *)rfc_request->raw, rfc_request->size); if (!sent) { @@ -309,7 +309,7 @@ void Proxy::call(StackValue *arguments) { char cmdBuffer[10] = ""; int cmdBufferLen = 0; sprintf(cmdBuffer, "%x\n%n", interruptDUMPCallbackmapping, &cmdBufferLen); - ProxySupervisor::getServer()->send(cmdBuffer, cmdBufferLen); + WARDuino::instance()->debugger->supervisor->send(cmdBuffer, cmdBufferLen); this->deserializeRFCResult(); } diff --git a/src/RFC/proxy_supervisor.cpp b/src/RFC/proxy_supervisor.cpp index 6b17efbc..a65c2b24 100644 --- a/src/RFC/proxy_supervisor.cpp +++ b/src/RFC/proxy_supervisor.cpp @@ -1,6 +1,5 @@ #ifndef ARDUINO #include "proxy_supervisor.h" -/* #include */ // Might be needed #include #include #include @@ -30,13 +29,6 @@ struct Address { struct hostent *aServer; }; -struct Socket { - int port; - int fileDescriptor; - struct sockaddr_in address; - pthread_mutex_t *mutex; -}; - bool is_success(const char *msg) { return (msg != nullptr) && (msg[0] == '\0'); // check if string is empty } @@ -77,7 +69,8 @@ bool continuing(pthread_mutex_t *mutex) { void *readSocket(void *input) { // Print value received as argument: dbg_info("\n=== LISTENING TO SOCKET (in separate thread) ===\n"); - ProxySupervisor::startPushDebuggerSocket((struct Socket *)input); + auto *supervisor = (ProxySupervisor *) input; + supervisor->startPushDebuggerSocket(); pthread_exit(nullptr); } @@ -89,41 +82,6 @@ Event *parseJSON(char *buff) { return new Event(*parsed.find("topic"), payload); } -ProxySupervisor *ProxySupervisor::proxyServer = nullptr; - -ProxySupervisor *ProxySupervisor::getServer() { - if (proxyServer == nullptr) proxyServer = new ProxySupervisor(); - return proxyServer; -} - -bool ProxySupervisor::registerMCUHost(uint8_t **data) { - int pull = (int)read_B32(data); - int push = pull + 1; - auto hostsize = (uint8_t)(*data)[0]; - char *hostname = new char[hostsize + 1]; - memcpy((void *)hostname, ++(*data), hostsize); - hostname[hostsize] = '\0'; - return ProxySupervisor::getServer()->registerAddresses(hostname, pull, - push); -} - -bool ProxySupervisor::registerAddresses(char *_host, int _pull_port, - int _push_port) { - if (this->host != nullptr) { - if (this->pull_port == _pull_port && strcmp(_host, this->host) == 0) { - return false; - } - this->closeConnections(); - free(this->host); - } - printf("Registering Proxy Host: %s PULL_PORT=%d PUSH_PORT=%d\n", _host, - _pull_port, _push_port); - this->host = _host; - this->pull_port = _pull_port; - this->push_port = _push_port; - return true; -} - void ProxySupervisor::updateExcpMsg(const char *msg) { delete[] this->exceptionMsg; auto msg_len = strlen(msg); @@ -132,27 +90,25 @@ void ProxySupervisor::updateExcpMsg(const char *msg) { memcpy(this->exceptionMsg, msg, msg_len); } -ProxySupervisor::ProxySupervisor() { - host = exceptionMsg = nullptr; - pull_port = 0; - push_port = 0; - pull_socket = -1; - push_socket = -1; - address = (struct Address *)malloc(sizeof(struct Address)); - addressPush = (struct Address *)malloc(sizeof(struct Address)); -} +ProxySupervisor::ProxySupervisor(int socket, pthread_mutex_t *mutex) { + printf("Started supervisor.\n"); + this->socket = socket; + this->channel = new Channel(socket); + this->mutex = mutex; -void ProxySupervisor::startPushDebuggerSocket(struct Socket *arg) { - int socket = arg->fileDescriptor; + pthread_create(&this->threadid, nullptr, readSocket, this); +} +void ProxySupervisor::startPushDebuggerSocket() { char _char; uint32_t buf_idx = 0; const uint32_t start_size = 1024; uint32_t current_size = start_size; char *buffer = (char *)malloc(start_size); - while (continuing(arg->mutex)) { - if (read(socket, &_char, 1) != -1) { + printf("Started listening for events from proxy device.\n"); + while (continuing(this->mutex)) { + if (read(this->socket, &_char, 1) != -1) { // increase buffer size if needed if (current_size <= (buf_idx + 1)) { char *new_buff = (char *)malloc(current_size + start_size); @@ -178,60 +134,8 @@ void ProxySupervisor::startPushDebuggerSocket(struct Socket *arg) { } } -pthread_t ProxySupervisor::openConnections(pthread_mutex_t *mutex) { - if (this->host == nullptr) { - this->updateExcpMsg(NO_HOST_ERR); - FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); - } - - // Create sockets - this->pull_socket = socket(AF_INET, SOCK_STREAM, 0); - this->push_socket = socket(AF_INET, SOCK_STREAM, 0); - if (this->pull_socket < 0 || this->push_socket < 0) { - this->updateExcpMsg(CREATE_SOCK_ERR); - FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); - } - - // Connect to pull socket - const char *msg = createConnection(pull_socket, this->host, this->pull_port, - this->address); - if (!is_success(msg)) { - this->updateExcpMsg(msg); - FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); - } - - // Connect to push socket - msg = createConnection(push_socket, this->host, this->push_port, - this->addressPush); - if (!is_success(msg)) { - this->updateExcpMsg(msg); // TODO differentiate between ports - FATAL("problem opening socket to MCU: %s\n", this->exceptionMsg); - } - - // Listen to push socket on new thread - pthread_t id; - auto *args = (struct Socket *)malloc(sizeof(struct Socket)); - args->port = this->push_port; - args->fileDescriptor = this->push_socket; - args->mutex = mutex; - args->address = this->addressPush->aserv_addr; - - pthread_create(&id, nullptr, readSocket, args); - - return id; -} - -void ProxySupervisor::closeConnections() { - if (this->pull_socket != -1) { - if (close(this->pull_socket) == -1) { - if (errno == EINTR) close(this->pull_socket); - } - this->pull_socket = -1; - } -} - bool ProxySupervisor::send(void *buffer, int size) { - int n = write(this->pull_socket, buffer, size); + int n = write(this->socket, buffer, size); if (n == size) return true; if (n < 0 && errno == EINTR) // write interrupted, thus retry @@ -248,7 +152,7 @@ bool ProxySupervisor::send(void *buffer, int size) { char *ProxySupervisor::readReply(short int amount) { char *buffer = new char[amount + 1]; bzero(buffer, amount + 1); - int n = read(this->pull_socket, buffer, amount); + int n = read(this->socket, buffer, amount); if (n > 0) return buffer; delete[] buffer; @@ -258,4 +162,5 @@ char *ProxySupervisor::readReply(short int amount) { this->updateExcpMsg(READ_ERR); return nullptr; } +pthread_t ProxySupervisor::getThreadID() { return this->threadid; } #endif diff --git a/src/RFC/proxy_supervisor.h b/src/RFC/proxy_supervisor.h index 35b5e04c..1005ef10 100644 --- a/src/RFC/proxy_supervisor.h +++ b/src/RFC/proxy_supervisor.h @@ -3,6 +3,7 @@ #include #include +#include "../Utils/sockets.h" #include "pthread.h" #include "sys/types.h" @@ -10,30 +11,22 @@ struct Address; class ProxySupervisor { private: - // for singleton - static ProxySupervisor *proxyServer; - - char *host; - int pull_port, push_port, pull_socket, push_socket; - - struct Address *address; - struct Address *addressPush; - - // private constructor for singleton - ProxySupervisor(); + Channel *channel; + int socket; + pthread_t threadid; + pthread_mutex_t *mutex; public: char *exceptionMsg; - static void startPushDebuggerSocket(struct Socket *arg); + // private constructor for singleton + ProxySupervisor(int socket, pthread_mutex_t *mutex); + + void startPushDebuggerSocket(); - bool registerAddresses(char *_host, int _pull_port, int _push_port); - void closeConnections(); - pthread_t openConnections(pthread_mutex_t *mutex); void updateExcpMsg(const char *msg); bool send(void *t_buffer, int t_size); char *readReply(short int amount = 1024); - static bool registerMCUHost(uint8_t **data); - static ProxySupervisor *getServer(); + pthread_t getThreadID(); }; diff --git a/src/WARDuino.h b/src/WARDuino.h index e3617b03..c49841de 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -9,6 +9,7 @@ #include #include "Debug/debugger.h" +#include "RFC/proxy_supervisor.h" #include "WARDuino/CallbackHandler.h" // Constants diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index 1a4a1f2c..73d3259f 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -864,7 +864,7 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, void WARDuino::unload_module(Module *m) { #ifndef ARDUINO this->debugger - ->disconnect_drone(); // TODO should this be in unload module? + ->disconnect_proxy(); // TODO should this be in unload module? #endif auto it = std::find(this->modules.begin(), this->modules.end(), m); if (it != this->modules.end()) this->modules.erase(it); From 3a964e3d89c9fa2f8111debc6ff3133af59685b6 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 17 Jun 2022 17:03:14 +0200 Subject: [PATCH 186/249] Clang-format --- src/Debug/debugger.cpp | 3 ++- src/RFC/proxy_supervisor.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index f743c32d..30709e51 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -988,7 +988,8 @@ void Debugger::startProxySupervisor(const char *proxy) { FILE *serial = fopen(proxy, "rw+"); int proxy_address = fileno(serial); - this->supervisor = new ProxySupervisor(proxy_address, &this->supervisor_mutex); + this->supervisor = + new ProxySupervisor(proxy_address, &this->supervisor_mutex); printf("Connected to proxy.\n"); } diff --git a/src/RFC/proxy_supervisor.cpp b/src/RFC/proxy_supervisor.cpp index a65c2b24..7119fbc3 100644 --- a/src/RFC/proxy_supervisor.cpp +++ b/src/RFC/proxy_supervisor.cpp @@ -1,5 +1,6 @@ #ifndef ARDUINO #include "proxy_supervisor.h" + #include #include #include @@ -69,7 +70,7 @@ bool continuing(pthread_mutex_t *mutex) { void *readSocket(void *input) { // Print value received as argument: dbg_info("\n=== LISTENING TO SOCKET (in separate thread) ===\n"); - auto *supervisor = (ProxySupervisor *) input; + auto *supervisor = (ProxySupervisor *)input; supervisor->startPushDebuggerSocket(); pthread_exit(nullptr); } From e260d334f08ce8c706050c53ae61637486e562fa Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 26 Jul 2022 10:47:54 +0200 Subject: [PATCH 187/249] Clean split Proxy and ProxySupervisor --- CMakeLists.txt | 2 +- platforms/CLI-Emulator/main.cpp | 1 + platforms/ESP-IDF/CMakeLists.txt | 1 + src/Debug/debugger.cpp | 20 +-- src/Debug/debugger.h | 5 +- src/Interpreter/instructions.cpp | 96 ++++------- src/RFC/RFC.cpp | 4 + src/RFC/RFC.h | 22 +++ src/RFC/proxy.cpp | 272 ++++--------------------------- src/RFC/proxy.h | 53 ++---- src/RFC/proxy_supervisor.cpp | 227 +++++++++++++++++++------- src/RFC/proxy_supervisor.h | 14 +- src/Utils/sockets.cpp | 10 +- src/Utils/sockets.h | 4 +- src/WARDuino.h | 5 +- 15 files changed, 301 insertions(+), 435 deletions(-) create mode 100644 src/RFC/RFC.cpp create mode 100644 src/RFC/RFC.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cfce40f4..73e013b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ if (BUILD_EMULATOR) src/Debug/debugger.cpp src/RFC/proxy.cpp src/RFC/proxy_supervisor.cpp - ) + src/RFC/RFC.cpp) set(TEST_FRAMEWORK tests/integration/wasm_tests.cpp diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 7ded526a..a5f0668c 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -114,6 +114,7 @@ void startDebuggerSocket(WARDuino *wac, Module *m) { struct sockaddr_in address = createAddress(8192); bindSocketToAddress(socket_fd, address); startListening(socket_fd); + dbg_info("Listening on port 172.0.0.1:8192\n"); int valread; uint8_t buffer[1024] = {0}; diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index ec53608b..d34a45fb 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCE_FILES ../../src/Primitives/idf.cpp ../../src/RFC/proxy.cpp ../../src/RFC/proxy_supervisor.cpp + ../../src/RFC/RFC.cpp ../../src/Utils/macros.cpp ../../src/Utils/sockets.cpp ../../src/Utils/util.cpp diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 30709e51..d3c60d7b 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -239,9 +239,10 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { free(interruptData); } break; #endif - case interruptDronify: { + case interruptProxify: { *program_state = WARDUINODrone; - printf("Dronified.\n"); + this->proxy = new Proxy(); // TODO delete + printf("Converting to proxy settings.\n"); break; } case interruptDUMPAllEvents: @@ -959,22 +960,19 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData) { uint8_t *data = interruptData; uint32_t fidx = read_L32(&data); - printf("Call func %" PRIu32 "\n", fidx); + dbg_info("Proxycall func %" PRIu32 "\n", fidx); Block *func = &m->functions[fidx]; StackValue *args = Proxy::readRFCArgs(func, data); - printf("Registering %" PRIu32 "as Callee\n", func->fidx); + dbg_trace("Enqueuing callee %" PRIu32 "\n", func->fidx); - // preserving execution state of call that got interrupted - ExecutionState *executionState = new ExecutionState; - executionState->program_state = *program_state; - executionState->sp = m->sp; - executionState->pc_ptr = m->pc_ptr; - executionState->csp = m->csp; - Proxy::registerRFCallee(fidx, func->type, args, executionState); + auto *rfc = new RFC(fidx, func->type, args); + this->proxy->pushRFC(m, rfc); *program_state = WARDuinoProxyRun; + dbg_trace("Program state: ProxyRun"); } + #ifndef ARDUINO void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { Proxy::registerRFCs(m, &interruptData); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 6593b92e..a99119ed 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -7,6 +7,7 @@ #include #include +#include "../RFC/proxy.h" #include "../RFC/proxy_supervisor.h" #include "../Utils/sockets.h" @@ -49,7 +50,7 @@ enum InterruptTypes { interruptRecvState = 0x62, interruptMonitorProxies = 0x63, interruptProxyCall = 0x64, - interruptDronify = 0x65, // wifi SSID \0 wifi PASS \0 + interruptProxify = 0x65, // wifi SSID \0 wifi PASS \0 // Push Debugging interruptDUMPAllEvents = 0x70, @@ -74,6 +75,8 @@ class Debugger { long interruptSize{}; bool receivingData = false; + Proxy *proxy = nullptr; // proxy module for debugger + #ifndef ARDUINO bool connected_to_proxy = false; pthread_mutex_t supervisor_mutex; diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 4ad19218..b4f045bb 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -101,27 +101,29 @@ void setup_call(Module *m, uint32_t fidx) { m->pc_ptr = func->start_ptr; } -#ifndef ARDUINO // performs proxy calls to an MCU -bool proxy_call(uint32_t fidx, Module *m) { - printf("Remote Function Call %d\n", fidx); - Proxy *rf = Proxy::getRFC(fidx); - StackValue *args = nullptr; - if (rf->type->param_count > 0) { - m->sp -= rf->type->param_count; - args = &m->stack[m->sp + 1]; +bool proxy_call(Module *m, uint32_t fidx) { + dbg_info("Remote Function Call %d\n", fidx); + ProxySupervisor *supervisor = m->warduino->debugger->supervisor; + RFC *rfc; + Type * type = m->functions[fidx].type; + if (type->param_count > 0) { + m->sp -= type->param_count; + StackValue *args = &m->stack[m->sp + 1]; + rfc = new RFC(fidx, type, args); + } else { + rfc = new RFC(fidx, type); } - rf->call(args); - if (!rf->succes) { + bool success = supervisor->call(rfc); + if (!rfc->success) { // TODO exception bugger might be too small and msg not null terminated? - memcpy(&exception, rf->exceptionMsg, strlen(rf->exceptionMsg)); + memcpy(&exception, rfc->exception, strlen(rfc->exception)); return false; } - if (rf->type->result_count > 0) m->stack[++m->sp] = *rf->result; + if (rfc->type->result_count > 0) m->stack[++m->sp] = *rfc->result; return true; } -#endif /* * WebAssembly Instructions @@ -365,11 +367,7 @@ bool i_instr_return(Module *m) { */ bool i_instr_call(Module *m) { uint32_t fidx = read_LEB_32(&m->pc_ptr); -#ifndef ARDUINO - if (Proxy::isRFC(fidx)) { - return proxy_call(fidx, m); - } -#endif + if (fidx < m->import_count) { return ((Primitive)m->functions[fidx].func_ptr)(m); } else { @@ -416,12 +414,6 @@ bool i_instr_call_indirect(Module *m) { fidx); #endif -#ifndef ARDUINO - if (Proxy::isRFC(fidx)) { - return proxy_call(fidx, m); - } -#endif - if (fidx < m->import_count) { // THUNK thunk_out(m, fidx); // import/thunk call } else { @@ -1499,11 +1491,8 @@ bool interpret(Module *m) { // set to true when finishes successfully bool program_done = false; - // TODO: this is actually a property of warduino m->warduino->program_state = WARDUINOrun; - // needed for Proxy - Proxy *callee = nullptr; while (!program_done && success) { if (m->warduino->program_state == WARDUINOstep) { m->warduino->program_state = WARDUINOpause; @@ -1515,41 +1504,6 @@ bool interpret(Module *m) { fflush(stdout); reset_wdt(); -#ifdef ARDUINO - // handle Proxy requested by emulator - if (m->warduino->program_state == WARDuinoProxyRun) { - if (callee == nullptr) { // TODO maybe use Proxy::hasRFCallee() - // call happens for the first time - callee = Proxy::currentCallee(); - Proxy::setupCalleeArgs(m, callee); - - // Primitive function proxy call happen instantly - if (callee->fid < m->import_count) { - callee->succes = - ((Primitive)m->functions[callee->fid].func_ptr)(m); - callee->returnResult(m); - callee->restoreExecutionState(m, - &m->warduino->program_state); - Proxy::removeRFCallee(); - callee = nullptr; - } else - setup_call(m, callee->fid); - } else { - // check if call completes - if (callee->callCompleted(m)) { - callee->returnResult(m); - - // TODO: this is likley no longer needed - callee->restoreExecutionState(m, - &m->warduino->program_state); - Proxy::removeRFCallee(); - callee = nullptr; - m->warduino->program_state = WARDUINODrone; - } - } - } -#endif - // Resolve 1 callback event if queue is not empty and VM not paused, and // no event currently resolving CallbackHandler::resolve_event(); @@ -1624,13 +1578,23 @@ bool interpret(Module *m) { // Call operators // case 0x10: { // call - success &= i_instr_call(m); + uint32_t fidx = read_LEB_32(&m->pc_ptr); + if (m->warduino->debugger->supervisor->isRFC(fidx)) { + success &= proxy_call(m, fidx); + } else { + success &= i_instr_call(m); + } continue; } - case 0x11: // call_indirect - success &= i_instr_call_indirect(m); + case 0x11: { // call_indirect + uint32_t fidx = read_LEB_32(&m->pc_ptr); + if (m->warduino->debugger->supervisor->isRFC(fidx)) { + success &= proxy_call(m, fidx); + } else { + success &= i_instr_call_indirect(m); + } continue; - + } // // Parametric operators // diff --git a/src/RFC/RFC.cpp b/src/RFC/RFC.cpp new file mode 100644 index 00000000..8bcf131e --- /dev/null +++ b/src/RFC/RFC.cpp @@ -0,0 +1,4 @@ +#include "RFC.h" + +RFC::RFC(uint32_t id, Type *t_type, StackValue *t_args) + : fidx(id), args(t_args), type(t_type) {} diff --git a/src/RFC/RFC.h b/src/RFC/RFC.h new file mode 100644 index 00000000..2f4b11f5 --- /dev/null +++ b/src/RFC/RFC.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../WARDuino.h" +// short unsigned serializationSize; +struct SerializeData { + const unsigned char *raw; + uint32_t size; +}; + +class RFC { + public: + const uint32_t fidx; + StackValue *args; + const Type *type; + StackValue *result; + + bool success; + char *exception; + uint16_t exception_size; + + RFC(uint32_t id, Type *t_type, StackValue *t_args = nullptr); +}; diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index cc4a0b6e..1292b884 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -7,6 +7,7 @@ #include #include +#include "../Interpreter/instructions.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "proxy_supervisor.h" @@ -16,84 +17,36 @@ ////TODO test with no return proxy unsigned short int sizeof_valuetype(uint32_t); -unsigned short int sizeSerializationRFC(const Type *); unsigned short int sizeSerializationRFCallee(Proxy *); void arguments_copy(unsigned char *, StackValue *, uint32_t); -std::map functions; -std::queue callees; - -/* - * Proxy Manager Client Side - */ -Proxy *Proxy::registerRFC(uint32_t t_fid, Type *t_type) { - auto *rfc = new Proxy(t_fid, t_type); - functions[t_fid] = rfc; - return rfc; -} - -void Proxy::unregisterRFC(uint32_t fid) { - auto it = functions.find(fid); - if (it != functions.end()) functions.erase(it); -} - -void Proxy::clearRFCs() { - std::map::iterator it; - for (it = functions.begin(); it != functions.end(); it++) delete it->second; - functions.clear(); -} - -bool Proxy::isRFC(uint32_t fid) { - auto it = functions.find(fid); - return it != functions.end(); -} - -Proxy *Proxy::getRFC(uint32_t fid) { - auto it = functions.find(fid); - return it->second; -} - -/* - * Proxy Manager Server Side - */ - -Proxy *Proxy::registerRFCallee(uint32_t t_fid, Type *t_type, StackValue *t_args, - ExecutionState *t_executionState) { - auto *rfc = new Proxy(t_fid, t_type, t_args, t_executionState); - callees.push(rfc); - return rfc; -} - -bool Proxy::hasRFCallee() { return !callees.empty(); } - -Proxy *Proxy::currentCallee() { return callees.front(); } - -void Proxy::removeRFCallee() { callees.pop(); } - /* * Proxy methods */ -Proxy::Proxy(uint32_t t_fid, Type *t_type, StackValue *t_args, - ExecutionState *t_exState) - : fid(t_fid), args(t_args), type(t_type), executionState(t_exState) { +Proxy::Proxy() { this->exceptionMsg = nullptr; this->excpMsgSize = 0; this->succes = true; this->result = nullptr; - if (t_type->result_count > 0) { - this->result = new StackValue; - this->result->value_type = t_type->results[0]; - } } -void Proxy::returnResult(Module *m) { +void Proxy::pushRFC(Module *m, RFC *rfc) { + // push proxy guard block to stack + this->pushProxyGuard(m); + // push RFC arguments to stack + this->setupCalleeArgs(m, rfc); + // push function to stack + setup_call(m, rfc->fidx); +} + +void Proxy::returnResult(Module *m, RFC *rfc) { // reading result from stack - if (this->succes && this->type->result_count > 0) { + if (this->succes && rfc->type->result_count > 0) { this->result->value_type = m->stack[m->sp].value_type; this->result->value = m->stack[m->sp].value; } else if (!this->succes) { - printf("some exeception will be returned\n"); + printf("some exception will be returned\n"); // TODO exception msg } @@ -103,59 +56,13 @@ void Proxy::returnResult(Module *m) { WARDuino::instance()->debugger->channel->write(data); } -void Proxy::restoreExecutionState(Module *m, - RunningState *program_state) const { - // restoring the original execution state - *program_state = this->executionState->program_state; - m->csp = this->executionState->csp; - m->sp = this->executionState->sp; - m->pc_ptr = this->executionState->pc_ptr; -} - -bool Proxy::callCompleted(Module *m) const { - return !this->succes || this->executionState->csp == m->csp; -} - -/* - * - * output: 1 byte | 4 bytes | sizeof(arg1.value_type) bytes | - * sizeof(arg2.value_type) bytes | ... interrupt | funID | arg1.value - * - * Output is also transformed to hexa - * - */ -struct Proxy::SerializeData *Proxy::serializeRFC() { - const unsigned short serializationSize = sizeSerializationRFC(this->type); - auto *buffer = new unsigned char[serializationSize]; - - // write to array: interrupt, function identifier and arguments - const unsigned char interrupt = interruptProxyCall; - memcpy(buffer, &interrupt, sizeof(unsigned char)); - memcpy(buffer + 1, &fid, sizeof(uint32_t)); - arguments_copy(buffer + 5, args, type->param_count); - - // array as hexa - const uint32_t hexa_size = serializationSize * 2; - auto *hexa = - new unsigned char[hexa_size + 2]; //+2 for '\n' and '0' termination - chars_as_hexa(hexa, buffer, serializationSize); - hexa[hexa_size] = '\n'; - hexa[hexa_size + 1] = '\0'; // TODO remove zero termination and +2 above - - delete[] buffer; - auto *ser = new SerializeData; - ser->size = hexa_size + 1; - ser->raw = hexa; - return ser; -} - -struct Proxy::SerializeData *Proxy::serializeRFCallee() { +struct SerializeData *Proxy::serializeRFCallee(RFC *callee) { const unsigned short serializationSize = sizeSerializationRFCallee(this); auto *raw = new unsigned char[serializationSize]; uint8_t suc = this->succes ? 1 : 0; memcpy(raw, &suc, sizeof(uint8_t)); - if (this->succes && this->type->result_count > 0) { + if (this->succes && callee->type->result_count > 0) { printf("serializeRFCallee: success value size=%u \n", sizeof_valuetype(this->result->value_type)); memcpy(raw + 1, &this->result->value, @@ -173,20 +80,8 @@ struct Proxy::SerializeData *Proxy::serializeRFCallee() { return ser; } -/* - * returns the quantity of bytes needed to serialize a Proxy. - * The size includes: Interrupt + Id of the function + parameters - */ -unsigned short int sizeSerializationRFC(const Type *type) { - short unsigned int paramSize = 0; - for (uint32_t i = 0; i < type->param_count; i++) - paramSize += sizeof_valuetype(type->params[i]); - - return 1 + sizeof(uint32_t) + paramSize; -} - -unsigned short int sizeSerializationRFCallee(Proxy *callee) { - if (!callee->succes) return 1 + sizeof(uint16_t) + callee->excpMsgSize; +unsigned short int sizeSerializationRFCallee(RFC *callee) { + if (!callee->success) return 1 + sizeof(uint16_t) + callee->exception_size; if (callee->type->result_count > 0) return 1 + sizeof_valuetype(callee->type->results[0]); @@ -207,125 +102,6 @@ unsigned short int sizeof_valuetype(uint32_t vt) { } } -void arguments_copy(unsigned char *dest, StackValue *args, - uint32_t param_count) { - uint32_t offset = 0; - for (uint32_t i = 0; i < param_count; i++) { - switch (args[i].value_type) { - case I32: { - memcpy(dest + offset, &args[i].value.uint32, sizeof(uint32_t)); - offset += sizeof(uint32_t); - break; - } - case F32: { - memcpy(dest + offset, &args[i].value.f32, sizeof(float)); - offset += sizeof(float); - break; - } - case I64: { - memcpy(dest + offset, &args[i].value.uint64, sizeof(uint64_t)); - offset += sizeof(uint64_t); - break; - } - case F64: { - memcpy(dest + offset, &args[i].value.f64, sizeof(double)); - offset += sizeof(double); - break; - } - default: - FATAL("incorrect StackValue type\n"); - break; - } - } -} - -void Proxy::deserializeRFCResult() { - ProxySupervisor *host = WARDuino::instance()->debugger->supervisor; - - auto *call_result = (uint8_t *)host->readReply(); - this->succes = (uint8_t)call_result[0] == 1; - - if (!this->succes) { - uint16_t msg_size = 0; - memcpy(&msg_size, call_result + 1, sizeof(uint16_t)); - if (msg_size > this->excpMsgSize) { - delete[] this->exceptionMsg; - this->exceptionMsg = new char[msg_size]; - this->excpMsgSize = msg_size; - } - memcpy(this->exceptionMsg, call_result + 1 + sizeof(uint16_t), - msg_size); - delete[] call_result; - return; - } - - if (this->type->result_count == 0) { - delete[] call_result; - return; - } - - this->result->value.uint64 = 0; - switch (this->result->value_type) { - case I32: - memcpy(&result->value.uint32, call_result + 1, sizeof(uint32_t)); - dbg_info("deserialized U32 %" PRIu32 "\n", result->value.uint32); - break; - case F32: - memcpy(&result->value.f32, call_result + 1, sizeof(float)); - dbg_info("deserialized f32 %f \n", result->value.f32); - break; - case I64: - memcpy(&result->value.uint64, call_result + 1, sizeof(uint64_t)); - dbg_info("deserialized I64 %" PRIu64 "\n", result->value.uint64); - break; - case F64: - memcpy(&result->value.f64, call_result + 1, sizeof(double)); - dbg_info("deserialized f32 %f \n", result->value.f64); - break; - default: - FATAL("Deserialization RFCResult\n"); - } - delete[] call_result; -} - -void Proxy::call(StackValue *arguments) { - this->args = arguments; - struct SerializeData *rfc_request = this->serializeRFC(); - - ProxySupervisor *host = WARDuino::instance()->debugger->supervisor; - printf("making the Proxy call\n"); - bool sent = host->send((void *)rfc_request->raw, rfc_request->size); - if (!sent) { - this->succes = false; - this->exceptionMsg = host->exceptionMsg; - - delete[] rfc_request->raw; - delete rfc_request; - printf("sent FAILED \n"); - return; - } - // Fetch new callback mapping - // convert message to hex TODO: move to proxyserver - char cmdBuffer[10] = ""; - int cmdBufferLen = 0; - sprintf(cmdBuffer, "%x\n%n", interruptDUMPCallbackmapping, &cmdBufferLen); - WARDuino::instance()->debugger->supervisor->send(cmdBuffer, cmdBufferLen); - this->deserializeRFCResult(); -} - -void Proxy::registerRFCs(Module *m, uint8_t **data) { - printf("registering_rfc_functions\n"); - Proxy::clearRFCs(); - uint32_t amount_funcs = read_B32(data); - printf("funcs_total %" PRIu32 "\n", amount_funcs); - for (uint32_t i = 0; i < amount_funcs; i++) { - uint32_t fid = read_B32(data); - printf("registering fid=%" PRIu32 "\n", fid); - Type *type = (m->functions[fid]).type; - Proxy::registerRFC(fid, type); - } -} - StackValue *Proxy::readRFCArgs(Block *func, uint8_t *data) { if (func->type->param_count == 0) { printf("ProxyFunc %" PRIu32 "takes no arg\n", func->fidx); @@ -374,9 +150,19 @@ StackValue *Proxy::readRFCArgs(Block *func, uint8_t *data) { return args; } -void Proxy::setupCalleeArgs(Module *m, Proxy *callee) { +void Proxy::setupCalleeArgs(Module *m, RFC *callee) { // adding arguments to the stack StackValue *args = callee->args; for (uint32_t i = 0; i < callee->type->param_count; i++) m->stack[++m->sp] = args[i]; } + +void Proxy::pushProxyGuard(Module *m) { + if (m == nullptr) { + return; + } + auto *guard = new Block(); + guard->block_type = 255; // 0xfe proxy guard + push_block(m, guard, m->sp); +} + diff --git a/src/RFC/proxy.h b/src/RFC/proxy.h index d4976777..91573829 100644 --- a/src/RFC/proxy.h +++ b/src/RFC/proxy.h @@ -6,57 +6,24 @@ #include "../WARDuino.h" -typedef struct { - int csp; - int sp; - uint8_t *pc_ptr; - RunningState program_state; -} ExecutionState; - class Proxy { private: - // short unsigned serializationSize; - struct SerializeData { - const unsigned char *raw; - uint32_t size; - }; + struct SerializeData *serializeRFCallee(RFC *callee); - struct SerializeData *serializeRFC(); - struct SerializeData *serializeRFCallee(); - void deserializeRFCResult(); + void setupCalleeArgs(Module *m, RFC *callee); + void pushProxyGuard(Module *m); public: - const uint32_t fid; - StackValue *args; - const Type *type; StackValue *result; bool succes; char *exceptionMsg; uint16_t excpMsgSize; - const ExecutionState *executionState; - - Proxy(uint32_t t_fid, Type *t_type, StackValue *t_args = nullptr, - ExecutionState *t_exState = nullptr); - void call(StackValue *args); - void returnResult(Module *m); - void restoreExecutionState(Module *m, RunningState *program_state) const; - bool callCompleted(Module *m) const; - - // Client side - static Proxy *registerRFC(uint32_t t_fid, Type *t_type); - static void registerRFCs(Module *m, uint8_t **data); - static void unregisterRFC(uint32_t fid); - static bool isRFC(uint32_t fid); - static Proxy *getRFC(uint32_t fid); - static void clearRFCs(); - - // Server side - static Proxy *registerRFCallee(uint32_t t_fid, Type *t_type, - StackValue *t_args, - ExecutionState *t_executionState); - static bool hasRFCallee(); - static Proxy *currentCallee(); - static void removeRFCallee(); + + Proxy(); + + void pushRFC(Module *m, RFC *rfc); + void returnResult(Module *m, RFC *rfc); + + // Server side ( arduino side ) static StackValue *readRFCArgs(Block *func, uint8_t *data); - static void setupCalleeArgs(Module *m, Proxy *callee); }; diff --git a/src/RFC/proxy_supervisor.cpp b/src/RFC/proxy_supervisor.cpp index 7119fbc3..8f3b9d53 100644 --- a/src/RFC/proxy_supervisor.cpp +++ b/src/RFC/proxy_supervisor.cpp @@ -1,9 +1,7 @@ #ifndef ARDUINO #include "proxy_supervisor.h" -#include #include -#include #include #include @@ -13,7 +11,6 @@ #include #include "../Utils/macros.h" -#include "../Utils/sockets.h" #include "../Utils/util.h" // TODO exception msg @@ -25,37 +22,10 @@ const char CONNECT_ERR[] = "Socket failed to connect"; const char WRITE_ERR[] = "ERROR writing to socket"; const char READ_ERR[] = "ERROR reading from socket"; -struct Address { - struct sockaddr_in aserv_addr; - struct hostent *aServer; -}; - bool is_success(const char *msg) { return (msg != nullptr) && (msg[0] == '\0'); // check if string is empty } -const char *createConnection(int socketfd, char *host, int port, - struct Address *address) { - struct hostent *server = gethostbyname(host); - if (server == nullptr) { - return INVALID_HOST; - } - - address->aServer = server; - struct sockaddr_in *server_address = &address->aserv_addr; - bzero((char *)server_address, sizeof(*server_address)); - server_address->sin_family = AF_INET; - bcopy((char *)server->h_addr, (char *)&server_address->sin_addr.s_addr, - server->h_length); - server_address->sin_port = htons(port); - if (connect(socketfd, (struct sockaddr *)server_address, - sizeof(*server_address)) < 0) { - return CONNECT_ERR; - } - - return SUCCESS; -} - bool continuing(pthread_mutex_t *mutex) { switch (pthread_mutex_trylock(mutex)) { case 0: /* if we got the lock, unlock and return false */ @@ -83,17 +53,8 @@ Event *parseJSON(char *buff) { return new Event(*parsed.find("topic"), payload); } -void ProxySupervisor::updateExcpMsg(const char *msg) { - delete[] this->exceptionMsg; - auto msg_len = strlen(msg); - this->exceptionMsg = new char[(msg_len + 1) / sizeof(char)]; - this->exceptionMsg[msg_len] = '\0'; - memcpy(this->exceptionMsg, msg, msg_len); -} - ProxySupervisor::ProxySupervisor(int socket, pthread_mutex_t *mutex) { printf("Started supervisor.\n"); - this->socket = socket; this->channel = new Channel(socket); this->mutex = mutex; @@ -109,7 +70,7 @@ void ProxySupervisor::startPushDebuggerSocket() { printf("Started listening for events from proxy device.\n"); while (continuing(this->mutex)) { - if (read(this->socket, &_char, 1) != -1) { + if (this->channel->read(&_char, 1) != -1) { // increase buffer size if needed if (current_size <= (buf_idx + 1)) { char *new_buff = (char *)malloc(current_size + start_size); @@ -135,33 +96,183 @@ void ProxySupervisor::startPushDebuggerSocket() { } } -bool ProxySupervisor::send(void *buffer, int size) { - int n = write(this->socket, buffer, size); - if (n == size) return true; - - if (n < 0 && errno == EINTR) // write interrupted, thus retry - return this->send(buffer, size); - else if (n < 0) { - this->updateExcpMsg(WRITE_ERR); - return false; - } - // send remaining bytes - char *buf = (char *)buffer + n; - return this->send((void *)buf, size - n); +bool ProxySupervisor::send( + void *buffer, int size) { // TODO buffer needs to be null terminated + int n = this->channel->write(static_cast(buffer)); + return n == size; } char *ProxySupervisor::readReply(short int amount) { char *buffer = new char[amount + 1]; bzero(buffer, amount + 1); - int n = read(this->socket, buffer, amount); + ssize_t n = this->channel->read(buffer, amount); if (n > 0) return buffer; delete[] buffer; - if (errno == EINTR) // read interrupted, thus retry - return this->readReply(amount); - - this->updateExcpMsg(READ_ERR); return nullptr; } + pthread_t ProxySupervisor::getThreadID() { return this->threadid; } + +unsigned short int sizeof_valuetype(uint32_t vt) { + switch (vt) { + case I32: + return 4; + case I64: + return 8; + case F32: + return sizeof(float); + default: + return sizeof(double); + } +} + +/* + * returns the quantity of bytes needed to serialize a Proxy. + * The size includes: Interrupt + Id of the function + parameters + */ +unsigned short int sizeSerializationRFC(const Type *type) { + short unsigned int paramSize = 0; + for (uint32_t i = 0; i < type->param_count; i++) + paramSize += sizeof_valuetype(type->params[i]); + + return 1 + sizeof(uint32_t) + paramSize; +} + +void arguments_copy(unsigned char *dest, StackValue *args, + uint32_t param_count) { + uint32_t offset = 0; + for (uint32_t i = 0; i < param_count; i++) { + switch (args[i].value_type) { + case I32: { + memcpy(dest + offset, &args[i].value.uint32, sizeof(uint32_t)); + offset += sizeof(uint32_t); + break; + } + case F32: { + memcpy(dest + offset, &args[i].value.f32, sizeof(float)); + offset += sizeof(float); + break; + } + case I64: { + memcpy(dest + offset, &args[i].value.uint64, sizeof(uint64_t)); + offset += sizeof(uint64_t); + break; + } + case F64: { + memcpy(dest + offset, &args[i].value.f64, sizeof(double)); + offset += sizeof(double); + break; + } + default: + FATAL("incorrect StackValue type\n"); + break; + } + } +} + +/* + * + * output: 1 byte | 4 bytes | sizeof(arg1.value_type) bytes | + * sizeof(arg2.value_type) bytes | ... interrupt | funID | arg1.value + * + * Output is also transformed to hexa + * + */ +struct SerializeData *ProxySupervisor::serializeRFC(RFC *callee) { + const unsigned short serializationSize = sizeSerializationRFC(callee->type); + auto *buffer = new unsigned char[serializationSize]; + + // write to array: interrupt, function identifier and arguments + const unsigned char interrupt = interruptProxyCall; + memcpy(buffer, &interrupt, sizeof(unsigned char)); + memcpy(buffer + 1, &callee->fidx, sizeof(uint32_t)); + arguments_copy(buffer + 5, callee->args, callee->type->param_count); + + // array as hexa + const uint32_t hexa_size = serializationSize * 2; + auto *hexa = + new unsigned char[hexa_size + 2]; //+2 for '\n' and '0' termination + chars_as_hexa(hexa, buffer, serializationSize); + hexa[hexa_size] = '\n'; + hexa[hexa_size + 1] = '\0'; // TODO remove zero termination and +2 above + + delete[] buffer; + auto *ser = new SerializeData; + ser->size = hexa_size + 1; + ser->raw = hexa; + return ser; +} + +void ProxySupervisor::deserializeRFCResult(RFC *rfc) { + uint8_t *call_result = nullptr; + while (call_result == nullptr) { + call_result = (uint8_t *)this->readReply(); + } + rfc->success = (uint8_t)call_result[0] == 1; + + if (!rfc->success) { + uint16_t msg_size = 0; + memcpy(&msg_size, call_result + 1, sizeof(uint16_t)); + if (msg_size > rfc->exception_size) { + delete[] rfc->exception; + rfc->exception = new char[msg_size]; + rfc->exception_size = msg_size; + } + memcpy(rfc->exception, call_result + 1 + sizeof(uint16_t), + msg_size); + delete[] call_result; + return; + } + + if (rfc->type->result_count == 0) { + delete[] call_result; + return; + } + + rfc->result->value.uint64 = 0; + switch (rfc->result->value_type) { + case I32: + memcpy(&rfc->result->value.uint32, call_result + 1, sizeof(uint32_t)); + dbg_info("deserialized U32 %" PRIu32 "\n", result->value.uint32); + break; + case F32: + memcpy(&rfc->result->value.f32, call_result + 1, sizeof(float)); + dbg_info("deserialized f32 %f \n", result->value.f32); + break; + case I64: + memcpy(&rfc->result->value.uint64, call_result + 1, sizeof(uint64_t)); + dbg_info("deserialized I64 %" PRIu64 "\n", result->value.uint64); + break; + case F64: + memcpy(&rfc->result->value.f64, call_result + 1, sizeof(double)); + dbg_info("deserialized f32 %f \n", result->value.f64); + break; + default: + FATAL("Deserialization RFCResult\n"); + } + delete[] call_result; +} + +bool ProxySupervisor::call(RFC *callee) { + struct SerializeData *rfc_request = this->serializeRFC(callee); + + bool sent = this->send((void *)rfc_request->raw, rfc_request->size); + if (!sent) { + callee->success = false; + + delete[] rfc_request->raw; + delete rfc_request; + dbg_trace("Sending RFC: FAILED\n"); + return false; + } + // Fetch new callback mapping + // convert message to hex TODO: move to proxyserver + char cmdBuffer[10] = ""; + int cmdBufferLen = 0; + sprintf(cmdBuffer, "%x\n%n", interruptDUMPCallbackmapping, &cmdBufferLen); + WARDuino::instance()->debugger->supervisor->send(cmdBuffer, cmdBufferLen); + this->deserializeRFCResult(callee); + return true; +} #endif diff --git a/src/RFC/proxy_supervisor.h b/src/RFC/proxy_supervisor.h index 1005ef10..af452b47 100644 --- a/src/RFC/proxy_supervisor.h +++ b/src/RFC/proxy_supervisor.h @@ -4,29 +4,29 @@ #include #include "../Utils/sockets.h" +#include "../WARDuino.h" +#include "RFC.h" #include "pthread.h" #include "sys/types.h" -struct Address; - class ProxySupervisor { private: Channel *channel; - int socket; pthread_t threadid; pthread_mutex_t *mutex; + std::map functions; + struct SerializeData *serializeRFC(RFC *callee); + void deserializeRFCResult(RFC *rfc); public: - char *exceptionMsg; - - // private constructor for singleton ProxySupervisor(int socket, pthread_mutex_t *mutex); void startPushDebuggerSocket(); - void updateExcpMsg(const char *msg); bool send(void *t_buffer, int t_size); char *readReply(short int amount = 1024); pthread_t getThreadID(); + + bool call(RFC *callee); }; diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index 96836129..070ff524 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -61,9 +62,14 @@ int listenForIncomingConnection(int socket_fd, struct sockaddr_in address) { Channel::Channel(int socket) { this->socket = socket; } -void Channel::write(const char *fmt, ...) const { +int Channel::write(const char *fmt, ...) const { va_list args; va_start(args, fmt); - vdprintf(this->socket, fmt, args); + int written = vdprintf(this->socket, fmt, args); va_end(args); + return written; } + +ssize_t Channel::read(void *out, size_t size) { + return ::read(this->socket, out, size); +} \ No newline at end of file diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h index c6e2d1c0..4e6ada10 100644 --- a/src/Utils/sockets.h +++ b/src/Utils/sockets.h @@ -1,5 +1,6 @@ #pragma once +#include void setFileDescriptorOptions(int socket_fd); int createSocketFileDescriptor(); @@ -19,5 +20,6 @@ class Channel { public: explicit Channel(int socket); - void write(char const *fmt, ...) const; + int write(char const *fmt, ...) const; + ssize_t read(void *out, size_t size); }; \ No newline at end of file diff --git a/src/WARDuino.h b/src/WARDuino.h index c49841de..ea616c81 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -68,8 +68,9 @@ typedef union FuncPtr { // A block or function typedef struct Block { - uint8_t block_type; // 0x00: function, 0x01: init_exp - // 0x02: block, 0x03: loop, 0x04: if, 0xff: cbk guard + uint8_t block_type; // 0x00: function, 0x01: init_exp, 0x02: block, + // 0x03: loop, 0x04: if, 0xfe: proxy guard, + // 0xff: cbk guard uint32_t fidx; // function only (index) Type *type; // params/results type uint32_t local_count; // function only From d9f9d8324467aa0d7baf5944106edc856dd53a94 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 28 Jul 2022 16:15:27 +0200 Subject: [PATCH 188/249] Clang format + fix some header includes --- platforms/CLI-Emulator/main.cpp | 1 + src/Interpreter/instructions.cpp | 2 +- src/RFC/RFC.h | 2 +- src/RFC/proxy.cpp | 3 +-- src/RFC/proxy.h | 2 +- src/RFC/proxy_supervisor.cpp | 9 +++++---- src/RFC/proxy_supervisor.h | 2 +- src/Utils/macros.cpp | 9 +++++---- 8 files changed, 16 insertions(+), 14 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index a5f0668c..03213138 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -12,6 +12,7 @@ #include "../../src/Debug/debugger.h" #include "../../src/Utils/macros.h" #include "../../src/Utils/sockets.h" +#include "../../src/WARDuino.h" #include "../../tests/integration/wasm_tests.h" // Constants diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index b4f045bb..f0842492 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -106,7 +106,7 @@ bool proxy_call(Module *m, uint32_t fidx) { dbg_info("Remote Function Call %d\n", fidx); ProxySupervisor *supervisor = m->warduino->debugger->supervisor; RFC *rfc; - Type * type = m->functions[fidx].type; + Type *type = m->functions[fidx].type; if (type->param_count > 0) { m->sp -= type->param_count; StackValue *args = &m->stack[m->sp + 1]; diff --git a/src/RFC/RFC.h b/src/RFC/RFC.h index 2f4b11f5..5b20a681 100644 --- a/src/RFC/RFC.h +++ b/src/RFC/RFC.h @@ -1,7 +1,7 @@ #pragma once #include "../WARDuino.h" -// short unsigned serializationSize; + struct SerializeData { const unsigned char *raw; uint32_t size; diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index 1292b884..960e3de0 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -162,7 +162,6 @@ void Proxy::pushProxyGuard(Module *m) { return; } auto *guard = new Block(); - guard->block_type = 255; // 0xfe proxy guard + guard->block_type = 255; // 0xfe proxy guard push_block(m, guard, m->sp); } - diff --git a/src/RFC/proxy.h b/src/RFC/proxy.h index 91573829..63d44e20 100644 --- a/src/RFC/proxy.h +++ b/src/RFC/proxy.h @@ -4,7 +4,7 @@ #include -#include "../WARDuino.h" +#include "RFC.h" class Proxy { private: diff --git a/src/RFC/proxy_supervisor.cpp b/src/RFC/proxy_supervisor.cpp index 8f3b9d53..6c357319 100644 --- a/src/RFC/proxy_supervisor.cpp +++ b/src/RFC/proxy_supervisor.cpp @@ -219,8 +219,7 @@ void ProxySupervisor::deserializeRFCResult(RFC *rfc) { rfc->exception = new char[msg_size]; rfc->exception_size = msg_size; } - memcpy(rfc->exception, call_result + 1 + sizeof(uint16_t), - msg_size); + memcpy(rfc->exception, call_result + 1 + sizeof(uint16_t), msg_size); delete[] call_result; return; } @@ -233,7 +232,8 @@ void ProxySupervisor::deserializeRFCResult(RFC *rfc) { rfc->result->value.uint64 = 0; switch (rfc->result->value_type) { case I32: - memcpy(&rfc->result->value.uint32, call_result + 1, sizeof(uint32_t)); + memcpy(&rfc->result->value.uint32, call_result + 1, + sizeof(uint32_t)); dbg_info("deserialized U32 %" PRIu32 "\n", result->value.uint32); break; case F32: @@ -241,7 +241,8 @@ void ProxySupervisor::deserializeRFCResult(RFC *rfc) { dbg_info("deserialized f32 %f \n", result->value.f32); break; case I64: - memcpy(&rfc->result->value.uint64, call_result + 1, sizeof(uint64_t)); + memcpy(&rfc->result->value.uint64, call_result + 1, + sizeof(uint64_t)); dbg_info("deserialized I64 %" PRIu64 "\n", result->value.uint64); break; case F64: diff --git a/src/RFC/proxy_supervisor.h b/src/RFC/proxy_supervisor.h index af452b47..25135518 100644 --- a/src/RFC/proxy_supervisor.h +++ b/src/RFC/proxy_supervisor.h @@ -4,7 +4,6 @@ #include #include "../Utils/sockets.h" -#include "../WARDuino.h" #include "RFC.h" #include "pthread.h" #include "sys/types.h" @@ -18,6 +17,7 @@ class ProxySupervisor { struct SerializeData *serializeRFC(RFC *callee); void deserializeRFCResult(RFC *rfc); + public: ProxySupervisor(int socket, pthread_mutex_t *mutex); diff --git a/src/Utils/macros.cpp b/src/Utils/macros.cpp index 9f6a28d9..070c4d76 100644 --- a/src/Utils/macros.cpp +++ b/src/Utils/macros.cpp @@ -240,10 +240,11 @@ char *block_repr(Block *b) { b->type->param_count, b->local_count, b->type->result_count); } else { snprintf(_block_str, 1023, "%s<0/0->%d>", - b->block_type == 0x01 ? "init" - : b->block_type == 0x02 ? "block" - : b->block_type == 0x03 ? "loop" - : "if", + b->block_type == 0x01 + ? "init" + : b->block_type == 0x02 + ? "block" + : b->block_type == 0x03 ? "loop" : "if", b->type->result_count); } return _block_str; From 91aa40a0aa5768c1aee6969badc9aab7f982140f Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 29 Jul 2022 13:52:03 +0200 Subject: [PATCH 189/249] Fix include errors --- src/RFC/RFC.h | 4 +++- src/RFC/proxy.h | 2 ++ src/RFC/proxy_supervisor.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/RFC/RFC.h b/src/RFC/RFC.h index 5b20a681..ee849512 100644 --- a/src/RFC/RFC.h +++ b/src/RFC/RFC.h @@ -1,6 +1,8 @@ #pragma once -#include "../WARDuino.h" +#include +struct StackValue; +struct Type; struct SerializeData { const unsigned char *raw; diff --git a/src/RFC/proxy.h b/src/RFC/proxy.h index 63d44e20..1ef578a0 100644 --- a/src/RFC/proxy.h +++ b/src/RFC/proxy.h @@ -5,6 +5,8 @@ #include #include "RFC.h" +struct Module; +struct Block; class Proxy { private: diff --git a/src/RFC/proxy_supervisor.h b/src/RFC/proxy_supervisor.h index 25135518..23abf739 100644 --- a/src/RFC/proxy_supervisor.h +++ b/src/RFC/proxy_supervisor.h @@ -2,6 +2,7 @@ #include #include +#include #include "../Utils/sockets.h" #include "RFC.h" From c8de5af180511e9da982160d2d145251518a9eba Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 29 Jul 2022 15:39:32 +0200 Subject: [PATCH 190/249] Handle proxy guard (return result) --- src/Debug/debugger.cpp | 15 +++++++++++---- src/Debug/debugger.h | 14 ++++++++------ src/Interpreter/instructions.cpp | 23 +++++++++++++++++------ src/RFC/proxy.cpp | 22 +++++++++++++--------- src/RFC/proxy.h | 7 ++++--- src/WARDuino/CallbackHandler.cpp | 4 ++-- 6 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index d3c60d7b..5f0cc244 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -240,9 +240,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } break; #endif case interruptProxify: { - *program_state = WARDUINODrone; + dbg_info("Converting to proxy settings.\n"); + *program_state = PROXYhalt; this->proxy = new Proxy(); // TODO delete - printf("Converting to proxy settings.\n"); break; } case interruptDUMPAllEvents: @@ -969,13 +969,20 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, auto *rfc = new RFC(fidx, func->type, args); this->proxy->pushRFC(m, rfc); - *program_state = WARDuinoProxyRun; + *program_state = PROXYrun; dbg_trace("Program state: ProxyRun"); } +void Debugger::sendProxyCallResult(Module *m) { + if (proxy == nullptr) { + return; + } + this->proxy->returnResult(m); +} + #ifndef ARDUINO void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { - Proxy::registerRFCs(m, &interruptData); + ProxySupervisor::registerRFCs(m, &interruptData); this->channel->write("done!\n"); } diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index a99119ed..ac2225d5 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -22,12 +22,12 @@ enum RunningState { WARDUINOrun, WARDUINOpause, WARDUINOstep, - WARDuinoProxyRun, // Running state used when executing a proxy call. During - // this state the call is set up and executed by the main - // loop. After execution, the state is restored to - // WARDUINODrone - WARDUINODrone // Do not run the program (program runs on computer, which - // sends messages for primitives, do forward interupts) + PROXYrun, // Running state used when executing a proxy call. During + // this state the call is set up and executed by the main + // loop. After execution, the state is restored to + // PROXYhalt + PROXYhalt // Do not run the program (program runs on computer, which + // sends messages for primitives, do forward interrupts) }; enum InterruptTypes { @@ -168,6 +168,8 @@ class Debugger { void handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData); + void sendProxyCallResult(Module *m); + #ifndef ARDUINO void startProxySupervisor(const char *proxy); diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index f0842492..528124a1 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -35,6 +35,13 @@ Block *pop_block(Module *m) { t = frame->block->type; } + if (frame->block->block_type == 0xfe) { + m->warduino->program_state = PROXYhalt; + m->warduino->debugger->sendProxyCallResult(m); + frame = &m->callstack[m->csp--]; + t = frame->block->type; + } + // TODO: validate return value if there is one m->fp = frame->fp; // Restore frame pointer @@ -115,7 +122,10 @@ bool proxy_call(Module *m, uint32_t fidx) { rfc = new RFC(fidx, type); } - bool success = supervisor->call(rfc); + if (!supervisor->call(rfc)) { + dbg_info(": FAILED TO SEND\n", fidx); + return false; + } if (!rfc->success) { // TODO exception bugger might be too small and msg not null terminated? memcpy(&exception, rfc->exception, strlen(rfc->exception)); @@ -460,7 +470,7 @@ bool i_instr_call_indirect(Module *m) { /** * 0x1a drop - * remvove a value from the stack + * remove a value from the stack */ bool i_instr_drop(Module *m) { m->sp--; @@ -1510,7 +1520,7 @@ bool interpret(Module *m) { // Skip the main loop if paused or drone if (m->warduino->program_state == WARDUINOpause || - m->warduino->program_state == WARDUINODrone) { + m->warduino->program_state == PROXYhalt) { continue; } @@ -1519,7 +1529,7 @@ bool interpret(Module *m) { // If BP and not the one we just unpaused if (m->warduino->debugger->isBreakpoint(m->pc_ptr) && m->warduino->debugger->skipBreakpoint != m->pc_ptr && - m->warduino->program_state != WARDuinoProxyRun) { + m->warduino->program_state != PROXYrun) { m->warduino->program_state = WARDUINOpause; m->warduino->debugger->notifyBreakpoint(m->pc_ptr); continue; @@ -1728,9 +1738,10 @@ bool interpret(Module *m) { } return false; } - if (m->warduino->program_state == WARDuinoProxyRun && !success) { + // TODO replace following with guard handle + if (m->warduino->program_state == PROXYrun && !success) { // Proxy call was unsuccessful - Proxy::currentCallee()->succes = false; +// Proxy::currentCallee()->succes = false; // TODO copy exceptionMsg success = true; } diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index 960e3de0..2dc3e2a3 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -28,7 +28,6 @@ Proxy::Proxy() { this->exceptionMsg = nullptr; this->excpMsgSize = 0; this->succes = true; - this->result = nullptr; } void Proxy::pushRFC(Module *m, RFC *rfc) { @@ -38,20 +37,25 @@ void Proxy::pushRFC(Module *m, RFC *rfc) { this->setupCalleeArgs(m, rfc); // push function to stack setup_call(m, rfc->fidx); + // keep RFC in queue + this->calls->push(rfc); } -void Proxy::returnResult(Module *m, RFC *rfc) { +void Proxy::returnResult(Module *m) { + RFC *rfc = this->calls->top(); // reading result from stack if (this->succes && rfc->type->result_count > 0) { - this->result->value_type = m->stack[m->sp].value_type; - this->result->value = m->stack[m->sp].value; + rfc->result->value_type = m->stack[m->sp].value_type; + rfc->result->value = m->stack[m->sp].value; } else if (!this->succes) { printf("some exception will be returned\n"); // TODO exception msg } + // remove call from lifo queue + calls->pop(); - // returning the result to the client - struct SerializeData *rfc_result = this->serializeRFCallee(); + // send the result to the client + struct SerializeData *rfc_result = this->serializeRFCallee(rfc); const char *data = (const char *)rfc_result->raw; WARDuino::instance()->debugger->channel->write(data); } @@ -64,9 +68,9 @@ struct SerializeData *Proxy::serializeRFCallee(RFC *callee) { memcpy(raw, &suc, sizeof(uint8_t)); if (this->succes && callee->type->result_count > 0) { printf("serializeRFCallee: success value size=%u \n", - sizeof_valuetype(this->result->value_type)); - memcpy(raw + 1, &this->result->value, - sizeof_valuetype(this->result->value_type)); + sizeof_valuetype(callee->result->value_type)); + memcpy(raw + 1, &callee->result->value, + sizeof_valuetype(callee->result->value_type)); } else if (!this->succes) { printf("serializeRFCallee: serializing exception\n"); memcpy(raw + 1, &this->excpMsgSize, sizeof(uint16_t)); diff --git a/src/RFC/proxy.h b/src/RFC/proxy.h index 1ef578a0..f803360c 100644 --- a/src/RFC/proxy.h +++ b/src/RFC/proxy.h @@ -3,6 +3,7 @@ #include #include +#include #include "RFC.h" struct Module; @@ -10,13 +11,13 @@ struct Block; class Proxy { private: - struct SerializeData *serializeRFCallee(RFC *callee); + std::stack *calls = new std::stack(); // lifo queue + struct SerializeData *serializeRFCallee(RFC *callee); void setupCalleeArgs(Module *m, RFC *callee); void pushProxyGuard(Module *m); public: - StackValue *result; bool succes; char *exceptionMsg; uint16_t excpMsgSize; @@ -24,7 +25,7 @@ class Proxy { Proxy(); void pushRFC(Module *m, RFC *rfc); - void returnResult(Module *m, RFC *rfc); + void returnResult(Module *m); // Server side ( arduino side ) static StackValue *readRFCArgs(Block *func, uint8_t *data); diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 4425fffc..c42cef0c 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -31,8 +31,8 @@ bool CallbackHandler::resolving_event = false; size_t CallbackHandler::pushed_cursor = 0; bool should_push_event() { - return WARDuino::instance()->program_state == WARDuinoProxyRun || - WARDuino::instance()->program_state == WARDUINODrone; + return WARDuino::instance()->program_state == PROXYrun || + WARDuino::instance()->program_state == PROXYhalt; } std::unordered_map *> From 0a5b5bff446b8e55e4074dccdfe6c630967478ab Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 29 Jul 2022 16:51:06 +0200 Subject: [PATCH 191/249] Track proxied calls in supervisor --- src/Debug/debugger.cpp | 11 ++++++++++- src/Interpreter/instructions.cpp | 6 +++--- src/RFC/proxy.cpp | 18 ++---------------- src/RFC/proxy_supervisor.cpp | 28 +++++++++++++++------------- src/RFC/proxy_supervisor.h | 9 +++++++-- src/Utils/macros.cpp | 9 ++++----- src/Utils/util.cpp | 13 +++++++++++++ src/Utils/util.h | 2 ++ 8 files changed, 56 insertions(+), 40 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 5f0cc244..ad8d7dea 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -982,7 +982,16 @@ void Debugger::sendProxyCallResult(Module *m) { #ifndef ARDUINO void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { - ProxySupervisor::registerRFCs(m, &interruptData); + uint32_t amount_funcs = read_B32(&interruptData); + printf("funcs_total %" PRIu32 "\n", amount_funcs); + + m->warduino->debugger->supervisor->unregisterAllProxiedCalls(); + for (uint32_t i = 0; i < amount_funcs; i++) { + uint32_t fidx = read_B32(&interruptData); + printf("registering fid=%" PRIu32 "\n", fidx); + m->warduino->debugger->supervisor->registerProxiedCall(fidx); + } + this->channel->write("done!\n"); } diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 528124a1..3a328fb1 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1589,7 +1589,7 @@ bool interpret(Module *m) { // case 0x10: { // call uint32_t fidx = read_LEB_32(&m->pc_ptr); - if (m->warduino->debugger->supervisor->isRFC(fidx)) { + if (m->warduino->debugger->supervisor->isProxied(fidx)) { success &= proxy_call(m, fidx); } else { success &= i_instr_call(m); @@ -1598,7 +1598,7 @@ bool interpret(Module *m) { } case 0x11: { // call_indirect uint32_t fidx = read_LEB_32(&m->pc_ptr); - if (m->warduino->debugger->supervisor->isRFC(fidx)) { + if (m->warduino->debugger->supervisor->isProxied(fidx)) { success &= proxy_call(m, fidx); } else { success &= i_instr_call_indirect(m); @@ -1741,7 +1741,7 @@ bool interpret(Module *m) { // TODO replace following with guard handle if (m->warduino->program_state == PROXYrun && !success) { // Proxy call was unsuccessful -// Proxy::currentCallee()->succes = false; + // Proxy::currentCallee()->succes = false; // TODO copy exceptionMsg success = true; } diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index 2dc3e2a3..266e3c1e 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -16,8 +16,7 @@ ////TODO test with many args proxy ////TODO test with no return proxy -unsigned short int sizeof_valuetype(uint32_t); -unsigned short int sizeSerializationRFCallee(Proxy *); +unsigned short int sizeSerializationRFCallee(RFC *); void arguments_copy(unsigned char *, StackValue *, uint32_t); /* @@ -61,7 +60,7 @@ void Proxy::returnResult(Module *m) { } struct SerializeData *Proxy::serializeRFCallee(RFC *callee) { - const unsigned short serializationSize = sizeSerializationRFCallee(this); + const unsigned short serializationSize = sizeSerializationRFCallee(callee); auto *raw = new unsigned char[serializationSize]; uint8_t suc = this->succes ? 1 : 0; @@ -93,19 +92,6 @@ unsigned short int sizeSerializationRFCallee(RFC *callee) { return 1; } -unsigned short int sizeof_valuetype(uint32_t vt) { - switch (vt) { - case I32: - return 4; - case I64: - return 8; - case F32: - return sizeof(float); - default: - return sizeof(double); - } -} - StackValue *Proxy::readRFCArgs(Block *func, uint8_t *data) { if (func->type->param_count == 0) { printf("ProxyFunc %" PRIu32 "takes no arg\n", func->fidx); diff --git a/src/RFC/proxy_supervisor.cpp b/src/RFC/proxy_supervisor.cpp index 6c357319..baed1101 100644 --- a/src/RFC/proxy_supervisor.cpp +++ b/src/RFC/proxy_supervisor.cpp @@ -114,19 +114,6 @@ char *ProxySupervisor::readReply(short int amount) { pthread_t ProxySupervisor::getThreadID() { return this->threadid; } -unsigned short int sizeof_valuetype(uint32_t vt) { - switch (vt) { - case I32: - return 4; - case I64: - return 8; - case F32: - return sizeof(float); - default: - return sizeof(double); - } -} - /* * returns the quantity of bytes needed to serialize a Proxy. * The size includes: Interrupt + Id of the function + parameters @@ -276,4 +263,19 @@ bool ProxySupervisor::call(RFC *callee) { this->deserializeRFCResult(callee); return true; } + +void ProxySupervisor::registerProxiedCall(uint32_t fidx) { + this->proxied->insert(fidx); +} + +void ProxySupervisor::unregisterProxiedCall(uint32_t fidx) { + this->proxied->erase(fidx); +} + +void ProxySupervisor::unregisterAllProxiedCalls() { this->proxied->clear(); } + +bool ProxySupervisor::isProxied(uint32_t fidx) { + return this->proxied->count(fidx) > 0; +} + #endif diff --git a/src/RFC/proxy_supervisor.h b/src/RFC/proxy_supervisor.h index 23abf739..c0b1ff34 100644 --- a/src/RFC/proxy_supervisor.h +++ b/src/RFC/proxy_supervisor.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include "../Utils/sockets.h" #include "RFC.h" @@ -14,7 +14,7 @@ class ProxySupervisor { Channel *channel; pthread_t threadid; pthread_mutex_t *mutex; - std::map functions; + std::set *proxied = new std::set(); struct SerializeData *serializeRFC(RFC *callee); void deserializeRFCResult(RFC *rfc); @@ -30,4 +30,9 @@ class ProxySupervisor { pthread_t getThreadID(); bool call(RFC *callee); + + void registerProxiedCall(uint32_t fidx); + void unregisterProxiedCall(uint32_t fidx); + void unregisterAllProxiedCalls(); + bool isProxied(uint32_t fidx); }; diff --git a/src/Utils/macros.cpp b/src/Utils/macros.cpp index 070c4d76..9f6a28d9 100644 --- a/src/Utils/macros.cpp +++ b/src/Utils/macros.cpp @@ -240,11 +240,10 @@ char *block_repr(Block *b) { b->type->param_count, b->local_count, b->type->result_count); } else { snprintf(_block_str, 1023, "%s<0/0->%d>", - b->block_type == 0x01 - ? "init" - : b->block_type == 0x02 - ? "block" - : b->block_type == 0x03 ? "loop" : "if", + b->block_type == 0x01 ? "init" + : b->block_type == 0x02 ? "block" + : b->block_type == 0x03 ? "loop" + : "if", b->type->result_count); } return _block_str; diff --git a/src/Utils/util.cpp b/src/Utils/util.cpp index 5777a44c..5323bafb 100644 --- a/src/Utils/util.cpp +++ b/src/Utils/util.cpp @@ -201,3 +201,16 @@ void chars_as_hexa(unsigned char *dest, unsigned char *source, dest[i * 2 + 1] = c2 > 9 ? (c2 - 10 + 'A') : (c2 + '0'); } } + +unsigned short int sizeof_valuetype(uint32_t vt) { + switch (vt) { + case I32: + return 4; + case I64: + return 8; + case F32: + return sizeof(float); + default: + return sizeof(double); + } +} diff --git a/src/Utils/util.h b/src/Utils/util.h index 28f036f0..c64618bf 100644 --- a/src/Utils/util.h +++ b/src/Utils/util.h @@ -75,4 +75,6 @@ uint32_t read_L32(uint8_t **bytes); void chars_as_hexa(unsigned char *dest, unsigned char *source, uint32_t len_source); +unsigned short int sizeof_valuetype(uint32_t); + #endif From 1eef39769afc462a3e18eb2d74c2655177b79fc5 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 29 Jul 2022 17:07:36 +0200 Subject: [PATCH 192/249] Forward exception in proxy call --- src/Debug/debugger.cpp | 7 +++++++ src/Debug/debugger.h | 2 ++ src/Interpreter/instructions.cpp | 16 +++++++++------- src/RFC/RFC.h | 2 +- src/RFC/proxy.cpp | 26 +++++++++++--------------- src/RFC/proxy.h | 5 +---- 6 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index ad8d7dea..744c4544 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -973,6 +973,13 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, dbg_trace("Program state: ProxyRun"); } +RFC *Debugger::topProxyCall() { + if (proxy == nullptr) { + return nullptr; + } + return this->proxy->topRFC(); +} + void Debugger::sendProxyCallResult(Module *m) { if (proxy == nullptr) { return; diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index ac2225d5..0a46e484 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -168,6 +168,8 @@ class Debugger { void handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData); + RFC *topProxyCall(); + void sendProxyCallResult(Module *m); #ifndef ARDUINO diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 3a328fb1..6901f919 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1738,13 +1738,15 @@ bool interpret(Module *m) { } return false; } - // TODO replace following with guard handle - if (m->warduino->program_state == PROXYrun && !success) { - // Proxy call was unsuccessful - // Proxy::currentCallee()->succes = false; - // TODO copy exceptionMsg - success = true; - } + } + + if (m->warduino->program_state == PROXYrun) { + dbg_info("Trap was thrown during proxy call.\n"); + RFC *rfc = m->warduino->debugger->topProxyCall(); + rfc->success = false; + rfc->exception = strdup(exception); + rfc->exception_size = strlen(exception); + m->warduino->debugger->sendProxyCallResult(m); } // Resolve all unhandled callback events diff --git a/src/RFC/RFC.h b/src/RFC/RFC.h index ee849512..2ed7b9c8 100644 --- a/src/RFC/RFC.h +++ b/src/RFC/RFC.h @@ -16,7 +16,7 @@ class RFC { const Type *type; StackValue *result; - bool success; + bool success = true; char *exception; uint16_t exception_size; diff --git a/src/RFC/proxy.cpp b/src/RFC/proxy.cpp index 266e3c1e..e15d1f8d 100644 --- a/src/RFC/proxy.cpp +++ b/src/RFC/proxy.cpp @@ -5,12 +5,10 @@ #include #include #include -#include #include "../Interpreter/instructions.h" #include "../Utils/macros.h" #include "../Utils/util.h" -#include "proxy_supervisor.h" // TODO tests with exceptions ////TODO test with many args proxy @@ -23,11 +21,7 @@ void arguments_copy(unsigned char *, StackValue *, uint32_t); * Proxy methods */ -Proxy::Proxy() { - this->exceptionMsg = nullptr; - this->excpMsgSize = 0; - this->succes = true; -} +Proxy::Proxy() = default; void Proxy::pushRFC(Module *m, RFC *rfc) { // push proxy guard block to stack @@ -40,13 +34,15 @@ void Proxy::pushRFC(Module *m, RFC *rfc) { this->calls->push(rfc); } +RFC *Proxy::topRFC() { return this->calls->top(); } + void Proxy::returnResult(Module *m) { RFC *rfc = this->calls->top(); // reading result from stack - if (this->succes && rfc->type->result_count > 0) { + if (rfc->success && rfc->type->result_count > 0) { rfc->result->value_type = m->stack[m->sp].value_type; rfc->result->value = m->stack[m->sp].value; - } else if (!this->succes) { + } else if (!rfc->success) { printf("some exception will be returned\n"); // TODO exception msg } @@ -62,19 +58,19 @@ void Proxy::returnResult(Module *m) { struct SerializeData *Proxy::serializeRFCallee(RFC *callee) { const unsigned short serializationSize = sizeSerializationRFCallee(callee); auto *raw = new unsigned char[serializationSize]; - uint8_t suc = this->succes ? 1 : 0; + uint8_t suc = callee->success ? 1 : 0; memcpy(raw, &suc, sizeof(uint8_t)); - if (this->succes && callee->type->result_count > 0) { + if (callee->success && callee->type->result_count > 0) { printf("serializeRFCallee: success value size=%u \n", sizeof_valuetype(callee->result->value_type)); memcpy(raw + 1, &callee->result->value, sizeof_valuetype(callee->result->value_type)); - } else if (!this->succes) { + } else if (!callee->success) { printf("serializeRFCallee: serializing exception\n"); - memcpy(raw + 1, &this->excpMsgSize, sizeof(uint16_t)); - memcpy(raw + 1 + sizeof(uint16_t), this->exceptionMsg, - this->excpMsgSize); + memcpy(raw + 1, &callee->exception_size, sizeof(uint16_t)); + memcpy(raw + 1 + sizeof(uint16_t), callee->exception, + callee->exception_size); } auto *ser = new struct SerializeData; diff --git a/src/RFC/proxy.h b/src/RFC/proxy.h index f803360c..8a7b349f 100644 --- a/src/RFC/proxy.h +++ b/src/RFC/proxy.h @@ -18,13 +18,10 @@ class Proxy { void pushProxyGuard(Module *m); public: - bool succes; - char *exceptionMsg; - uint16_t excpMsgSize; - Proxy(); void pushRFC(Module *m, RFC *rfc); + RFC *topRFC(); void returnResult(Module *m); // Server side ( arduino side ) From ee506a758c32b68681dcb57610470d55cf8e9bbd Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 09:40:09 +0200 Subject: [PATCH 193/249] Add `--socket` arg to cli --- platforms/CLI-Emulator/main.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 03213138..1610db30 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -50,9 +50,12 @@ void print_help() { fprintf(stdout, " --no-socket Run without socket " "(default: false)\n"); + fprintf(stdout, + " --socket Run without socket " + "(default: 8192)\n"); fprintf(stdout, " --paused Pause program on entry (default: false)\n"); - fprintf(stdout, " --proxy Proxy VM to connect to\n"); + fprintf(stdout, " --proxy Connect to proxy device\n"); } Module *load(WARDuino wac, const char *file_name, Options opt) { @@ -110,12 +113,12 @@ void startDebuggerStd(WARDuino *wac, Module *m) { } } -void startDebuggerSocket(WARDuino *wac, Module *m) { +void startDebuggerSocket(WARDuino *wac, Module *m, int port = 8192) { int socket_fd = createSocketFileDescriptor(); - struct sockaddr_in address = createAddress(8192); + struct sockaddr_in address = createAddress(port); bindSocketToAddress(socket_fd, address); startListening(socket_fd); - dbg_info("Listening on port 172.0.0.1:8192\n"); + printf("Listening on port 172.0.0.1:%i\n", port); int valread; uint8_t buffer[1024] = {0}; @@ -146,6 +149,7 @@ int main(int argc, const char *argv[]) { bool return_exception = true; bool run_tests = false; bool no_socket = false; + const char *socket = "8192"; bool paused = false; const char *file_name = nullptr; const char *proxy = nullptr; @@ -175,6 +179,8 @@ int main(int argc, const char *argv[]) { ARGV_GET(watcompiler); } else if (!strcmp("--no-socket", arg)) { no_socket = true; + } else if (!strcmp("--socket", arg)) { + ARGV_GET(socket); } else if (!strcmp("--paused", arg)) { wac->program_state = WARDUINOpause; } else if (!strcmp("--proxy", arg)) { @@ -219,7 +225,7 @@ int main(int argc, const char *argv[]) { if (no_socket) { startDebuggerStd(wac, m); } else { - startDebuggerSocket(wac, m); + startDebuggerSocket(wac, m, std::stoi(socket)); } int *ptr; pthread_join(id, (void **)&ptr); From a4285a561f1b0d4006ba8329c713a273c631f917 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 09:41:27 +0200 Subject: [PATCH 194/249] Fix segmentation fault at call instr --- src/Debug/debugger.cpp | 9 +++++++++ src/Debug/debugger.h | 2 ++ src/Interpreter/instructions.cpp | 19 +++++++------------ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 744c4544..d6f33b9d 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -958,6 +958,11 @@ uintptr_t Debugger::readPointer(uint8_t **data) { void Debugger::handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData) { + if (this->proxy == nullptr) { + dbg_info("No proxy available to send proxy call to.\n"); + // TODO how to handle this error? + return; + } uint8_t *data = interruptData; uint32_t fidx = read_L32(&data); dbg_info("Proxycall func %" PRIu32 "\n", fidx); @@ -987,6 +992,10 @@ void Debugger::sendProxyCallResult(Module *m) { this->proxy->returnResult(m); } +bool Debugger::isProxied(uint32_t fidx) const { + return this->supervisor != nullptr && this->supervisor->isProxied(fidx); +} + #ifndef ARDUINO void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { uint32_t amount_funcs = read_B32(&interruptData); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 0a46e484..f4bc466c 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -172,6 +172,8 @@ class Debugger { void sendProxyCallResult(Module *m); + bool isProxied(uint32_t fidx) const; + #ifndef ARDUINO void startProxySupervisor(const char *proxy); diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 6901f919..36157da8 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -378,6 +378,10 @@ bool i_instr_return(Module *m) { bool i_instr_call(Module *m) { uint32_t fidx = read_LEB_32(&m->pc_ptr); + if (m->warduino->debugger->isProxied(fidx)) { + return proxy_call(m, fidx); + } + if (fidx < m->import_count) { return ((Primitive)m->functions[fidx].func_ptr)(m); } else { @@ -1588,21 +1592,12 @@ bool interpret(Module *m) { // Call operators // case 0x10: { // call - uint32_t fidx = read_LEB_32(&m->pc_ptr); - if (m->warduino->debugger->supervisor->isProxied(fidx)) { - success &= proxy_call(m, fidx); - } else { - success &= i_instr_call(m); - } + success &= i_instr_call(m); continue; } case 0x11: { // call_indirect - uint32_t fidx = read_LEB_32(&m->pc_ptr); - if (m->warduino->debugger->supervisor->isProxied(fidx)) { - success &= proxy_call(m, fidx); - } else { - success &= i_instr_call_indirect(m); - } + uint32_t tidx = read_LEB_32(&m->pc_ptr); + success &= i_instr_call_indirect(m); continue; } // From 559b3556fd17f52bffb96563a030db25450e1679 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 09:49:14 +0200 Subject: [PATCH 195/249] Fix call_indirect --- src/Interpreter/instructions.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index 36157da8..eec40db0 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -1596,7 +1596,6 @@ bool interpret(Module *m) { continue; } case 0x11: { // call_indirect - uint32_t tidx = read_LEB_32(&m->pc_ptr); success &= i_instr_call_indirect(m); continue; } From 89a83c8884c260870c7089e7c0f79ba607505873 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 10:00:33 +0200 Subject: [PATCH 196/249] Set version number to v0.2.1 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 5c717b48..3c19512d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WARDuino -version=0.9.2 +version=0.2.1 author=Robbert Gurdeep Singh , Christophe Scholliers , Tom Lauwaerts , Carlos Rojas Castillo , Joel Martin maintainer=Robbert Gurdeep Singh , Christophe Scholliers , Tom Lauwaerts sentence=A library that enables the use of WebAssembly on Arduino boards with debugging support From ae2171badbcec7d2c753292611cc7fe63161059c Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 10:21:59 +0200 Subject: [PATCH 197/249] Use espressif/esp-idf-ci-action@v1 --- .github/workflows/compile.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index a62783ea..ef473460 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -110,7 +110,7 @@ jobs: submodules: 'recursive' - name: Build WARDuino for ESP-IDF - uses: espressif/esp-idf-ci-action@main + uses: espressif/esp-idf-ci-action@v1 with: esp_idf_version: latest target: esp32 From d2173a5f499a886404aa1d3b812017b022ded887 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 10:29:42 +0200 Subject: [PATCH 198/249] Remove valread completely --- platforms/Arduino/Arduino.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index 052f5bf0..33c50340 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -21,7 +21,6 @@ Module* m; #define UART_PIN 3 void startDebuggerStd(void* pvParameter) { - int valread; uint8_t buffer[1024] = {0}; wac->debugger->socket = fileno(stdout); write(fileno(stdout), "Got a message ... \n", 19); @@ -40,7 +39,7 @@ void startDebuggerStd(void* pvParameter) { write(fileno(stdout), "Reading message ..... \n", 19); fflush(stdout); wac->handleInterrupt(buff_len, buffer); - write(fileno(stdout), buffer, valread); + write(fileno(stdout), buffer, buff_len); fflush(stdout); } } From df100259dc65317740b03d061b31878bcc23b0dc Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 10:32:25 +0200 Subject: [PATCH 199/249] Remove unecessary `#ifndef ARDUINO` guards --- src/Debug/debugger.cpp | 8 -------- src/Debug/debugger.h | 4 ---- src/RFC/proxy_supervisor.cpp | 7 ++++--- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 45cdbd20..da8a1b65 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -232,13 +232,11 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { this->handleProxyCall(m, program_state, interruptData + 1); free(interruptData); } break; -#ifndef ARDUINO case interruptMonitorProxies: { printf("receiving functions list to proxy\n"); this->handleMonitorProxies(m, interruptData + 1); free(interruptData); } break; -#endif case interruptProxify: { dbg_info("Converting to proxy settings.\n"); *program_state = PROXYhalt; @@ -257,11 +255,9 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { case interruptPOPEvent: CallbackHandler::resolve_event(true); break; -#ifndef ARDUINO case interruptPUSHEvent: this->handlePushedEvent(reinterpret_cast(interruptData)); break; -#endif case interruptRecvCallbackmapping: Debugger::updateCallbackmapping( m, reinterpret_cast(interruptData + 2)); @@ -580,7 +576,6 @@ bool Debugger::handleChangedLocal(Module *m, uint8_t *bytes) const { return true; } -#ifndef ARDUINO void Debugger::notifyPushedEvent() const { this->channel->write("new pushed event"); } @@ -594,7 +589,6 @@ bool Debugger::handlePushedEvent(char *bytes) const { this->notifyPushedEvent(); return true; } -#endif void Debugger::woodDump(Module *m) { debug("asked for doDump\n"); @@ -996,7 +990,6 @@ bool Debugger::isProxied(uint32_t fidx) const { return this->supervisor != nullptr && this->supervisor->isProxied(fidx); } -#ifndef ARDUINO void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { uint32_t amount_funcs = read_B32(&interruptData); printf("funcs_total %" PRIu32 "\n", amount_funcs); @@ -1034,7 +1027,6 @@ void Debugger::disconnect_proxy() { pthread_mutex_unlock(&this->supervisor_mutex); pthread_join(this->supervisor->getThreadID(), (void **)&ptr); } -#endif void Debugger::updateCallbackmapping(Module *m, const char *data) { nlohmann::basic_json<> parsed = nlohmann::json::parse(data); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 848bd844..b29a6511 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -77,10 +77,8 @@ class Debugger { Proxy *proxy = nullptr; // proxy module for debugger -#ifndef ARDUINO bool connected_to_proxy = false; pthread_mutex_t supervisor_mutex; -#endif // Private methods @@ -174,7 +172,6 @@ class Debugger { bool isProxied(uint32_t fidx) const; -#ifndef ARDUINO void startProxySupervisor(const char *proxy); bool proxy_connected() const; @@ -190,5 +187,4 @@ class Debugger { void notifyPushedEvent() const; bool handlePushedEvent(char *bytes) const; -#endif }; diff --git a/src/RFC/proxy_supervisor.cpp b/src/RFC/proxy_supervisor.cpp index baed1101..ce888eab 100644 --- a/src/RFC/proxy_supervisor.cpp +++ b/src/RFC/proxy_supervisor.cpp @@ -1,4 +1,3 @@ -#ifndef ARDUINO #include "proxy_supervisor.h" #include @@ -8,7 +7,11 @@ #include #include #include +#ifndef ARDUINO #include +#else +#include "../../lib/json/single_include/nlohmann/json.hpp" +#endif #include "../Utils/macros.h" #include "../Utils/util.h" @@ -277,5 +280,3 @@ void ProxySupervisor::unregisterAllProxiedCalls() { this->proxied->clear(); } bool ProxySupervisor::isProxied(uint32_t fidx) { return this->proxied->count(fidx) > 0; } - -#endif From 62130c81948df476b61a96c068bfa2d729d0548a Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 10:35:36 +0200 Subject: [PATCH 200/249] Remove breaking import --- platforms/ESP-IDF/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/ESP-IDF/main.cpp b/platforms/ESP-IDF/main.cpp index 81544f1c..32033694 100644 --- a/platforms/ESP-IDF/main.cpp +++ b/platforms/ESP-IDF/main.cpp @@ -9,7 +9,7 @@ #include "driver/uart.h" #include "esp_err.h" #include "esp_task_wdt.h" -#include "esp_vfs_dev.h" +//#include "esp_vfs_dev.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "sdkconfig.h" From 124661df917d548f6f7ee5491fa2bbd3342a59ba Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 10:40:28 +0200 Subject: [PATCH 201/249] Remove unused variables --- src/Debug/debugger.cpp | 8 ++++---- src/Debug/debugger.h | 4 ++-- src/Primitives/arduino.cpp | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 567fb78a..2bcf9f06 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -269,7 +269,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; #ifndef ARDUINO case interruptPUSHEvent: - this->handlePushedEvent(m, reinterpret_cast(interruptData)); + this->handlePushedEvent(reinterpret_cast(interruptData)); break; #endif case interruptRecvCallbackmapping: @@ -367,7 +367,7 @@ void Debugger::dump(Module *m, bool full) const { // start of bytes dprintf(this->socket, R"("start":["%p"],)", (void *)m->bytes); - this->dumpBreakpoints(m); + this->dumpBreakpoints(); this->dumpFunctions(m); @@ -384,7 +384,7 @@ void Debugger::dump(Module *m, bool full) const { // fflush(stdout); } -void Debugger::dumpBreakpoints(Module *m) const { +void Debugger::dumpBreakpoints() const { dprintf(this->socket, "\"breakpoints\":["); { size_t i = 0; @@ -596,7 +596,7 @@ void Debugger::notifyPushedEvent() const { dprintf(this->socket, "new pushed event"); } -bool Debugger::handlePushedEvent(Module *m, char *bytes) const { +bool Debugger::handlePushedEvent(char *bytes) const { if (*bytes != interruptPUSHEvent) return false; auto parsed = nlohmann::json::parse(bytes); printf("handle pushed event: %s", bytes); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 3bec1f3c..95ad2e71 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -95,7 +95,7 @@ class Debugger { void dumpLocals(Module *m) const; - void dumpBreakpoints(Module *m) const; + void dumpBreakpoints() const; void dumpFunctions(Module *m) const; @@ -175,6 +175,6 @@ class Debugger { void notifyPushedEvent() const; #endif - bool handlePushedEvent(Module *m, char *bytes) const; + bool handlePushedEvent(char *bytes) const; #endif }; diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index 67d86d0a..59af2eaf 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -307,7 +307,6 @@ def_prim(wifi_connected, NoneToOneU32) { def_prim(wifi_localip, twoToOneU32) { uint32_t buff = arg1.uint32; - uint32_t size = arg0.uint32; IPAddress ip = WiFi.localIP(); String ipString = String(ip[0]); From 128b10087fcddb846ba3b601a894db3b55595374 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 11:46:12 +0200 Subject: [PATCH 202/249] Fix dump_callbacks --- src/Primitives/emulated.cpp | 21 ++++++++++++++++++++- src/WARDuino/CallbackHandler.cpp | 13 +++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index f89534b9..55c34abd 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -225,6 +225,14 @@ def_prim(abort, NoneToNoneU32) { return false; } +def_prim(millis, NoneToOneU64) { + struct timeval tv {}; + gettimeofday(&tv, nullptr); + unsigned long millis = 1000 * tv.tv_sec + tv.tv_usec; + pushUInt64(millis); + return true; +} + def_prim(micros, NoneToOneU64) { struct timeval tv {}; gettimeofday(&tv, nullptr); @@ -430,6 +438,11 @@ def_prim(subscribe_interrupt, threeToNoneU32) { uint8_t mode = arg0.uint32; debug("EMU: subscribe_interrupt(%u, %u, %u) \n", pin, fidx, mode); + std::string topic = "interrupt"; + topic.append(std::to_string(pin)); + + Callback c = Callback(m, topic, fidx); + CallbackHandler::add_callback(c); pop_args(3); return true; } @@ -468,25 +481,31 @@ void install_primitives() { dbg_info("INSTALLING PRIMITIVES\n"); dbg_info("INSTALLING FAKE ARDUINO\n"); install_primitive(abort); + install_primitive(millis); install_primitive(micros); - install_primitive(test); + install_primitive(print_int); install_primitive(print_string); + install_primitive(wifi_connect); install_primitive(wifi_status); install_primitive(wifi_connected); install_primitive(wifi_localip); + install_primitive(http_get); install_primitive(http_post); + install_primitive(chip_pin_mode); install_primitive(chip_digital_write); install_primitive(chip_delay); install_primitive(chip_digital_read); install_primitive(chip_analog_read); install_primitive(chip_delay_us); + install_primitive(spi_begin); install_primitive(write_spi_byte); install_primitive(write_spi_bytes_16); + install_primitive(subscribe_interrupt); install_primitive(init_pixels); diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 015dfad5..5551dd38 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -171,16 +171,13 @@ std::string CallbackHandler::dump_callbacks() { auto iterator = CallbackHandler::callbacks->begin(); while (iterator != CallbackHandler::callbacks->end()) { repr += R"({")" + iterator->first + R"(": [)"; - for (const auto &value : *iterator->second) { - auto callback = std::begin(*iterator->second); - while (callback != std::end(*iterator->second)) { - repr += std::to_string(callback->table_index); - repr += (++callback != iterator->second->end()) ? ", " : ""; - } + auto callback = std::begin(*iterator->second); + while (callback != std::end(*iterator->second)) { + repr += std::to_string(callback->table_index); + repr += (++callback != iterator->second->end()) ? ", " : ""; } - iterator++; repr += "]}"; - repr += (iterator != CallbackHandler::callbacks->end()) ? ", " : ""; + repr += (++iterator != CallbackHandler::callbacks->end()) ? ", " : ""; } repr += "]}"; return repr; From 13b0a439c981c0ee07418a18bdeb0d2db575583a Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 1 Aug 2022 12:57:07 +0200 Subject: [PATCH 203/249] Fix nullptr exception on ESP --- src/Debug/debugger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index b29a6511..c073e4f9 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -130,7 +130,7 @@ class Debugger { public: // Public fields Channel *channel; - ProxySupervisor *supervisor; + ProxySupervisor *supervisor = nullptr; std::set breakpoints = {}; // Vector, we expect few breakpoints uint8_t *skipBreakpoint = From 17b116732f3b0f95ad884ce34befaf0e860ac678 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 2 Aug 2022 10:10:53 +0200 Subject: [PATCH 204/249] Update main --- platforms/CLI-Emulator/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 1610db30..0f04ea91 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -32,7 +32,7 @@ } void print_help() { - fprintf(stdout, "WARDuino WebAssembly Runtime - 0.1.1\n\n"); + fprintf(stdout, "WARDuino WebAssembly Runtime - 0.2.1\n\n"); fprintf(stdout, "Usage:\n"); fprintf(stdout, " warduino [options] \n"); fprintf(stdout, "Options:\n"); @@ -120,7 +120,7 @@ void startDebuggerSocket(WARDuino *wac, Module *m, int port = 8192) { startListening(socket_fd); printf("Listening on port 172.0.0.1:%i\n", port); - int valread; + ssize_t valread; uint8_t buffer[1024] = {0}; while (true) { int socket = listenForIncomingConnection(socket_fd, address); From e34f2c8382e07cf0a91023bb34c29129fb6abbd6 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 2 Aug 2022 11:03:46 +0200 Subject: [PATCH 205/249] Connect to proxy via local socket --- platforms/CLI-Emulator/main.cpp | 33 ++++++++++++++++++++++++++++++-- src/Debug/debugger.cpp | 12 ++++++++++-- src/Debug/debugger.h | 4 +++- src/Interpreter/instructions.cpp | 1 - 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 0f04ea91..371d02ec 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -1,6 +1,7 @@ // // WARDuino - WebAssembly interpreter for embedded devices. // +#include #include #include #include @@ -133,6 +134,33 @@ void startDebuggerSocket(WARDuino *wac, Module *m, int port = 8192) { } } +int connect_to_proxy(int proxy) { + int sock = 0; + struct sockaddr_in address = createAddress(proxy); + const char hostname[] = "localhost"; + struct hostent *resolvedhost = gethostbyname(hostname); + /* resolve hostname */ + if (resolvedhost == nullptr) { + return -1; /* error */ + } + + /* copy the network address to sockaddr_in structure */ + memcpy(&address.sin_addr, resolvedhost->h_addr_list[0], + resolvedhost->h_length); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("\n Socket creation error \n"); + return -1; + } + + if (connect(sock, (struct sockaddr *)&address, sizeof(address)) < 0) { + printf("\nConnection Failed \n"); + return -1; + } + + return sock; +} + WARDuino *wac = WARDuino::instance(); Module *m; @@ -218,7 +246,8 @@ int main(int argc, const char *argv[]) { // Connect to proxy device if (proxy) { - wac->debugger->startProxySupervisor(proxy); + int socket = connect_to_proxy(std::stoi(proxy)); + wac->debugger->startProxySupervisor(socket); } // Start debugger @@ -232,4 +261,4 @@ int main(int argc, const char *argv[]) { } return 0; -} +} \ No newline at end of file diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index da8a1b65..080b6499 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -1004,13 +1004,21 @@ void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { this->channel->write("done!\n"); } -void Debugger::startProxySupervisor(const char *proxy) { +void Debugger::connectToFdProxy(const char *proxyfd) { this->connected_to_proxy = true; pthread_mutex_init(&this->supervisor_mutex, nullptr); pthread_mutex_lock(&this->supervisor_mutex); - FILE *serial = fopen(proxy, "rw+"); + FILE *serial = fopen(proxyfd, "rw+"); int proxy_address = fileno(serial); + this->startProxySupervisor(proxy_address); +} + +void Debugger::startProxySupervisor(int proxy_address) { + this->connected_to_proxy = true; + pthread_mutex_init(&this->supervisor_mutex, nullptr); + pthread_mutex_lock(&this->supervisor_mutex); + this->supervisor = new ProxySupervisor(proxy_address, &this->supervisor_mutex); printf("Connected to proxy.\n"); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index c073e4f9..791e6820 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -172,7 +172,9 @@ class Debugger { bool isProxied(uint32_t fidx) const; - void startProxySupervisor(const char *proxy); + void connectToFdProxy(const char *proxy); + + void startProxySupervisor(int socket); bool proxy_connected() const; diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index eec40db0..d8f511eb 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -4,7 +4,6 @@ #include #include "../Memory/mem.h" -#include "../RFC/proxy.h" #include "../Utils/macros.h" #include "../Utils/util.h" #include "../Utils/util_arduino.h" From a0f03ab605269c1b3440ea936d70a57c667625f8 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 2 Aug 2022 12:05:24 +0200 Subject: [PATCH 206/249] Move connection code to main --- platforms/CLI-Emulator/main.cpp | 40 +++++++++++++++------------------ src/Debug/debugger.cpp | 14 ++---------- src/Debug/debugger.h | 2 -- src/Utils/sockets.cpp | 11 +++++++++ src/Utils/sockets.h | 2 ++ 5 files changed, 33 insertions(+), 36 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 371d02ec..25e58bfd 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -1,7 +1,6 @@ // // WARDuino - WebAssembly interpreter for embedded devices. // -#include #include #include #include @@ -56,7 +55,7 @@ void print_help() { "(default: 8192)\n"); fprintf(stdout, " --paused Pause program on entry (default: false)\n"); - fprintf(stdout, " --proxy Connect to proxy device\n"); + fprintf(stdout, " --proxy Port of proxy to connect to\n"); } Module *load(WARDuino wac, const char *file_name, Options opt) { @@ -134,31 +133,28 @@ void startDebuggerSocket(WARDuino *wac, Module *m, int port = 8192) { } } -int connect_to_proxy(int proxy) { - int sock = 0; - struct sockaddr_in address = createAddress(proxy); - const char hostname[] = "localhost"; - struct hostent *resolvedhost = gethostbyname(hostname); - /* resolve hostname */ - if (resolvedhost == nullptr) { - return -1; /* error */ - } - - /* copy the network address to sockaddr_in structure */ - memcpy(&address.sin_addr, resolvedhost->h_addr_list[0], - resolvedhost->h_length); +// Connect to proxy via a web socket +int connectToProxySocket(int proxy) { + int channel; + struct sockaddr_in address = createLocalhostAddress(proxy); - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - printf("\n Socket creation error \n"); + if ((channel = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + dbg_info("Socket creation error\n"); return -1; } - if (connect(sock, (struct sockaddr *)&address, sizeof(address)) < 0) { - printf("\nConnection Failed \n"); + if (connect(channel, (struct sockaddr *)&address, sizeof(address)) < 0) { + dbg_info("Connection failed\n"); return -1; } - return sock; + return channel; +} + +// Connect to proxy via file descriptor +int connectToProxyFd(const char *proxyfd) { + FILE *serial = fopen(proxyfd, "rw+"); + return fileno(serial); } WARDuino *wac = WARDuino::instance(); @@ -246,8 +242,8 @@ int main(int argc, const char *argv[]) { // Connect to proxy device if (proxy) { - int socket = connect_to_proxy(std::stoi(proxy)); - wac->debugger->startProxySupervisor(socket); + int connection = connectToProxySocket(std::stoi(proxy)); + wac->debugger->startProxySupervisor(connection); } // Start debugger diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 080b6499..ae35db79 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -1004,23 +1004,13 @@ void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { this->channel->write("done!\n"); } -void Debugger::connectToFdProxy(const char *proxyfd) { - this->connected_to_proxy = true; - pthread_mutex_init(&this->supervisor_mutex, nullptr); - pthread_mutex_lock(&this->supervisor_mutex); - - FILE *serial = fopen(proxyfd, "rw+"); - int proxy_address = fileno(serial); - this->startProxySupervisor(proxy_address); -} - -void Debugger::startProxySupervisor(int proxy_address) { +void Debugger::startProxySupervisor(int socket) { this->connected_to_proxy = true; pthread_mutex_init(&this->supervisor_mutex, nullptr); pthread_mutex_lock(&this->supervisor_mutex); this->supervisor = - new ProxySupervisor(proxy_address, &this->supervisor_mutex); + new ProxySupervisor(socket, &this->supervisor_mutex); printf("Connected to proxy.\n"); } diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 791e6820..b9198e61 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -172,8 +172,6 @@ class Debugger { bool isProxied(uint32_t fidx) const; - void connectToFdProxy(const char *proxy); - void startProxySupervisor(int socket); bool proxy_connected() const; diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index 070ff524..4b1e8c8e 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -1,5 +1,6 @@ #include "sockets.h" +#include #include #include #include @@ -7,6 +8,7 @@ #include #include #include +#include // Socket Debugger Interface void setFileDescriptorOptions(int socket_fd) { @@ -42,6 +44,15 @@ struct sockaddr_in createAddress(int port) { return address; } +struct sockaddr_in createLocalhostAddress(int port) { + struct sockaddr_in address = createAddress(port); + const char hostname[] = "localhost"; + struct hostent *resolvedhost = gethostbyname(hostname); + memcpy(&address.sin_addr, resolvedhost->h_addr_list[0], + resolvedhost->h_length); + return address; +} + void startListening(int socket_fd) { if (listen(socket_fd, 1) < 0) { perror("listen"); diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h index 4e6ada10..b0d6fa21 100644 --- a/src/Utils/sockets.h +++ b/src/Utils/sockets.h @@ -9,6 +9,8 @@ void bindSocketToAddress(int socket_fd, struct sockaddr_in address); struct sockaddr_in createAddress(int port); +struct sockaddr_in createLocalhostAddress(int port); + void startListening(int socket_fd); int listenForIncomingConnection(int socket_fd, struct sockaddr_in address); From 2742ad6fd7b1c94a88ca181868c7499696f1e645 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 2 Aug 2022 13:47:46 +0200 Subject: [PATCH 207/249] Move RFC to Edward --- CMakeLists.txt | 6 +++--- platforms/CLI-Emulator/main.cpp | 2 +- platforms/ESP-IDF/CMakeLists.txt | 6 +++--- src/Debug/debugger.cpp | 7 +++---- src/Debug/debugger.h | 4 ++-- src/{RFC => Edward}/RFC.cpp | 0 src/{RFC => Edward}/RFC.h | 0 src/{RFC => Edward}/proxy.cpp | 0 src/{RFC => Edward}/proxy.h | 0 src/{RFC => Edward}/proxy_supervisor.cpp | 0 src/{RFC => Edward}/proxy_supervisor.h | 0 src/WARDuino.h | 2 +- 12 files changed, 13 insertions(+), 14 deletions(-) rename src/{RFC => Edward}/RFC.cpp (100%) rename src/{RFC => Edward}/RFC.h (100%) rename src/{RFC => Edward}/proxy.cpp (100%) rename src/{RFC => Edward}/proxy.h (100%) rename src/{RFC => Edward}/proxy_supervisor.cpp (100%) rename src/{RFC => Edward}/proxy_supervisor.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73e013b8..09efe83d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,9 +40,9 @@ if (BUILD_EMULATOR) src/Utils/macros.cpp src/Utils/sockets.cpp src/Debug/debugger.cpp - src/RFC/proxy.cpp - src/RFC/proxy_supervisor.cpp - src/RFC/RFC.cpp) + src/Edward/proxy.cpp + src/Edward/proxy_supervisor.cpp + src/Edward/RFC.cpp) set(TEST_FRAMEWORK tests/integration/wasm_tests.cpp diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 25e58bfd..66378eb4 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -51,7 +51,7 @@ void print_help() { " --no-socket Run without socket " "(default: false)\n"); fprintf(stdout, - " --socket Run without socket " + " --socket The port number to attach the socket on" "(default: 8192)\n"); fprintf(stdout, " --paused Pause program on entry (default: false)\n"); diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt index d34a45fb..335bdc5c 100644 --- a/platforms/ESP-IDF/CMakeLists.txt +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -3,9 +3,9 @@ set(SOURCE_FILES ../../src/Interpreter/instructions.cpp ../../src/Memory/mem.cpp ../../src/Primitives/idf.cpp - ../../src/RFC/proxy.cpp - ../../src/RFC/proxy_supervisor.cpp - ../../src/RFC/RFC.cpp + ../../src/Edward/proxy.cpp + ../../src/Edward/proxy_supervisor.cpp + ../../src/Edward/RFC.cpp ../../src/Utils/macros.cpp ../../src/Utils/sockets.cpp ../../src/Utils/util.cpp diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index ae35db79..62002c93 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -9,9 +9,9 @@ #include "../../lib/json/single_include/nlohmann/json.hpp" #endif +#include "../Edward/proxy.h" +#include "../Edward/proxy_supervisor.h" #include "../Memory/mem.h" -#include "../RFC/proxy.h" -#include "../RFC/proxy_supervisor.h" #include "../Utils//util.h" #include "../Utils/macros.h" @@ -1009,8 +1009,7 @@ void Debugger::startProxySupervisor(int socket) { pthread_mutex_init(&this->supervisor_mutex, nullptr); pthread_mutex_lock(&this->supervisor_mutex); - this->supervisor = - new ProxySupervisor(socket, &this->supervisor_mutex); + this->supervisor = new ProxySupervisor(socket, &this->supervisor_mutex); printf("Connected to proxy.\n"); } diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index b9198e61..39362669 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -7,8 +7,8 @@ #include #include -#include "../RFC/proxy.h" -#include "../RFC/proxy_supervisor.h" +#include "../Edward/proxy.h" +#include "../Edward/proxy_supervisor.h" #include "../Utils/sockets.h" #ifndef ARDUINO diff --git a/src/RFC/RFC.cpp b/src/Edward/RFC.cpp similarity index 100% rename from src/RFC/RFC.cpp rename to src/Edward/RFC.cpp diff --git a/src/RFC/RFC.h b/src/Edward/RFC.h similarity index 100% rename from src/RFC/RFC.h rename to src/Edward/RFC.h diff --git a/src/RFC/proxy.cpp b/src/Edward/proxy.cpp similarity index 100% rename from src/RFC/proxy.cpp rename to src/Edward/proxy.cpp diff --git a/src/RFC/proxy.h b/src/Edward/proxy.h similarity index 100% rename from src/RFC/proxy.h rename to src/Edward/proxy.h diff --git a/src/RFC/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp similarity index 100% rename from src/RFC/proxy_supervisor.cpp rename to src/Edward/proxy_supervisor.cpp diff --git a/src/RFC/proxy_supervisor.h b/src/Edward/proxy_supervisor.h similarity index 100% rename from src/RFC/proxy_supervisor.h rename to src/Edward/proxy_supervisor.h diff --git a/src/WARDuino.h b/src/WARDuino.h index ea616c81..4744bdce 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -9,7 +9,7 @@ #include #include "Debug/debugger.h" -#include "RFC/proxy_supervisor.h" +#include "Edward/proxy_supervisor.h" #include "WARDuino/CallbackHandler.h" // Constants From 4dfb65f5df8e7f80fa32c51aec577acff21ab205 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 2 Aug 2022 15:00:52 +0200 Subject: [PATCH 208/249] Add `--mode` to cli --- platforms/CLI-Emulator/main.cpp | 24 ++++++++++++++++++------ src/Debug/debugger.cpp | 8 ++++++-- src/Debug/debugger.h | 2 ++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 66378eb4..c742a64d 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -55,7 +55,12 @@ void print_help() { "(default: 8192)\n"); fprintf(stdout, " --paused Pause program on entry (default: false)\n"); - fprintf(stdout, " --proxy Port of proxy to connect to\n"); + fprintf(stdout, + " --proxy Port of proxy to connect to (ignored if mode " + "is 'proxy')\n"); + fprintf(stdout, + " --mode The mode to run in: interpreter, proxy " + "(default: interpreter)\n"); } Module *load(WARDuino wac, const char *file_name, Options opt) { @@ -177,6 +182,7 @@ int main(int argc, const char *argv[]) { bool paused = false; const char *file_name = nullptr; const char *proxy = nullptr; + const char *mode = "interpreter"; const char *asserts_file = nullptr; const char *watcompiler = "wat2wasm"; @@ -209,6 +215,8 @@ int main(int argc, const char *argv[]) { wac->program_state = WARDUINOpause; } else if (!strcmp("--proxy", arg)) { ARGV_GET(proxy); // /dev/ttyUSB0 + } else if (!strcmp("--mode", arg)) { + ARGV_GET(mode); } } @@ -236,16 +244,20 @@ int main(int argc, const char *argv[]) { if (m) { m->warduino = wac; - // Run Wasm module - pthread_t id; - pthread_create(&id, nullptr, runWAC, nullptr); - + // Run in proxy mode + if (strcmp(mode, "proxy") == 0) { + wac->debugger->proxify(); + } // Connect to proxy device - if (proxy) { + else if (proxy) { int connection = connectToProxySocket(std::stoi(proxy)); wac->debugger->startProxySupervisor(connection); } + // Run Wasm module + pthread_t id; + pthread_create(&id, nullptr, runWAC, nullptr); + // Start debugger if (no_socket) { startDebuggerStd(wac, m); diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 62002c93..0662e936 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -239,8 +239,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { } break; case interruptProxify: { dbg_info("Converting to proxy settings.\n"); - *program_state = PROXYhalt; - this->proxy = new Proxy(); // TODO delete + this->proxify(); break; } case interruptDUMPAllEvents: @@ -950,6 +949,11 @@ uintptr_t Debugger::readPointer(uint8_t **data) { return bp; } +void Debugger::proxify() { + WARDuino::instance()->program_state = PROXYhalt; + this->proxy = new Proxy(); // TODO delete +} + void Debugger::handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData) { if (this->proxy == nullptr) { diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 39362669..af7fa3c3 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -163,6 +163,8 @@ class Debugger { void woodDump(Module *m); + void proxify(); + void handleProxyCall(Module *m, RunningState *program_state, uint8_t *interruptData); From e2a4c05bc792b8633d19bc4a27fb104f910220d4 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 2 Sep 2022 15:55:38 +0200 Subject: [PATCH 209/249] Fix: remove unnecessary writes to stdout from Arduino.ino fixes bug with unxepected json token in plugin --- platforms/Arduino/Arduino.ino | 4 ---- 1 file changed, 4 deletions(-) diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index 385287ad..86e93664 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -36,11 +36,7 @@ void startDebuggerStd(void* pvParameter) { } if (buff_len) { buffer[buff_len] = '\0'; - write(fileno(stdout), "Reading message ..... \n", 19); - fflush(stdout); wac->handleInterrupt(buff_len, buffer); - write(fileno(stdout), buffer, buff_len); - fflush(stdout); } } } From 868d628794d0da49d6f4490c2f079ff3ccd49a91 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Fri, 9 Sep 2022 16:36:53 +0200 Subject: [PATCH 210/249] Fix ESP-IDF compilation error use PRIu32, PRIx32, PRId32 from for formatting Co-authored-by: tolauwae --- src/Edward/proxy.cpp | 10 ++++++---- src/Edward/proxy_supervisor.cpp | 2 +- src/Interpreter/instructions.cpp | 7 ++++--- src/WARDuino/WARDuino.cpp | 20 ++++++++++++-------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Edward/proxy.cpp b/src/Edward/proxy.cpp index e15d1f8d..6468a337 100644 --- a/src/Edward/proxy.cpp +++ b/src/Edward/proxy.cpp @@ -104,27 +104,29 @@ StackValue *Proxy::readRFCArgs(Block *func, uint8_t *data) { case I32: { memcpy(&args[i].value.uint32, data, sizeof(uint32_t)); data += sizeof(uint32_t); - printf("arg %d: i32 value %" PRIu32 "\n", i, + printf("arg %" PRIu32 ": i32 value %" PRIu32 "\n", i, args[i].value.uint32); break; } case F32: { memcpy(&args[i].value.f32, data, sizeof(float)); data += sizeof(float); - printf("arg %d: F32 value %.7f \n", i, args[i].value.f32); + printf("arg %" PRIu32 ": F32 value %.7f \n", i, + args[i].value.f32); break; } case I64: { memcpy(&args[i].value.uint64, data, sizeof(uint64_t)); data += sizeof(uint64_t); - printf("arg %d: I64 value %" PRIu64 "\n", i, + printf("arg %" PRIu32 ": I64 value %" PRIu64 "\n", i, args[i].value.uint64); break; } case F64: { memcpy(&args[i].value.f64, data, sizeof(double)); data += sizeof(double); - printf("arg %d: f64 value %.7f \n", i, args[i].value.f64); + printf("arg %" PRIu32 ": f64 value %.7f \n", i, + args[i].value.f64); break; } default: { diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index ce888eab..9a3a90cf 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -81,7 +81,7 @@ void ProxySupervisor::startPushDebuggerSocket() { free(buffer); buffer = new_buff; current_size += start_size; - printf("increasing PushClient's buffer size to %d\n", + printf("increasing PushClient's buffer size to %" PRId32 "\n", current_size); } buffer[buf_idx++] = _char; diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index d8f511eb..d5f085cd 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -332,7 +332,7 @@ bool i_instr_br_table(Module *m) { uint32_t count = read_LEB_32(&m->pc_ptr); if (count > BR_TABLE_SIZE) { // TODO: check this prior to runtime - sprintf(exception, "br_table size %d exceeds max %d\n", count, + sprintf(exception, "br_table size %" PRIu32 " exceeds max %d\n", count, BR_TABLE_SIZE); return false; } @@ -416,8 +416,9 @@ bool i_instr_call_indirect(Module *m) { val = val - (uint32_t)((uint64_t)m->table.entries); } if (val >= m->table.maximum) { - sprintf(exception, "undefined element 0x%x (max: 0x%x) in table", val, - m->table.maximum); + sprintf(exception, + "undefined element 0x%" PRIx32 " (max: 0x%" PRIx32 ") in table", + val, m->table.maximum); return false; } diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index 73d3259f..09e2871a 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -324,9 +324,9 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, uint8_t *pos = bytes; word = read_uint32(&pos); debug("Magic number is 0x%x\n", word); - ASSERT(word == WA_MAGIC, "Wrong module magic 0x%x\n", word); + ASSERT(word == WA_MAGIC, "Wrong module magic 0x%" PRIx32 "\n", word); word = read_uint32(&pos); - ASSERT(word == WA_VERSION, "Wrong module version 0x%x\n", word); + ASSERT(word == WA_VERSION, "Wrong module version 0x%" PRIx32 "\n", word); // Read the sections uint8_t *bytes_end = bytes + byte_count; @@ -366,7 +366,8 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, Type *type = &m->types[c]; type->form = read_LEB(&pos, 7); ASSERT(type->form == FUNC, - "%u-th type def was not a function type", c); + "%" PRIu32 " -th type def was not a function type", + c); // read vector params type->param_count = read_LEB_32(&pos); @@ -719,8 +720,9 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, m->table.entries, offset); if (!m->options.disable_memory_bounds) { ASSERT(offset + num_elem <= m->table.size, - "table overflow %d+%d > %d\n", offset, num_elem, - m->table.size); + "table overflow %" PRIu32 "+%" PRIu32 + " > %" PRIu32 "\n", + offset, num_elem, m->table.size); } for (uint32_t n = 0; n < num_elem; n++) { debug( @@ -752,7 +754,9 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, uint32_t size = read_LEB_32(&pos); if (!m->options.disable_memory_bounds) { ASSERT(offset + size <= m->memory.pages * PAGE_SIZE, - "memory overflow %d+%d > %d\n", offset, size, + "memory overflow %" PRIu32 "+%" PRIu32 + " > %" PRIu32 "\n", + offset, size, (uint32_t)(m->memory.pages * PAGE_SIZE)); } dbg_info( @@ -816,7 +820,7 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, break; } default: - FATAL("Section %d unimplemented\n", id); + FATAL("Section %" PRIu32 " unimplemented\n", id); pos += section_len; } } @@ -834,7 +838,7 @@ Module *WARDuino::load_module(uint8_t *bytes, uint32_t byte_count, // dbg_dump_stack(m); ASSERT(m->functions[fidx].type->result_count == 0, - "start function 0x%x must not have arguments!", fidx); + "start function 0x%" PRIx32 " must not have arguments!", fidx); if (fidx < m->import_count) { // THUNK thunk_out(m, fidx); // import/thunk call From 2114dd103d711536b62458956521f28c2da39829 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 5 Sep 2022 17:37:42 +0200 Subject: [PATCH 211/249] Fix Arduino subscribe interrupt with macros Warning: new version only supports 1 function per pin. --- src/Primitives/arduino.cpp | 156 ++++++++++++++++++++++--------- src/Primitives/emulated.cpp | 2 +- src/WARDuino/CallbackHandler.cpp | 3 +- src/WARDuino/CallbackHandler.h | 2 +- 4 files changed, 114 insertions(+), 49 deletions(-) diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index 2d3dad56..ee7c75d0 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -35,7 +35,7 @@ Adafruit_NeoPixel pixels = #include SPIClass *spi = new SPIClass(); -// Hardeware SPI +// Hardware SPI void write_spi_byte(unsigned char c) { spi->beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0)); spi->transfer(c); @@ -52,6 +52,78 @@ void write_spi_bytes_16_prim(int times, uint32_t color) { spi->endTransaction(); } +// Hardware Interrupts + +#define ALL_ISRS 25 // number of installed ISRs + +typedef struct ISREntry { + int pin; + void (*ISR_callback)(); +} ISREntry; + +ISREntry ISRs[ALL_ISRS]; +int isr_index = 0; + +/* Private macro to install an ISR */ +#define install_isr(number) \ + { \ + dbg_info("installing isr number: %d of %d with name: %s\n", \ + isr_index + 1, ALL_ISRS, isr_##number); \ + if (isr_index < ALL_ISRS) { \ + ISREntry *p = &ISRs[isr_index]; \ + p->pin = number; \ + p->ISR_callback = &(isr_##number); \ + } else { \ + FATAL("isr_index out of bounds"); \ + } \ + } + +/* Private macro to create an ISR for a specific pin*/ +#define def_isr(pin) \ + void isr_##pin() { CallbackHandler::push_event("interrupt_##pin", "", 0); } + +/* Common GPIO pins on ESP32 devices:*/ +def_isr(1); +def_isr(2); +def_isr(3); +def_isr(4); +def_isr(5); +def_isr(12); +def_isr(13); +def_isr(14); +def_isr(15); +def_isr(16); +def_isr(17); +def_isr(18); +def_isr(19); +def_isr(21); +def_isr(22); +def_isr(23); +def_isr(25); +def_isr(26); +def_isr(27); +def_isr(32); +def_isr(33); +def_isr(34); +def_isr(35); +def_isr(36); +def_isr(39); + +int resolve_isr(int pin) { + debug("Resolve ISR (%d) for %s \n", ALL_ISRS, pin); + + for (int i = 0; i < ALL_ISRS; i++) { + auto &isr = ISRs[i]; + if (pin == isr.pin) { + debug("FOUND ISR\n"); + return i; + } + } + return -1; +} + +// Primitives + #define NUM_PRIMITIVES 0 #define NUM_PRIMITIVES_ARDUINO 37 @@ -60,8 +132,6 @@ void write_spi_bytes_16_prim(int times, uint32_t color) { // Global index for installing primitives int prim_index = 0; -double sensor_emu = 0; - /* Private macros to install a primitive */ @@ -526,45 +596,20 @@ def_prim(chip_ledc_attach_pin, twoToNoneU32) { // INTERRUPTS -class Interrupt { - public: - void setup(uint8_t pin, void (*ISR_callback)(void), uint8_t mode) { - this->pin = pin; - this->mode = mode; - Serial.print("Attaching to "); - Serial.print(pin); - Serial.println(""); - attachInterrupt(digitalPinToInterrupt(pin), ISR_callback, mode); - } - - void handleInterrupt(); - uint8_t pin; - - private: - uint8_t mode; - void (*ISR_callback)(); -}; - -void Interrupt::handleInterrupt() { - String topic = "interrupt"; - topic += String(pin); - auto *empty = reinterpret_cast(""); - CallbackHandler::push_event(topic.c_str(), empty, 0); -} - -std::vector handlers; - def_prim(subscribe_interrupt, threeToNoneU32) { uint8_t pin = arg2.uint32; // GPIOPin uint8_t fidx = arg1.uint32; // Callback function uint8_t mode = arg0.uint32; - Interrupt *handler = new Interrupt(); - handlers.push_back(handler); - handler->setup( - pin, [] { handlers.back()->handleInterrupt(); }, mode); + int index = resolve_isr(pin); + if (index < 0) { + dbg_info("subscribe_interrupt: no ISR found for pin %i", pin); + return false; + } + + attachInterrupt(digitalPinToInterrupt(pin), ISRs[index].ISR_callback, mode); - String callback_id = "interrupt"; + String callback_id = "interrupt_"; callback_id += String(pin); Callback c = Callback(m, callback_id.c_str(), fidx); CallbackHandler::add_callback(c); @@ -576,14 +621,7 @@ def_prim(subscribe_interrupt, threeToNoneU32) { def_prim(unsubscribe_interrupt, oneToNoneU32) { uint8_t pin = arg0.uint32; - auto it = std::remove_if( - handlers.begin(), handlers.end(), - [pin](Interrupt *handler) { return handler->pin == pin; }); - - if (it != handlers.end()) { - handlers.erase(it, handlers.end()); - detachInterrupt(digitalPinToInterrupt(pin)); - } + detachInterrupt(digitalPinToInterrupt(pin)); pop_args(1); return true; @@ -607,7 +645,7 @@ def_prim(mqtt_init, threeToNoneU32) { mqttClient.setServer(server, port); mqttClient.setCallback([](const char *topic, const unsigned char *payload, unsigned int length) { - CallbackHandler::push_event(topic, payload, length); + CallbackHandler::push_event(topic, (const char *)payload, length); }); #if DEBUG @@ -902,6 +940,34 @@ void install_primitives() { install_primitive(chip_ledc_attach_pin); } +void install_isrs() { + install_isr(1); + install_isr(2); + install_isr(3); + install_isr(4); + install_isr(5); + install_isr(12); + install_isr(13); + install_isr(14); + install_isr(15); + install_isr(16); + install_isr(17); + install_isr(18); + install_isr(19); + install_isr(21); + install_isr(22); + install_isr(23); + install_isr(25); + install_isr(26); + install_isr(27); + install_isr(32); + install_isr(33); + install_isr(34); + install_isr(35); + install_isr(36); + install_isr(39); +} + //------------------------------------------------------ // resolving the primitives //------------------------------------------------------ diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 55c34abd..8638d5d8 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -251,7 +251,7 @@ def_prim(test, oneToNoneU32) { Callback c = Callback(m, topic, fidx); CallbackHandler::add_callback(c); auto *payload = reinterpret_cast("TestPayload"); - CallbackHandler::push_event(topic, payload, 11); + CallbackHandler::push_event(topic, (const char *)payload, 11); pop_args(1); return true; } diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 399988bb..223ab1c6 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -68,8 +68,7 @@ size_t CallbackHandler::callback_count(const std::string &topic) { // WARNING: Push event functions should not use IO functions, since they can be // called from ISR callbacks -void CallbackHandler::push_event(std::string topic, - const unsigned char *payload, +void CallbackHandler::push_event(std::string topic, const char *payload, unsigned int length) { char *message = (char *)(malloc(sizeof(char) * length + 1)); snprintf(message, length + 1, "%s", payload); diff --git a/src/WARDuino/CallbackHandler.h b/src/WARDuino/CallbackHandler.h index c95e5dec..7e5bb3d2 100644 --- a/src/WARDuino/CallbackHandler.h +++ b/src/WARDuino/CallbackHandler.h @@ -40,7 +40,7 @@ class CallbackHandler { static void clear_callbacks(); static std::string dump_callbacks(); static size_t callback_count(const std::string &topic); - static void push_event(std::string topic, const unsigned char *payload, + static void push_event(std::string topic, const char *payload, unsigned int length); static void push_event(Event *event); static bool resolve_event(bool force = false); From cfb362b345eeb41e7d9dea55a5b2f27954bbfe1e Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 5 Sep 2022 17:38:45 +0200 Subject: [PATCH 212/249] Rename analog write primitive Co-authored-by: carllocos --- src/Primitives/arduino.cpp | 7 ++++--- src/Primitives/emulated.cpp | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index ee7c75d0..5b3d6892 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -560,8 +560,9 @@ def_prim(clear_pixels, NoneToNoneU32) { return true; } -// Temporary Primitives needed for analogWrite in ESP32 -def_prim(chip_ledc_analog_write, threeToNoneU32) { +// LED Control primitives + +def_prim(chip_analog_write, threeToNoneU32) { uint8_t channel = arg2.uint32; uint32_t value = arg1.uint32; uint32_t maxValue = arg0.uint32; @@ -935,7 +936,7 @@ void install_primitives() { install_primitive(show_pixels); // temporary primitives needed for analogWrite in ESP32 - install_primitive(chip_ledc_analog_write); + install_primitive(chip_analog_write); install_primitive(chip_ledc_setup); install_primitive(chip_ledc_attach_pin); } diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 8638d5d8..ffae4725 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -448,12 +448,12 @@ def_prim(subscribe_interrupt, threeToNoneU32) { } // Temporary Primitives needed for analogWrite in ESP32 -def_prim(chip_ledc_analog_write, threeToNoneU32) { +def_prim(chip_analog_write, threeToNoneU32) { uint8_t channel = arg2.uint32; uint32_t value = arg1.uint32; uint32_t maxValue = arg0.uint32; // calculate duty, 4095 from 2 ^ 12 - 1 - printf("chip_ledc_analog_write(%u, %u, %u)\n", channel, value, maxValue); + printf("chip_analog_write(%u, %u, %u)\n", channel, value, maxValue); pop_args(3); return true; } @@ -514,7 +514,7 @@ void install_primitives() { install_primitive(show_pixels); // temporary mock primitives needed for analogWrite in ESP32 - install_primitive(chip_ledc_analog_write); + install_primitive(chip_analog_write); install_primitive(chip_ledc_setup); install_primitive(chip_ledc_attach_pin); } From 5f293dcd151e95348b2c91d46fc78ddbfee93ff4 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 16 Sep 2022 13:31:30 +0200 Subject: [PATCH 213/249] Free `interruptData` buffer Co-authored-by: carllocos --- src/Debug/debugger.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 0662e936..9b24142b 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -240,6 +240,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { case interruptProxify: { dbg_info("Converting to proxy settings.\n"); this->proxify(); + free(interruptData); break; } case interruptDUMPAllEvents: @@ -250,19 +251,24 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { this->channel->write("{"); this->dumpEvents(start, size); this->channel->write("}\n"); + free(interruptData); break; case interruptPOPEvent: CallbackHandler::resolve_event(true); + free(interruptData); break; case interruptPUSHEvent: this->handlePushedEvent(reinterpret_cast(interruptData)); + free(interruptData); break; case interruptRecvCallbackmapping: Debugger::updateCallbackmapping( m, reinterpret_cast(interruptData + 2)); + free(interruptData); break; case interruptDUMPCallbackmapping: this->dumpCallbackmapping(); + free(interruptData); break; default: // handle later From 39f22cfb8e5cbc16a90120a6c83642b9753f32e9 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 16 Sep 2022 14:11:34 +0200 Subject: [PATCH 214/249] Allow connections to proxy over serial in cli --- platforms/CLI-Emulator/main.cpp | 47 ++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index c742a64d..16e7b090 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -1,6 +1,7 @@ // // WARDuino - WebAssembly interpreter for embedded devices. // +#include #include #include #include @@ -8,6 +9,7 @@ #include #include #include +#include #include "../../src/Debug/debugger.h" #include "../../src/Utils/macros.h" @@ -48,15 +50,16 @@ void print_help() { fprintf(stdout, " --file Wasm file (module) to load and execute\n"); fprintf(stdout, - " --no-socket Run without socket " + " --no-socket Run debug on stdout" "(default: false)\n"); fprintf(stdout, - " --socket The port number to attach the socket on" + " --socket Port number for debug socket (ignored if " + "'--no-socket' is true)" "(default: 8192)\n"); fprintf(stdout, " --paused Pause program on entry (default: false)\n"); fprintf(stdout, - " --proxy Port of proxy to connect to (ignored if mode " + " --proxy Localhost port or serial port (ignored if mode " "is 'proxy')\n"); fprintf(stdout, " --mode The mode to run in: interpreter, proxy " @@ -157,10 +160,7 @@ int connectToProxySocket(int proxy) { } // Connect to proxy via file descriptor -int connectToProxyFd(const char *proxyfd) { - FILE *serial = fopen(proxyfd, "rw+"); - return fileno(serial); -} +int connectToProxyFd(const char *proxyfd) { return open(proxyfd, O_RDWR); } WARDuino *wac = WARDuino::instance(); Module *m; @@ -244,17 +244,38 @@ int main(int argc, const char *argv[]) { if (m) { m->warduino = wac; - // Run in proxy mode if (strcmp(mode, "proxy") == 0) { + // Run in proxy mode wac->debugger->proxify(); - } - // Connect to proxy device - else if (proxy) { - int connection = connectToProxySocket(std::stoi(proxy)); + } else if (proxy) { + int connection = -1; + + // Connect to proxy device + try { + int port = std::stoi(proxy); + connection = connectToProxySocket(port); + } catch (std::invalid_argument const &ex) { + // argument is not a port + // treat as filename + connection = connectToProxyFd(proxy); + } catch (std::out_of_range const &ex) { + // argument is an integer but is out of range + fprintf(stderr, + "wdcli: out of range integer argument for --proxy\n"); + return 1; + } + + if (connection < 0) { + // Failed to connect stop program + fprintf(stderr, "wdcli: failed to connect to proxy device\n"); + return 1; + } + + // Start supervising proxy device (new thread) wac->debugger->startProxySupervisor(connection); } - // Run Wasm module + // Run Wasm module (new thread) pthread_t id; pthread_create(&id, nullptr, runWAC, nullptr); From 882139dfe29c24fc7e1e83f9a2698ff6c3cee254 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 20 Sep 2022 08:57:55 +0200 Subject: [PATCH 215/249] Fix build of benchmarks Remove .config file requirement (wifi no longer needed) --- benchmarks/benchmarks.cpp | 1 + benchmarks/makefile | 15 ++++++++------- benchmarks/tasks/makefile | 14 +------------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/benchmarks/benchmarks.cpp b/benchmarks/benchmarks.cpp index 50e39dd9..aafb2261 100644 --- a/benchmarks/benchmarks.cpp +++ b/benchmarks/benchmarks.cpp @@ -2,6 +2,7 @@ #include +#include "../src/Debug/debugger.h" #include "../src/Utils/macros.h" #include "../src/WARDuino.h" #include "timer.h" diff --git a/benchmarks/makefile b/benchmarks/makefile index 5b762243..95b6bc36 100644 --- a/benchmarks/makefile +++ b/benchmarks/makefile @@ -15,7 +15,7 @@ DEBUGFLAGS = -DDEBUG=$(DEBUG) -DTRACE=$(TRACE) -DINFO=$(INFO) -DWARN=$(WARN) CXX = g++ CC = gcc CFLAGS = -g -Wall -c -CXXFLAGS = -g -v -std=c++11 -Wall +CXXFLAGS = -g -v -std=c++11 -I ../lib/json/single_include -Wall @@ -35,10 +35,11 @@ CXXSOURCES = \ ../src/WARDuino/CallbackHandler.cpp \ ../src/Primitives/emulated.cpp \ ../src/Interpreter/instructions.cpp \ - ../src/RFC/rfc.cpp \ - ../src/RFC/proxy_server.cpp \ - ../src/RFC/SocketServer.cpp \ + ../src/Edward/RFC.cpp \ + ../src/Edward/proxy.cpp \ + ../src/Edward/proxy_supervisor.cpp \ ../src/Utils/sockets.cpp \ + ../lib/json/single_include/nlohmann/json.hpp \ benchmarks.cpp all: $(OUTPUTDIR)$(TARGET) $(addprefix tasks/,$(addsuffix /wast/impl.wasm, $(TASKS))) @@ -55,8 +56,8 @@ run: all $(OUTPUTDIR)$(TARGET) clean: mostlyclean - $(MAKE) -C tasks clean + -$(MAKE) -C tasks clean mostlyclean: - $(RM) -rf $(OUTPUTDIR) - $(RM) $(COBJECTS) + -$(RM) -rf $(OUTPUTDIR) + -$(RM) $(COBJECTS) diff --git a/benchmarks/tasks/makefile b/benchmarks/tasks/makefile index 39570e31..d83f95b4 100644 --- a/benchmarks/tasks/makefile +++ b/benchmarks/tasks/makefile @@ -1,16 +1,5 @@ TASKS=$(patsubst %/.,%,$(wildcard */.)) -CONFIG = .config -include ${CONFIG} - -ifndef SSID -$(error SSID is not set. Use a .config file.) -endif - -ifndef PASSWORD -$(error PASSWORD is not set. Use a .config file.) -endif - all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/edward/edward.ino,$(TASKS)) $(addsuffix /wast/wasm3/wasm3.ino,$(TASKS)) $(addsuffix /wast/impl.wast,$(TASKS)) $(addsuffix /wast/impl.wasm,$(TASKS)) $(addsuffix /c/arduino.ino,$(TASKS)) echo $(TASKS) @@ -22,12 +11,11 @@ all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/edward/ sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ cat ../warduino.ino.template >> $@ -%/wast/edward/edward.ino: %/wast/impl.wasm .config +%/wast/edward/edward.ino: %/wast/impl.wasm -mkdir $(@D) xxd -i $< $@ sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ cat ../edward.ino.template >> $@ - sed -i 's/{{SSID}}/$(SSID)/g; s/{{Password}}/$(PASSWORD)/g' $@ %/wast/wasm3/wasm3.ino: %/wast/impl.wasm -mkdir $(@D) From b2a4f7f6a1df2f850f53c7adfa3d588a85ada715 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 20 Sep 2022 09:03:36 +0200 Subject: [PATCH 216/249] Add Rebench config with native tests Change flash_and_check.py to output the correct format, take the name of the benchmark as an argument, and never flash. Change native_bench.sh to only execute one benchmark and take the name as an argument. Restore old upload script only for benchmarks. --- benchmarks/.gitignore | 3 ++- benchmarks/flash_and_check.py | 27 +++++++++++---------- benchmarks/native_bench.sh | 32 +++++++++++-------------- benchmarks/tasks/makefile | 6 ++--- benchmarks/upload | 36 ++++++++++++++++++++++++++++ benchmarks/warduino.conf | 44 +++++++++++++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 36 deletions(-) create mode 100755 benchmarks/upload create mode 100644 benchmarks/warduino.conf diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore index f027464a..cc37b2a9 100644 --- a/benchmarks/.gitignore +++ b/benchmarks/.gitignore @@ -4,4 +4,5 @@ bin/ output *.csv -.config +*.json +*.data diff --git a/benchmarks/flash_and_check.py b/benchmarks/flash_and_check.py index b5e29449..d83294e6 100644 --- a/benchmarks/flash_and_check.py +++ b/benchmarks/flash_and_check.py @@ -7,6 +7,7 @@ import serial.tools.list_ports import time import sys +import math def await_output(s: serial.Serial, target: str, failure=None): @@ -49,19 +50,17 @@ def await_output(s: serial.Serial, target: str, failure=None): port = ports[0] print(f"using {port}", file=sys.stderr) + with serial.Serial(port, 115200) as serial: if len(sys.argv) == 2: - with open(sys.argv[1], "rb") as inputText: - serial.write(inputText.read(-1)) - serial.write(b'\n\n') - print("Bytes sent", file=sys.stderr) - print("Await start", file=sys.stderr) - await_output(serial, "START\n") - startTime = time.monotonic() - print("START found, waiting for DONE", file=sys.stderr) - success = await_output(serial, "DONE\n", failure="Guru Meditation Error") - if success: - endTime = time.monotonic() - print(endTime - startTime) - else: - print("\nnan") + print("Await start", file=sys.stderr) + await_output(serial, "START\n") + startTime = time.monotonic() + print("START found, waiting for DONE", file=sys.stderr) + success = await_output(serial, "DONE\n", failure="Guru Meditation Error") + if success: + endTime = time.monotonic() + print(f"{sys.argv[1]}: iterations=1 runtime: {math.floor((endTime - startTime) * 1000000)}us") + else: + print("\nnan") + diff --git a/benchmarks/native_bench.sh b/benchmarks/native_bench.sh index 3d87de0d..9b71d803 100755 --- a/benchmarks/native_bench.sh +++ b/benchmarks/native_bench.sh @@ -1,24 +1,20 @@ #!/usr/bin/sh -# Name: Upload all programs in bench.list to arduino and time -# By Robbert Gurdeep Singh +# This scripts takes the name of a benchmark from the tasks folder and uploads +# it to arduino and times the execution ################################################################################ + tmpfile="$(mktemp --tmpdir)" trap "rm '$tmpfile'" EXIT cd "$(dirname "$0")" -outloc=${1:--} -date >$1 -make clean all -make -C tasks all +outloc=${2:--} -cat bench.list | while read l; do - echo $l | tee -a $1 - ../scripts/upload ${BOARD:-ESP32WROVER} ./tasks/$l/c/arduino.ino 2>&1 >"$tmpfile" - if [ "$?" -eq "0" ]; then - echo "flashed" - python flash_and_check.py | tee -a $1 - else - cat $tmpfile - echo "FAILED!" - exit 1 - fi -done +echo $1 | tee -a $2 +./upload ${BOARD:-ESP32WROVER} ./tasks/$1/c/c.ino 2>&1 >"$tmpfile" +if [ "$?" -eq "0" ]; then + echo "flashed" + python3 flash_and_check.py $1 | tee -a $2 +else + cat $tmpfile + echo "FAILED!" + exit 1 +fi diff --git a/benchmarks/tasks/makefile b/benchmarks/tasks/makefile index d83f95b4..4d5c6deb 100644 --- a/benchmarks/tasks/makefile +++ b/benchmarks/tasks/makefile @@ -1,6 +1,6 @@ TASKS=$(patsubst %/.,%,$(wildcard */.)) -all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/edward/edward.ino,$(TASKS)) $(addsuffix /wast/wasm3/wasm3.ino,$(TASKS)) $(addsuffix /wast/impl.wast,$(TASKS)) $(addsuffix /wast/impl.wasm,$(TASKS)) $(addsuffix /c/arduino.ino,$(TASKS)) +all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/edward/edward.ino,$(TASKS)) $(addsuffix /wast/wasm3/wasm3.ino,$(TASKS)) $(addsuffix /wast/impl.wast,$(TASKS)) $(addsuffix /wast/impl.wasm,$(TASKS)) $(addsuffix /c/c.ino,$(TASKS)) echo $(TASKS) @@ -23,7 +23,7 @@ all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/edward/ sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ cat ../wasm3.ino.template >> $@ -%/c/arduino.ino: %/wast/impl.c ../c.ino.template +%/c/c.ino: %/wast/impl.c ../c.ino.template -mkdir $(@D) echo '#include "Arduino.h"' > $@ echo '#pragma GCC optimize ("O0")' >> $@ @@ -49,5 +49,5 @@ all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/edward/ wasm2wat -f $< > $@ clean: - -find -iname "impl.wast" -o -iname "impl.wasm" -o -iname "arduino.ino" -o -iname "warduino.ino" -o -iname "edward.ino" -o -iname "wasm3.ino" | xargs rm + -find -iname "impl.wast" -o -iname "impl.wasm" -o -iname "c.ino" -o -iname "warduino.ino" -o -iname "edward.ino" -o -iname "wasm3.ino" | xargs rm diff --git a/benchmarks/upload b/benchmarks/upload new file mode 100755 index 00000000..9f3e5059 --- /dev/null +++ b/benchmarks/upload @@ -0,0 +1,36 @@ +#!/bin/sh +# Name: +# By Robbert Gurdeep Singh +# --pref build.path=/tmp/build +# The above extra arguments allows specifying a build loc +################################################################################ +set -x -e + +device="$(echo "${1?-Please specify a device type}" | tr '[:lower:]' '[:upper:]')" +file=${2?-No file to upload} +shift 2 + +if [ -n "$USE_TMPDIR" ]; then + tmpfile="$(mktemp -d --tmpdir)" + trap "rm -rf '$tmpfile'" EXIT + cp "$file" "$tmpfile/prog.c" + cd "$tmpfile" + file="prog.c" +fi + +case "$device" in +"ESP32") + exec arduino --upload "$file" --board "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$@" + ;; +"ESP32WROVER") + exec arduino --upload "$file" --board "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$@" + ;; +"ESP8266") + exec arduino --upload "$file" --board "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$@" + ;; +*) + echo "Unknown device: $device" + exit 1 +esac + +echo "done" diff --git a/benchmarks/warduino.conf b/benchmarks/warduino.conf new file mode 100644 index 00000000..d5885093 --- /dev/null +++ b/benchmarks/warduino.conf @@ -0,0 +1,44 @@ +# this run definition will be chosen if no parameters are given to rebench +default_experiment: all +default_data_file: 'example.data' + +reporting: + rebenchdb: + db_url: https://rebench.stefan-marr.de/rebenchdb + repo_url: https://github.com/TOPLLab/WARDuino + record_all: true + project_name: WARDuino + +# a set of suites with different benchmarks and possibly different settings +benchmark_suites: + Microbenchmarks: + gauge_adapter: RebenchLog + command: "" + benchmarks: + - catalan + - fac + - fib + - gcd + - primes + - tak + - tak-mem + +# a set of executables for the benchmark execution +executors: + native: + path: . + executable: native_bench.sh + env: + PATH: /snap/bin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + args: " %(benchmark)s" + build: + - cd tasks; make + +# combining benchmark suites and executions +experiments: + Example: + suites: + - Microbenchmarks + executions: + - native + From 83e25800df0312e837b1b6f8c3b10cbbb8ab0564 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 20 Sep 2022 10:22:39 +0200 Subject: [PATCH 217/249] Add WARDuino executor to Rebench config --- benchmarks/warduino.conf | 12 +++++++++++- benchmarks/warduino_bench.sh | 32 ++++++++++++++------------------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/benchmarks/warduino.conf b/benchmarks/warduino.conf index d5885093..f56dae6d 100644 --- a/benchmarks/warduino.conf +++ b/benchmarks/warduino.conf @@ -28,11 +28,20 @@ executors: native: path: . executable: native_bench.sh - env: + env: PATH: /snap/bin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin args: " %(benchmark)s" build: - cd tasks; make + warduino: + path: . + executable: warduino_bench.sh + env: + PATH: /snap/bin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + args: " %(benchmark)s" + build: + - cd tasks; make + # combining benchmark suites and executions experiments: @@ -41,4 +50,5 @@ experiments: - Microbenchmarks executions: - native + - warduino diff --git a/benchmarks/warduino_bench.sh b/benchmarks/warduino_bench.sh index 48c588ec..4589840c 100755 --- a/benchmarks/warduino_bench.sh +++ b/benchmarks/warduino_bench.sh @@ -1,24 +1,20 @@ #!/usr/bin/sh -# Name: Upload all programs in bench.list to arduino (WARDuino) and time -# By Robbert Gurdeep Singh +# This scripts takes the name of a benchmark from the tasks folder and uploads +# it to arduino and times the execution ################################################################################ + tmpfile="$(mktemp --tmpdir)" trap "rm '$tmpfile'" EXIT cd "$(dirname "$0")" -date >$1 -make clean all -make -C tasks all +outloc=${2:--} -cat bench.list | while read l; do - echo $l | tee -a $1 - arduino-cli compile --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" ./tasks/$l/wast/warduino/warduino.ino 2>&1 >"$tmpfile" - arduino-cli upload --fqbn "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" ./tasks/$l/wast/warduino/warduino.ino -p /dev/ttyUSB0 2>&1 >"$tmpfile" - if [ "$?" -eq "0" ]; then - echo "flashed" - python3 flash_and_check.py | tee -a $1 - else - cat $tmpfile - echo "FAILED!" - exit 1 - fi -done +echo $1 | tee -a $2 +./upload ${BOARD:-ESP32WROVER} ./tasks/$1/wast/warduino/warduino.ino 2>&1 >"$tmpfile" +if [ "$?" -eq "0" ]; then + echo "flashed" + python3 flash_and_check.py $1 | tee -a $2 +else + cat $tmpfile + echo "FAILED!" + exit 1 +fi From 7b1e6f049e218431d55be29d3958cee7e7b30c96 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 20 Sep 2022 14:55:01 +0200 Subject: [PATCH 218/249] Rename rebench conf file + remove native executor Closes #88 --- benchmarks/{warduino.conf => rebench.conf} | 9 --------- 1 file changed, 9 deletions(-) rename benchmarks/{warduino.conf => rebench.conf} (81%) diff --git a/benchmarks/warduino.conf b/benchmarks/rebench.conf similarity index 81% rename from benchmarks/warduino.conf rename to benchmarks/rebench.conf index f56dae6d..84bc6310 100644 --- a/benchmarks/warduino.conf +++ b/benchmarks/rebench.conf @@ -25,14 +25,6 @@ benchmark_suites: # a set of executables for the benchmark execution executors: - native: - path: . - executable: native_bench.sh - env: - PATH: /snap/bin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - args: " %(benchmark)s" - build: - - cd tasks; make warduino: path: . executable: warduino_bench.sh @@ -49,6 +41,5 @@ experiments: suites: - Microbenchmarks executions: - - native - warduino From 3d73519df144a9b9a51c9621bc7cbc0240f22cf6 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 21 Sep 2022 14:18:38 +0200 Subject: [PATCH 219/249] Add `--no-debug` flag Flag to disable debug thread. --- platforms/CLI-Emulator/main.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 16e7b090..9b775c9d 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -49,6 +49,9 @@ void print_help() { "binaries (default: wat2wasm)\n"); fprintf(stdout, " --file Wasm file (module) to load and execute\n"); + fprintf(stdout, + " --no-debug Run without debug thread" + "(default: false)\n"); fprintf(stdout, " --no-socket Run debug on stdout" "(default: false)\n"); @@ -177,6 +180,7 @@ int main(int argc, const char *argv[]) { bool return_exception = true; bool run_tests = false; + bool no_debug = false; bool no_socket = false; const char *socket = "8192"; bool paused = false; @@ -207,7 +211,9 @@ int main(int argc, const char *argv[]) { ARGV_GET(asserts_file); } else if (!strcmp("--watcompiler", arg)) { ARGV_GET(watcompiler); - } else if (!strcmp("--no-socket", arg)) { + } else if (!strcmp("--no-debug", arg)) { + no_debug = true; + } else if (!strcmp("--no-socket", arg)) { no_socket = true; } else if (!strcmp("--socket", arg)) { ARGV_GET(socket); @@ -280,10 +286,12 @@ int main(int argc, const char *argv[]) { pthread_create(&id, nullptr, runWAC, nullptr); // Start debugger - if (no_socket) { - startDebuggerStd(wac, m); - } else { - startDebuggerSocket(wac, m, std::stoi(socket)); + if (!no_debug) { + if (no_socket) { + startDebuggerStd(wac, m); + } else { + startDebuggerSocket(wac, m, std::stoi(socket)); + } } int *ptr; pthread_join(id, (void **)&ptr); From ee12182d052d92a06f95584c3080bb6a9f2c3574 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 21 Sep 2022 14:20:06 +0200 Subject: [PATCH 220/249] Fix segmentation fault in `disconnect_proxy` Fix: invert wrong check at start of function --- platforms/CLI-Emulator/main.cpp | 2 +- src/Debug/debugger.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 9b775c9d..15d62a0e 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -213,7 +213,7 @@ int main(int argc, const char *argv[]) { ARGV_GET(watcompiler); } else if (!strcmp("--no-debug", arg)) { no_debug = true; - } else if (!strcmp("--no-socket", arg)) { + } else if (!strcmp("--no-socket", arg)) { no_socket = true; } else if (!strcmp("--socket", arg)) { ARGV_GET(socket); diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 9b24142b..f2eb237f 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -1026,7 +1026,7 @@ void Debugger::startProxySupervisor(int socket) { bool Debugger::proxy_connected() const { return this->connected_to_proxy; } void Debugger::disconnect_proxy() { - if (this->proxy_connected()) { + if (!this->proxy_connected()) { return; } int *ptr; From e7cedcac0650cacde085fb5ae0887c3bc4fca8f9 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 21 Sep 2022 16:52:53 +0200 Subject: [PATCH 221/249] Remove \n from emu print_string primitive --- src/Primitives/emulated.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index ffae4725..45a9b13d 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -268,7 +268,7 @@ def_prim(print_string, twoToNoneU32) { uint32_t size = arg0.uint32; std::string text = parse_utf8_string(m->memory.bytes, size, addr); debug("EMU: print string at %i: ", addr); - printf("%s\n", text.c_str()); + printf("%s", text.c_str()); pop_args(2); return true; } From 0483510de425b2fab17a5b98437a6f9c0579e8fc Mon Sep 17 00:00:00 2001 From: tolauwae Date: Thu, 22 Sep 2022 18:14:48 +0200 Subject: [PATCH 222/249] Move interpret loop to main thread --- platforms/CLI-Emulator/main.cpp | 46 ++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 15d62a0e..b0119881 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -124,7 +124,7 @@ void startDebuggerStd(WARDuino *wac, Module *m) { } } -void startDebuggerSocket(WARDuino *wac, Module *m, int port = 8192) { +void startDebuggerSocket(WARDuino *wac, int port = 8192) { int socket_fd = createSocketFileDescriptor(); struct sockaddr_in address = createAddress(port); bindSocketToAddress(socket_fd, address); @@ -168,11 +168,23 @@ int connectToProxyFd(const char *proxyfd) { return open(proxyfd, O_RDWR); } WARDuino *wac = WARDuino::instance(); Module *m; -void *runWAC(void *p) { - // Print value received as argument: - dbg_info("\n=== STARTED INTERPRETATION (in separate thread) ===\n"); - wac->run_module(m); - wac->unload_module(m); +struct debugger_options { + const char *socket; + bool no_socket; +}; + +void *runDebugger(void *arg) { + auto *options = (debugger_options *)arg; + dbg_info("\n=== STARTED DEBUGGER (in separate thread) ===\n"); + // Start debugger + if (options->no_socket) { + free(arg); + startDebuggerStd(wac, m); + } else { + int port = std::stoi(options->socket); + free(arg); + startDebuggerSocket(wac, port); + } } int main(int argc, const char *argv[]) { @@ -281,18 +293,22 @@ int main(int argc, const char *argv[]) { wac->debugger->startProxySupervisor(connection); } - // Run Wasm module (new thread) + // Start debugger (new thread) pthread_t id; - pthread_create(&id, nullptr, runWAC, nullptr); - - // Start debugger + struct debugger_options *options; if (!no_debug) { - if (no_socket) { - startDebuggerStd(wac, m); - } else { - startDebuggerSocket(wac, m, std::stoi(socket)); - } + options = + (debugger_options *)malloc(sizeof(struct debugger_options)); + options->no_socket = no_socket; + options->socket = socket; + pthread_create(&id, nullptr, runDebugger, options); } + + // Run Wasm module + dbg_info("\n=== STARTED INTERPRETATION (main thread) ===\n"); + wac->run_module(m); + wac->unload_module(m); + int *ptr; pthread_join(id, (void **)&ptr); } From a657473ce73ad8f01f88fd92e72dee24fca3bf93 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 23 Sep 2022 23:27:35 +0100 Subject: [PATCH 223/249] Make `Channel` virtual + add open and close methods Add FileDescriptorChannel and WebSocket implementations. --- src/Debug/debugger.cpp | 7 +++--- src/Debug/debugger.h | 4 ++-- src/Utils/sockets.cpp | 49 ++++++++++++++++++++++++++++++++++++++---- src/Utils/sockets.h | 30 +++++++++++++++++++++++--- 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index f2eb237f..fed4b43c 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -17,13 +17,13 @@ // Debugger -Debugger::Debugger(int address) { this->channel = new Channel(address); } +Debugger::Debugger(Channel *duplex) { this->channel = duplex; } // Public methods -void Debugger::setChannel(int address) { +void Debugger::setChannel(Channel *duplex) { delete this->channel; - this->channel = new Channel(address); + this->channel = duplex; } void Debugger::addDebugMessage(size_t len, const uint8_t *buff) { @@ -152,6 +152,7 @@ bool Debugger::checkDebugMessages(Module *m, RunningState *program_state) { break; case interruptHALT: this->channel->write("STOP!\n"); + this->channel->close(); free(interruptData); exit(0); case interruptPAUSE: diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index af7fa3c3..91d60ae8 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -137,9 +137,9 @@ class Debugger { nullptr; // Breakpoint to skip in the next interpretation step // Constructor - explicit Debugger(int address); + explicit Debugger(Channel *duplex); - void setChannel(int address); + void setChannel(Channel *duplex); // Interrupts diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index 4b1e8c8e..5886047f 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -71,9 +71,42 @@ int listenForIncomingConnection(int socket_fd, struct sockaddr_in address) { return new_socket; } -Channel::Channel(int socket) { this->socket = socket; } +FileDescriptorChannel::FileDescriptorChannel(int fileDescriptor) { this->fileDescriptor = fileDescriptor; } -int Channel::write(const char *fmt, ...) const { +int FileDescriptorChannel::write(const char *fmt, ...) const { + va_list args; + va_start(args, fmt); + int written = vdprintf(this->fileDescriptor, fmt, args); + va_end(args); + return written; +} + +ssize_t FileDescriptorChannel::read(void *out, size_t size) { + return ::read(this->fileDescriptor, out, size); +} + +WebSocket::WebSocket(int port) { + this->port = port; + this->fileDescriptor = -1; + this->socket = -1; +} + +void WebSocket::open() { + // bind socket to address + this->fileDescriptor = createSocketFileDescriptor(); + struct sockaddr_in address = createAddress(this->port); + bindSocketToAddress(this->fileDescriptor, address); + startListening(this->fileDescriptor); + printf("Listening on port 172.0.0.1:%i\n", this->port); + + // block until a connection is established + this->socket = listenForIncomingConnection(this->fileDescriptor, address); +} + +int WebSocket::write(const char *fmt, ...) const { + if (this->socket < 0) { + return 0; + } va_list args; va_start(args, fmt); int written = vdprintf(this->socket, fmt, args); @@ -81,6 +114,14 @@ int Channel::write(const char *fmt, ...) const { return written; } -ssize_t Channel::read(void *out, size_t size) { +ssize_t WebSocket::read(void *out, size_t size) { + if (this->socket < 0) { + return 0; + } return ::read(this->socket, out, size); -} \ No newline at end of file +} + +void WebSocket::close() { + // TODO stop listenForIncomingConnection + shutdown(this->fileDescriptor, SHUT_RDWR); +} diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h index b0d6fa21..cbe7230b 100644 --- a/src/Utils/sockets.h +++ b/src/Utils/sockets.h @@ -16,12 +16,36 @@ void startListening(int socket_fd); int listenForIncomingConnection(int socket_fd, struct sockaddr_in address); class Channel { + public: + virtual void open() {} + virtual int write(char const *fmt, ...) const {} + virtual ssize_t read(void *out, size_t size) {} + virtual void close() {} + virtual ~Channel() = default; +}; + +class FileDescriptorChannel : Channel { + protected: + int fileDescriptor; + + public: + explicit FileDescriptorChannel(int fileDescriptor); + + int write(char const *fmt, ...) const override; + ssize_t read(void *out, size_t size) override; +}; + +class WebSocket : Channel { private: + int port; + int fileDescriptor; int socket; public: - explicit Channel(int socket); + explicit WebSocket(int port); - int write(char const *fmt, ...) const; - ssize_t read(void *out, size_t size); + void open() override; + int write(char const *fmt, ...) const override; + ssize_t read(void *out, size_t size) override; + void close() override; }; \ No newline at end of file From 71fc608099aeffcd90762270ae68cf564c0463ce Mon Sep 17 00:00:00 2001 From: tolauwae Date: Sat, 24 Sep 2022 20:00:57 +0100 Subject: [PATCH 224/249] Update code to use new Channel classes Fixes emulator compilation. --- platforms/CLI-Emulator/main.cpp | 46 ++++++++++----------------------- src/Debug/debugger.cpp | 2 +- src/Debug/debugger.h | 2 +- src/Edward/proxy_supervisor.cpp | 4 +-- src/Edward/proxy_supervisor.h | 2 +- src/Utils/sockets.cpp | 27 ++++++++++++++++--- src/Utils/sockets.h | 21 ++++++++++++--- 7 files changed, 59 insertions(+), 45 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index b0119881..50f5a072 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -109,37 +109,16 @@ Module *load(WARDuino wac, const char *file_name, Options opt) { return nullptr; } -void startDebuggerStd(WARDuino *wac, Module *m) { - int valread; - uint8_t buffer[1024] = {0}; - wac->debugger->setChannel(fileno(stdout)); - while (true) { - debug("waiting for debug command\n"); - while ((valread = read(fileno(stdin), buffer, 1024)) != -1) { - write(fileno(stdout), "got a message ... \n", 19); - wac->handleInterrupt(valread - 1, buffer); - write(fileno(stdout), buffer, valread); - fflush(stdout); - } - } -} - -void startDebuggerSocket(WARDuino *wac, int port = 8192) { - int socket_fd = createSocketFileDescriptor(); - struct sockaddr_in address = createAddress(port); - bindSocketToAddress(socket_fd, address); - startListening(socket_fd); - printf("Listening on port 172.0.0.1:%i\n", port); +void startDebugger(WARDuino *wac, Channel *duplex) { + wac->debugger->setChannel(duplex); + duplex->open(); ssize_t valread; uint8_t buffer[1024] = {0}; while (true) { - int socket = listenForIncomingConnection(socket_fd, address); - wac->debugger->setChannel(socket); - while ((valread = read(socket, buffer, 1024)) != -1) { - write(socket, "got a message ... \n", 19); + while ((valread = duplex->read(buffer, 1024)) != -1) { + duplex->write("got a message ... \n", 19); wac->handleInterrupt(valread - 1, buffer); - write(socket, buffer, valread); } } } @@ -177,14 +156,16 @@ void *runDebugger(void *arg) { auto *options = (debugger_options *)arg; dbg_info("\n=== STARTED DEBUGGER (in separate thread) ===\n"); // Start debugger + Channel *duplex; if (options->no_socket) { free(arg); - startDebuggerStd(wac, m); + duplex = new FileChannel(stdin, stdout); } else { int port = std::stoi(options->socket); free(arg); - startDebuggerSocket(wac, port); + duplex = new WebSocket(port); } + startDebugger(wac, duplex); } int main(int argc, const char *argv[]) { @@ -266,16 +247,15 @@ int main(int argc, const char *argv[]) { // Run in proxy mode wac->debugger->proxify(); } else if (proxy) { - int connection = -1; - // Connect to proxy device + Channel *connection = nullptr; try { int port = std::stoi(proxy); - connection = connectToProxySocket(port); + connection = new WebSocket(port); } catch (std::invalid_argument const &ex) { // argument is not a port // treat as filename - connection = connectToProxyFd(proxy); + connection = new FileDescriptorChannel(open(proxy, O_RDWR)); } catch (std::out_of_range const &ex) { // argument is an integer but is out of range fprintf(stderr, @@ -283,7 +263,7 @@ int main(int argc, const char *argv[]) { return 1; } - if (connection < 0) { + if (connection == nullptr) { // Failed to connect stop program fprintf(stderr, "wdcli: failed to connect to proxy device\n"); return 1; diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index fed4b43c..c1880cb1 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -1015,7 +1015,7 @@ void Debugger::handleMonitorProxies(Module *m, uint8_t *interruptData) { this->channel->write("done!\n"); } -void Debugger::startProxySupervisor(int socket) { +void Debugger::startProxySupervisor(Channel *socket) { this->connected_to_proxy = true; pthread_mutex_init(&this->supervisor_mutex, nullptr); pthread_mutex_lock(&this->supervisor_mutex); diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 91d60ae8..62c68385 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -174,7 +174,7 @@ class Debugger { bool isProxied(uint32_t fidx) const; - void startProxySupervisor(int socket); + void startProxySupervisor(Channel *socket); bool proxy_connected() const; diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index 9a3a90cf..c9f9bae1 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -56,9 +56,9 @@ Event *parseJSON(char *buff) { return new Event(*parsed.find("topic"), payload); } -ProxySupervisor::ProxySupervisor(int socket, pthread_mutex_t *mutex) { +ProxySupervisor::ProxySupervisor(Channel *duplex, pthread_mutex_t *mutex) { printf("Started supervisor.\n"); - this->channel = new Channel(socket); + this->channel = duplex; this->mutex = mutex; pthread_create(&this->threadid, nullptr, readSocket, this); diff --git a/src/Edward/proxy_supervisor.h b/src/Edward/proxy_supervisor.h index c0b1ff34..a9bd1961 100644 --- a/src/Edward/proxy_supervisor.h +++ b/src/Edward/proxy_supervisor.h @@ -20,7 +20,7 @@ class ProxySupervisor { void deserializeRFCResult(RFC *rfc); public: - ProxySupervisor(int socket, pthread_mutex_t *mutex); + ProxySupervisor(Channel *duplex, pthread_mutex_t *mutex); void startPushDebuggerSocket(); diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index 5886047f..8fafb951 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -71,18 +71,39 @@ int listenForIncomingConnection(int socket_fd, struct sockaddr_in address) { return new_socket; } -FileDescriptorChannel::FileDescriptorChannel(int fileDescriptor) { this->fileDescriptor = fileDescriptor; } +FileChannel::FileChannel(FILE *inStream, FILE *outStream) { + this->outStream = outStream; + this->outDescriptor = fileno(outStream); + this->inDescriptor = fileno(inStream); +} + +int FileChannel::write(const char *fmt, ...) const { + va_list args; + va_start(args, fmt); + int written = vdprintf(this->outDescriptor, fmt, args); + va_end(args); + fflush(this->outStream); + return written; +} + +ssize_t FileChannel::read(void *out, size_t size) { + return ::read(this->inDescriptor, out, size); +} + +FileDescriptorChannel::FileDescriptorChannel(int fileDescriptor) { + this->fd = fileDescriptor; +} int FileDescriptorChannel::write(const char *fmt, ...) const { va_list args; va_start(args, fmt); - int written = vdprintf(this->fileDescriptor, fmt, args); + int written = vdprintf(this->fd, fmt, args); va_end(args); return written; } ssize_t FileDescriptorChannel::read(void *out, size_t size) { - return ::read(this->fileDescriptor, out, size); + return ::read(this->fd, out, size); } WebSocket::WebSocket(int port) { diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h index cbe7230b..e93207d4 100644 --- a/src/Utils/sockets.h +++ b/src/Utils/sockets.h @@ -24,9 +24,22 @@ class Channel { virtual ~Channel() = default; }; -class FileDescriptorChannel : Channel { - protected: - int fileDescriptor; +class FileChannel : public Channel { + private: + FILE *outStream; + int outDescriptor; + int inDescriptor; + + public: + explicit FileChannel(FILE *in, FILE *out); + + int write(char const *fmt, ...) const override; + ssize_t read(void *out, size_t size) override; +}; + +class FileDescriptorChannel : public Channel { + private: + int fd; public: explicit FileDescriptorChannel(int fileDescriptor); @@ -35,7 +48,7 @@ class FileDescriptorChannel : Channel { ssize_t read(void *out, size_t size) override; }; -class WebSocket : Channel { +class WebSocket : public Channel { private: int port; int fileDescriptor; From c79dc231adbdfe54d8f554be705659b34ca48160 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Sat, 24 Sep 2022 20:26:50 +0100 Subject: [PATCH 225/249] Update mcu platforms Fixes IDF and Arduino compilation. --- platforms/Arduino/Arduino.ino | 8 ++++---- platforms/ESP-IDF/main.cpp | 11 ++++++----- src/Utils/sockets.cpp | 14 +++++++++----- src/Utils/sockets.h | 17 ++++++++++++----- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index 86e93664..cc490cb1 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -21,12 +21,12 @@ Module* m; #define UART_PIN 3 void startDebuggerStd(void* pvParameter) { + Channel* sink = new OutChannel(stdout); + wac->debugger->setChannel(sink); + sink->open(); + uint8_t buffer[1024] = {0}; - wac->debugger->setChannel(fileno(stdout)); - write(fileno(stdout), "Got a message ... \n", 19); while (true) { - // taskYIELD(); - // vTaskDelay(100 / portTICK_PERIOD_MS); yield(); while (Serial.available()) { diff --git a/platforms/ESP-IDF/main.cpp b/platforms/ESP-IDF/main.cpp index dd961bc7..1349b810 100644 --- a/platforms/ESP-IDF/main.cpp +++ b/platforms/ESP-IDF/main.cpp @@ -28,18 +28,19 @@ WARDuino* wac = WARDuino::instance(); Module* m; void startDebuggerStd(void* pvParameter) { + Channel* duplex = new FileChannel(stdin, stdout); + wac->debugger->setChannel(duplex); + duplex->open(); + int valread; uint8_t buffer[1024] = {0}; - wac->debugger->setChannel(fileno(stdout)); while (true) { taskYIELD(); vTaskDelay(1000 / portTICK_PERIOD_MS); - while ((valread = read(fileno(stdin), buffer, 1024)) != -1) { - write(fileno(stdout), "got a message ... \n", 19); + while ((valread = duplex->read(buffer, 1024)) != -1) { + duplex->write("got a message ... \n", 19); wac->handleInterrupt(valread - 1, buffer); - write(fileno(stdout), buffer, valread); - fflush(stdout); } } } diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index 8fafb951..7512a857 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -71,13 +71,12 @@ int listenForIncomingConnection(int socket_fd, struct sockaddr_in address) { return new_socket; } -FileChannel::FileChannel(FILE *inStream, FILE *outStream) { - this->outStream = outStream; - this->outDescriptor = fileno(outStream); - this->inDescriptor = fileno(inStream); +OutChannel::OutChannel(FILE *out) { + this->outStream = out; + this->outDescriptor = fileno(out); } -int FileChannel::write(const char *fmt, ...) const { +int OutChannel::write(const char *fmt, ...) const { va_list args; va_start(args, fmt); int written = vdprintf(this->outDescriptor, fmt, args); @@ -86,6 +85,11 @@ int FileChannel::write(const char *fmt, ...) const { return written; } +FileChannel::FileChannel(FILE *inStream, FILE *outStream) + : OutChannel(outStream) { + this->inDescriptor = fileno(inStream); +} + ssize_t FileChannel::read(void *out, size_t size) { return ::read(this->inDescriptor, out, size); } diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h index e93207d4..9c90cb36 100644 --- a/src/Utils/sockets.h +++ b/src/Utils/sockets.h @@ -18,22 +18,29 @@ int listenForIncomingConnection(int socket_fd, struct sockaddr_in address); class Channel { public: virtual void open() {} - virtual int write(char const *fmt, ...) const {} - virtual ssize_t read(void *out, size_t size) {} + virtual int write(char const *fmt, ...) const { return 0; } + virtual ssize_t read(void *out, size_t size) { return 0; } virtual void close() {} virtual ~Channel() = default; }; -class FileChannel : public Channel { +class OutChannel : public Channel { private: FILE *outStream; int outDescriptor; + + public: + explicit OutChannel(FILE *out); + int write(char const *fmt, ...) const override; +}; + +class FileChannel : public OutChannel { + private: int inDescriptor; public: - explicit FileChannel(FILE *in, FILE *out); + explicit FileChannel(FILE *inStream, FILE *outStream); - int write(char const *fmt, ...) const override; ssize_t read(void *out, size_t size) override; }; From baed0be98913e50815b00281c635412a6104f536 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Sat, 24 Sep 2022 21:03:34 +0100 Subject: [PATCH 226/249] Refactor Channel types to self-documenting names --- platforms/CLI-Emulator/main.cpp | 2 +- src/Utils/sockets.cpp | 10 +++++----- src/Utils/sockets.h | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 50f5a072..6aec24b2 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -159,7 +159,7 @@ void *runDebugger(void *arg) { Channel *duplex; if (options->no_socket) { free(arg); - duplex = new FileChannel(stdin, stdout); + duplex = new Duplex(stdin, stdout); } else { int port = std::stoi(options->socket); free(arg); diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index 7512a857..69458630 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -71,12 +71,12 @@ int listenForIncomingConnection(int socket_fd, struct sockaddr_in address) { return new_socket; } -OutChannel::OutChannel(FILE *out) { +Sink::Sink(FILE *out) { this->outStream = out; this->outDescriptor = fileno(out); } -int OutChannel::write(const char *fmt, ...) const { +int Sink::write(const char *fmt, ...) const { va_list args; va_start(args, fmt); int written = vdprintf(this->outDescriptor, fmt, args); @@ -85,12 +85,12 @@ int OutChannel::write(const char *fmt, ...) const { return written; } -FileChannel::FileChannel(FILE *inStream, FILE *outStream) - : OutChannel(outStream) { +Duplex::Duplex(FILE *inStream, FILE *outStream) + : Sink(outStream) { this->inDescriptor = fileno(inStream); } -ssize_t FileChannel::read(void *out, size_t size) { +ssize_t Duplex::read(void *out, size_t size) { return ::read(this->inDescriptor, out, size); } diff --git a/src/Utils/sockets.h b/src/Utils/sockets.h index 9c90cb36..b13b575b 100644 --- a/src/Utils/sockets.h +++ b/src/Utils/sockets.h @@ -24,22 +24,22 @@ class Channel { virtual ~Channel() = default; }; -class OutChannel : public Channel { +class Sink : public Channel { private: FILE *outStream; int outDescriptor; public: - explicit OutChannel(FILE *out); + explicit Sink(FILE *out); int write(char const *fmt, ...) const override; }; -class FileChannel : public OutChannel { +class Duplex : public Sink { private: int inDescriptor; public: - explicit FileChannel(FILE *inStream, FILE *outStream); + explicit Duplex(FILE *inStream, FILE *outStream); ssize_t read(void *out, size_t size) override; }; From 5fd063b0f0b77515615700bb5deb7d0f6c4e9135 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Sat, 24 Sep 2022 21:54:06 +0100 Subject: [PATCH 227/249] Add `debugger.stop` function to close debugger Channel. --- platforms/CLI-Emulator/main.cpp | 27 ++++++++++++++++----------- src/Debug/debugger.cpp | 8 ++++++++ src/Debug/debugger.h | 4 ++++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 6aec24b2..02f31117 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -109,8 +109,12 @@ Module *load(WARDuino wac, const char *file_name, Options opt) { return nullptr; } -void startDebugger(WARDuino *wac, Channel *duplex) { - wac->debugger->setChannel(duplex); +void *startDebuggerCommunication(void *arg) { + Channel *duplex = WARDuino::instance()->debugger->channel; + if (duplex == nullptr) { + return nullptr; + } + duplex->open(); ssize_t valread; @@ -118,7 +122,7 @@ void startDebugger(WARDuino *wac, Channel *duplex) { while (true) { while ((valread = duplex->read(buffer, 1024)) != -1) { duplex->write("got a message ... \n", 19); - wac->handleInterrupt(valread - 1, buffer); + WARDuino::instance()->handleInterrupt(valread - 1, buffer); } } } @@ -152,20 +156,18 @@ struct debugger_options { bool no_socket; }; -void *runDebugger(void *arg) { - auto *options = (debugger_options *)arg; +void *setupDebuggerCommunication(debugger_options *options) { dbg_info("\n=== STARTED DEBUGGER (in separate thread) ===\n"); // Start debugger Channel *duplex; if (options->no_socket) { - free(arg); duplex = new Duplex(stdin, stdout); } else { int port = std::stoi(options->socket); - free(arg); duplex = new WebSocket(port); } - startDebugger(wac, duplex); + + wac->debugger->setChannel(duplex); } int main(int argc, const char *argv[]) { @@ -275,19 +277,22 @@ int main(int argc, const char *argv[]) { // Start debugger (new thread) pthread_t id; - struct debugger_options *options; if (!no_debug) { - options = + auto *options = (debugger_options *)malloc(sizeof(struct debugger_options)); options->no_socket = no_socket; options->socket = socket; - pthread_create(&id, nullptr, runDebugger, options); + setupDebuggerCommunication(options); + free(options); + + pthread_create(&id, nullptr, startDebuggerCommunication, nullptr); } // Run Wasm module dbg_info("\n=== STARTED INTERPRETATION (main thread) ===\n"); wac->run_module(m); wac->unload_module(m); + wac->debugger->stop(); int *ptr; pthread_join(id, (void **)&ptr); diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index c1880cb1..d007c9bd 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -1048,3 +1048,11 @@ void Debugger::updateCallbackmapping(Module *m, const char *data) { } } } + +// Stop the debugger +void Debugger::stop() { + if (this->channel != nullptr) { + this->channel->close(); + this->channel = nullptr; + } +} diff --git a/src/Debug/debugger.h b/src/Debug/debugger.h index 62c68385..cfa99646 100644 --- a/src/Debug/debugger.h +++ b/src/Debug/debugger.h @@ -141,6 +141,10 @@ class Debugger { void setChannel(Channel *duplex); + // Public methods + + void stop(); + // Interrupts void addDebugMessage(size_t len, const uint8_t *buff); From 237620e0a368189f28c787f2c039ee291432853a Mon Sep 17 00:00:00 2001 From: tolauwae Date: Sat, 24 Sep 2022 22:11:51 +0100 Subject: [PATCH 228/249] Fix #91 Use alarm signal to interrupt blocking calls (such as accept). --- src/Utils/sockets.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Utils/sockets.cpp b/src/Utils/sockets.cpp index 69458630..516604b2 100644 --- a/src/Utils/sockets.cpp +++ b/src/Utils/sockets.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -85,8 +86,7 @@ int Sink::write(const char *fmt, ...) const { return written; } -Duplex::Duplex(FILE *inStream, FILE *outStream) - : Sink(outStream) { +Duplex::Duplex(FILE *inStream, FILE *outStream) : Sink(outStream) { this->inDescriptor = fileno(inStream); } @@ -146,7 +146,15 @@ ssize_t WebSocket::read(void *out, size_t size) { return ::read(this->socket, out, size); } +void sendAlarm() { + struct sigaction sact {}; + sigemptyset(&sact.sa_mask); + sact.sa_flags = 0; + sigaction(SIGALRM, &sact, nullptr); + alarm(0); +} + void WebSocket::close() { - // TODO stop listenForIncomingConnection - shutdown(this->fileDescriptor, SHUT_RDWR); + sendAlarm(); // stop possible blocking accept call + shutdown(this->fileDescriptor, SHUT_RDWR); // shutdown connection } From 24c91f5ea0b7f024999a546751171d9d2da413c8 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Sat, 24 Sep 2022 22:20:23 +0100 Subject: [PATCH 229/249] Quickfix compilation --- platforms/Arduino/Arduino.ino | 2 +- platforms/ESP-IDF/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/Arduino/Arduino.ino b/platforms/Arduino/Arduino.ino index cc490cb1..20f3514c 100644 --- a/platforms/Arduino/Arduino.ino +++ b/platforms/Arduino/Arduino.ino @@ -21,7 +21,7 @@ Module* m; #define UART_PIN 3 void startDebuggerStd(void* pvParameter) { - Channel* sink = new OutChannel(stdout); + Channel* sink = new Sink(stdout); wac->debugger->setChannel(sink); sink->open(); diff --git a/platforms/ESP-IDF/main.cpp b/platforms/ESP-IDF/main.cpp index 1349b810..ae6922c9 100644 --- a/platforms/ESP-IDF/main.cpp +++ b/platforms/ESP-IDF/main.cpp @@ -28,7 +28,7 @@ WARDuino* wac = WARDuino::instance(); Module* m; void startDebuggerStd(void* pvParameter) { - Channel* duplex = new FileChannel(stdin, stdout); + Channel* duplex = new Duplex(stdin, stdout); wac->debugger->setChannel(duplex); duplex->open(); From e7b738b1673c292817fc7016b687f899b2766473 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Mon, 26 Sep 2022 16:52:16 +0100 Subject: [PATCH 230/249] Remove "got a message ..." These debugging messages could mess up json responses. --- platforms/CLI-Emulator/main.cpp | 1 - platforms/ESP-IDF/main.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/platforms/CLI-Emulator/main.cpp b/platforms/CLI-Emulator/main.cpp index 02f31117..4414c6f3 100644 --- a/platforms/CLI-Emulator/main.cpp +++ b/platforms/CLI-Emulator/main.cpp @@ -121,7 +121,6 @@ void *startDebuggerCommunication(void *arg) { uint8_t buffer[1024] = {0}; while (true) { while ((valread = duplex->read(buffer, 1024)) != -1) { - duplex->write("got a message ... \n", 19); WARDuino::instance()->handleInterrupt(valread - 1, buffer); } } diff --git a/platforms/ESP-IDF/main.cpp b/platforms/ESP-IDF/main.cpp index ae6922c9..a4df9175 100644 --- a/platforms/ESP-IDF/main.cpp +++ b/platforms/ESP-IDF/main.cpp @@ -39,7 +39,6 @@ void startDebuggerStd(void* pvParameter) { vTaskDelay(1000 / portTICK_PERIOD_MS); while ((valread = duplex->read(buffer, 1024)) != -1) { - duplex->write("got a message ... \n", 19); wac->handleInterrupt(valread - 1, buffer); } } From 0c5336d4bb3df670aefec39287b615d2e5a99e1a Mon Sep 17 00:00:00 2001 From: tolauwae Date: Thu, 6 Oct 2022 14:29:36 +0200 Subject: [PATCH 231/249] Change `startPushDebuggerSocket()` to also receive proxy replies Expects proxy replies to be json. --- src/Edward/proxy_supervisor.cpp | 34 +++++++++++++++++++++++---------- src/Edward/proxy_supervisor.h | 5 ++++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index c9f9bae1..43097740 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -60,10 +60,19 @@ ProxySupervisor::ProxySupervisor(Channel *duplex, pthread_mutex_t *mutex) { printf("Started supervisor.\n"); this->channel = duplex; this->mutex = mutex; + this->proxyResult = nullptr; pthread_create(&this->threadid, nullptr, readSocket, this); } +bool isEvent(nlohmann::basic_json<> parsed) { + return parsed.find("topic") != parsed.end(); +} + +bool isReply(nlohmann::basic_json<> parsed) { + return parsed.find("success") != parsed.end(); +} + void ProxySupervisor::startPushDebuggerSocket() { char _char; uint32_t buf_idx = 0; @@ -89,9 +98,19 @@ void ProxySupervisor::startPushDebuggerSocket() { // first len argument buffer[buf_idx] = '\0'; try { - Event *event = parseJSON(buffer); - CallbackHandler::push_event(event); - WARDuino::instance()->debugger->notifyPushedEvent(); + nlohmann::basic_json<> parsed = nlohmann::json::parse(buffer); + debug("parseJSON: %s\n", parsed.dump().c_str()); + + if (isEvent(parsed)) { + CallbackHandler::push_event(new Event( + *parsed.find("topic"), *parsed.find("payload"))); + WARDuino::instance()->debugger->notifyPushedEvent(); + } + + if (isReply(parsed)) { + this->proxyResult = parsed; + } + buf_idx = 0; } catch (const nlohmann::detail::parse_error &e) { } @@ -105,13 +124,8 @@ bool ProxySupervisor::send( return n == size; } -char *ProxySupervisor::readReply(short int amount) { - char *buffer = new char[amount + 1]; - bzero(buffer, amount + 1); - ssize_t n = this->channel->read(buffer, amount); - if (n > 0) return buffer; - - delete[] buffer; +char *ProxySupervisor::readReply() { + // TODO use this->proxyResult return nullptr; } diff --git a/src/Edward/proxy_supervisor.h b/src/Edward/proxy_supervisor.h index a9bd1961..632d5016 100644 --- a/src/Edward/proxy_supervisor.h +++ b/src/Edward/proxy_supervisor.h @@ -6,6 +6,7 @@ #include "../Utils/sockets.h" #include "RFC.h" +#include "nlohmann/json.hpp" #include "pthread.h" #include "sys/types.h" @@ -16,6 +17,8 @@ class ProxySupervisor { pthread_mutex_t *mutex; std::set *proxied = new std::set(); + nlohmann::basic_json<> proxyResult; + struct SerializeData *serializeRFC(RFC *callee); void deserializeRFCResult(RFC *rfc); @@ -25,7 +28,7 @@ class ProxySupervisor { void startPushDebuggerSocket(); bool send(void *t_buffer, int t_size); - char *readReply(short int amount = 1024); + char *readReply(); pthread_t getThreadID(); From facb3cadbd6875dc44ffb0ba9e49f172922f9430 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 6 Oct 2022 14:56:11 +0200 Subject: [PATCH 232/249] RFC returns JSON --- src/Edward/proxy.cpp | 61 +++++++++++++++++++------------------------- src/Edward/proxy.h | 1 - 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/Edward/proxy.cpp b/src/Edward/proxy.cpp index 6468a337..8f14de1f 100644 --- a/src/Edward/proxy.cpp +++ b/src/Edward/proxy.cpp @@ -14,9 +14,8 @@ ////TODO test with many args proxy ////TODO test with no return proxy -unsigned short int sizeSerializationRFCallee(RFC *); void arguments_copy(unsigned char *, StackValue *, uint32_t); - +char *printValue(StackValue *v); /* * Proxy methods */ @@ -50,42 +49,34 @@ void Proxy::returnResult(Module *m) { calls->pop(); // send the result to the client - struct SerializeData *rfc_result = this->serializeRFCallee(rfc); - const char *data = (const char *)rfc_result->raw; - WARDuino::instance()->debugger->channel->write(data); + char *val = printValue(rfc->result); + WARDuino::instance()->debugger->channel->write(R"({"success":"%d",%s})", + rfc->success ? 1 : 0, val); + free(val); } -struct SerializeData *Proxy::serializeRFCallee(RFC *callee) { - const unsigned short serializationSize = sizeSerializationRFCallee(callee); - auto *raw = new unsigned char[serializationSize]; - uint8_t suc = callee->success ? 1 : 0; - - memcpy(raw, &suc, sizeof(uint8_t)); - if (callee->success && callee->type->result_count > 0) { - printf("serializeRFCallee: success value size=%u \n", - sizeof_valuetype(callee->result->value_type)); - memcpy(raw + 1, &callee->result->value, - sizeof_valuetype(callee->result->value_type)); - } else if (!callee->success) { - printf("serializeRFCallee: serializing exception\n"); - memcpy(raw + 1, &callee->exception_size, sizeof(uint16_t)); - memcpy(raw + 1 + sizeof(uint16_t), callee->exception, - callee->exception_size); +char *printValue(StackValue *v) { + char *buff = (char *)malloc(256); + switch (v->value_type) { + case I32: + snprintf(buff, 255, R"("type":"i32","value":%)" PRIi32, + v->value.uint32); + break; + case I64: + snprintf(buff, 255, R"("type":"i64","value":%)" PRIi64, + v->value.uint64); + break; + case F32: + snprintf(buff, 255, R"("type":"F32","value":%.7f)", v->value.f32); + break; + case F64: + snprintf(buff, 255, R"("type":"F64","value":%.7f)", v->value.f64); + break; + default: + snprintf(buff, 255, R"("type":"%02x","value":"%)" PRIx64 "\"", + v->value_type, v->value.uint64); } - - auto *ser = new struct SerializeData; - ser->raw = raw; - ser->size = serializationSize; - return ser; -} - -unsigned short int sizeSerializationRFCallee(RFC *callee) { - if (!callee->success) return 1 + sizeof(uint16_t) + callee->exception_size; - - if (callee->type->result_count > 0) - return 1 + sizeof_valuetype(callee->type->results[0]); - else - return 1; + return buff; } StackValue *Proxy::readRFCArgs(Block *func, uint8_t *data) { diff --git a/src/Edward/proxy.h b/src/Edward/proxy.h index 8a7b349f..20993f50 100644 --- a/src/Edward/proxy.h +++ b/src/Edward/proxy.h @@ -13,7 +13,6 @@ class Proxy { private: std::stack *calls = new std::stack(); // lifo queue - struct SerializeData *serializeRFCallee(RFC *callee); void setupCalleeArgs(Module *m, RFC *callee); void pushProxyGuard(Module *m); From 4125fe6c749008cc20d36281aeb3a254165d3cc9 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Thu, 6 Oct 2022 15:01:12 +0200 Subject: [PATCH 233/249] Fix Arduino compilation --- src/Edward/proxy_supervisor.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Edward/proxy_supervisor.h b/src/Edward/proxy_supervisor.h index 632d5016..55b2d461 100644 --- a/src/Edward/proxy_supervisor.h +++ b/src/Edward/proxy_supervisor.h @@ -6,7 +6,11 @@ #include "../Utils/sockets.h" #include "RFC.h" -#include "nlohmann/json.hpp" +#ifndef ARDUINO +#include +#else +#include "../../lib/json/single_include/nlohmann/json.hpp" +#endif #include "pthread.h" #include "sys/types.h" From 79e91ca9014829dab6105aa8c3874d77c2334283 Mon Sep 17 00:00:00 2001 From: Carlos Rojas Date: Thu, 6 Oct 2022 15:55:24 +0200 Subject: [PATCH 234/249] replace type to be int --- src/Edward/proxy.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Edward/proxy.cpp b/src/Edward/proxy.cpp index 8f14de1f..486f6356 100644 --- a/src/Edward/proxy.cpp +++ b/src/Edward/proxy.cpp @@ -59,18 +59,18 @@ char *printValue(StackValue *v) { char *buff = (char *)malloc(256); switch (v->value_type) { case I32: - snprintf(buff, 255, R"("type":"i32","value":%)" PRIi32, + snprintf(buff, 255, R"("type":%d,"value":%)" PRIi32, I32, v->value.uint32); break; case I64: - snprintf(buff, 255, R"("type":"i64","value":%)" PRIi64, + snprintf(buff, 255, R"("type":%d,"value":%)" PRIi64, I64, v->value.uint64); break; case F32: - snprintf(buff, 255, R"("type":"F32","value":%.7f)", v->value.f32); + snprintf(buff, 255, R"("type":%d,"value":%.7f)", F32, v->value.f32); break; case F64: - snprintf(buff, 255, R"("type":"F64","value":%.7f)", v->value.f64); + snprintf(buff, 255, R"("type":%d,"value":%.7f)", F64, v->value.f64); break; default: snprintf(buff, 255, R"("type":"%02x","value":"%)" PRIx64 "\"", From a2c41e08213ada107514902d2f0fd4b07c166769 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Thu, 6 Oct 2022 16:08:35 +0200 Subject: [PATCH 235/249] Update readReply to handle json --- src/Edward/proxy_supervisor.cpp | 76 +++++++++++---------------------- src/Edward/proxy_supervisor.h | 3 +- 2 files changed, 27 insertions(+), 52 deletions(-) diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index 43097740..721dc783 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -108,6 +108,7 @@ void ProxySupervisor::startPushDebuggerSocket() { } if (isReply(parsed)) { + this->hasReplied = true; this->proxyResult = parsed; } @@ -124,9 +125,10 @@ bool ProxySupervisor::send( return n == size; } -char *ProxySupervisor::readReply() { - // TODO use this->proxyResult - return nullptr; +nlohmann::basic_json<> ProxySupervisor::readReply() { + while(!this->hasReplied); + this->hasReplied = false; + return this->proxyResult; } pthread_t ProxySupervisor::getThreadID() { return this->threadid; } @@ -209,54 +211,26 @@ struct SerializeData *ProxySupervisor::serializeRFC(RFC *callee) { } void ProxySupervisor::deserializeRFCResult(RFC *rfc) { - uint8_t *call_result = nullptr; - while (call_result == nullptr) { - call_result = (uint8_t *)this->readReply(); - } - rfc->success = (uint8_t)call_result[0] == 1; - - if (!rfc->success) { - uint16_t msg_size = 0; - memcpy(&msg_size, call_result + 1, sizeof(uint16_t)); - if (msg_size > rfc->exception_size) { - delete[] rfc->exception; - rfc->exception = new char[msg_size]; - rfc->exception_size = msg_size; - } - memcpy(rfc->exception, call_result + 1 + sizeof(uint16_t), msg_size); - delete[] call_result; - return; - } - - if (rfc->type->result_count == 0) { - delete[] call_result; - return; - } - - rfc->result->value.uint64 = 0; - switch (rfc->result->value_type) { - case I32: - memcpy(&rfc->result->value.uint32, call_result + 1, - sizeof(uint32_t)); - dbg_info("deserialized U32 %" PRIu32 "\n", result->value.uint32); - break; - case F32: - memcpy(&rfc->result->value.f32, call_result + 1, sizeof(float)); - dbg_info("deserialized f32 %f \n", result->value.f32); - break; - case I64: - memcpy(&rfc->result->value.uint64, call_result + 1, - sizeof(uint64_t)); - dbg_info("deserialized I64 %" PRIu64 "\n", result->value.uint64); - break; - case F64: - memcpy(&rfc->result->value.f64, call_result + 1, sizeof(double)); - dbg_info("deserialized f32 %f \n", result->value.f64); - break; - default: - FATAL("Deserialization RFCResult\n"); - } - delete[] call_result; + nlohmann::basic_json<> call_result = this->readReply(); // blocking + rfc->success = *call_result.find("success") == 1; + +// if (!rfc->success) { +// uint16_t msg_size = 0; +// memcpy(&msg_size, call_result + 1, sizeof(uint16_t)); +// if (msg_size > rfc->exception_size) { +// delete[] rfc->exception; +// rfc->exception = new char[msg_size]; +// rfc->exception_size = msg_size; +// } +// memcpy(rfc->exception, call_result + 1 + sizeof(uint16_t), msg_size); +// return; +// } + + uint8_t type = *call_result.find("type"); + auto *result = (StackValue *)malloc(sizeof (struct StackValue)); + result->value_type = type; + result->value = {*call_result.find("value")}; + rfc->result = result; } bool ProxySupervisor::call(RFC *callee) { diff --git a/src/Edward/proxy_supervisor.h b/src/Edward/proxy_supervisor.h index 55b2d461..e9a088bf 100644 --- a/src/Edward/proxy_supervisor.h +++ b/src/Edward/proxy_supervisor.h @@ -21,6 +21,7 @@ class ProxySupervisor { pthread_mutex_t *mutex; std::set *proxied = new std::set(); + bool hasReplied = false; nlohmann::basic_json<> proxyResult; struct SerializeData *serializeRFC(RFC *callee); @@ -32,7 +33,7 @@ class ProxySupervisor { void startPushDebuggerSocket(); bool send(void *t_buffer, int t_size); - char *readReply(); + nlohmann::basic_json<>readReply(); pthread_t getThreadID(); From 03e3e7077ce09db8c205bb1a517fd84e43cd438b Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 7 Oct 2022 08:44:58 +0200 Subject: [PATCH 236/249] Clang format --- src/Edward/proxy_supervisor.cpp | 27 ++++++++++++++------------- src/Edward/proxy_supervisor.h | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index 721dc783..eb183395 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -126,7 +126,8 @@ bool ProxySupervisor::send( } nlohmann::basic_json<> ProxySupervisor::readReply() { - while(!this->hasReplied); + while (!this->hasReplied) + ; this->hasReplied = false; return this->proxyResult; } @@ -214,20 +215,20 @@ void ProxySupervisor::deserializeRFCResult(RFC *rfc) { nlohmann::basic_json<> call_result = this->readReply(); // blocking rfc->success = *call_result.find("success") == 1; -// if (!rfc->success) { -// uint16_t msg_size = 0; -// memcpy(&msg_size, call_result + 1, sizeof(uint16_t)); -// if (msg_size > rfc->exception_size) { -// delete[] rfc->exception; -// rfc->exception = new char[msg_size]; -// rfc->exception_size = msg_size; -// } -// memcpy(rfc->exception, call_result + 1 + sizeof(uint16_t), msg_size); -// return; -// } + // if (!rfc->success) { + // uint16_t msg_size = 0; + // memcpy(&msg_size, call_result + 1, sizeof(uint16_t)); + // if (msg_size > rfc->exception_size) { + // delete[] rfc->exception; + // rfc->exception = new char[msg_size]; + // rfc->exception_size = msg_size; + // } + // memcpy(rfc->exception, call_result + 1 + sizeof(uint16_t), + // msg_size); return; + // } uint8_t type = *call_result.find("type"); - auto *result = (StackValue *)malloc(sizeof (struct StackValue)); + auto *result = (StackValue *)malloc(sizeof(struct StackValue)); result->value_type = type; result->value = {*call_result.find("value")}; rfc->result = result; diff --git a/src/Edward/proxy_supervisor.h b/src/Edward/proxy_supervisor.h index e9a088bf..a34691cb 100644 --- a/src/Edward/proxy_supervisor.h +++ b/src/Edward/proxy_supervisor.h @@ -33,7 +33,7 @@ class ProxySupervisor { void startPushDebuggerSocket(); bool send(void *t_buffer, int t_size); - nlohmann::basic_json<>readReply(); + nlohmann::basic_json<> readReply(); pthread_t getThreadID(); From 9f6590efad380031c000afd0c5ffc1d671716b96 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 7 Oct 2022 10:39:25 +0200 Subject: [PATCH 237/249] Hotfix: add missing install step of ISRs + fix ISR indexing --- src/Primitives/arduino.cpp | 69 ++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index 5b3d6892..32862354 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -70,7 +70,7 @@ int isr_index = 0; dbg_info("installing isr number: %d of %d with name: %s\n", \ isr_index + 1, ALL_ISRS, isr_##number); \ if (isr_index < ALL_ISRS) { \ - ISREntry *p = &ISRs[isr_index]; \ + ISREntry *p = &ISRs[isr_index++]; \ p->pin = number; \ p->ISR_callback = &(isr_##number); \ } else { \ @@ -79,8 +79,10 @@ int isr_index = 0; } /* Private macro to create an ISR for a specific pin*/ +#define topic(pin) "interrupt_" #pin + #define def_isr(pin) \ - void isr_##pin() { CallbackHandler::push_event("interrupt_##pin", "", 0); } + void isr_##pin() { CallbackHandler::push_event(#pin, "", 0); } /* Common GPIO pins on ESP32 devices:*/ def_isr(1); @@ -110,10 +112,11 @@ def_isr(36); def_isr(39); int resolve_isr(int pin) { - debug("Resolve ISR (%d) for %s \n", ALL_ISRS, pin); + debug("Resolve ISR (%d) for %i \n", ALL_ISRS, pin); for (int i = 0; i < ALL_ISRS; i++) { auto &isr = ISRs[i]; + debug("Checking entry %i of %i: pin = %i \n", i, ALL_ISRS, isr.pin); if (pin == isr.pin) { debug("FOUND ISR\n"); return i; @@ -887,11 +890,38 @@ int32_t http_post_request(Module *m, const String url, const String body, } //------------------------------------------------------ -// Installing all the primitives +// Installing all the primitives & ISRs //------------------------------------------------------ +void install_isrs() { + install_isr(1); + install_isr(2); + install_isr(3); + install_isr(4); + install_isr(5); + install_isr(12); + install_isr(13); + install_isr(14); + install_isr(15); + install_isr(16); + install_isr(17); + install_isr(18); + install_isr(19); + install_isr(21); + install_isr(22); + install_isr(23); + install_isr(25); + install_isr(26); + install_isr(27); + install_isr(32); + install_isr(33); + install_isr(34); + install_isr(35); + install_isr(36); + install_isr(39); +} + void install_primitives() { dbg_info("INSTALLING PRIMITIVES\n"); - dbg_info("INSTALLING ARDUINO\n"); install_primitive(abort); install_primitive(millis); install_primitive(micros); @@ -939,34 +969,9 @@ void install_primitives() { install_primitive(chip_analog_write); install_primitive(chip_ledc_setup); install_primitive(chip_ledc_attach_pin); -} -void install_isrs() { - install_isr(1); - install_isr(2); - install_isr(3); - install_isr(4); - install_isr(5); - install_isr(12); - install_isr(13); - install_isr(14); - install_isr(15); - install_isr(16); - install_isr(17); - install_isr(18); - install_isr(19); - install_isr(21); - install_isr(22); - install_isr(23); - install_isr(25); - install_isr(26); - install_isr(27); - install_isr(32); - install_isr(33); - install_isr(34); - install_isr(35); - install_isr(36); - install_isr(39); + dbg_info("INSTALLING ISRs\n"); + install_isrs(); } //------------------------------------------------------ From 512e959e09b88175484e9835b8d2b390153ee5aa Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 7 Oct 2022 10:37:38 +0200 Subject: [PATCH 238/249] Introduce `INTERRUPT_TOPIC_PREFIX` macro --- src/Primitives/arduino.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index 32862354..9d162948 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -78,11 +78,13 @@ int isr_index = 0; } \ } -/* Private macro to create an ISR for a specific pin*/ -#define topic(pin) "interrupt_" #pin +#define INTERRUPT_TOPIC_PREFIX "interrupt_" -#define def_isr(pin) \ - void isr_##pin() { CallbackHandler::push_event(#pin, "", 0); } +/* Private macro to create an ISR for a specific pin*/ +#define def_isr(pin) \ + void isr_##pin() { \ + CallbackHandler::push_event(INTERRUPT_TOPIC_PREFIX #pin, "", 0); \ + } /* Common GPIO pins on ESP32 devices:*/ def_isr(1); @@ -613,7 +615,7 @@ def_prim(subscribe_interrupt, threeToNoneU32) { attachInterrupt(digitalPinToInterrupt(pin), ISRs[index].ISR_callback, mode); - String callback_id = "interrupt_"; + String callback_id = INTERRUPT_TOPIC_PREFIX; callback_id += String(pin); Callback c = Callback(m, callback_id.c_str(), fidx); CallbackHandler::add_callback(c); From ce0b417ae427d642743d6d3a801cd390664d6bd4 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 7 Oct 2022 10:40:09 +0200 Subject: [PATCH 239/249] Remove verbose Arduino compilation output --- platforms/Arduino/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/Arduino/Makefile b/platforms/Arduino/Makefile index bb35f086..3e189220 100644 --- a/platforms/Arduino/Makefile +++ b/platforms/Arduino/Makefile @@ -7,7 +7,7 @@ flash: arduino-cli upload -p $(PORT) --fqbn $(FQBN) Arduino.ino compile: - arduino-cli -v compile --fqbn $(FQBN) Arduino.ino + arduino-cli compile --fqbn $(FQBN) Arduino.ino monitor: arduino-cli monitor -p $(PORT) -c baudrate=115200 From 2e79e1f35cd416e8ed0d3abc6635a563bf0bcdd9 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Thu, 11 Aug 2022 10:51:21 +0200 Subject: [PATCH 240/249] Update to new CI ubuntu runtimes For more details see --- .github/workflows/compile.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index ef473460..19c559d9 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -26,7 +26,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-18.04, ubuntu-20.04, macos-latest] + os: [ubuntu-20.04, ubuntu-22.04, macos-latest] steps: - name: Checkout uses: actions/checkout@v2 From f810f903aab7184576151937cc839346d543d9d6 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 11 Oct 2022 09:28:48 +0200 Subject: [PATCH 241/249] Fix #95 --- src/WARDuino/CallbackHandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 223ab1c6..08a1ec8e 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -115,7 +115,6 @@ bool CallbackHandler::resolve_event(bool force) { CallbackHandler::resolving_event = true; CallbackHandler::events->pop_front(); - CallbackHandler::pushed_cursor--; debug("Resolving an event. (%lu remaining)\n", CallbackHandler::events->size()); From ab5b6c71ba14cdeba1e7e53dc7535319a85aa6d3 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 11 Oct 2022 13:59:31 +0200 Subject: [PATCH 242/249] Fix #102 Primitive proxy calls were not supported. Cannot be used with `setup_call` because the don't have a valid `func->start_ptr`. --- src/Debug/debugger.cpp | 3 --- src/Edward/proxy.cpp | 25 +++++++++++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index d007c9bd..85e5d51d 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -978,9 +978,6 @@ void Debugger::handleProxyCall(Module *m, RunningState *program_state, auto *rfc = new RFC(fidx, func->type, args); this->proxy->pushRFC(m, rfc); - - *program_state = PROXYrun; - dbg_trace("Program state: ProxyRun"); } RFC *Debugger::topProxyCall() { diff --git a/src/Edward/proxy.cpp b/src/Edward/proxy.cpp index 486f6356..377a7742 100644 --- a/src/Edward/proxy.cpp +++ b/src/Edward/proxy.cpp @@ -23,24 +23,37 @@ char *printValue(StackValue *v); Proxy::Proxy() = default; void Proxy::pushRFC(Module *m, RFC *rfc) { - // push proxy guard block to stack - this->pushProxyGuard(m); + // keep RFC in queue + this->calls->push(rfc); + // push RFC arguments to stack this->setupCalleeArgs(m, rfc); + + if (rfc->fidx < m->import_count) { + // execute primitives directly + ((Primitive)m->functions[rfc->fidx].func_ptr)(m); + // send result directly + m->warduino->program_state = PROXYhalt; + m->warduino->debugger->sendProxyCallResult(m); + return; + } + + // push proxy guard block to stack + this->pushProxyGuard(m); // push function to stack setup_call(m, rfc->fidx); - // keep RFC in queue - this->calls->push(rfc); + + m->warduino->program_state = PROXYrun; } RFC *Proxy::topRFC() { return this->calls->top(); } void Proxy::returnResult(Module *m) { RFC *rfc = this->calls->top(); + // reading result from stack if (rfc->success && rfc->type->result_count > 0) { - rfc->result->value_type = m->stack[m->sp].value_type; - rfc->result->value = m->stack[m->sp].value; + rfc->result = &m->stack[m->sp]; } else if (!rfc->success) { printf("some exception will be returned\n"); // TODO exception msg From bafcd772ae3fbebb885f2ffb54acf18309d1a1ef Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 12 Oct 2022 11:47:47 +0200 Subject: [PATCH 243/249] Fix readReply for proxy calls over serial Works towards solving #87 but the emulator crashes after completing the deserialization. --- src/Edward/proxy_supervisor.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index eb183395..b6e523a3 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -80,7 +80,7 @@ void ProxySupervisor::startPushDebuggerSocket() { uint32_t current_size = start_size; char *buffer = (char *)malloc(start_size); - printf("Started listening for events from proxy device.\n"); + dbg_info("Proxy supervisor listening to remote device...\n"); while (continuing(this->mutex)) { if (this->channel->read(&_char, 1) != -1) { // increase buffer size if needed @@ -114,9 +114,14 @@ void ProxySupervisor::startPushDebuggerSocket() { buf_idx = 0; } catch (const nlohmann::detail::parse_error &e) { + if (_char == '\n') { + // discard buffer + buf_idx = 0; + } } } } + dbg_info("Proxy supervisor shutting down.\n"); } bool ProxySupervisor::send( From 8c13441e3842d4c659a07533616fce54cf0bbad1 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Wed, 12 Oct 2022 13:14:19 +0200 Subject: [PATCH 244/249] Use boolean in json reply for proxy call Fixes: Wrong type of field caused the supervisor to crash after a proxy call. --- src/Edward/proxy.cpp | 4 ++-- src/Edward/proxy_supervisor.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Edward/proxy.cpp b/src/Edward/proxy.cpp index 377a7742..998c5da0 100644 --- a/src/Edward/proxy.cpp +++ b/src/Edward/proxy.cpp @@ -63,8 +63,8 @@ void Proxy::returnResult(Module *m) { // send the result to the client char *val = printValue(rfc->result); - WARDuino::instance()->debugger->channel->write(R"({"success":"%d",%s})", - rfc->success ? 1 : 0, val); + WARDuino::instance()->debugger->channel->write( + R"({"success":%s,%s})", rfc->success ? "true" : "false", val); free(val); } diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index b6e523a3..8d490664 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -218,7 +218,7 @@ struct SerializeData *ProxySupervisor::serializeRFC(RFC *callee) { void ProxySupervisor::deserializeRFCResult(RFC *rfc) { nlohmann::basic_json<> call_result = this->readReply(); // blocking - rfc->success = *call_result.find("success") == 1; + rfc->success = *call_result.find("success"); // if (!rfc->success) { // uint16_t msg_size = 0; From aca2b0de81bb417057f331bd0e4e62e844314f9c Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 14 Oct 2022 08:54:53 +0200 Subject: [PATCH 245/249] Fix mistake in default case for `printValue` in proxy Fix access of class member --- src/Edward/proxy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Edward/proxy.cpp b/src/Edward/proxy.cpp index 998c5da0..159cf802 100644 --- a/src/Edward/proxy.cpp +++ b/src/Edward/proxy.cpp @@ -59,7 +59,7 @@ void Proxy::returnResult(Module *m) { // TODO exception msg } // remove call from lifo queue - calls->pop(); + this->calls->pop(); // send the result to the client char *val = printValue(rfc->result); @@ -86,7 +86,7 @@ char *printValue(StackValue *v) { snprintf(buff, 255, R"("type":%d,"value":%.7f)", F64, v->value.f64); break; default: - snprintf(buff, 255, R"("type":"%02x","value":"%)" PRIx64 "\"", + snprintf(buff, 255, R"("type":%02x,"value":%)" PRIx64, v->value_type, v->value.uint64); } return buff; From 7a1595137394da63355b5f771d78322d5ef42353 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 14 Oct 2022 12:01:42 +0200 Subject: [PATCH 246/249] Fix: don't send a value in proxy result when the call has no return values Fixes #87 --- src/Edward/proxy.cpp | 24 +++++++++++++++--------- src/Edward/proxy_supervisor.cpp | 4 ++++ src/Interpreter/instructions.cpp | 6 +++++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/Edward/proxy.cpp b/src/Edward/proxy.cpp index 159cf802..b03dbc60 100644 --- a/src/Edward/proxy.cpp +++ b/src/Edward/proxy.cpp @@ -51,20 +51,26 @@ RFC *Proxy::topRFC() { return this->calls->top(); } void Proxy::returnResult(Module *m) { RFC *rfc = this->calls->top(); - // reading result from stack - if (rfc->success && rfc->type->result_count > 0) { - rfc->result = &m->stack[m->sp]; - } else if (!rfc->success) { - printf("some exception will be returned\n"); - // TODO exception msg - } // remove call from lifo queue this->calls->pop(); + if (!rfc->success) { + // TODO exception msg + WARDuino::instance()->debugger->channel->write(R"({"success":false})"); + return; + } + + if (rfc->type->result_count == 0) { + // reading result from stack + WARDuino::instance()->debugger->channel->write(R"({"success":true})"); + return; + } + // send the result to the client + rfc->result = &m->stack[m->sp]; char *val = printValue(rfc->result); - WARDuino::instance()->debugger->channel->write( - R"({"success":%s,%s})", rfc->success ? "true" : "false", val); + WARDuino::instance()->debugger->channel->write(R"({"success":true,%s})", + val); free(val); } diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index 8d490664..8c9ded84 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -220,6 +220,10 @@ void ProxySupervisor::deserializeRFCResult(RFC *rfc) { nlohmann::basic_json<> call_result = this->readReply(); // blocking rfc->success = *call_result.find("success"); + if (rfc->type->result_count == 0) { + return ; + } + // if (!rfc->success) { // uint16_t msg_size = 0; // memcpy(&msg_size, call_result + 1, sizeof(uint16_t)); diff --git a/src/Interpreter/instructions.cpp b/src/Interpreter/instructions.cpp index d5f085cd..da68d394 100644 --- a/src/Interpreter/instructions.cpp +++ b/src/Interpreter/instructions.cpp @@ -125,12 +125,16 @@ bool proxy_call(Module *m, uint32_t fidx) { dbg_info(": FAILED TO SEND\n", fidx); return false; } + if (!rfc->success) { // TODO exception bugger might be too small and msg not null terminated? memcpy(&exception, rfc->exception, strlen(rfc->exception)); return false; } - if (rfc->type->result_count > 0) m->stack[++m->sp] = *rfc->result; + + if (rfc->type->result_count > 0) { + m->stack[++m->sp] = *rfc->result; + } return true; } From 2074174cd637f03cdc042557d8530c491dc164d8 Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 14 Oct 2022 13:39:10 +0200 Subject: [PATCH 247/249] Improve self-documentation of supervisor --- src/Edward/proxy_supervisor.cpp | 18 +++++++++--------- src/Edward/proxy_supervisor.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index 8c9ded84..97961a38 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -40,11 +40,11 @@ bool continuing(pthread_mutex_t *mutex) { } } -void *readSocket(void *input) { +void *runSupervisor(void *input) { // Print value received as argument: dbg_info("\n=== LISTENING TO SOCKET (in separate thread) ===\n"); auto *supervisor = (ProxySupervisor *)input; - supervisor->startPushDebuggerSocket(); + supervisor->listenToSocket(); pthread_exit(nullptr); } @@ -57,12 +57,12 @@ Event *parseJSON(char *buff) { } ProxySupervisor::ProxySupervisor(Channel *duplex, pthread_mutex_t *mutex) { - printf("Started supervisor.\n"); + debug("Starting supervisor.\n"); this->channel = duplex; this->mutex = mutex; this->proxyResult = nullptr; - pthread_create(&this->threadid, nullptr, readSocket, this); + pthread_create(&this->threadid, nullptr, runSupervisor, this); } bool isEvent(nlohmann::basic_json<> parsed) { @@ -73,7 +73,7 @@ bool isReply(nlohmann::basic_json<> parsed) { return parsed.find("success") != parsed.end(); } -void ProxySupervisor::startPushDebuggerSocket() { +void ProxySupervisor::listenToSocket() { char _char; uint32_t buf_idx = 0; const uint32_t start_size = 1024; @@ -185,9 +185,9 @@ void arguments_copy(unsigned char *dest, StackValue *args, /* * - * output: 1 byte | 4 bytes | sizeof(arg1.value_type) bytes | - * sizeof(arg2.value_type) bytes | ... interrupt | funID | arg1.value - * + * output: 1 byte (interrupt code) | 4 bytes (fidx) | sizeof(arg_1) arg_1 ... + sizeof(arg_n) arg_n + * Output is also transformed to hexa * */ @@ -221,7 +221,7 @@ void ProxySupervisor::deserializeRFCResult(RFC *rfc) { rfc->success = *call_result.find("success"); if (rfc->type->result_count == 0) { - return ; + return; } // if (!rfc->success) { diff --git a/src/Edward/proxy_supervisor.h b/src/Edward/proxy_supervisor.h index a34691cb..33e40b9b 100644 --- a/src/Edward/proxy_supervisor.h +++ b/src/Edward/proxy_supervisor.h @@ -30,7 +30,7 @@ class ProxySupervisor { public: ProxySupervisor(Channel *duplex, pthread_mutex_t *mutex); - void startPushDebuggerSocket(); + void listenToSocket(); bool send(void *t_buffer, int t_size); nlohmann::basic_json<> readReply(); From dde0f99f90ad72df84dc2a08f5db3be94dc26bfc Mon Sep 17 00:00:00 2001 From: tolauwae Date: Fri, 14 Oct 2022 16:12:22 +0200 Subject: [PATCH 248/249] Add acknowledgement of successful proxy. Fix: keep debug socket alive during proxy call. --- src/Edward/proxy_supervisor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Edward/proxy_supervisor.cpp b/src/Edward/proxy_supervisor.cpp index 97961a38..7a15f026 100644 --- a/src/Edward/proxy_supervisor.cpp +++ b/src/Edward/proxy_supervisor.cpp @@ -133,6 +133,7 @@ bool ProxySupervisor::send( nlohmann::basic_json<> ProxySupervisor::readReply() { while (!this->hasReplied) ; + WARDuino::instance()->debugger->channel->write("read reply: succeeded\n"); this->hasReplied = false; return this->proxyResult; } From addd9c7498f365b8a118e1ddacba4d8cae425b8e Mon Sep 17 00:00:00 2001 From: tolauwae Date: Tue, 18 Oct 2022 13:09:10 +0200 Subject: [PATCH 249/249] Add disclaimer for ESP IDF primitives --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ba2b38cb..cbbdc30d 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ The WARDuino VM can be compiled with both the Arduino and ESP-IDF toolchains, an ### Build for ESP-IDF +> warning: primitive support for IDF is under construction + Before you can compile and flash with ESP-IDF, you must install and enable [the toolchain](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-macos-setup.html). You also need to disable the watchdog timer: