Commit 9b3c6f8a9467f49f02896965ffbdef0c371dd6cc
receivedFri, 2. Dec 2022, 18:58:17 (by user sx)
Fri, 2 Dec 2022 17:58:17 +0000 (18:58 +0100)
authorManfred Steiner <sx@htl-kaindorf.at>
Fri, 2 Dec 2022 17:58:06 +0000 (18:58 +0100)
committerManfred Steiner <sx@htl-kaindorf.at>
Fri, 2 Dec 2022 17:58:06 +0000 (18:58 +0100)
5 files changed:
Makefile.common
examples/simuc/.vscode/settings.json
examples/simuc/src/main.cpp
examples/simuc/src/simavr/simavr.cpp
examples/simuc/src/simavr/simavr.h

index 6823733c8a7a974f6c687ba48e56038c8aad5fc6..0cfe5279ed7859ed1767e4eece065566af5dc85f 100644 (file)
@@ -39,7 +39,7 @@ SIMAVR                := ${shell for p in . .. ../.. ../../..;do test -d $$p/simavr/sim && ech
 # get the first character of what the compiler says it is, unless it's 'x86_64' doh
 ARCH           := ${shell $(CC) -dumpmachine | sed -e 's/^x/i/' -e 's/\(.\).*/\1/'}
 
-CFLAGS         += -O2 -Wall -Wextra -Wno-unused-parameter \
+CFLAGS         += -O0 -Wall -Wextra -Wno-unused-parameter \
                        -Wno-unused-result -Wno-missing-field-initializers \
                        -Wno-sign-compare
 CFLAGS         += -g
index cb0d49d32ce110ef793e205aa46020a9d6ee7aa4..4d4585d395b2ab394667ba491a93c9bdeebba919 100644 (file)
@@ -70,6 +70,7 @@
         "eeprom",
         "eesize",
         "evws",
+        "fusesize",
         "ioend",
         "lfcrlf",
         "lockbits",
index 2da3f340902ca18b0ca36bf0e0097d62f6a3cac3..5606fa9a1737813d8e2a0155f012937a469dad68 100644 (file)
@@ -8,7 +8,7 @@
 #include "simavr/simavr.h"
 
 void printHelp () {
-    printf("simuc V0.0.3 (%s,%s)\n", __DATE__, __TIME__);
+    printf("simuc V0.0.4 (%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");
@@ -20,6 +20,8 @@ void printHelp () {
     printf("    --vcc ...          set voltage VCC in Volt\n");
     printf("    --avcc ...         set voltage AVCC in Volt\n");
     printf("    --aref ...         set voltage AREF in Volt\n\n");
+    printf("    --log ...          set simavr log level\n");
+    printf("                       (none, output, error, warning, trace or debug)\n");
     printf("  example:\n");
     printf("    simuc --mmcu atmega328p --frequency 16000000 --pc 0x7000 a.out\n");
     printf("    simuc --board arduino a.out\n\n");
@@ -32,6 +34,7 @@ struct SimUcInit {
 
 
 int main (int argc, char **argv) {
+    struct SimUcInit *simUcInit = NULL;
     struct StartParameters params;
     memset((void *)&params, 0, sizeof(params));
     params.filenames = NULL;
@@ -39,11 +42,12 @@ int main (int argc, char **argv) {
     params.frequency = -1;
     params.mmcu = NULL;
     params.board = BoardUnknown;
+    params.pc = -1;
     params.vcc = -1;
     params.avcc = -1;
     params.aref = -1;
     params.nosync = 0;
-    struct SimUcInit *simUcInit = NULL;
+    params.log = LOG_NONE;
 
     if (argc <= 1) {
         const char *fileName = ".simucinit";
@@ -133,27 +137,47 @@ int main (int argc, char **argv) {
             if (strcmp(argv[i], "--board") == 0 && argc >= (i + 1)) {
                 i++;
                 continue;
-            } else if (strcmp(argv[i], "--mmcu") == 0) {
+            } else if (strcmp(argv[i], "--mmcu") == 0 && argc >= (i + 1)) {
                 params.mmcu = argv[++i];
-            } else if (strcmp(argv[i], "--port") == 0) {
+            } else if (strcmp(argv[i], "--port") == 0 && argc >= (i + 1)) {
                 sscanf(argv[++i], "%d", &params.gdbPort);
-            } else if (strcmp(argv[i], "--frequency") == 0) {
+            } else if (strcmp(argv[i], "--frequency") == 0 && argc >= (i + 1)) {
                 sscanf(argv[++i], "%" PRIu64, &params.frequency);
-            } else if (strcmp(argv[i], "--pc") == 0) {
+            } else if (strcmp(argv[i], "--pc") == 0 && argc >= (i + 1)) {
                 i++;
                 if (argv[i][0] == '0' && argv[i][1] == 'x') {
                     sscanf(&argv[i][2], "%x", &params.pc);
                 } else {
                     sscanf(argv[++i], "%d", &params.pc);
                 }
-            } else if (strcmp(argv[i], "--vcc") == 0) {
+            } else if (strcmp(argv[i], "--vcc") == 0 && argc >= (i + 1)) {
                 sscanf(argv[++i], "%d", &params.vcc);
-            } else if (strcmp(argv[i], "--avcc") == 0) {
+            } else if (strcmp(argv[i], "--avcc") == 0 && argc >= (i + 1)) {
                 sscanf(argv[++i], "%d", &params.avcc);
-            } else if (strcmp(argv[i], "--aref") == 0) {
+            } else if (strcmp(argv[i], "--aref") == 0 && argc >= (i + 1)) {
                 sscanf(argv[++i], "%d", &params.aref);
-            } else if (strcmp(argv[i], "--nosync") == 0) {
+            } else if (strcmp(argv[i], "--nosync") == 0 && argc >= (i + 1)) {
                 params.nosync = 1;
+            } else if (strcmp(argv[i], "--log") == 0 && argc >= (i + 1)) {
+                params.nosync = 1;
+                i++;
+                if (strcmp("none", argv[i]) == 0) {
+                    params.log = LOG_NONE;
+                } else if (strcmp("output", argv[i]) == 0) {
+                    params.log = LOG_OUTPUT;
+                } else if (strcmp("error", argv[i]) == 0) {
+                    params.log = LOG_ERROR;
+                } else if (strcmp("warning", argv[i]) == 0) {
+                    params.log = LOG_WARNING;
+                } else if (strcmp("trace", argv[i]) == 0) {
+                    params.log = LOG_TRACE;
+                } else if (strcmp("debug", argv[i]) == 0) {
+                    params.log = LOG_DEBUG;
+                } else {
+                    fprintf(stderr, "ERROR: invalid option %s, use --help to show usage\n\n", argv[i - 1]);
+                    return 1;
+                }
+
             } else {
                 fprintf(stderr, "ERROR: invalid option %s, use --help to show usage\n\n", argv[i]);
                 return 1;
index ec59848312dba0c83cb2e652c0637458981d89eb..7c70c960b08fb498dbe6b4a3f438dc13f2f099e1 100644 (file)
@@ -67,10 +67,10 @@ void SimAvr::load (struct 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()));
                        }
+                       printf("--------------------------------------------------------------------\n");
                }
                if (params->mmcu != NULL) {
                        strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu));
@@ -115,35 +115,105 @@ void SimAvr::load (struct StartParameters *params) {
                } else {
                        avr->gdb_port = 1234;
                }
-               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);
+               if (params->log >= LOG_TRACE) {
+                       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;
 
-               if (avr_init(avr) != 0) {
-                       throw std::logic_error(error(AT, "avr_init() fails"));
+               // firmware->eeprom = (uint8_t *)malloc(1024);
+               // for (int i = 0; i < 1024; i++) {
+               //      firmware->eeprom[i] = 0xff;
+               // }
+               // firmware->eeprom[0] = 0x01;
+               // firmware->eesize = 1024;
+
+               // fuse values set in section .fuse (ORIGIN = 0x820000)
+           // lock bit values set in section .lock (ORIGIN = 0x830000)
+               printf("Fuse- and Lockbits:");
+               if (firmware->fusesize == 0 && firmware->lockbits == NULL) {
+                       printf(" not defined (neither section .eeprom nor section .lock found");
+               } else {
+                       if (firmware->fusesize >= 0) {
+                               for (uint32_t i = 0; i < firmware->fusesize; i++) {
+                                       switch (i) {
+                                               case 0: printf("  LFUSE"); break;
+                                               case 1: printf("  HFUSE"); break;
+                                               case 2: printf("  EFUSE"); break;
+                                               default: printf("  ?="); break;
+                                       }
+                                       printf("=0x%02x", firmware->fuse[i]);
+                               }
+                       }
+                       if (firmware->lockbits != NULL) {
+                               printf("  LOCK=0x%02x", *firmware->lockbits);
+                       }
+                       printf("\n");
+                       if (firmware->fusesize >= 2) {
+                               if (strcmp("atmega324p", firmware->mmcu) == 0 ||
+                                   strcmp("atmega328p", firmware->mmcu) == 0 || 
+                                       strcmp("atmega16", firmware->mmcu) == 0) {
+
+                                       uint8_t bootsz = ~(firmware->fuse[1] >> 1) & 0x03;
+                                       uint8_t bootrst = ~(firmware->fuse[1]) & 0x01;
+                                       if (bootrst && startParameters->pc < 0) {
+                                               switch (bootsz) {
+                                                       case 0: avr->reset_pc = 0x7000; break; 
+                                                       case 1: avr->reset_pc = 0x7800; break; 
+                                                       case 2: avr->reset_pc = 0x7c00; break; 
+                                                       case 3: avr->reset_pc = 0x7e00; break; 
+                                               }
+                                               printf("reset on 0x%04x (HFUSE-> BOOTRST=%d, BOOTSZ=%d%d)\n", avr->reset_pc, bootrst, bootsz & 0x02, bootsz & 0x01);
+                                       }
+                               } else {
+                                       printf("WARNING: cannot decode FUSE (%s not supported)", firmware->mmcu);
+                               }
+                       }
+               }
+
+               printf("EEPROM: ");
+               if (firmware->eesize == 0) {
+                       printf("not defined (no section .eeprom found)");
+               } else {
+                       printf("%d bytes defined (", firmware->eesize);
+                       for (uint32_t i = 0; i < firmware->eesize; i++) {
+                               if (i > 6) {
+                                       printf(" ...");
+                                       break;
+                               } else if (i > 0) {
+                                       printf(" ");
+                               }
+                               printf("0x%02x", firmware->eeprom[i]);
+                       }
+                       printf(")\n");
+               }
+
+               if (params->pc >= 0) {
+                       avr->reset_pc = params->pc;
+                       printf("reset on 0x%04x (option --pc)\n", avr->reset_pc);
                }
 
-               
-               firmware->eeprom = (uint8_t *)malloc(1024);
-               for (int i = 0; i < 1024; i++) {
-                       firmware->eeprom[i] = 0xff;
+               avr->log = params->log;
+               printf("simavr log level: ");
+               switch (avr->log) {
+                       case LOG_NONE: printf("NONE\n"); break;
+                       case LOG_OUTPUT: printf("OUTPUT\n"); break;
+                       case LOG_ERROR: printf("ERROR\n"); break;
+                       case LOG_WARNING: printf("WARNING\n"); break;
+                       case LOG_TRACE: printf("TRACE\n"); break;
+                       case LOG_DEBUG: printf("DEBUG\n"); break;
+                       default: printf(" ? (=%d)\n", avr->log); break;
+               }
+
+               if (avr_init(avr) != 0) {
+                       throw std::logic_error(error(AT, "avr_init() fails"));
                }
-               firmware->eeprom[0] = 0xf0;
-               firmware->eesize = 1024;
 
                avr_load_firmware(avr, firmware);
                status.state = StateLoaded;
 
-               avr->fuse[AVR_FUSE_LOW] = 0xe7;
-               avr->fuse[AVR_FUSE_HIGH] = 0xd8;
-               avr->fuse[AVR_FUSE_EXT] = 0xff;
-               avr->lockbits = 0xff;
-
-               avr->gdb_port = 1234;
+               avr->gdb_port = params->gdbPort > 0 ? params->gdbPort : 1234;
                avr_gdb_init(avr);
-               if (params->pc >= 0) {
-                       avr->pc = params->pc;
-               }
 
                pthread_mutex_unlock(&lock);
 
index 38c84f4670f2265a20b038ffe4e40ec3a61f4cfd..1f2090b3dfd931dfdc742d8c054f67eaa831da5e 100644 (file)
@@ -31,6 +31,7 @@ struct StartParameters {
     int32_t avcc;
     int32_t aref;
        int nosync;
+       int log;
 };
 
 enum SimAvrState {