Commit cb338bf147fbd35c3e4e214425d0e6b3cecc5396
receivedFri, 2. Dec 2022, 13:08:44 (by user sx)
Fri, 2 Dec 2022 12:08:44 +0000 (13:08 +0100)
authorManfred Steiner <sx@htl-kaindorf.at>
Fri, 2 Dec 2022 12:08:40 +0000 (13:08 +0100)
committerManfred Steiner <sx@htl-kaindorf.at>
Fri, 2 Dec 2022 12:08:40 +0000 (13:08 +0100)
7 files changed:
examples/simuc/.gitignore
examples/simuc/.vscode/launch.json
examples/simuc/Makefile
examples/simuc/src/main.cpp
examples/simuc/src/sim/sim.cpp
examples/simuc/src/simavr/simavr.cpp
examples/simuc/src/simavr/simavr.h

index d45c0b1afcbb17fa07042a521d36471840738d86..b0d2201a5a0a3e274a64963459a90188ba7888d3 100644 (file)
@@ -1,3 +1,6 @@
 dist/**
 build/**
 **/*.vcd
+**/.simucinit
+**/.gdbinit
+**/.gdb_history
index c6fe1da95f0bc14b24f37315dabcd96e9c3dcd00..4c40c7b04869fba69971bb7af3171ad204886949 100644 (file)
@@ -10,7 +10,7 @@
             "request": "launch",
             "program": "${workspaceFolder}/dist/simuc",
             "args": [],
-            "stopAtEntry": true,
+            "stopAtEntry": false,
             "cwd": "${workspaceFolder}",
             "environment": [],
             "externalConsole": false,
index 8a265acdccea800f117cd4bbaa38763c00597115..01a98a04100a6fb31dc3ec6dc4d6f10a01924154 100644 (file)
@@ -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
 
index b75ab45b4fb575473de5e1c8d05fab6a79c0ed51..161957cca603bde01e1f6d29a935b626e2d0d12e 100644 (file)
@@ -1,16 +1,19 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
+#include <string>
+#include <regex>
 
 #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 *)&params, 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<std::string::iterator> i(sTrimmed.begin(), sTrimmed.end(), e, -1);
+            std::regex_token_iterator<std::string::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", &params.avcc);
             } else if (strcmp(argv[i], "--aref") == 0) {
                 sscanf(argv[++i], "%d", &params.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(&params);
     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);
index 32a23b6cc4370f739a5f30cf8da44f4110a55713..7f0e3e3b9ce52c49faeeebe7feec8efc25d685b8 100644 (file)
@@ -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()));
index 444e671f8b5a5377e60cfdcd02ea806543ceba2a..ec59848312dba0c83cb2e652c0637458981d89eb 100644 (file)
@@ -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]) {
index 3d8d8e7c2314897852fb8c2eae12da3fc00f75c4..38c84f4670f2265a20b038ffe4e40ec3a61f4cfd 100644 (file)
@@ -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