Commit 051807bbee1640db76b5493a2fea94eeca81d859
authorMichel Pollet <buserror@gmail.com>
Fri, 17 Feb 2017 09:20:55 +0000 (09:20 +0000)
committerMichel Pollet <buserror@gmail.com>
Fri, 17 Feb 2017 09:58:24 +0000 (09:58 +0000)
Now allow cool stuff, like tracking pending IRQs, their exact execution
time, and also a global one that shows which ones are running and when

Signed-off-by: Michel Pollet <buserror@gmail.com>
3 files changed:
simavr/sim/avr/avr_mcu_section.h
simavr/sim/sim_elf.c
simavr/sim/sim_elf.h

index e5289553d2e14577be4e77404236835d4be07e28..cb52dd74f791e6f12e2fc5811c862bec2f60b707 100644 (file)
@@ -61,6 +61,7 @@ enum {
        AVR_MMCU_TAG_VCD_PERIOD,
        AVR_MMCU_TAG_VCD_TRACE,
        AVR_MMCU_TAG_VCD_PORTPIN,
+       AVR_MMCU_TAG_VCD_IRQ,
        AVR_MMCU_TAG_PORT_EXTERNAL_PULL,
 };
 
@@ -207,6 +208,27 @@ struct avr_mmcu_vcd_trace_t {
                (((unsigned long)((_port)&0xff) << 8) | \
                ((_pin)&0xff)));
 
+/*!
+ * These allows you to add a trace showing how long an IRQ vector is pending,
+ * and also how long it is running. You can specify the IRQ as a vector name
+ * straight from the firmware file, and it will be named properly in the trace
+ */
+
+#define AVR_MCU_VCD_IRQ_TRACE(_vect_number, __what, _trace_name) \
+       const struct avr_mmcu_vcd_trace_t DO_CONCAT(DO_CONCAT(_, _tag), __LINE__) _MMCU_ = {\
+       .tag = AVR_MMCU_TAG_VCD_IRQ, \
+       .len = sizeof(struct avr_mmcu_vcd_trace_t) - 2,\
+       .mask = _vect_number, \
+       .what = (void*)__what, \
+       .name = _trace_name, \
+       };
+#define AVR_MCU_VCD_IRQ(_irq_name) \
+       AVR_MCU_VCD_IRQ_TRACE(_irq_name##_vect_num, 1, #_irq_name)
+#define AVR_MCU_VCD_IRQ_PENDING(_irq_name) \
+       AVR_MCU_VCD_IRQ_TRACE(_irq_name##_vect_num, 0, #_irq_name " pend")
+#define AVR_MCU_VCD_ALL_IRQ() \
+       AVR_MCU_VCD_IRQ_TRACE(0xff, 1, "IRQ")
+
 /*!
  * This tag allows you to specify the voltages used by your board
  * It is optional in most cases, but you will need it if you use
index 583011be48fc3ef188ec182da19422f9aab74124..595652caade1e5681cdec67de99f534134c1ee87 100644 (file)
@@ -128,7 +128,14 @@ avr_load_firmware(
        }
 
        for (int ti = 0; ti < firmware->tracecount; ti++) {
-               if (firmware->trace[ti].mask == 0xff ||
+               if (firmware->trace[ti].kind == AVR_MMCU_TAG_VCD_IRQ) {
+                       avr_irq_t * bit = avr_get_interrupt_irq(avr, firmware->trace[ti].mask);
+                       if (bit && firmware->trace[ti].addr < AVR_INT_IRQ_COUNT)
+                               avr_vcd_add_signal(avr->vcd,
+                                               &bit[firmware->trace[ti].addr],
+                                               firmware->trace[ti].mask == 0xff ? 8 : 1,
+                                               firmware->trace[ti].name);
+               } else if (firmware->trace[ti].mask == 0xff ||
                                firmware->trace[ti].mask == 0) {
                        // easy one
                        avr_irq_t * all = avr_iomem_getirq(avr,
@@ -226,6 +233,7 @@ elf_parse_mmcu_section(
                                                break;
                                        }
                        }       break;
+                       case AVR_MMCU_TAG_VCD_IRQ:
                        case AVR_MMCU_TAG_VCD_TRACE: {
                                uint8_t mask = src[0];
                                uint16_t addr = src[1] | (src[2] << 8);
@@ -233,6 +241,7 @@ elf_parse_mmcu_section(
                                AVR_LOG(NULL, LOG_TRACE,
                                                "AVR_MMCU_TAG_VCD_TRACE %04x:%02x - %s\n",
                                                addr, mask, name);
+                               firmware->trace[firmware->tracecount].kind = tag;
                                firmware->trace[firmware->tracecount].mask = mask;
                                firmware->trace[firmware->tracecount].addr = addr;
                                strncpy(firmware->trace[firmware->tracecount].name, name,
index 997b8d7e5eef75906284e604208b2cdbd6f2c4d2..6a6b490ea8def794be06626f4d7a0f42de09f816 100644 (file)
@@ -49,6 +49,7 @@ typedef struct elf_firmware_t {
        uint32_t        traceperiod;
        int                     tracecount;
        struct {
+               uint8_t kind;
                uint8_t mask;
                uint16_t addr;
                char    name[64];