From cb338bf147fbd35c3e4e214425d0e6b3cecc5396 Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Fri, 2 Dec 2022 13:08:40 +0100 Subject: [PATCH] simuc V0.0.3 --- examples/simuc/.gitignore | 3 + examples/simuc/.vscode/launch.json | 2 +- examples/simuc/Makefile | 4 +- examples/simuc/src/main.cpp | 124 ++++++++++++++++++++++----- examples/simuc/src/sim/sim.cpp | 8 +- examples/simuc/src/simavr/simavr.cpp | 17 ++-- examples/simuc/src/simavr/simavr.h | 4 +- 7 files changed, 125 insertions(+), 37 deletions(-) diff --git a/examples/simuc/.gitignore b/examples/simuc/.gitignore index d45c0b1..b0d2201 100644 --- a/examples/simuc/.gitignore +++ b/examples/simuc/.gitignore @@ -1,3 +1,6 @@ dist/** build/** **/*.vcd +**/.simucinit +**/.gdbinit +**/.gdb_history diff --git a/examples/simuc/.vscode/launch.json b/examples/simuc/.vscode/launch.json index c6fe1da..4c40c7b 100644 --- a/examples/simuc/.vscode/launch.json +++ b/examples/simuc/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "program": "${workspaceFolder}/dist/simuc", "args": [], - "stopAtEntry": true, + "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, diff --git a/examples/simuc/Makefile b/examples/simuc/Makefile index 8a265ac..01a98a0 100644 --- a/examples/simuc/Makefile +++ b/examples/simuc/Makefile @@ -7,8 +7,8 @@ $(PRJ): dist/simuc start: $(PRJ) dist/simuc -#X_CFLAGS = -O0 -g -Wall -CFLAGS = -Os -Wall -g +CFLAGS = -O0 -g -Wall +#CFLAGS = -Os -g -Wall CFLAGS += -isystem ./include #CFLAGS += -isystem ./include/parts diff --git a/examples/simuc/src/main.cpp b/examples/simuc/src/main.cpp index b75ab45..161957c 100644 --- a/examples/simuc/src/main.cpp +++ b/examples/simuc/src/main.cpp @@ -1,16 +1,19 @@ #include #include #include +#include +#include #include "sim/sim.h" #include "simavr/simavr.h" void printHelp () { - printf("simuc V0.0.2 (%s,%s)\n", __DATE__, __TIME__); - printf("usage: simuc [options] elf-file\n\n"); - printf(" available options:\n"); + printf("simuc V0.0.3 (%s,%s)\n", __DATE__, __TIME__); + printf("usage: simuc [options] elf-file [elf-file ...]\n\n"); + printf(" available options (you can use file .simucinit instead):\n"); + printf(" --port ... listining port for gdb (default 1234)\n"); printf(" --board ... set board (arduino, sure, evws1)\n"); - printf(" --sync sync elapsed µC-time with real time\n\n"); + printf(" --nosync do not sync elapsed µC-time with real time\n\n"); printf(" --mmcu ... set target device type\n"); printf(" --frequency ... set target frequency in Hz\n"); printf(" --pc ... set start program counter (default is 0)\n"); @@ -22,10 +25,16 @@ void printHelp () { printf(" simuc --board arduino a.out\n\n"); } +struct SimUcInit { + int argc; + char *argv[]; +}; + + int main (int argc, char **argv) { struct StartParameters params; memset((void *)¶ms, 0, sizeof(params)); - params.filename = NULL; + params.filenames = NULL; params.gdbPort = -1; params.frequency = -1; params.mmcu = NULL; @@ -33,13 +42,56 @@ int main (int argc, char **argv) { params.vcc = -1; params.avcc = -1; params.aref = -1; - + params.nosync = 0; + struct SimUcInit *simUcInit = NULL; if (argc <= 1) { - printHelp(); - return 1; + const char *fileName = ".simucinit"; + FILE *fp = fopen(fileName, "r"); + if (fp == NULL) { + printHelp(); + return 1; + } + char * line = NULL; + size_t len = 0; + ssize_t read; + simUcInit = (struct SimUcInit *)malloc(sizeof(struct SimUcInit)); + if (!simUcInit) { + fprintf(stderr, "ERROR: out of memory?"); + return 1; + } + + simUcInit->argc = 0; + simUcInit->argv[simUcInit->argc] = (char *)malloc(strlen(fileName) + 1); + strcpy(simUcInit->argv[simUcInit->argc], ".simucinit"); + simUcInit->argc++; + + while ((read = getline(&line, &len, fp)) != -1) { + std::string sLine = std::string(line); + std::string sTrimmed = std::regex_replace(sLine, std::regex("(^[ \\t]+)|([ \\t]*\\n$)"), ""); + if (sTrimmed.length() == 0 || sTrimmed.at(0) == '#') { + continue; + } + std::regex e("\\s+"); + std::regex_token_iterator i(sTrimmed.begin(), sTrimmed.end(), e, -1); + std::regex_token_iterator end; + while (i != end) { + std::string s = (*i++).str(); + simUcInit = (struct SimUcInit *)realloc(simUcInit, sizeof(struct SimUcInit) + sizeof(char *) * (simUcInit->argc + 1)); + simUcInit->argv[simUcInit->argc] = (char *)malloc(s.length() + 1); + strcpy(simUcInit->argv[simUcInit->argc], s.c_str()); + simUcInit->argc++; + } + } + fclose(fp); } + if (simUcInit != NULL && simUcInit->argc > 0) { + argc = simUcInit->argc; + argv = simUcInit->argv; + } + + int filenameIndex = -1; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { if (strcmp(argv[i], "--help") == 0) { @@ -72,7 +124,15 @@ int main (int argc, char **argv) { fprintf(stderr, "ERROR: invalid board %s, use --help to show usage\n\n", argv[i]); return 1; } + } + } + } + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + if (strcmp(argv[i], "--board") == 0 && argc >= (i + 1)) { + i++; + continue; } else if (strcmp(argv[i], "--mmcu") == 0) { params.mmcu = argv[++i]; } else if (strcmp(argv[i], "--port") == 0) { @@ -92,36 +152,43 @@ int main (int argc, char **argv) { sscanf(argv[++i], "%d", ¶ms.avcc); } else if (strcmp(argv[i], "--aref") == 0) { sscanf(argv[++i], "%d", ¶ms.aref); + } else if (strcmp(argv[i], "--nosync") == 0) { + params.nosync = 1; } else { fprintf(stderr, "ERROR: invalid option %s, use --help to show usage\n\n", argv[i]); return 1; } continue; } - params.filename = argv[i]; - break; + params.filenames = (const char **)realloc(params.filenames, sizeof(params.filenames[0]) * (++filenameIndex + 2)); + params.filenames[filenameIndex] = argv[i]; + params.filenames[filenameIndex + 1] = NULL; } - if (params.filename == NULL) { + if (params.filenames == NULL || params.filenames[0] == NULL) { printf("ERROR: missing target elf file, use --help to show usage\n\n"); return 1; } + printf("--------------------------------------------------------------------\n"); init(¶ms); if (errno == 1) { return 1; } - printf("available commands: i (interrupt), c (continue), s (stack)\n"); - printf("----------------------------------------------------------\n"); + printf("--------------------------------------------------------------------\n"); + printf("available commands: i (interrupt), c (continue), s (stack), q (quit)\n"); + printf("--------------------------------------------------------------------\n"); printf("init done - press key to start\n"); getchar(); - printf("----------------------------------------------------------\n"); + printf("--------------------------------------------------------------------\n"); start(); // int cnt = 0; char *line = NULL; size_t size = 0; - while (1) { + int quit = 0; + + while (!quit) { // struct SimAvrEvent ev = waitForEvent(); // printf("%10.03lf: event %s (%d) received \r", ev.cycle / 20E6, eventText((EnumSimEvent)ev.event), ev.event); // fflush(stdout); @@ -132,7 +199,7 @@ int main (int argc, char **argv) { // } if (getline(&line, &size, stdin) > 0) { - const char *commands[] = { "interrupt", "continue", "stack" }; + const char *commands[] = { "quit", "interrupt", "continue", "stack" }; try { int foundIndex = -1; int foundCnt = 0; @@ -157,9 +224,14 @@ int main (int argc, char **argv) { } // printf("foundCnt=%d foundIndex=%d command=%s\n", foundCnt, foundIndex, foundIndex >= 0 ? commands[foundIndex] : ""); if (foundCnt == 1 || length == 0) { - setCommand((EnumSimAvrCommand)(foundCnt > 0 ? foundIndex + 2 : 1), NULL); + EnumSimAvrCommand cmd = (EnumSimAvrCommand)(foundCnt > 0 ? foundIndex + 2 : 1); + setCommand(cmd, NULL); while (1) { struct SimAvrEvent ev = waitForEvent(); + if (ev.event == EventShutdown || (cmd == CommandQuit && ev.event == EventCommandExecuted)) { + quit = 1; + break; + } if (ev.event == EventCommandExecuted) { break; } @@ -181,12 +253,20 @@ int main (int argc, char **argv) { } } - while (1) { - struct SimAvrEvent ev = waitForEvent(); - printf("event %s (%d) received\n", eventText((EnumSimEvent)ev.event), ev.event); - if (ev.event == EventShutdown) { - break; + // while (1) { + // struct SimAvrEvent ev = waitForEvent(); + // printf("event %s (%d) received\n", eventText((EnumSimEvent)ev.event), ev.event); + // if (ev.event == EventShutdown) { + // break; + // } + // } + + if (simUcInit != NULL) { + for (int i = 0; i < simUcInit->argc; i++) { + free(simUcInit->argv[i]); } + free(simUcInit); + simUcInit = NULL; } usleep(10000); diff --git a/examples/simuc/src/sim/sim.cpp b/examples/simuc/src/sim/sim.cpp index 32a23b6..7f0e3e3 100644 --- a/examples/simuc/src/sim/sim.cpp +++ b/examples/simuc/src/sim/sim.cpp @@ -149,11 +149,9 @@ void init (struct StartParameters *param) { // switchStdErr(NULL); // std::cout.rdbuf(0); // std::cerr.rdbuf(0); - const char *filename = param->filename != NULL - ? param->filename - // : "../gdb-stub-sm_atmega324p/sim/dist/gdb-stub-sm_atmega324p.axf"; - : "../gdb-stub-sm_atmega324p/sim/dist/gdb-stub-sm_atmega324p.axf"; - printf("firmware file \"%s\"\n", filename); + if (param->filenames == NULL || param->filenames[0] == NULL || *param->filenames[0] == 0) { + std::logic_error(error(AT, "missing elf filename")); + } simavr.load(param); if (strcmp(simavr.getTargetDeviceName(), "atmega324p") != 0) { std::logic_error(error(AT, "invalid target device %s", simavr.getTargetDeviceName())); diff --git a/examples/simuc/src/simavr/simavr.cpp b/examples/simuc/src/simavr/simavr.cpp index 444e671..ec59848 100644 --- a/examples/simuc/src/simavr/simavr.cpp +++ b/examples/simuc/src/simavr/simavr.cpp @@ -57,15 +57,20 @@ void SimAvr::load (struct StartParameters *params) { throw std::logic_error(error(AT, "firmware already loaded")); } - startParameters = params; firmware = (elf_firmware_t *) malloc(sizeof(elf_firmware_t)); - std::string filename = std::string(params->filename); if (params->mmcu != NULL) { // elf_read_firmware needs mmcu to malloc proper flash size strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu)); } - if (firmware == NULL || elf_read_firmware(filename.c_str(), firmware) != 0) { - throw std::logic_error(error(AT, "elf_read_firmware() from %s fails", filename.c_str())); + startParameters = params; + + for (int i = 0; params->filenames[i] != NULL; i++) { + std::string filename = std::string(params->filenames[i]); + printf("firmware file \"%s\"\n", params->filenames[i]); + + if (firmware == NULL || elf_read_firmware(filename.c_str(), firmware) != 0) { + throw std::logic_error(error(AT, "elf_read_firmware() from %s fails", filename.c_str())); + } } if (params->mmcu != NULL) { strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu)); @@ -110,7 +115,7 @@ void SimAvr::load (struct StartParameters *params) { } else { avr->gdb_port = 1234; } - printf("init with port=%d, mmcu=%s, f=%u, vcc=%d, avcc=%d, aref=%d, pc=0x%04x\n", + printf("init with gdb-port=%d, mmcu=%s, f=%u, vcc=%d, avcc=%d, aref=%d, pc=0x%04x\n", avr->gdb_port, firmware->mmcu, firmware->frequency, firmware->vcc, firmware->avcc, firmware->aref, params->pc < 0 ? 0 : params->pc); status.freqHz = firmware->frequency; @@ -604,7 +609,7 @@ void SimAvr::avrRun () { if (cancelThread) { cnt = -1; cancelThread = false; - } else { + } else if (!startParameters->nosync) { if (syncTime[0] != syncTime[1]) { syncTime[0] = syncTime[1]; if (syncTime[0]) { diff --git a/examples/simuc/src/simavr/simavr.h b/examples/simuc/src/simavr/simavr.h index 3d8d8e7..38c84f4 100644 --- a/examples/simuc/src/simavr/simavr.h +++ b/examples/simuc/src/simavr/simavr.h @@ -21,7 +21,7 @@ typedef enum { struct StartParameters { - char *filename; + const char **filenames; int gdbPort; int64_t frequency; const char *mmcu; @@ -30,6 +30,7 @@ struct StartParameters { int32_t vcc; int32_t avcc; int32_t aref; + int nosync; }; enum SimAvrState { @@ -55,6 +56,7 @@ typedef enum { typedef enum { ReadyForNewCommand = 0, CommandStatus, + CommandQuit, CommandInterrupt, CommandContinue, CommandStack -- 2.39.5