QP/C++
qs.h
Go to the documentation of this file.
00001 
00002 // Product: QP/C++
00003 // Last Updated for Version: 4.5.04
00004 // Date of the Last Update:  Jan 16, 2013
00005 //
00006 //                    Q u a n t u m     L e a P s
00007 //                    ---------------------------
00008 //                    innovating embedded systems
00009 //
00010 // Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
00011 //
00012 // This program is open source software: you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as published
00014 // by the Free Software Foundation, either version 2 of the License, or
00015 // (at your option) any later version.
00016 //
00017 // Alternatively, this program may be distributed and modified under the
00018 // terms of Quantum Leaps commercial licenses, which expressly supersede
00019 // the GNU General Public License and are specifically designed for
00020 // licensees interested in retaining the proprietary status of their code.
00021 //
00022 // This program is distributed in the hope that it will be useful,
00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00025 // GNU General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License
00028 // along with this program. If not, see <http://www.gnu.org/licenses/>.
00029 //
00030 // Contact information:
00031 // Quantum Leaps Web sites: http://www.quantum-leaps.com
00032 //                          http://www.state-machine.com
00033 // e-mail:                  info@quantum-leaps.com
00035 #ifndef qs_h
00036 #define qs_h
00037 
00043 
00044 #ifndef Q_SPY
00045     #error "Q_SPY must be defined to include qs.h"
00046 #endif
00047 
00048 #ifndef Q_ROM                      // provide the default if Q_ROM NOT defined
00049     #define Q_ROM
00050 #endif
00051 #ifndef Q_ROM_VAR              // provide the default if Q_ROM_VAR NOT defined
00052     #define Q_ROM_VAR
00053 #endif
00054 #ifndef Q_ROM_BYTE            // provide the default if Q_ROM_BYTE NOT defined
00055     #define Q_ROM_BYTE(rom_var_)   (rom_var_)
00056 #endif
00057 
00058 #ifndef QS_TIME_SIZE
00059 
00066     #define QS_TIME_SIZE 4
00067 #endif
00068 
00070 QP_BEGIN_
00071 
00078 
00079 enum QSpyRecords {
00080     QS_QP_RESET,                 
00081 
00082     // QEP records
00083     QS_QEP_STATE_ENTRY,                               
00084     QS_QEP_STATE_EXIT,                                 
00085     QS_QEP_STATE_INIT,         
00086     QS_QEP_INIT_TRAN,           
00087     QS_QEP_INTERN_TRAN,                  
00088     QS_QEP_TRAN,                           
00089     QS_QEP_IGNORED,             
00090     QS_QEP_DISPATCH,          
00091     QS_QEP_UNHANDLED,               
00092 
00093     // QF records
00094     QS_QF_ACTIVE_ADD,                
00095     QS_QF_ACTIVE_REMOVE,         
00096     QS_QF_ACTIVE_SUBSCRIBE,                  
00097     QS_QF_ACTIVE_UNSUBSCRIBE,              
00098     QS_QF_ACTIVE_POST_FIFO,  
00099     QS_QF_ACTIVE_POST_LIFO,  
00100     QS_QF_ACTIVE_GET, 
00101     QS_QF_ACTIVE_GET_LAST,      
00102     QS_QF_EQUEUE_INIT,                     
00103     QS_QF_EQUEUE_POST_FIFO,     
00104     QS_QF_EQUEUE_POST_LIFO,     
00105     QS_QF_EQUEUE_GET,              
00106     QS_QF_EQUEUE_GET_LAST,              
00107     QS_QF_MPOOL_INIT,                       
00108     QS_QF_MPOOL_GET,        
00109     QS_QF_MPOOL_PUT,         
00110     QS_QF_PUBLISH,       
00111     QS_QF_RESERVED8,
00112     QS_QF_NEW,                                         
00113     QS_QF_GC_ATTEMPT,                          
00114     QS_QF_GC,                                          
00115     QS_QF_TICK,                                     
00116     QS_QF_TIMEEVT_ARM,                             
00117     QS_QF_TIMEEVT_AUTO_DISARM,      
00118     QS_QF_TIMEEVT_DISARM_ATTEMPT,
00119     QS_QF_TIMEEVT_DISARM,           
00120     QS_QF_TIMEEVT_REARM,                         
00121     QS_QF_TIMEEVT_POST,      
00122     QS_QF_TIMEEVT_CTR,                 
00123     QS_QF_CRIT_ENTRY,                        
00124     QS_QF_CRIT_EXIT,                          
00125     QS_QF_ISR_ENTRY,                                   
00126     QS_QF_ISR_EXIT,                                     
00127     QS_QF_INT_DISABLE,                           
00128     QS_QF_INT_ENABLE,                             
00129     QS_QF_RESERVED4,
00130     QS_QF_RESERVED3,
00131     QS_QF_RESERVED2,
00132     QS_QF_RESERVED1,
00133     QS_QF_RESERVED0,
00134 
00135     // QK records
00136     QS_QK_MUTEX_LOCK,                             
00137     QS_QK_MUTEX_UNLOCK,                         
00138     QS_QK_SCHEDULE,      
00139     QS_QK_RESERVED6,
00140     QS_QK_RESERVED5,
00141     QS_QK_RESERVED4,
00142     QS_QK_RESERVED3,
00143     QS_QK_RESERVED2,
00144     QS_QK_RESERVED1,
00145     QS_QK_RESERVED0,
00146 
00147     // Miscellaneous QS records
00148     QS_SIG_DIC,                                   
00149     QS_OBJ_DIC,                                   
00150     QS_FUN_DIC,                                 
00151     QS_USR_DIC,                           
00152     QS_RESERVED4,
00153     QS_RESERVED3,
00154     QS_RESERVED2,
00155     QS_RESERVED1,
00156     QS_RESERVED0,
00157     QS_ASSERT,                                
00158 
00159     // User records
00160     QS_USER                
00161 };
00162 
00165 uint8_t const QS_ALL_RECORDS = static_cast<uint8_t>(0xFF);
00166 
00169 uint16_t const QS_EOD  = static_cast<uint16_t>(0xFFFF);
00170 
00171 
00172 #if (QS_TIME_SIZE == 1)
00173     typedef uint8_t QSTimeCtr;
00174     #define QS_TIME_()   (QP_ QS::u8_(QP_ QS::onGetTime()))
00175 #elif (QS_TIME_SIZE == 2)
00176     typedef uint16_t QSTimeCtr;
00177     #define QS_TIME_()   (QP_ QS::u16_(QP_ QS::onGetTime()))
00178 #elif (QS_TIME_SIZE == 4)
00179 
00183     typedef uint32_t QSTimeCtr;
00184 
00186     #define QS_TIME_()   (QP_ QS::u32_(QP_ QS::onGetTime()))
00187 #else
00188     #error "QS_TIME_SIZE defined incorrectly, expected 1, 2, or 4"
00189 #endif
00190 
00195 class QS {
00196 public:
00197 
00203     static char_t const Q_ROM * Q_ROM_VAR getVersion(void);
00204 
00223     static void initBuf(uint8_t sto[], uint32_t const stoSize);
00224 
00238     static void filterOn(uint8_t const rec);
00239 
00252     static void filterOff(uint8_t const rec);
00253 
00260     static void begin(uint8_t const rec);
00261 
00268     static void end(void);
00269 
00270     // unformatted data elements output ......................................
00271 
00275     static void u8_(uint8_t const d);
00276 
00280     static void u16_(uint16_t d);
00281 
00285     static void u32_(uint32_t d);
00286 
00291     static void str_(char_t const *s);
00292 
00297     static void str_ROM_(char_t const Q_ROM * Q_ROM_VAR s);
00298 
00299     // formatted data elements output ........................................
00300 
00304     static void u8(uint8_t const format, uint8_t const d);
00305 
00309     static void u16(uint8_t const format, uint16_t d);
00310 
00314     static void u32(uint8_t const format, uint32_t d);
00315 
00320     static void f32(uint8_t const format, float32_t const d);
00321 
00326     static void f64(uint8_t const format, float64_t const d);
00327 
00332     static void str(char_t const *s);
00333 
00338     static void str_ROM(char_t const Q_ROM * Q_ROM_VAR s);
00339 
00343     static void mem(uint8_t const *blk, uint8_t size);
00344 
00345 #if (QS_OBJ_PTR_SIZE == 8) || (QS_FUN_PTR_SIZE == 8)
00346 
00347 
00348 
00349     static void u64_(uint64_t d);
00350 
00354     static void u64(uint8_t format, uint64_t d);
00355 #endif
00356 
00357     // QS buffer access ......................................................
00358 
00367     static uint16_t getByte(void);
00368 
00389     static uint8_t const *getBlock(uint16_t * const pNbytes);
00390 
00392     // platform-dependent callback functions to be implemented by clients
00393 
00394     // platform-specific callback functions, need to be implemented by clients
00410     static bool onStartup(void const *arg);
00411 
00418     static void onCleanup(void);
00419 
00426     static void onFlush(void);
00427 
00441     static QSTimeCtr onGetTime(void);
00442 
00444     // Global and Local QS filters
00445     static uint8_t glbFilter_[32];                
00446     static void const *smObj_;         
00447     static void const *aoObj_;       
00448     static void const *mpObj_;            
00449     static void const *eqObj_;             
00450     static void const *teObj_;            
00451     static void const *apObj_;
00452 
00454     // Miscallaneous
00456     static QSTimeCtr tickCtr_;
00457 };
00458 
00463 enum QSType {
00464     QS_I8_T,                                  
00465     QS_U8_T,                                
00466     QS_I16_T,                                
00467     QS_U16_T,                              
00468     QS_I32_T,                                
00469     QS_U32_T,                              
00470     QS_F32_T,                                
00471     QS_F64_T,                                
00472     QS_STR_T,                         
00473     QS_MEM_T,                         
00474     QS_SIG_T,                                         
00475     QS_OBJ_T,                                       
00476     QS_FUN_T,                                     
00477     QS_I64_T,                                
00478     QS_U64_T,                              
00479     QS_U32_HEX_T                    
00480 };
00481 
00485 extern uint8_t QF_critNest_;
00486 
00487 QP_END_
00488 
00489 
00491 // Macros for adding QS instrumentation to the client code
00492 
00498 #define QS_INIT(arg_)           (QP_ QS::onStartup(arg_))
00499 
00505 #define QS_EXIT()               (QP_ QS::onCleanup())
00506 
00514 #define QS_FILTER_ON(rec_)      (QP_ QS::filterOn(static_cast<uint8_t>(rec_)))
00515 
00522 #define QS_FILTER_OFF(rec_)    (QP_ QS::filterOff(static_cast<uint8_t>(rec_)))
00523 
00547 #define QS_FILTER_SM_OBJ(obj_)  (QP_ QS::smObj_ = (obj_))
00548 
00566 #define QS_FILTER_AO_OBJ(obj_)  (QP_ QS::aoObj_ = (obj_))
00567 
00584 #define QS_FILTER_MP_OBJ(obj_)  (QP_ QS::mpObj_ = (obj_))
00585 
00602 #define QS_FILTER_EQ_OBJ(obj_)  (QP_ QS::eqObj_ = (obj_))
00603 
00621 #define QS_FILTER_TE_OBJ(obj_)  (QP_ QS::teObj_ = (obj_))
00622 
00636 #define QS_FILTER_AP_OBJ(obj_)  (QP_ QS::apObj_ = (obj_))
00637 
00638 
00640 // Macros to generate user QS records
00641 
00642 #define QS_GLB_FILTER_(rec_) \
00643     ((QP_ QS::glbFilter_[static_cast<uint8_t>(rec_) >> 3] \
00644       & (static_cast<uint8_t>(1U << (static_cast<uint8_t>(rec_) \
00645                                      & static_cast<uint8_t>(7))))) \
00646              != static_cast<uint8_t>(0))
00647 
00649 #define QS_BEGIN_NOCRIT(rec_, obj_) \
00650     if (QS_GLB_FILTER_(rec_) \
00651         && ((QP_ QS::apObj_ == static_cast<void *>(0)) \
00652             || (QP_ QS::apObj_ == (obj_)))) \
00653     { \
00654         QP_ QS::begin(static_cast<uint8_t>(rec_)); \
00655         QS_TIME_();
00656 
00658 #define QS_END_NOCRIT() \
00659     QS_END_NOCRIT_()
00660 
00661                                                // QS-specific critical section
00662 #ifndef QF_CRIT_STAT_TYPE
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673     #define QS_CRIT_STAT_
00674 
00684     #define QS_CRIT_ENTRY_()    QF_CRIT_ENTRY(dummy)
00685 
00695     #define QS_CRIT_EXIT_()     QF_CRIT_EXIT(dummy)
00696 
00697 #else
00698     #define QS_CRIT_STAT_       QF_CRIT_STAT_TYPE critStat_;
00699     #define QS_CRIT_ENTRY_()    QF_CRIT_ENTRY(critStat_)
00700     #define QS_CRIT_EXIT_()     QF_CRIT_EXIT(critStat_)
00701 #endif
00702 
00710 #define QS_BEGIN(rec_, obj_) \
00711     if (QS_GLB_FILTER_(rec_) \
00712         && ((QP_ QS::apObj_ == static_cast<void *>(0)) \
00713             || (QP_ QS::apObj_ == (obj_)))) \
00714     { \
00715         QS_CRIT_STAT_ \
00716         QS_CRIT_ENTRY_(); \
00717         QP_ QS::begin(static_cast<uint8_t>(rec_)); \
00718         QS_TIME_();
00719 
00723 #define QS_END() \
00724     QS_END_()
00725 
00726 
00728 // Macros for use inside other macros or internally in the QP code
00729 
00734 #define QS_BEGIN_(rec_, objFilter_, obj_) \
00735     if (QS_GLB_FILTER_(rec_) \
00736         && (((objFilter_) == static_cast<void *>(0)) \
00737             || ((objFilter_) == (obj_)))) \
00738     { \
00739         QS_CRIT_ENTRY_(); \
00740         QP_ QS::begin(static_cast<uint8_t>(rec_));
00741 
00746 #define QS_END_() \
00747         QP_ QS::end(); \
00748         QS_CRIT_EXIT_(); \
00749     }
00750 
00755 #define QS_BEGIN_NOCRIT_(rec_, objFilter_, obj_) \
00756     if (QS_GLB_FILTER_(rec_) \
00757         && (((objFilter_) == static_cast<void *>(0)) \
00758             || ((objFilter_) == (obj_)))) \
00759     { \
00760         QP_ QS::begin(static_cast<uint8_t>(rec_));
00761 
00766 #define QS_END_NOCRIT_() \
00767         QP_ QS::end(); \
00768     }
00769 
00770 #if (Q_SIGNAL_SIZE == 1)
00771 
00772 
00773 
00774     #define QS_SIG_(sig_)    (QP_ QS::u8_(static_cast<uint8_t>(sig_)))
00775 #elif (Q_SIGNAL_SIZE == 2)
00776     #define QS_SIG_(sig_)    (QP_ QS::u16_(static_cast<uint16_t>(sig_)))
00777 #elif (Q_SIGNAL_SIZE == 4)
00778     #define QS_SIG_(sig_)    (QP_ QS::u32_(static_cast<uint32_t>(sig_)))
00779 #endif
00780 
00782 #define QS_U8_(data_)        (QP_ QS::u8_(data_))
00783 
00785 #define QS_U16_(data_)       (QP_ QS::u16_(data_))
00786 
00788 #define QS_U32_(data_)       (QP_ QS::u32_(data_))
00789 
00790 
00791 #if (QS_OBJ_PTR_SIZE == 1)
00792     #define QS_OBJ_(obj_)    (QP_ QS::u8_(reinterpret_cast<uint8_t>(obj_)))
00793 #elif (QS_OBJ_PTR_SIZE == 2)
00794     #define QS_OBJ_(obj_)    (QP_ QS::u16_(reinterpret_cast<uint16_t>(obj_)))
00795 #elif (QS_OBJ_PTR_SIZE == 4)
00796     #define QS_OBJ_(obj_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(obj_)))
00797 #elif (QS_OBJ_PTR_SIZE == 8)
00798     #define QS_OBJ_(obj_)    (QP_ QS::u64_(reinterpret_cast<uint64_t>(obj_)))
00799 #else
00800 
00805     #define QS_OBJ_(obj_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(obj_)))
00806 #endif
00807 
00808 
00809 #if (QS_FUN_PTR_SIZE == 1)
00810     #define QS_FUN_(fun_)    (QP_ QS::u8_(reinterpret_cast<uint8_t>(fun_)))
00811 #elif (QS_FUN_PTR_SIZE == 2)
00812     #define QS_FUN_(fun_)    (QP_ QS::u16_(reinterpret_cast<uint16_t>(fun_)))
00813 #elif (QS_FUN_PTR_SIZE == 4)
00814     #define QS_FUN_(fun_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(fun_)))
00815 #elif (QS_FUN_PTR_SIZE == 8)
00816     #define QS_FUN_(fun_)    (QP_ QS::u64_(reinterpret_cast<uint64_t>(fun_)))
00817 #else
00818 
00823     #define QS_FUN_(fun_)    (QP_ QS::u32_(reinterpret_cast<uint32_t>(fun_)))
00824 #endif
00825 
00828 #define QS_STR_(msg_)        (QP_ QS::str_(msg_))
00829 
00832 #define QS_STR_ROM_(msg_)    (QP_ QS::str_ROM_(msg_))
00833 
00835 // Macros for use in the client code
00836 
00838 #define QS_I8(width_, data_) \
00839     (QP_ QS::u8(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00840         | static_cast<uint8_t>(QP_ QS_I8_T)), (data_)))
00841 
00843 #define QS_U8(width_, data_) \
00844     (QP_ QS::u8(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00845         | static_cast<uint8_t>(QP_ QS_U8_T)), (data_)))
00846 
00848 #define QS_I16(width_, data_) \
00849     (QP_ QS::u16(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00850         | static_cast<uint8_t>(QP_ QS_I16_T)), (data_)))
00851 
00853 #define QS_U16(width_, data_) \
00854     (QP_ QS::u16(static_cast<uint8_t>((((width_) << 4)) \
00855         | static_cast<uint8_t>(QP_ QS_U16_T)), (data_)))
00856 
00858 #define QS_I32(width_, data_) \
00859     (QP_ QS::u32(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00860         | static_cast<uint8_t>(QP_ QS_I32_T)), (data_)))
00861 
00863 #define QS_U32(width_, data_) \
00864     (QP_ QS::u32(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00865         | static_cast<uint8_t>(QP_ QS_U32_T)), (data_)))
00866 
00868 #define QS_F32(width_, data_) \
00869     (QP_ QS::f32(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00870         | static_cast<uint8_t>(QP_ QS_F32_T)), (data_)))
00871 
00873 #define QS_F64(width_, data_) \
00874     (QP_ QS::f64(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00875         | static_cast<uint8_t>(QP_ QS_F64_T)), (data_)))
00876 
00878 #define QS_I64(width_, data_) \
00879     (QP_ QS::u64(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00880         | static_cast<uint8_t>(QP_ QS_I64_T)), (data_)))
00881 
00883 #define QS_U64(width_, data_) \
00884     (QP_ QS::u64(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00885         | static_cast<uint8_t>(QP_ QS_U64_T)), (data_)))
00886 
00888 #define QS_U32_HEX(width_, data_) \
00889     (QP_ QS::u32(static_cast<uint8_t>((static_cast<uint8_t>((width_) << 4)) \
00890         | static_cast<uint8_t>(QP_ QS_U32_HEX_T)), (data_)))
00891 
00893 #define QS_STR(str_)            (QP_ QS::str(str_))
00894 
00897 #define QS_STR_ROM(str_)        (QP_ QS::str_ROM(str_))
00898 
00901 #define QS_MEM(mem_, size_)     (QP_ QS::mem((mem_), (size_)))
00902 
00903 
00904 #if (QS_OBJ_PTR_SIZE == 1)
00905     #define QS_OBJ(obj_)        (QP_ QS::u8(QS_OBJ_T, (uint8_t)(obj_)))
00906 #elif (QS_OBJ_PTR_SIZE == 2)
00907     #define QS_OBJ(obj_)        (QP_ QS::u16(QS_OBJ_T, (uint16_t)(obj_)))
00908 #elif (QS_OBJ_PTR_SIZE == 4)
00909     #define QS_OBJ(obj_)        (QP_ QS::u32(QS_OBJ_T, (uint32_t)(obj_)))
00910 #elif (QS_OBJ_PTR_SIZE == 8)
00911     #define QS_OBJ(obj_)        (QP_ QS::u64(QS_OBJ_T, (uint64_t)(obj_)))
00912 #else
00913 
00914     #define QS_OBJ(obj_)        (QP_ QS::u32(QS_OBJ_T, (uint32_t)(obj_)))
00915 #endif
00916 
00917 
00918 #if (QS_FUN_PTR_SIZE == 1)
00919     #define QS_FUN(fun_)        (QP_ QS::u8(QS_FUN_T, (uint8_t)(fun_)))
00920 #elif (QS_FUN_PTR_SIZE == 2)
00921     #define QS_FUN(fun_)        (QP_ QS::u16(QS_FUN_T, (uint16_t)(fun_)))
00922 #elif (QS_FUN_PTR_SIZE == 4)
00923     #define QS_FUN(fun_)        (QP_ QS::u32(QS_FUN_T, (uint32_t)(fun_)))
00924 #elif (QS_FUN_PTR_SIZE == 8)
00925     #define QS_FUN(fun_)        (QP_ QS::u64(QS_FUN_T, (uint64_t)(fun_)))
00926 #else
00927 
00928     #define QS_FUN(fun_)        (QP_ QS::u32(QS_FUN_T, (uint32_t)(fun_)))
00929 #endif
00930 
00931 
00936 #define QS_RESET() do { \
00937     if (QS_GLB_FILTER_(QP_ QS_QP_RESET)) { \
00938         QS_CRIT_STAT_ \
00939         QS_CRIT_ENTRY_(); \
00940         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_QP_RESET)); \
00941         QP_ QS::end(); \
00942         QS_CRIT_EXIT_(); \
00943         QP_ QS::onFlush(); \
00944     } \
00945 } while (false)
00946 
00986 #define QS_SIG_DICTIONARY(sig_, obj_) do { \
00987     if (QS_GLB_FILTER_(QP_ QS_SIG_DIC)) { \
00988         static char_t const Q_ROM Q_ROM_VAR sig_name_[] = #sig_; \
00989         QS_CRIT_STAT_ \
00990         QS_CRIT_ENTRY_(); \
00991         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_SIG_DIC)); \
00992         QS_SIG_(sig_); \
00993         QS_OBJ_(obj_); \
00994         QS_STR_ROM_(&sig_name_[0]); \
00995         QP_ QS::end(); \
00996         QS_CRIT_EXIT_(); \
00997         QP_ QS::onFlush(); \
00998     } \
00999 } while (false)
01000 
01013 #define QS_OBJ_DICTIONARY(obj_) do { \
01014     if (QS_GLB_FILTER_(QP_ QS_OBJ_DIC)) { \
01015         static char_t const Q_ROM Q_ROM_VAR obj_name_[] = #obj_; \
01016         QS_CRIT_STAT_ \
01017         QS_CRIT_ENTRY_(); \
01018         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_OBJ_DIC)); \
01019         QS_OBJ_(obj_); \
01020         QS_STR_ROM_(&obj_name_[0]); \
01021         QP_ QS::end(); \
01022         QS_CRIT_EXIT_(); \
01023         QP_ QS::onFlush(); \
01024     } \
01025 } while (false)
01026 
01038 #define QS_FUN_DICTIONARY(fun_) do { \
01039     if (QS_GLB_FILTER_(QP_ QS_FUN_DIC)) { \
01040         static char_t const Q_ROM Q_ROM_VAR fun_name_[] = #fun_; \
01041         QS_CRIT_STAT_ \
01042         QS_CRIT_ENTRY_(); \
01043         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_FUN_DIC)); \
01044         QS_FUN_(fun_); \
01045         QS_STR_ROM_(&fun_name_[0]); \
01046         QP_ QS::end(); \
01047         QS_CRIT_EXIT_(); \
01048         QP_ QS::onFlush(); \
01049     } \
01050 } while (false)
01051 
01056 #define QS_USR_DICTIONARY(rec_) do { \
01057     if (QS_GLB_FILTER_(QP_ QS_USR_DIC)) { \
01058         static char_t const Q_ROM Q_ROM_VAR usr_name_[] = #rec_; \
01059         QS_CRIT_STAT_ \
01060         QS_CRIT_ENTRY_(); \
01061         QP_ QS::begin(static_cast<uint8_t>(QP_ QS_USR_DIC)); \
01062         QS_U8_(static_cast<uint8_t>(rec_)); \
01063         QS_STR_ROM_(&usr_name_[0]); \
01064         QP_ QS::end(); \
01065         QS_CRIT_EXIT_(); \
01066         QP_ QS::onFlush(); \
01067     } \
01068 } while (false)
01069 
01071 #define QS_ASSERTION(module_, loc_) do { \
01072     QS_BEGIN_NOCRIT_(QP_ QS_ASSERT, \
01073         static_cast<void *>(0), static_cast<void *>(0)) \
01074         QS_TIME_(); \
01075         QS_U16_(static_cast<uint16_t>(loc_)); \
01076         QS_STR_ROM_(module_); \
01077     QS_END_NOCRIT_() \
01078     QP_ QS::onFlush(); \
01079 } while (false)
01080 
01087 #define QS_FLUSH()   (QP_ QS::onFlush())
01088 
01090 #define QF_QS_CRIT_ENTRY() \
01091     QS_BEGIN_NOCRIT_(QP_ QS_QF_CRIT_ENTRY, \
01092         static_cast<void *>(0), static_cast<void *>(0)) \
01093         QS_TIME_(); \
01094         QS_U8_((uint8_t)(++QF_critNest_)); \
01095     QS_END_NOCRIT_()
01096 
01098 #define QF_QS_CRIT_EXIT() \
01099     QS_BEGIN_NOCRIT_(QP_ QS_QF_CRIT_EXIT, \
01100         static_cast<void *>(0), static_cast<void *>(0)) \
01101         QS_TIME_(); \
01102         QS_U8_((uint8_t)(QF_critNest_--)); \
01103     QS_END_NOCRIT_()
01104 
01106 #define QF_QS_ISR_ENTRY(isrnest_, prio_) \
01107     QS_BEGIN_NOCRIT_(QP_ QS_QF_ISR_ENTRY, \
01108         static_cast<void *>(0), static_cast<void *>(0)) \
01109         QS_TIME_(); \
01110         QS_U8_(isrnest_); \
01111         QS_U8_(prio_); \
01112     QS_END_NOCRIT_()
01113 
01115 #define QF_QS_ISR_EXIT(isrnest_, prio_) \
01116     QS_BEGIN_NOCRIT_(QP_ QS_QF_ISR_EXIT,  \
01117         static_cast<void *>(0), static_cast<void *>(0)) \
01118         QS_TIME_(); \
01119         QS_U8_(isrnest_); \
01120         QS_U8_(prio_); \
01121     QS_END_NOCRIT_()
01122 
01124 #define QF_QS_ACTION(act_)      (act_)
01125 
01126 #endif                                                                 // qs_h