Commit 9d7be97b6830f6e5a0e794b70b7b4a7ee95f049f
receivedSat, 30. Sep 2023, 17:06:46 (by user sx)
Sat, 30 Sep 2023 15:06:46 +0000 (17:06 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Sat, 30 Sep 2023 15:06:34 +0000 (17:06 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Sat, 30 Sep 2023 15:06:34 +0000 (17:06 +0200)
7 files changed:
examples/simuc/Makefile
examples/simuc/README.md
examples/simuc/src/main.cpp
examples/simuc/src/sim/sim.cpp
examples/simuc/src/sim/sim.h
examples/simuc/src/simavr/simavr.cpp
examples/simuc/src/simavr/simavr.h

index e3ee48d512b2d1c4c3a57cb67c26ecdb41760f67..c47fb4aead6129bf4f01da075f2f12290f5e470c 100644 (file)
@@ -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)
index 1453dd1ceb40591065c6e845ee103eb42dc03522..aded0e6ba82a821117ad4f65f89d667b046e5356 100644 (file)
@@ -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`
index 575165b6223acce97d498b904bf3b6d45895b092..040fbf3a25ab76f4c86bc7bfd2875a9d381615d6 100644 (file)
@@ -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(&params);
     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);
index 4ba1da09719a0a673e0e283ed59fe521d125e80d..c1ec1e3d17bd814acc9ab2750eaf8274bf81060d 100644 (file)
@@ -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());
index d980f263030046c59039160e28d73b1bd595f2de..eb6199241a560aa283e2c142d16189f9b1169426 100644 (file)
@@ -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);
index c3fc119c93625c3a19f88d96c9456b54808ae6f4..675f1b995bb6bc05dd0d5eb73c93dc066d5d71c5 100644 (file)
@@ -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;
index 0184f5b6a8d0bc9e2f5c34f49dbc34bb6a99527e..ff391bc49bb94d25c3f64341a41e0bf10d361b6a 100644 (file)
@@ -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);
 };