Data Watch-point and Trace unit(DWT) interface.
Diff: Dwt.h
- Revision:
- 0:37014c6bb5cd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Dwt.h Sun Oct 08 05:51:12 2017 +0000 @@ -0,0 +1,177 @@ +/** + * DWT class + */ +#ifndef DWT_H +#define DWT_H + +/** + * The Data Watchpoint and Trace unit intarface + * + * @code + * #include "mbed.h" + * #include "Dwt.h" + * + * Serial pc(SERIAL_TX, SERIAL_RX); + * Dwt dwt; + * + * int main() { + * uint32_t t; + * uint32_t n; + * + * dwt.enableCYCCNT(); + * dwt.resetCYCCNT(); + * dwt.startCount(); + * <Write some codes to measure the execution cycle here.> + * dwt.stopCount(); + * t = dwt.getCYCCNT(); + * n = dwt.getInstructionCount(); + * pc.printf("%d cycles, %d instructions.\n", t, n); + * } + * @endcode + */ +#define DWT_MAJOR_VERSION (0) +#define DWT_MINOR_VERSION (1) + +class Dwt +{ + /** + * The Data Watchpoint and Trace unit intarface + */ +public: + + /** + * Create a DWT interface + */ + Dwt(); + + /// Returns whether the implementation supports trace sampling and exception tracing. + /// true : Trace sampling and exception tracing supported. + /// false : Trace sampling and exception tracing not supported. + bool isTRCPKT_Available(); + /// Returns whether the implementation includes external match signals, CMPMATCH[N]. + bool isEXTTRIG_Available(); + /// Returns whether the implementation supports a cycle counter. + bool isCYCCNT_Available(); + /// Returns whether the implementation supports the profiling counters. + bool isPRFCNT_Available(); + + void enableCYCCNT(); + void disableCYCCNT(); + inline void startCYCCNT() { + _regs->DWT_CTRL |= CYCCNTENA; + } + inline void stopCYCCNT() { + _regs->DWT_CTRL &= ~CYCCNTENA; + } + inline void resetCYCCNT() { + _regs->DWT_CYCCNT = 0; + } + inline uint32_t getCYCCNT() { + return(_regs->DWT_CYCCNT); + } + inline uint32_t readDwtCtrl() { + return(_regs->DWT_CTRL); + } + inline uint32_t getNumComp() { + return((_regs->DWT_CTRL & NUMCOMP_MASK) >> NUMCOMP_POS); + } + void setEvent(uint32_t ev); + inline uint32_t getEvent() { + return(_regs->DWT_CTRL & EVENA_MASK); + } + /// Returns additional cycles required to execute multicycle instructions and + /// instruction fetch stalls. + inline uint32_t getCPICNT() { + return(_regs->DWT_CPICNT); + } + /// Returns the total cycles spent in exception processing. + inline uint32_t getEXCCNT() { + return(_regs->DWT_EXCCNT); + } + /// Returns the total number of cycles that the processor is sleeping. + inline uint32_t getSLEEPCNT() { + return(_regs->DWT_SLEEPCNT); + } + /// Returns the additional cycles required to execute all load or + /// store instructions. + inline uint32_t getLSUCNT() { + return(_regs->DWT_LSUCNT); + } + /// Returns the number of instructions that takes 0 cycles. + inline uint32_t getFOLDCNT() { + return(_regs->DWT_FOLDCNT); + } + /// start all counters + inline void startCount() { + _regs->DWT_CTRL |= (Dwt::CPIEVTENA | Dwt::EXCEVTENA | Dwt::SLEEPEVTENA | + Dwt::LSUEVTENA | Dwt::FOLDEVTENA | Dwt::CYCCNTENA); + } + /// stop all counters + inline void stopCount() { + _regs->DWT_CTRL &= ~(Dwt::CPIEVTENA | Dwt::EXCEVTENA | Dwt::SLEEPEVTENA | + Dwt::LSUEVTENA | Dwt::FOLDEVTENA | Dwt::CYCCNTENA); + } + /// Returns number of executed instructions. + uint32_t getInstructionCount(); +private: + typedef struct { + uint32_t DWT_COMP; ///< Provides a reference value for use by + ///< comparator n. + uint32_t DWT_MASK; ///< Provides the size of the ignore mask applied + ///< to the access address for address range + ///< matching by comparator n. + uint32_t DWT_FUNCTION; ///< Controls the operation of comparator n. + uint32_t reserved; + } dwt_cmp_regs_t; + + typedef struct { + uint32_t DWT_CTRL; ///< Control register + uint32_t DWT_CYCCNT; ///< Shows or sets the value of the processor + ///< cycle counter, CYCCNT. + uint32_t DWT_CPICNT; ///< Counts additional cycles required to execute + ///< multicycle instructions and instruction + ///< fetch stalls. + uint32_t DWT_EXCCNT; ///< Counts the total cycles spent in exception + ///< processing. + uint32_t DWT_SLEEPCNT; ///< Counts the total number of cycles that the + ///< processor is sleeping. + uint32_t DWT_LSUCNT; ///< Increments on the additional cycles required + ///< to execute all load or store instructions. + uint32_t DWT_FOLDCNT; ///< Increments on each instruction that takes 0 + ///< cycles. + uint32_t DWT_PCSR; ///< Samples the current value of the program + ///< counter. + dwt_cmp_regs_t regs[16]; + } dwt_regs_t; + + static const uint32_t DWT_REGS_ADDR; + static const uint32_t SCB_DEMCR_ADDR; + + static const uint32_t NUMCOMP_POS; + static const uint32_t NUMCOMP_MASK; + static const uint32_t NOTRCPKT; + static const uint32_t NOEXTTRIG; + static const uint32_t NOCYCCNT; + static const uint32_t NOPRFCNT; +public: + static const uint32_t CYCEVTENA; /// Enables POSTCNT underflow Event counter packets generation. + static const uint32_t FOLDEVTENA; /// Enables generation of the Folded-instruction counter overflow event. + static const uint32_t LSUEVTENA; /// Enables generation of the LSU counter overflow event. + static const uint32_t SLEEPEVTENA; /// Enables generation of the Sleep counter overflow event. + static const uint32_t EXCEVTENA; /// Enables generation of the Exception overhead counter overflow event: + static const uint32_t CPIEVTENA; /// Enables generation of the CPI counter overflow event. + static const uint32_t EXCTRCENA; /// Enables generation of the CPI counter overflow event. + static const uint32_t PCSAMPLENA; /// Enables use of POSTCNT counter as a timer for Periodic PC sample packet generation. + static const uint32_t CYCCNTENA; /// Enables CYCCNT. + +private: + static const uint32_t TRCENA; + static const uint32_t EVENA_MASK; + +private: + volatile dwt_regs_t *_regs; + volatile uint32_t *_scb_demcr_regs; +}; + + +#endif /* DWT_H */