From 9b3c6f8a9467f49f02896965ffbdef0c371dd6cc Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Fri, 2 Dec 2022 18:58:06 +0100 Subject: [PATCH] simuc: configuration/initialization improvements --- Makefile.common | 2 +- examples/simuc/.vscode/settings.json | 1 + examples/simuc/src/main.cpp | 44 ++++++++--- examples/simuc/src/simavr/simavr.cpp | 110 ++++++++++++++++++++++----- examples/simuc/src/simavr/simavr.h | 1 + 5 files changed, 127 insertions(+), 31 deletions(-) diff --git a/Makefile.common b/Makefile.common index 6823733..0cfe527 100644 --- a/Makefile.common +++ b/Makefile.common @@ -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 diff --git a/examples/simuc/.vscode/settings.json b/examples/simuc/.vscode/settings.json index cb0d49d..4d4585d 100644 --- a/examples/simuc/.vscode/settings.json +++ b/examples/simuc/.vscode/settings.json @@ -70,6 +70,7 @@ "eeprom", "eesize", "evws", + "fusesize", "ioend", "lfcrlf", "lockbits", diff --git a/examples/simuc/src/main.cpp b/examples/simuc/src/main.cpp index 2da3f34..5606fa9 100644 --- a/examples/simuc/src/main.cpp +++ b/examples/simuc/src/main.cpp @@ -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 *)¶ms, 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", ¶ms.gdbPort); - } else if (strcmp(argv[i], "--frequency") == 0) { + } else if (strcmp(argv[i], "--frequency") == 0 && argc >= (i + 1)) { sscanf(argv[++i], "%" PRIu64, ¶ms.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", ¶ms.pc); } else { sscanf(argv[++i], "%d", ¶ms.pc); } - } else if (strcmp(argv[i], "--vcc") == 0) { + } else if (strcmp(argv[i], "--vcc") == 0 && argc >= (i + 1)) { sscanf(argv[++i], "%d", ¶ms.vcc); - } else if (strcmp(argv[i], "--avcc") == 0) { + } else if (strcmp(argv[i], "--avcc") == 0 && argc >= (i + 1)) { sscanf(argv[++i], "%d", ¶ms.avcc); - } else if (strcmp(argv[i], "--aref") == 0) { + } else if (strcmp(argv[i], "--aref") == 0 && argc >= (i + 1)) { sscanf(argv[++i], "%d", ¶ms.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; diff --git a/examples/simuc/src/simavr/simavr.cpp b/examples/simuc/src/simavr/simavr.cpp index ec59848..7c70c96 100644 --- a/examples/simuc/src/simavr/simavr.cpp +++ b/examples/simuc/src/simavr/simavr.cpp @@ -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); diff --git a/examples/simuc/src/simavr/simavr.h b/examples/simuc/src/simavr/simavr.h index 38c84f4..1f2090b 100644 --- a/examples/simuc/src/simavr/simavr.h +++ b/examples/simuc/src/simavr/simavr.h @@ -31,6 +31,7 @@ struct StartParameters { int32_t avcc; int32_t aref; int nosync; + int log; }; enum SimAvrState { -- 2.39.5