From 9d7be97b6830f6e5a0e794b70b7b4a7ee95f049f Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Sat, 30 Sep 2023 17:06:34 +0200 Subject: [PATCH] command for reset and power on reset --- examples/simuc/Makefile | 1 - examples/simuc/README.md | 2 +- examples/simuc/src/main.cpp | 35 +++++++++++++++------- examples/simuc/src/sim/sim.cpp | 6 ++-- examples/simuc/src/sim/sim.h | 2 +- examples/simuc/src/simavr/simavr.cpp | 45 ++++++++++++++++++++++------ examples/simuc/src/simavr/simavr.h | 9 ++++-- 7 files changed, 72 insertions(+), 28 deletions(-) diff --git a/examples/simuc/Makefile b/examples/simuc/Makefile index e3ee48d..c47fb4a 100644 --- a/examples/simuc/Makefile +++ b/examples/simuc/Makefile @@ -51,7 +51,6 @@ ifeq ($(ARCH), arm-linux-gnueabihf) DEBARCH="armhf" endif -DEBVERSION := 0.0.5~1 DEBNAME := dpkg/htl-simuc_version_arch DEBSRC := dpkg/htl-simuc_version_arch DEBARCH := $(shell dpkg --print-architecture) diff --git a/examples/simuc/README.md b/examples/simuc/README.md index 1453dd1..aded0e6 100644 --- a/examples/simuc/README.md +++ b/examples/simuc/README.md @@ -66,7 +66,7 @@ Executable `simuc` available in folder `dist` ```sh user@host:~ $ cd ~/simavr/examples/simuc -user@host:~/simavr/examples/simuc $ make deb +user@host:~/simavr/examples/simuc $ export DEBVERSION="0.0.6~1"; make deb ``` Debian packet available in folder `dpkg` diff --git a/examples/simuc/src/main.cpp b/examples/simuc/src/main.cpp index 575165b..040fbf3 100644 --- a/examples/simuc/src/main.cpp +++ b/examples/simuc/src/main.cpp @@ -7,8 +7,12 @@ #include "sim/sim.h" #include "simavr/simavr.h" +void printVersion () { + printf("simuc V0.0.6 (%s,%s)\n", __DATE__, __TIME__); +} + void printHelp () { - printf("simuc V0.0.5 (%s,%s)\n", __DATE__, __TIME__); + printVersion(); 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"); @@ -190,22 +194,33 @@ int main (int argc, char **argv) { } if (params.filenames == NULL || params.filenames[0] == NULL) { + printVersion(); printf("ERROR: missing target elf file, use --help to show usage\n\n"); return 1; } - printf("--------------------------------------------------------------------\n"); + printf("----------------------------------------------------------------------\n"); init(¶ms); if (errno == 1) { return 1; } - printf("--------------------------------------------------------------------\n"); - printf("available commands: i (interrupt), c (continue), s (stack), r (reset), q (quit)\n"); - printf("--------------------------------------------------------------------\n"); + printf("----------------------------------------------------------------------\n"); + printf("available commands:\n"); + printf(" b (break), c (continue), s (stack), r (reset), p (power), q (quit)\n"); + printf("----------------------------------------------------------------------\n"); printf("init done - press key to start\n"); - getchar(); - printf("--------------------------------------------------------------------\n"); - start(); + char c = getchar(); + getchar(); // remove line feed from stdin + printf("----------------------------------------------------------------------\n"); + + switch (c) { + case 'b': start(CommandBreak, NULL); break; + case 's': start(CommandStack, NULL); break; + case 'r': start(CommandReset, NULL); break; + case 'p': start(CommandPower, NULL); break; + case 'q': return 0; + default: start(ReadyForNewCommand, NULL); break; + } // int cnt = 0; char *line = NULL; @@ -223,7 +238,7 @@ int main (int argc, char **argv) { // } if (getline(&line, &size, stdin) > 0) { - const char *commands[] = { "quit", "interrupt", "continue", "stack", "reset" }; + const char *commands[] = { "quit", "break", "continue", "stack", "reset", "power" }; try { int foundIndex = -1; int foundCnt = 0; @@ -246,7 +261,7 @@ int main (int argc, char **argv) { } } } - // printf("foundCnt=%d foundIndex=%d command=%s\n", foundCnt, foundIndex, foundIndex >= 0 ? commands[foundIndex] : ""); + printf("foundCnt=%d foundIndex=%d command=%s\n", foundCnt, foundIndex, foundIndex >= 0 ? commands[foundIndex] : ""); if (foundCnt == 1 || length == 0) { EnumSimAvrCommand cmd = (EnumSimAvrCommand)(foundCnt > 0 ? foundIndex + 2 : 1); setCommand(cmd, NULL); diff --git a/examples/simuc/src/sim/sim.cpp b/examples/simuc/src/sim/sim.cpp index 4ba1da0..c1ec1e3 100644 --- a/examples/simuc/src/sim/sim.cpp +++ b/examples/simuc/src/sim/sim.cpp @@ -154,7 +154,7 @@ void init (struct StartParameters *param) { } simavr.load(param); - printf("--------------------------------------------------------------------\n"); + printf("----------------------------------------------------------------------\n"); simavr.setUartDumpEnabled(false); // simavr.registerIoWrite(PORTB, handleWritePortB); simavr.setUartPtyEnabled(0, true); @@ -199,9 +199,9 @@ void shutdown () { } } -void start () { +void start (EnumSimAvrCommand cmd, void *param) { try { - simavr.start(); + simavr.start(cmd, param); } catch (std::exception& e) { lastErrorMessage = "start() fails, caused by " + std::string(e.what()); diff --git a/examples/simuc/src/sim/sim.h b/examples/simuc/src/sim/sim.h index d980f26..eb61992 100644 --- a/examples/simuc/src/sim/sim.h +++ b/examples/simuc/src/sim/sim.h @@ -22,7 +22,7 @@ typedef enum { extern void init (struct StartParameters *param); extern void shutdown (); extern const char * lastError (); -extern void start (); +extern void start (EnumSimAvrCommand cmd, void *param); extern void stop (); extern void setCommand (EnumSimAvrCommand cmd, void *param); extern void addEvent (EnumSimEvent event); diff --git a/examples/simuc/src/simavr/simavr.cpp b/examples/simuc/src/simavr/simavr.cpp index c3fc119..675f1b9 100644 --- a/examples/simuc/src/simavr/simavr.cpp +++ b/examples/simuc/src/simavr/simavr.cpp @@ -70,7 +70,7 @@ void SimAvr::load (struct StartParameters *params) { 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"); + printf("----------------------------------------------------------------------\n"); } if (params->mmcu != NULL) { strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu)); @@ -131,7 +131,7 @@ void SimAvr::load (struct StartParameters *params) { printf("EEPROM: "); if (firmware->eesize == 0) { - printf("not defined (no section .eeprom found)"); + printf("not defined (no section .eeprom found)\n"); } else { printf("%d bytes defined (", firmware->eesize); for (uint32_t i = 0; i < firmware->eesize; i++) { @@ -155,7 +155,7 @@ void SimAvr::load (struct StartParameters *params) { if (avr_init(avr) != 0) { throw std::logic_error(error(AT, "avr_init() fails")); } - + // now we can chang log level to desired value avr->log = params->log; printf("simavr log level: "); @@ -325,7 +325,7 @@ uint32_t SimAvr::getTargetFrequency () { } } -void SimAvr::start () { +void SimAvr::start (EnumSimAvrCommand cmd, void *param) { if (pthread_mutex_lock(&lock)) { throw std::logic_error(error(AT, "start() fails caused by mutex error")); } @@ -339,6 +339,7 @@ void SimAvr::start () { if (avr == NULL) { throw std::logic_error("avr not ready (check if load done)"); } + command = cmd; syncTime[0] = !syncTime[1]; avrRunThread = new std::thread(&SimAvr::avrRun, this); pthread_mutex_unlock(&lock); @@ -546,6 +547,23 @@ bool SimAvr::sprintfLedStatus (char *s, size_t size, bool onlyOnChange) { return rv; } +void SimAvr::reset (ResetType type) { + avr_reset(avr); + + switch (type) { + case powerOn: avr_regbit_set(avr, avr->reset_flags.porf); break; + case external: avr_regbit_set(avr, avr->reset_flags.extrf); break; + case brownout: avr_regbit_set(avr, avr->reset_flags.borf); break; + case watchdog: avr_regbit_set(avr, avr->reset_flags.wdrf); break; + } + + // bugfix, also clear r0..r31, and set SP to 0 + for (int i = 0; i < 0x20; i++) { + avr->data[i] = 0; + } + _avr_sp_set(avr, 0); +} + void SimAvr::avrRun () { long cnt = 0; @@ -730,7 +748,7 @@ void SimAvr::avrRun () { printf(" %s\n", s); break; } - case CommandInterrupt: { + case CommandBreak: { if (avr->state == cpu_Running) { avr->state = cpu_Stopped; } @@ -767,10 +785,19 @@ void SimAvr::avrRun () { } case CommandReset: { - avr_reset(avr); - printf("RESET done -> PC=0x%04x, use command 'continue' to start!\n", avr->pc); - avr->state = cpu_Stopped; - break; + reset(external); + printf("\n\n----------------------------------------------------------------\n"); + printf("RESET done (registers set to init value, SRAM remains unchanged)\n"); + command = CommandBreak; + continue; + } + + case CommandPower: { + reset(powerOn); + printf("\n\n-----------------------------------------------\n"); + printf("Power-On done (SRAM cleared and power-on reset)\n"); + command = CommandBreak; + continue; } default: break; diff --git a/examples/simuc/src/simavr/simavr.h b/examples/simuc/src/simavr/simavr.h index 0184f5b..ff391bc 100644 --- a/examples/simuc/src/simavr/simavr.h +++ b/examples/simuc/src/simavr/simavr.h @@ -58,10 +58,11 @@ typedef enum { ReadyForNewCommand = 0, CommandStatus, CommandQuit, - CommandInterrupt, + CommandBreak, CommandContinue, CommandStack, - CommandReset + CommandReset, + CommandPower } EnumSimAvrCommand; struct SimAvrStatus { @@ -80,6 +81,7 @@ struct SimAvrEvent { class SimAvr; typedef void (*avrsim_io_write_callback_t)(avr_t *avr, avr_io_addr_t addr, uint8_t value, SimAvr *simavr); +typedef enum { powerOn = 1, external = 2, brownout = 4, watchdog = 8 } ResetType; class SimAvr { @@ -94,7 +96,7 @@ public: public: void load (struct StartParameters *params); void shutdown (); - void start (); + void start (EnumSimAvrCommand cmd, void *param); void stop (); void addEvent (int event); void setUartDumpEnabled (bool enabled); @@ -127,6 +129,7 @@ private: uint64_t timeMicrosOnSyncStart = 0; Semaphore eventCount; uart_pty_t *uartPty[2] = { NULL, NULL }; + void reset (ResetType type); void printCyclesAndElapsedTime (); bool sprintfLedStatus (char *s, size_t size, bool onlyOnChange); }; -- 2.39.5