core: Deinitialize GDB in avr_terminate()
[simavr] / simavr / sim / sim_avr.c
index 8a1b994..d3e6706 100644 (file)
@@ -64,6 +64,10 @@ void avr_terminate(avr_t * avr)
 {
        if (avr->special_deinit)
                avr->special_deinit(avr);
+       if (avr->gdb) {
+               avr_deinit_gdb(avr);
+               avr->gdb = NULL;
+       }
        if (avr->vcd) {
                avr_vcd_close(avr->vcd);
                avr->vcd = NULL;
@@ -173,9 +177,25 @@ void avr_loadcode(avr_t * avr, uint8_t * code, uint32_t size, avr_flashaddr_t ad
        memcpy(avr->flash + address, code, size);
 }
 
+/**
+ * Accumulates sleep requests (and returns a sleep time of 0) until
+ * a minimum count of requested sleep microseconds are reached
+ * (low amounts cannot be handled accurately).
+ */
+static inline uint32_t avr_pending_sleep_usec(avr_t * avr, avr_cycle_count_t howLong)
+{
+       avr->sleep_usec += avr_cycles_to_usec(avr, howLong);
+       uint32_t usec = avr->sleep_usec;
+       if (usec > 200) {
+               avr->sleep_usec = 0;
+               return usec;
+       }
+       return 0;
+}
+
 void avr_callback_sleep_gdb(avr_t * avr, avr_cycle_count_t howLong)
 {
-       uint32_t usec = avr_cycles_to_usec(avr, howLong);
+       uint32_t usec = avr_pending_sleep_usec(avr, howLong);
        while (avr_gdb_processor(avr, usec))
                ;
 }
@@ -217,7 +237,6 @@ void avr_callback_run_gdb(avr_t * avr)
                if (!avr->sreg[S_I]) {
                        if (avr->log)
                                printf("simavr: sleeping with interrupts off, quitting gracefully\n");
-                       avr_terminate(avr);
                        avr->state = cpu_Done;
                        return;
                }
@@ -239,8 +258,10 @@ void avr_callback_run_gdb(avr_t * avr)
 
 void avr_callback_sleep_raw(avr_t * avr, avr_cycle_count_t howLong)
 {
-       uint32_t usec = avr_cycles_to_usec(avr, howLong);
-       usleep(usec);
+       uint32_t usec = avr_pending_sleep_usec(avr, howLong);
+       if (usec > 0) {
+               usleep(usec);
+       }
 }
 
 void avr_callback_run_raw(avr_t * avr)
@@ -270,7 +291,6 @@ void avr_callback_run_raw(avr_t * avr)
                if (!avr->sreg[S_I]) {
                        if (avr->log)
                                printf("simavr: sleeping with interrupts off, quitting gracefully\n");
-                       avr_terminate(avr);
                        avr->state = cpu_Done;
                        return;
                }
@@ -315,7 +335,7 @@ avr_make_mcu_by_name(
                        }
        }
        if (!maker) {
-               fprintf(stderr, "%s: AVR '%s' now known\n", __FUNCTION__, name);
+               fprintf(stderr, "%s: AVR '%s' not known\n", __FUNCTION__, name);
                return NULL;
        }