00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00028 #ifndef qs_h
00029 #define qs_h
00030
00036
00037 #ifndef Q_SPY
00038 #error "Q_SPY must be defined to include qs.h"
00039 #endif
00040
00042
00049 enum QSpyRecords {
00050
00051 QS_QEP_STATE_EMPTY,
00052 QS_QEP_STATE_ENTRY,
00053 QS_QEP_STATE_EXIT,
00054 QS_QEP_STATE_INIT,
00055 QS_QEP_INIT_TRAN,
00056 QS_QEP_INTERN_TRAN,
00057 QS_QEP_TRAN,
00058 QS_QEP_IGNORED,
00059 QS_QEP_RESERVED1,
00060 QS_QEP_RESERVED0,
00061
00062
00063 QS_QF_ACTIVE_ADD,
00064 QS_QF_ACTIVE_REMOVE,
00065 QS_QF_ACTIVE_SUBSCRIBE,
00066 QS_QF_ACTIVE_UNSUBSCRIBE,
00067 QS_QF_ACTIVE_POST_FIFO,
00068 QS_QF_ACTIVE_POST_LIFO,
00069 QS_QF_ACTIVE_GET,
00070 QS_QF_ACTIVE_GET_LAST,
00071 QS_QF_EQUEUE_INIT,
00072 QS_QF_EQUEUE_POST_FIFO,
00073 QS_QF_EQUEUE_POST_LIFO,
00074 QS_QF_EQUEUE_GET,
00075 QS_QF_EQUEUE_GET_LAST,
00076 QS_QF_MPOOL_INIT,
00077 QS_QF_MPOOL_GET,
00078 QS_QF_MPOOL_PUT,
00079 QS_QF_PUBLISH,
00080 QS_QF_RESERVED8,
00081 QS_QF_NEW,
00082 QS_QF_GC_ATTEMPT,
00083 QS_QF_GC,
00084 QS_QF_TICK,
00085 QS_QF_TIMEEVT_ARM,
00086 QS_QF_TIMEEVT_AUTO_DISARM,
00087 QS_QF_TIMEEVT_DISARM_ATTEMPT,
00088 QS_QF_TIMEEVT_DISARM,
00089 QS_QF_TIMEEVT_REARM,
00090 QS_QF_TIMEEVT_POST,
00091 QS_QF_RESERVED7,
00092 QS_QF_INT_LOCK,
00093 QS_QF_INT_UNLOCK,
00094 QS_QF_ISR_ENTRY,
00095 QS_QF_ISR_EXIT,
00096 QS_QF_RESERVED6,
00097 QS_QF_RESERVED5,
00098 QS_QF_RESERVED4,
00099 QS_QF_RESERVED3,
00100 QS_QF_RESERVED2,
00101 QS_QF_RESERVED1,
00102 QS_QF_RESERVED0,
00103
00104
00105 QS_QK_MUTEX_LOCK,
00106 QS_QK_MUTEX_UNLOCK,
00107 QS_QK_SCHEDULE,
00108 QS_QK_RESERVED6,
00109 QS_QK_RESERVED5,
00110 QS_QK_RESERVED4,
00111 QS_QK_RESERVED3,
00112 QS_QK_RESERVED2,
00113 QS_QK_RESERVED1,
00114 QS_QK_RESERVED0,
00115
00116
00117 QS_SIG_DICTIONARY,
00118 QS_OBJ_DICTIONARY,
00119 QS_FUN_DICTIONARY,
00120 QS_ASSERT,
00121 QS_RESERVED5,
00122 QS_RESERVED4,
00123 QS_RESERVED3,
00124 QS_RESERVED2,
00125 QS_RESERVED1,
00126 QS_RESERVED0,
00127
00128
00129 QS_USER
00130 };
00131
00134 #define QS_ALL_RECORDS ((uint8_t)0xFF)
00135
00138 #define QS_EOD ((uint16_t)0xFFFF)
00139
00140
00141 #ifndef QS_TIME_SIZE
00142
00149 #define QS_TIME_SIZE 4
00150 #endif
00151 #if (QS_TIME_SIZE == 1)
00152 typedef uint8_t QSTimeCtr;
00153 #define QS_TIME_() QS::u8_(QS::onGetTime())
00154 #elif (QS_TIME_SIZE == 2)
00155 typedef uint16_t QSTimeCtr;
00156 #define QS_TIME_() QS::u16_(QS::onGetTime())
00157 #elif (QS_TIME_SIZE == 4)
00158
00162 typedef uint32_t QSTimeCtr;
00163
00165 #define QS_TIME_() QS::u32_(QS::onGetTime())
00166 #else
00167 #error "QS_TIME_SIZE defined incorrectly, expected 1, 2, or 4"
00168 #endif
00169
00170 #ifndef Q_ROM // provide the default if Q_ROM NOT defined
00171 #define Q_ROM
00172 #endif
00173 #ifndef Q_ROM_VAR // provide the default if Q_ROM_VAR NOT defined
00174 #define Q_ROM_VAR
00175 #endif
00176 #ifndef Q_ROM_BYTE // provide the default if Q_ROM_BYTE NOT defined
00177 #define Q_ROM_BYTE(rom_var_) (rom_var_)
00178 #endif
00179
00180
00185 class QS {
00186 public:
00187
00193 static char const Q_ROM * Q_ROM_VAR getVersion(void);
00194
00213 static void initBuf(uint8_t sto[], uint32_t stoSize);
00214
00228 static void filterOn(uint8_t rec);
00229
00242 static void filterOff(uint8_t rec);
00243
00250 static void begin(uint8_t rec);
00251
00258 static void end(void);
00259
00260
00261
00265 static void u8_(uint8_t d);
00266
00270 static void u16_(uint16_t d);
00271
00275 static void u32_(uint32_t d);
00276
00281 static void str_(char const *s);
00282
00287 static void str_ROM_(char const Q_ROM * Q_ROM_VAR s);
00288
00289
00290
00294 static void u8(uint8_t format, uint8_t d);
00295
00299 static void u16(uint8_t format, uint16_t d);
00300
00304 static void u32(uint8_t format, uint32_t d);
00305
00310 static void f32(uint8_t format, float d);
00311
00316 static void f64(uint8_t format, double d);
00317
00322 static void str(char const *s);
00323
00328 static void str_ROM(char const Q_ROM * Q_ROM_VAR s);
00329
00333 static void mem(uint8_t const *blk, uint8_t size);
00334
00335
00336
00345 static uint16_t getByte(void);
00346
00367 static uint8_t const *getBlock(uint16_t *pNbytes);
00368
00369
00370 public:
00371
00372
00388 static uint8_t onStartup(void const *arg);
00389
00396 static void onCleanup(void);
00397
00404 static void onFlush(void);
00405
00419 static QSTimeCtr onGetTime(void);
00420
00421
00422 public:
00423 static uint8_t glbFilter_[32];
00424 static void const *smObj_;
00425 static void const *aoObj_;
00426 static void const *mpObj_;
00427 static void const *eqObj_;
00428 static void const *teObj_;
00429 static void const *apObj_;
00430
00431
00432 public:
00434 static QSTimeCtr volatile tickCtr_;
00435 };
00436
00437
00439
00440
00446 #define QS_INIT(arg_) QS::onStartup(arg_)
00447
00453 #define QS_EXIT() QS::onCleanup()
00454
00462 #define QS_FILTER_ON(rec_) QS::filterOn(rec_)
00463
00470 #define QS_FILTER_OFF(rec_) QS::filterOff(rec_)
00471
00495 #define QS_FILTER_SM_OBJ(obj_) (QS::smObj_ = (obj_))
00496
00514 #define QS_FILTER_AO_OBJ(obj_) (QS::aoObj_ = (obj_))
00515
00532 #define QS_FILTER_MP_OBJ(obj_) (QS::mpObj_ = (obj_))
00533
00550 #define QS_FILTER_EQ_OBJ(obj_) (QS::eqObj_ = (obj_))
00551
00569 #define QS_FILTER_TE_OBJ(obj_) (QS::teObj_ = (obj_))
00570
00584 #define QS_FILTER_AP_OBJ(obj_) (QS_apObj_ = (obj_))
00585
00586
00588
00589
00591 #define QS_BEGIN_NOLOCK(rec_, obj_) \
00592 if (((QS::glbFilter_[(uint8_t)(rec_) >> 3U] \
00593 & (1U << ((uint8_t)(rec_) & 7U))) != 0) \
00594 && ((QS::apObj_ == (void *)0) || (QS::apObj_ == (obj_)))) \
00595 { \
00596 QS::begin((uint8_t)(rec_)); \
00597 QS_TIME_();
00598
00600 #define QS_END_NOLOCK() \
00601 QS_END_NOLOCK_()
00602
00603
00604 #ifndef QF_INT_KEY_TYPE
00612 #define QS_INT_LOCK_KEY_
00613
00622 #define QS_INT_LOCK_() QF_INT_LOCK(ignore_)
00623
00632 #define QS_INT_UNLOCK_() QF_INT_UNLOCK(ignore_)
00633 #else
00634 #define QS_INT_LOCK_KEY_ QF_INT_KEY_TYPE intLockKey_;
00635 #define QS_INT_LOCK_() QF_INT_LOCK(intLockKey_)
00636 #define QS_INT_UNLOCK_() QF_INT_UNLOCK(intLockKey_)
00637 #endif
00638
00646 #define QS_BEGIN(rec_, obj_) \
00647 if (((QS::glbFilter_[(uint8_t)(rec_) >> 3U] \
00648 & (1U << ((uint8_t)(rec_) & 7U))) != 0U) \
00649 && ((QS::apObj_ == (void *)0) || (QS::apObj_ == (obj_)))) \
00650 { \
00651 QS_INT_LOCK_KEY_ \
00652 QS_INT_LOCK_(); \
00653 QS::begin((uint8_t)(rec_)); \
00654 QS_TIME_();
00655
00659 #define QS_END() \
00660 QS_END_()
00661
00662
00664
00665
00669 #define QS_BEGIN_(rec_, objFilter_, obj_) \
00670 if (((QS::glbFilter_[(uint8_t)(rec_) >> 3U] \
00671 & (1U << ((uint8_t)(rec_) & 7U))) != 0U) \
00672 && (((objFilter_) == (void *)0) || ((objFilter_) == (obj_)))) \
00673 { \
00674 QS_INT_LOCK_(); \
00675 QS::begin((uint8_t)(rec_));
00676
00680 #define QS_END_() \
00681 QS::end(); \
00682 QS_INT_UNLOCK_(); \
00683 }
00684
00689 #define QS_BEGIN_NOLOCK_(rec_, objFilter_, obj_) \
00690 if (((QS::glbFilter_[(uint8_t)(rec_) >> 3U] \
00691 & (1U << ((uint8_t)(rec_) & 7U))) != 0U) \
00692 && (((objFilter_) == (void *)0) || ((objFilter_) == (obj_)))) \
00693 { \
00694 QS::begin((uint8_t)(rec_));
00695
00700 #define QS_END_NOLOCK_() \
00701 QS::end(); \
00702 }
00703
00705 #define QS_U8_(data_) QS::u8_(data_)
00706
00708 #define QS_U16_(data_) QS::u16_(data_)
00709
00711 #define QS_U32_(data_) QS::u32_(data_)
00712
00713
00714 #if (QS_OBJ_PTR_SIZE == 1)
00715 #define QS_OBJ_(obj_) QS::u8_((uint8_t)(obj_))
00716 #elif (QS_OBJ_PTR_SIZE == 2)
00717 #define QS_OBJ_(obj_) QS::u16_((uint16_t)(obj_))
00718 #elif (QS_OBJ_PTR_SIZE == 4)
00719 #define QS_OBJ_(obj_) QS::u32_((uint32_t)(obj_))
00720 #else
00721
00726 #define QS_OBJ_(obj_) QS::u32_((uint32_t)(obj_))
00727 #endif
00728
00729
00730 #if (QS_FUN_PTR_SIZE == 1)
00731 #define QS_FUN_(fun_) QS::u8_((uint8_t)(fun_))
00732 #elif (QS_FUN_PTR_SIZE == 2)
00733 #define QS_FUN_(fun_) QS::u16_((uint16_t)(fun_))
00734 #elif (QS_FUN_PTR_SIZE == 4)
00735 #define QS_FUN_(fun_) QS::u32_((uint32_t)(fun_))
00736 #else
00737
00742 #define QS_FUN_(fun_) QS::u32_((uint32_t)(fun_))
00743 #endif
00744
00747 #define QS_STR_(msg_) QS::str_(msg_)
00748
00751 #define QS_STR_ROM_(msg_) QS::str_ROM_(msg_)
00752
00754
00755
00760 enum QSType {
00761 QS_I8_T,
00762 QS_U8_T,
00763 QS_I16_T,
00764 QS_U16_T,
00765 QS_I32_T,
00766 QS_U32_T,
00767 QS_F32_T,
00768 QS_F64_T,
00769 QS_STR_T,
00770 QS_MEM_T,
00771 QS_SIG_T,
00772 QS_OBJ_T,
00773 QS_FUN_T
00774 };
00775
00777 #define QS_I8(width_, data_) \
00778 QS::u8((uint8_t)(((width_) << 4)) | QS_I8_T, (data_))
00779
00781 #define QS_U8(width_, data_) \
00782 QS::u8((uint8_t)(((width_) << 4)) | QS_U8_T, (data_))
00783
00785 #define QS_I16(width_, data_) \
00786 QS::u16((uint8_t)(((width_) << 4)) | QS_I16_T, (data_))
00787
00789 #define QS_U16(width_, data_) \
00790 QS::u16((uint8_t)(((width_) << 4)) | QS_U16_T, (data_))
00791
00793 #define QS_I32(width_, data_) \
00794 QS::u32((uint8_t)(((width_) << 4)) | QS_I32_T, (data_))
00795
00797 #define QS_U32(width_, data_) \
00798 QS::u32((uint8_t)(((width_) << 4)) | QS_U32_T, (data_))
00799
00801 #define QS_F32(width_, data_) \
00802 QS::f32((uint8_t)(((width_) << 4)) | QS_F32_T, (data_))
00803
00805 #define QS_F64(width_, data_) \
00806 QS::f64((uint8_t)(((width_) << 4)) | QS_F64_T, (data_))
00807
00809 #define QS_STR(str_) QS::str(str_)
00810
00813 #define QS_STR_ROM(str_) QS::str_ROM(str_)
00814
00817 #define QS_MEM(mem_, size_) QS::mem((mem_), (size_))
00818
00819
00820 #if (QS_OBJ_PTR_SIZE == 1)
00821 #define QS_OBJ(obj_) QS::u8(QS_OBJ_T, (uint8_t)(obj_))
00822 #elif (QS_OBJ_PTR_SIZE == 2)
00823 #define QS_OBJ(obj_) QS::u16(QS_OBJ_T, (uint16_t)(obj_))
00824 #elif (QS_OBJ_PTR_SIZE == 4)
00825 #define QS_OBJ(obj_) QS::u32(QS_OBJ_T, (uint32_t)(obj_))
00826 #else
00828 #define QS_OBJ(obj_) QS::u32(QS_OBJ_T, (uint32_t)(obj_))
00829 #endif
00830
00831
00832 #if (QS_FUN_PTR_SIZE == 1)
00833 #define QS_FUN(fun_) QS::u8(QS_FUN_T, (uint8_t)(fun_))
00834 #elif (QS_FUN_PTR_SIZE == 2)
00835 #define QS_FUN(fun_) QS::u16(QS_FUN_T, (uint16_t)(fun_))
00836 #elif (QS_FUN_PTR_SIZE == 4)
00837 #define QS_FUN(fun_) QS::u32(QS_FUN_T, (uint32_t)(fun_))
00838 #else
00840 #define QS_FUN(fun_) QS::u32(QS_FUN_T, (uint32_t)(fun_))
00841 #endif
00842
00843
00883 #define QS_SIG_DICTIONARY(sig_, obj_) \
00884 if (((QS::glbFilter_[(uint8_t)QS_SIG_DICTIONARY >> 3U] \
00885 & (1U << ((uint8_t)QS_SIG_DICTIONARY & 7U))) != 0U)) \
00886 { \
00887 static char const Q_ROM Q_ROM_VAR sig_name__[] = #sig_; \
00888 QS_INT_LOCK_KEY_ \
00889 QS_INT_LOCK_(); \
00890 QS::begin((uint8_t)QS_SIG_DICTIONARY); \
00891 QS_SIG_(sig_); \
00892 QS_OBJ_(obj_); \
00893 QS_STR_ROM_(sig_name__); \
00894 QS::end(); \
00895 QS_INT_UNLOCK_(); \
00896 QS::onFlush(); \
00897 } else ((void)0)
00898
00911 #define QS_OBJ_DICTIONARY(obj_) \
00912 if (((QS::glbFilter_[(uint8_t)QS_OBJ_DICTIONARY >> 3U] \
00913 & (1U << ((uint8_t)QS_OBJ_DICTIONARY & 7U))) != 0U)) \
00914 { \
00915 static char const Q_ROM Q_ROM_VAR obj_name__[] = #obj_; \
00916 QS_INT_LOCK_KEY_ \
00917 QS_INT_LOCK_(); \
00918 QS::begin((uint8_t)QS_OBJ_DICTIONARY); \
00919 QS_OBJ_(obj_); \
00920 QS_STR_ROM_(obj_name__); \
00921 QS::end(); \
00922 QS_INT_UNLOCK_(); \
00923 QS::onFlush(); \
00924 } else ((void)0)
00925
00937 #define QS_FUN_DICTIONARY(fun_) \
00938 if (((QS::glbFilter_[(uint8_t)QS_FUN_DICTIONARY >> 3U] \
00939 & (1U << ((uint8_t)QS_FUN_DICTIONARY & 7U))) != 0U)) \
00940 { \
00941 static char const Q_ROM Q_ROM_VAR fun_name__[] = #fun_; \
00942 QS_INT_LOCK_KEY_ \
00943 QS_INT_LOCK_(); \
00944 QS::begin((uint8_t)QS_FUN_DICTIONARY); \
00945 QS_FUN_(fun_); \
00946 QS_STR_ROM_(fun_name__); \
00947 QS::end(); \
00948 QS_INT_UNLOCK_(); \
00949 QS::onFlush(); \
00950 } else ((void)0)
00951
00958 #define QS_FLUSH() QS::onFlush()
00959
00960
00962 #define QF_QS_INT_LOCK() \
00963 QS_BEGIN_NOLOCK_(QS_QF_INT_LOCK, (void *)0, (void *)0); \
00964 QS_TIME_(); \
00965 QS_U8_((uint8_t)(++QF_intLockNest_)); \
00966 QS_END_NOLOCK_()
00967
00969 #define QF_QS_INT_UNLOCK() \
00970 QS_BEGIN_NOLOCK_(QS_QF_INT_UNLOCK, (void *)0, (void *)0); \
00971 QS_TIME_(); \
00972 QS_U8_((uint8_t)(QF_intLockNest_--)); \
00973 QS_END_NOLOCK_()
00974
00976 #define QF_QS_ISR_ENTRY(isrnest_, prio_) \
00977 QS_BEGIN_NOLOCK_(QS_QF_ISR_ENTRY, (void *)0, (void *)0); \
00978 QS_TIME_(); \
00979 QS_U8_(isrnest_); \
00980 QS_U8_(prio_); \
00981 QS_END_NOLOCK_()
00982
00984 #define QF_QS_ISR_EXIT(isrnest_, prio_) \
00985 QS_BEGIN_NOLOCK_(QS_QF_ISR_EXIT, (void *)0, (void *)0); \
00986 QS_TIME_(); \
00987 QS_U8_(isrnest_); \
00988 QS_U8_(prio_); \
00989 QS_END_NOLOCK_()
00990
00992 #define QF_QS_ACTION(act_) (act_)
00993
00997 extern uint8_t QF_intLockNest_;
00998
00999 #endif // qs_h