Data Watch-point and Trace unit(DWT) interface.
Dwt.h@0:37014c6bb5cd, 2017-10-08 (annotated)
- Committer:
- YasuhiroKawai
- Date:
- Sun Oct 08 05:51:12 2017 +0000
- Revision:
- 0:37014c6bb5cd
Initial revision
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
YasuhiroKawai | 0:37014c6bb5cd | 1 | /** |
YasuhiroKawai | 0:37014c6bb5cd | 2 | * DWT class |
YasuhiroKawai | 0:37014c6bb5cd | 3 | */ |
YasuhiroKawai | 0:37014c6bb5cd | 4 | #ifndef DWT_H |
YasuhiroKawai | 0:37014c6bb5cd | 5 | #define DWT_H |
YasuhiroKawai | 0:37014c6bb5cd | 6 | |
YasuhiroKawai | 0:37014c6bb5cd | 7 | /** |
YasuhiroKawai | 0:37014c6bb5cd | 8 | * The Data Watchpoint and Trace unit intarface |
YasuhiroKawai | 0:37014c6bb5cd | 9 | * |
YasuhiroKawai | 0:37014c6bb5cd | 10 | * @code |
YasuhiroKawai | 0:37014c6bb5cd | 11 | * #include "mbed.h" |
YasuhiroKawai | 0:37014c6bb5cd | 12 | * #include "Dwt.h" |
YasuhiroKawai | 0:37014c6bb5cd | 13 | * |
YasuhiroKawai | 0:37014c6bb5cd | 14 | * Serial pc(SERIAL_TX, SERIAL_RX); |
YasuhiroKawai | 0:37014c6bb5cd | 15 | * Dwt dwt; |
YasuhiroKawai | 0:37014c6bb5cd | 16 | * |
YasuhiroKawai | 0:37014c6bb5cd | 17 | * int main() { |
YasuhiroKawai | 0:37014c6bb5cd | 18 | * uint32_t t; |
YasuhiroKawai | 0:37014c6bb5cd | 19 | * uint32_t n; |
YasuhiroKawai | 0:37014c6bb5cd | 20 | * |
YasuhiroKawai | 0:37014c6bb5cd | 21 | * dwt.enableCYCCNT(); |
YasuhiroKawai | 0:37014c6bb5cd | 22 | * dwt.resetCYCCNT(); |
YasuhiroKawai | 0:37014c6bb5cd | 23 | * dwt.startCount(); |
YasuhiroKawai | 0:37014c6bb5cd | 24 | * <Write some codes to measure the execution cycle here.> |
YasuhiroKawai | 0:37014c6bb5cd | 25 | * dwt.stopCount(); |
YasuhiroKawai | 0:37014c6bb5cd | 26 | * t = dwt.getCYCCNT(); |
YasuhiroKawai | 0:37014c6bb5cd | 27 | * n = dwt.getInstructionCount(); |
YasuhiroKawai | 0:37014c6bb5cd | 28 | * pc.printf("%d cycles, %d instructions.\n", t, n); |
YasuhiroKawai | 0:37014c6bb5cd | 29 | * } |
YasuhiroKawai | 0:37014c6bb5cd | 30 | * @endcode |
YasuhiroKawai | 0:37014c6bb5cd | 31 | */ |
YasuhiroKawai | 0:37014c6bb5cd | 32 | #define DWT_MAJOR_VERSION (0) |
YasuhiroKawai | 0:37014c6bb5cd | 33 | #define DWT_MINOR_VERSION (1) |
YasuhiroKawai | 0:37014c6bb5cd | 34 | |
YasuhiroKawai | 0:37014c6bb5cd | 35 | class Dwt |
YasuhiroKawai | 0:37014c6bb5cd | 36 | { |
YasuhiroKawai | 0:37014c6bb5cd | 37 | /** |
YasuhiroKawai | 0:37014c6bb5cd | 38 | * The Data Watchpoint and Trace unit intarface |
YasuhiroKawai | 0:37014c6bb5cd | 39 | */ |
YasuhiroKawai | 0:37014c6bb5cd | 40 | public: |
YasuhiroKawai | 0:37014c6bb5cd | 41 | |
YasuhiroKawai | 0:37014c6bb5cd | 42 | /** |
YasuhiroKawai | 0:37014c6bb5cd | 43 | * Create a DWT interface |
YasuhiroKawai | 0:37014c6bb5cd | 44 | */ |
YasuhiroKawai | 0:37014c6bb5cd | 45 | Dwt(); |
YasuhiroKawai | 0:37014c6bb5cd | 46 | |
YasuhiroKawai | 0:37014c6bb5cd | 47 | /// Returns whether the implementation supports trace sampling and exception tracing. |
YasuhiroKawai | 0:37014c6bb5cd | 48 | /// true : Trace sampling and exception tracing supported. |
YasuhiroKawai | 0:37014c6bb5cd | 49 | /// false : Trace sampling and exception tracing not supported. |
YasuhiroKawai | 0:37014c6bb5cd | 50 | bool isTRCPKT_Available(); |
YasuhiroKawai | 0:37014c6bb5cd | 51 | /// Returns whether the implementation includes external match signals, CMPMATCH[N]. |
YasuhiroKawai | 0:37014c6bb5cd | 52 | bool isEXTTRIG_Available(); |
YasuhiroKawai | 0:37014c6bb5cd | 53 | /// Returns whether the implementation supports a cycle counter. |
YasuhiroKawai | 0:37014c6bb5cd | 54 | bool isCYCCNT_Available(); |
YasuhiroKawai | 0:37014c6bb5cd | 55 | /// Returns whether the implementation supports the profiling counters. |
YasuhiroKawai | 0:37014c6bb5cd | 56 | bool isPRFCNT_Available(); |
YasuhiroKawai | 0:37014c6bb5cd | 57 | |
YasuhiroKawai | 0:37014c6bb5cd | 58 | void enableCYCCNT(); |
YasuhiroKawai | 0:37014c6bb5cd | 59 | void disableCYCCNT(); |
YasuhiroKawai | 0:37014c6bb5cd | 60 | inline void startCYCCNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 61 | _regs->DWT_CTRL |= CYCCNTENA; |
YasuhiroKawai | 0:37014c6bb5cd | 62 | } |
YasuhiroKawai | 0:37014c6bb5cd | 63 | inline void stopCYCCNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 64 | _regs->DWT_CTRL &= ~CYCCNTENA; |
YasuhiroKawai | 0:37014c6bb5cd | 65 | } |
YasuhiroKawai | 0:37014c6bb5cd | 66 | inline void resetCYCCNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 67 | _regs->DWT_CYCCNT = 0; |
YasuhiroKawai | 0:37014c6bb5cd | 68 | } |
YasuhiroKawai | 0:37014c6bb5cd | 69 | inline uint32_t getCYCCNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 70 | return(_regs->DWT_CYCCNT); |
YasuhiroKawai | 0:37014c6bb5cd | 71 | } |
YasuhiroKawai | 0:37014c6bb5cd | 72 | inline uint32_t readDwtCtrl() { |
YasuhiroKawai | 0:37014c6bb5cd | 73 | return(_regs->DWT_CTRL); |
YasuhiroKawai | 0:37014c6bb5cd | 74 | } |
YasuhiroKawai | 0:37014c6bb5cd | 75 | inline uint32_t getNumComp() { |
YasuhiroKawai | 0:37014c6bb5cd | 76 | return((_regs->DWT_CTRL & NUMCOMP_MASK) >> NUMCOMP_POS); |
YasuhiroKawai | 0:37014c6bb5cd | 77 | } |
YasuhiroKawai | 0:37014c6bb5cd | 78 | void setEvent(uint32_t ev); |
YasuhiroKawai | 0:37014c6bb5cd | 79 | inline uint32_t getEvent() { |
YasuhiroKawai | 0:37014c6bb5cd | 80 | return(_regs->DWT_CTRL & EVENA_MASK); |
YasuhiroKawai | 0:37014c6bb5cd | 81 | } |
YasuhiroKawai | 0:37014c6bb5cd | 82 | /// Returns additional cycles required to execute multicycle instructions and |
YasuhiroKawai | 0:37014c6bb5cd | 83 | /// instruction fetch stalls. |
YasuhiroKawai | 0:37014c6bb5cd | 84 | inline uint32_t getCPICNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 85 | return(_regs->DWT_CPICNT); |
YasuhiroKawai | 0:37014c6bb5cd | 86 | } |
YasuhiroKawai | 0:37014c6bb5cd | 87 | /// Returns the total cycles spent in exception processing. |
YasuhiroKawai | 0:37014c6bb5cd | 88 | inline uint32_t getEXCCNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 89 | return(_regs->DWT_EXCCNT); |
YasuhiroKawai | 0:37014c6bb5cd | 90 | } |
YasuhiroKawai | 0:37014c6bb5cd | 91 | /// Returns the total number of cycles that the processor is sleeping. |
YasuhiroKawai | 0:37014c6bb5cd | 92 | inline uint32_t getSLEEPCNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 93 | return(_regs->DWT_SLEEPCNT); |
YasuhiroKawai | 0:37014c6bb5cd | 94 | } |
YasuhiroKawai | 0:37014c6bb5cd | 95 | /// Returns the additional cycles required to execute all load or |
YasuhiroKawai | 0:37014c6bb5cd | 96 | /// store instructions. |
YasuhiroKawai | 0:37014c6bb5cd | 97 | inline uint32_t getLSUCNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 98 | return(_regs->DWT_LSUCNT); |
YasuhiroKawai | 0:37014c6bb5cd | 99 | } |
YasuhiroKawai | 0:37014c6bb5cd | 100 | /// Returns the number of instructions that takes 0 cycles. |
YasuhiroKawai | 0:37014c6bb5cd | 101 | inline uint32_t getFOLDCNT() { |
YasuhiroKawai | 0:37014c6bb5cd | 102 | return(_regs->DWT_FOLDCNT); |
YasuhiroKawai | 0:37014c6bb5cd | 103 | } |
YasuhiroKawai | 0:37014c6bb5cd | 104 | /// start all counters |
YasuhiroKawai | 0:37014c6bb5cd | 105 | inline void startCount() { |
YasuhiroKawai | 0:37014c6bb5cd | 106 | _regs->DWT_CTRL |= (Dwt::CPIEVTENA | Dwt::EXCEVTENA | Dwt::SLEEPEVTENA | |
YasuhiroKawai | 0:37014c6bb5cd | 107 | Dwt::LSUEVTENA | Dwt::FOLDEVTENA | Dwt::CYCCNTENA); |
YasuhiroKawai | 0:37014c6bb5cd | 108 | } |
YasuhiroKawai | 0:37014c6bb5cd | 109 | /// stop all counters |
YasuhiroKawai | 0:37014c6bb5cd | 110 | inline void stopCount() { |
YasuhiroKawai | 0:37014c6bb5cd | 111 | _regs->DWT_CTRL &= ~(Dwt::CPIEVTENA | Dwt::EXCEVTENA | Dwt::SLEEPEVTENA | |
YasuhiroKawai | 0:37014c6bb5cd | 112 | Dwt::LSUEVTENA | Dwt::FOLDEVTENA | Dwt::CYCCNTENA); |
YasuhiroKawai | 0:37014c6bb5cd | 113 | } |
YasuhiroKawai | 0:37014c6bb5cd | 114 | /// Returns number of executed instructions. |
YasuhiroKawai | 0:37014c6bb5cd | 115 | uint32_t getInstructionCount(); |
YasuhiroKawai | 0:37014c6bb5cd | 116 | private: |
YasuhiroKawai | 0:37014c6bb5cd | 117 | typedef struct { |
YasuhiroKawai | 0:37014c6bb5cd | 118 | uint32_t DWT_COMP; ///< Provides a reference value for use by |
YasuhiroKawai | 0:37014c6bb5cd | 119 | ///< comparator n. |
YasuhiroKawai | 0:37014c6bb5cd | 120 | uint32_t DWT_MASK; ///< Provides the size of the ignore mask applied |
YasuhiroKawai | 0:37014c6bb5cd | 121 | ///< to the access address for address range |
YasuhiroKawai | 0:37014c6bb5cd | 122 | ///< matching by comparator n. |
YasuhiroKawai | 0:37014c6bb5cd | 123 | uint32_t DWT_FUNCTION; ///< Controls the operation of comparator n. |
YasuhiroKawai | 0:37014c6bb5cd | 124 | uint32_t reserved; |
YasuhiroKawai | 0:37014c6bb5cd | 125 | } dwt_cmp_regs_t; |
YasuhiroKawai | 0:37014c6bb5cd | 126 | |
YasuhiroKawai | 0:37014c6bb5cd | 127 | typedef struct { |
YasuhiroKawai | 0:37014c6bb5cd | 128 | uint32_t DWT_CTRL; ///< Control register |
YasuhiroKawai | 0:37014c6bb5cd | 129 | uint32_t DWT_CYCCNT; ///< Shows or sets the value of the processor |
YasuhiroKawai | 0:37014c6bb5cd | 130 | ///< cycle counter, CYCCNT. |
YasuhiroKawai | 0:37014c6bb5cd | 131 | uint32_t DWT_CPICNT; ///< Counts additional cycles required to execute |
YasuhiroKawai | 0:37014c6bb5cd | 132 | ///< multicycle instructions and instruction |
YasuhiroKawai | 0:37014c6bb5cd | 133 | ///< fetch stalls. |
YasuhiroKawai | 0:37014c6bb5cd | 134 | uint32_t DWT_EXCCNT; ///< Counts the total cycles spent in exception |
YasuhiroKawai | 0:37014c6bb5cd | 135 | ///< processing. |
YasuhiroKawai | 0:37014c6bb5cd | 136 | uint32_t DWT_SLEEPCNT; ///< Counts the total number of cycles that the |
YasuhiroKawai | 0:37014c6bb5cd | 137 | ///< processor is sleeping. |
YasuhiroKawai | 0:37014c6bb5cd | 138 | uint32_t DWT_LSUCNT; ///< Increments on the additional cycles required |
YasuhiroKawai | 0:37014c6bb5cd | 139 | ///< to execute all load or store instructions. |
YasuhiroKawai | 0:37014c6bb5cd | 140 | uint32_t DWT_FOLDCNT; ///< Increments on each instruction that takes 0 |
YasuhiroKawai | 0:37014c6bb5cd | 141 | ///< cycles. |
YasuhiroKawai | 0:37014c6bb5cd | 142 | uint32_t DWT_PCSR; ///< Samples the current value of the program |
YasuhiroKawai | 0:37014c6bb5cd | 143 | ///< counter. |
YasuhiroKawai | 0:37014c6bb5cd | 144 | dwt_cmp_regs_t regs[16]; |
YasuhiroKawai | 0:37014c6bb5cd | 145 | } dwt_regs_t; |
YasuhiroKawai | 0:37014c6bb5cd | 146 | |
YasuhiroKawai | 0:37014c6bb5cd | 147 | static const uint32_t DWT_REGS_ADDR; |
YasuhiroKawai | 0:37014c6bb5cd | 148 | static const uint32_t SCB_DEMCR_ADDR; |
YasuhiroKawai | 0:37014c6bb5cd | 149 | |
YasuhiroKawai | 0:37014c6bb5cd | 150 | static const uint32_t NUMCOMP_POS; |
YasuhiroKawai | 0:37014c6bb5cd | 151 | static const uint32_t NUMCOMP_MASK; |
YasuhiroKawai | 0:37014c6bb5cd | 152 | static const uint32_t NOTRCPKT; |
YasuhiroKawai | 0:37014c6bb5cd | 153 | static const uint32_t NOEXTTRIG; |
YasuhiroKawai | 0:37014c6bb5cd | 154 | static const uint32_t NOCYCCNT; |
YasuhiroKawai | 0:37014c6bb5cd | 155 | static const uint32_t NOPRFCNT; |
YasuhiroKawai | 0:37014c6bb5cd | 156 | public: |
YasuhiroKawai | 0:37014c6bb5cd | 157 | static const uint32_t CYCEVTENA; /// Enables POSTCNT underflow Event counter packets generation. |
YasuhiroKawai | 0:37014c6bb5cd | 158 | static const uint32_t FOLDEVTENA; /// Enables generation of the Folded-instruction counter overflow event. |
YasuhiroKawai | 0:37014c6bb5cd | 159 | static const uint32_t LSUEVTENA; /// Enables generation of the LSU counter overflow event. |
YasuhiroKawai | 0:37014c6bb5cd | 160 | static const uint32_t SLEEPEVTENA; /// Enables generation of the Sleep counter overflow event. |
YasuhiroKawai | 0:37014c6bb5cd | 161 | static const uint32_t EXCEVTENA; /// Enables generation of the Exception overhead counter overflow event: |
YasuhiroKawai | 0:37014c6bb5cd | 162 | static const uint32_t CPIEVTENA; /// Enables generation of the CPI counter overflow event. |
YasuhiroKawai | 0:37014c6bb5cd | 163 | static const uint32_t EXCTRCENA; /// Enables generation of the CPI counter overflow event. |
YasuhiroKawai | 0:37014c6bb5cd | 164 | static const uint32_t PCSAMPLENA; /// Enables use of POSTCNT counter as a timer for Periodic PC sample packet generation. |
YasuhiroKawai | 0:37014c6bb5cd | 165 | static const uint32_t CYCCNTENA; /// Enables CYCCNT. |
YasuhiroKawai | 0:37014c6bb5cd | 166 | |
YasuhiroKawai | 0:37014c6bb5cd | 167 | private: |
YasuhiroKawai | 0:37014c6bb5cd | 168 | static const uint32_t TRCENA; |
YasuhiroKawai | 0:37014c6bb5cd | 169 | static const uint32_t EVENA_MASK; |
YasuhiroKawai | 0:37014c6bb5cd | 170 | |
YasuhiroKawai | 0:37014c6bb5cd | 171 | private: |
YasuhiroKawai | 0:37014c6bb5cd | 172 | volatile dwt_regs_t *_regs; |
YasuhiroKawai | 0:37014c6bb5cd | 173 | volatile uint32_t *_scb_demcr_regs; |
YasuhiroKawai | 0:37014c6bb5cd | 174 | }; |
YasuhiroKawai | 0:37014c6bb5cd | 175 | |
YasuhiroKawai | 0:37014c6bb5cd | 176 | |
YasuhiroKawai | 0:37014c6bb5cd | 177 | #endif /* DWT_H */ |