QP/C
qs.h
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * Product:  QS/C platform-independent public interface.
00003 * Last Updated for Version: 4.4.00
00004 * Date of the Last Update:  Jan 17, 2011
00005 *
00006 *                    Q u a n t u m     L e a P s
00007 *                    ---------------------------
00008 *                    innovating embedded systems
00009 *
00010 * Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
00011 *
00012 * This software may be distributed and modified under the terms of the GNU
00013 * General Public License version 2 (GPL) as published by the Free Software
00014 * Foundation and appearing in the file GPL.TXT included in the packaging of
00015 * this file. Please note that GPL Section 2[b] requires that all works based
00016 * on this software must also be made publicly available under the terms of
00017 * the GPL ("Copyleft").
00018 *
00019 * Alternatively, this software may be distributed and modified under the
00020 * terms of Quantum Leaps commercial licenses, which expressly supersede
00021 * the GPL and are specifically designed for licensees interested in
00022 * retaining the proprietary status of their code.
00023 *
00024 * Contact information:
00025 * Quantum Leaps Web site:  http://www.quantum-leaps.com
00026 * e-mail:                  info@quantum-leaps.com
00027 *****************************************************************************/
00028 #ifndef qs_h
00029 #define qs_h
00030 
00040 #ifndef Q_SPY
00041     #error "Q_SPY must be defined to include qs.h"
00042 #endif
00043 
00044 /****************************************************************************/
00052 enum QSpyRecords {
00053     /* QEP records */
00054     QS_QEP_STATE_EMPTY,
00055     QS_QEP_STATE_ENTRY,                            
00056     QS_QEP_STATE_EXIT,                              
00057     QS_QEP_STATE_INIT,       
00058     QS_QEP_INIT_TRAN,        
00059     QS_QEP_INTERN_TRAN,               
00060     QS_QEP_TRAN,                        
00061     QS_QEP_IGNORED,          
00062     QS_QEP_DISPATCH,       
00063     QS_QEP_RESERVED0,
00064 
00065     /* QF records */
00066     QS_QF_ACTIVE_ADD,             
00067     QS_QF_ACTIVE_REMOVE,      
00068     QS_QF_ACTIVE_SUBSCRIBE,               
00069     QS_QF_ACTIVE_UNSUBSCRIBE,           
00070     QS_QF_ACTIVE_POST_FIFO,  
00071     QS_QF_ACTIVE_POST_LIFO,  
00072     QS_QF_ACTIVE_GET, 
00073     QS_QF_ACTIVE_GET_LAST,      
00074     QS_QF_EQUEUE_INIT,                  
00075     QS_QF_EQUEUE_POST_FIFO,  
00076     QS_QF_EQUEUE_POST_LIFO,  
00077     QS_QF_EQUEUE_GET,           
00078     QS_QF_EQUEUE_GET_LAST,           
00079     QS_QF_MPOOL_INIT,                    
00080     QS_QF_MPOOL_GET,     
00081     QS_QF_MPOOL_PUT,      
00082     QS_QF_PUBLISH,                              
00083     QS_QF_RESERVED8,
00084     QS_QF_NEW,                                      
00085     QS_QF_GC_ATTEMPT,                       
00086     QS_QF_GC,                                       
00087     QS_QF_TICK,                                   
00088     QS_QF_TIMEEVT_ARM,                          
00089     QS_QF_TIMEEVT_AUTO_DISARM,   
00090     QS_QF_TIMEEVT_DISARM_ATTEMPT,
00091     QS_QF_TIMEEVT_DISARM,        
00092     QS_QF_TIMEEVT_REARM,                      
00093     QS_QF_TIMEEVT_POST,   
00094     QS_QF_TIMEEVT_CTR,              
00095     QS_QF_CRIT_ENTRY,                     
00096     QS_QF_CRIT_EXIT,                       
00097     QS_QF_ISR_ENTRY,                                
00098     QS_QF_ISR_EXIT,                                  
00099     QS_QF_INT_DISABLE,                        
00100     QS_QF_INT_ENABLE,                          
00101     QS_QF_RESERVED4,
00102     QS_QF_RESERVED3,
00103     QS_QF_RESERVED2,
00104     QS_QF_RESERVED1,
00105     QS_QF_RESERVED0,
00106 
00107     /* QK records */
00108     QS_QK_MUTEX_LOCK,                          
00109     QS_QK_MUTEX_UNLOCK,                      
00110     QS_QK_SCHEDULE,             
00111     QS_QK_RESERVED6,
00112     QS_QK_RESERVED5,
00113     QS_QK_RESERVED4,
00114     QS_QK_RESERVED3,
00115     QS_QK_RESERVED2,
00116     QS_QK_RESERVED1,
00117     QS_QK_RESERVED0,
00118 
00119     /* Miscellaneous QS records */
00120     QS_SIG_DIC,                                
00121     QS_OBJ_DIC,                                
00122     QS_FUN_DIC,                              
00123     QS_ASSERT,                             
00124     QS_RESERVED5,
00125     QS_RESERVED4,
00126     QS_RESERVED3,
00127     QS_RESERVED2,
00128     QS_RESERVED1,
00129     QS_RESERVED0,
00130 
00131     /* User records */
00132     QS_USER             
00133 };
00134 
00135 /* Global and Local QS filters .............................................*/
00136 extern uint8_t QS_glbFilter_[32];              
00137 extern void const *QS_smObj_;       
00138 extern void const *QS_aoObj_;        
00139 extern void const *QS_mpObj_;          
00140 extern void const *QS_eqObj_;           
00141 extern void const *QS_teObj_;          
00142 extern void const *QS_apObj_; 
00147 #define QS_ALL_RECORDS          ((uint8_t)0xFF)
00148 
00149 #ifndef QS_TIME_SIZE
00150 
00158     #define QS_TIME_SIZE 4
00159 #endif
00160 
00161 #if (QS_TIME_SIZE == 1)
00162     typedef uint8_t QSTimeCtr;
00163     #define QS_TIME_()          QS_u8_(QS_onGetTime())
00164 #elif (QS_TIME_SIZE == 2)
00165     typedef uint16_t QSTimeCtr;
00166     #define QS_TIME_()          QS_u16_(QS_onGetTime())
00167 #elif (QS_TIME_SIZE == 4)
00168 
00172     typedef uint32_t QSTimeCtr;
00175     #define QS_TIME_()          QS_u32_(QS_onGetTime())
00176 #else
00177     #error "QS_TIME_SIZE defined incorrectly, expected 1, 2, or 4"
00178 #endif
00179 
00181 extern QSTimeCtr QS_tickCtr_;
00182 
00183 #ifndef Q_ROM                   /* provide the default if Q_ROM NOT defined */
00184     #define Q_ROM
00185 #endif
00186 #ifndef Q_ROM_VAR           /* provide the default if Q_ROM_VAR NOT defined */
00187     #define Q_ROM_VAR
00188 #endif
00189 #ifndef Q_ROM_BYTE         /* provide the default if Q_ROM_BYTE NOT defined */
00190     #define Q_ROM_BYTE(rom_var_)   (rom_var_)
00191 #endif
00192 
00193 /*****************************************************************************
00194 * QS services.
00195 */
00196 /* public methods */
00203 char_t const Q_ROM * Q_ROM_VAR QS_getVersion(void);
00204 
00223 void QS_initBuf(uint8_t sto[], uint32_t stoSize);
00224 
00237 void QS_filterOn(uint8_t rec);
00238 
00250 void QS_filterOff(uint8_t rec);
00251 
00259 void QS_begin(uint8_t rec);
00260 
00268 void QS_end(void);
00269 
00270 /* unformatted data elements output ........................................*/
00275 void QS_u8_(uint8_t d);
00276 
00281 void QS_u16_(uint16_t d);
00282 
00287 void QS_u32_(uint32_t d);
00288 
00294 void QS_str_(char_t const *s);
00295 
00301 void QS_str_ROM_(char_t const Q_ROM * Q_ROM_VAR s);
00302 
00303 /* formatted data elements output ..........................................*/
00308 void QS_u8(uint8_t format, uint8_t d);
00309 
00314 void QS_u16(uint8_t format, uint16_t d);
00315 
00320 void QS_u32(uint8_t format, uint32_t d);
00321 
00326 void QS_f32(uint8_t format, float32_t f);
00327 
00332 void QS_f64(uint8_t format, float64_t d);
00333 
00338 void QS_str(char_t const *s);
00339 
00345 void QS_str_ROM(char_t const Q_ROM * Q_ROM_VAR s);
00346 
00351 void QS_mem(uint8_t const *blk, uint8_t size);
00352 
00353 #if (QS_OBJ_PTR_SIZE == 8) || (QS_FUN_PTR_SIZE == 8)
00354 
00358     void QS_u64_(uint64_t d);
00359 
00364     void QS_u64(uint8_t format, uint64_t d);
00365 #endif
00366 
00367 /* QS buffer access ........................................................*/
00377 uint16_t QS_getByte(void);
00378 
00382 #define QS_EOD ((uint16_t)0xFFFF)
00383 
00404 uint8_t const *QS_getBlock(uint16_t *pNbytes);
00405 
00406 /* platform-specific callback functions, need to be implemented by clients  */
00422 uint8_t QS_onStartup(void const *arg);
00423 
00431 void QS_onCleanup(void);
00432 
00440 void QS_onFlush(void);
00441 
00456 QSTimeCtr QS_onGetTime(void);
00457 
00458 
00459 /* Macros for adding QS instrumentation to the client code .................*/
00460 
00467 #define QS_INIT(arg_)           (QS_onStartup(arg_) != (uint8_t)0)
00468 
00475 #define QS_EXIT()               QS_onCleanup()
00476 
00485 #define QS_FILTER_ON(rec_)      QS_filterOn((uint8_t)(rec_))
00486 
00494 #define QS_FILTER_OFF(rec_)     QS_filterOff((uint8_t)(rec_))
00495 
00520 #define QS_FILTER_SM_OBJ(obj_)  (QS_smObj_ = (obj_))
00521 
00540 #define QS_FILTER_AO_OBJ(obj_)  (QS_aoObj_ = (obj_))
00541 
00559 #define QS_FILTER_MP_OBJ(obj_)  (QS_mpObj_ = (obj_))
00560 
00578 #define QS_FILTER_EQ_OBJ(obj_)  (QS_eqObj_ = (obj_))
00579 
00598 #define QS_FILTER_TE_OBJ(obj_)  (QS_teObj_ = (obj_))
00599 
00614 #define QS_FILTER_AP_OBJ(obj_)  (QS_apObj_ = (obj_))
00615 
00616 /* Macros to generate user QS records ......................................*/
00617 
00620 #define QS_BEGIN_NOCRIT(rec_, obj_) \
00621     if (((QS_glbFilter_[(rec_) >> 3] \
00622           & (uint8_t)(1U << ((uint8_t)(rec_) & (uint8_t)7))) != (uint8_t)0) \
00623         && ((QS_apObj_ == (void *)0) || (QS_apObj_ == (obj_)))) \
00624     { \
00625         QS_begin((uint8_t)(rec_)); \
00626         QS_TIME_(); {
00627 
00630 #define QS_END_NOCRIT() } \
00631     QS_END_NOCRIT_()
00632 
00633                                             /* QS-specific critical section */
00634 #ifndef QF_CRIT_STAT_TYPE
00635 
00645     #define QS_CRIT_STAT_
00646 
00656     #define QS_CRIT_ENTRY_()    QF_CRIT_ENTRY(dummy)
00657 
00667     #define QS_CRIT_EXIT_()     QF_CRIT_EXIT(dummy)
00668 
00669 #else
00670     #define QS_CRIT_STAT_       QF_CRIT_STAT_TYPE critStat_;
00671     #define QS_CRIT_ENTRY_()    QF_CRIT_ENTRY(critStat_)
00672     #define QS_CRIT_EXIT_()     QF_CRIT_EXIT(critStat_)
00673 #endif
00674 
00683 #define QS_BEGIN(rec_, obj_) \
00684     if (((QS_glbFilter_[(uint8_t)(rec_) >> 3] \
00685           & (uint8_t)(1U << ((uint8_t)(rec_) & (uint8_t)7))) != (uint8_t)0) \
00686         && ((QS_apObj_ == (void *)0) || (QS_apObj_ == (obj_)))) \
00687     { \
00688         QS_CRIT_STAT_ \
00689         QS_CRIT_ENTRY_(); \
00690         QS_begin((uint8_t)(rec_)); \
00691         QS_TIME_(); {
00692 
00697 #define QS_END() } \
00698     QS_END_()
00699 
00700 
00701 /*****************************************************************************
00702 * Macros for use inside other macros or internally in the QP code
00703 */
00704 
00711 #define QS_BEGIN_(rec_, objFilter_, obj_) \
00712     if (((QS_glbFilter_[(uint8_t)(rec_) >> 3] \
00713           & (uint8_t)(1U << ((uint8_t)(rec_) & (uint8_t)7))) != (uint8_t)0) \
00714         && (((objFilter_) == (void *)0) || ((objFilter_) == (obj_)))) \
00715     { \
00716         QS_CRIT_ENTRY_(); \
00717         QS_begin((uint8_t)(rec_));
00718 
00725 #define QS_END_() \
00726         QS_end(); \
00727         QS_CRIT_EXIT_(); \
00728     }
00729 
00736 #define QS_BEGIN_NOCRIT_(rec_, objFilter_, obj_) \
00737     if (((QS_glbFilter_[(uint8_t)(rec_) >> 3] \
00738           & (uint8_t)(1U << ((uint8_t)(rec_) & (uint8_t)7))) != (uint8_t)0) \
00739         && (((objFilter_) == (void *)0) || ((objFilter_) == (obj_)))) \
00740     { \
00741         QS_begin((uint8_t)(rec_));
00742 
00748 #define QS_END_NOCRIT_() \
00749         QS_end(); \
00750     }
00751 
00753 #define QS_U8_(data_)           QS_u8_(data_)
00754 
00756 #define QS_U16_(data_)          QS_u16_(data_)
00757 
00759 #define QS_U32_(data_)          QS_u32_(data_)
00760 
00761 
00762 #if (QS_OBJ_PTR_SIZE == 1)
00763     #define QS_OBJ_(obj_)       QS_u8_((uint8_t)(obj_))
00764 #elif (QS_OBJ_PTR_SIZE == 2)
00765     #define QS_OBJ_(obj_)       QS_u16_((uint16_t)(obj_))
00766 #elif (QS_OBJ_PTR_SIZE == 4)
00767     #define QS_OBJ_(obj_)       QS_u32_((uint32_t)(obj_))
00768 #elif (QS_OBJ_PTR_SIZE == 8)
00769     #define QS_OBJ_(obj_)       QS_u64_((uint64_t)(obj_))
00770 #else
00771 
00777     #define QS_OBJ_(obj_)       QS_u32_((uint32_t)(obj_))
00778 #endif
00779 
00780 
00781 #if (QS_FUN_PTR_SIZE == 1)
00782     #define QS_FUN_(fun_)       QS_u8_((uint8_t)(fun_))
00783 #elif (QS_FUN_PTR_SIZE == 2)
00784     #define QS_FUN_(fun_)       QS_u16_((uint16_t)(fun_))
00785 #elif (QS_FUN_PTR_SIZE == 4)
00786     #define QS_FUN_(fun_)       QS_u32_((uint32_t)(fun_))
00787 #elif (QS_FUN_PTR_SIZE == 8)
00788     #define QS_FUN_(fun_)       QS_u64_((uint64_t)(fun_))
00789 #else
00790 
00796     #define QS_FUN_(fun_)       QS_u32_((uint32_t)(fun_))
00797 #endif
00798 
00799 
00803 #define QS_STR_(msg_)           QS_str_(msg_)
00804 
00808 #define QS_STR_ROM_(msg_)       QS_str_ROM_(msg_)
00809 
00810 /*****************************************************************************
00811 * Macros for use in the client code
00812 */
00813 
00819 enum QSType {
00820     QS_I8_T,                               
00821     QS_U8_T,                             
00822     QS_I16_T,                             
00823     QS_U16_T,                           
00824     QS_I32_T,                             
00825     QS_U32_T,                           
00826     QS_F32_T,                             
00827     QS_F64_T,                             
00828     QS_STR_T,                      
00829     QS_MEM_T,                      
00830     QS_SIG_T,                                      
00831     QS_OBJ_T,                                    
00832     QS_FUN_T,                                  
00833     QS_I64_T,                             
00834     QS_U64_T,                           
00835     QS_U32_HEX_T                 
00836 };
00837 
00839 #define QS_I8(width_, data_) \
00840     QS_u8((uint8_t)(((width_) << 4)) | (uint8_t)QS_I8_T, (data_))
00841 
00843 #define QS_U8(width_, data_) \
00844     QS_u8((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_))
00845 
00847 #define QS_I16(width_, data_) \
00848     QS_u16((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_))
00849 
00851 #define QS_U16(width_, data_) \
00852     QS_u16((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_))
00853 
00855 #define QS_I32(width_, data_) \
00856     QS_u32((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_))
00857 
00859 #define QS_U32(width_, data_) \
00860     QS_u32((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_))
00861 
00863 #define QS_F32(width_, data_) \
00864     QS_f32((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_))
00865 
00867 #define QS_F64(width_, data_) \
00868     QS_f64((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_))
00869 
00871 #define QS_I64(width_, data_) \
00872     QS_u64((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_))
00873 
00875 #define QS_U64(width_, data_) \
00876     QS_u64((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_))
00877 
00879 #define QS_U32_HEX(width_, data_) \
00880     QS_u32((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_HEX_T, (data_))
00881 
00883 #define QS_STR(str_)            QS_str(str_)
00884 
00888 #define QS_STR_ROM(str_)        QS_str_ROM(str_)
00889 
00893 #define QS_MEM(mem_, size_)     QS_mem((mem_), (size_))
00894 
00895 
00896 #if (QS_OBJ_PTR_SIZE == 1)
00897     #define QS_OBJ(obj_)        QS_u8(QS_OBJ_T, (uint8_t)(obj_))
00898 #elif (QS_OBJ_PTR_SIZE == 2)
00899     #define QS_OBJ(obj_)        QS_u16(QS_OBJ_T, (uint16_t)(obj_))
00900 #elif (QS_OBJ_PTR_SIZE == 4)
00901     #define QS_OBJ(obj_)        QS_u32(QS_OBJ_T, (uint32_t)(obj_))
00902 #elif (QS_OBJ_PTR_SIZE == 8)
00903     #define QS_OBJ(obj_)        QS_u64(QS_OBJ_T, (uint64_t)(obj_))
00904 #else
00905 
00906     #define QS_OBJ(obj_)        QS_u32(QS_OBJ_T, (uint32_t)(obj_))
00907 #endif
00908 
00909 
00910 #if (QS_FUN_PTR_SIZE == 1)
00911     #define QS_FUN(fun_)        QS_u8(QS_FUN_T, (uint8_t)(fun_))
00912 #elif (QS_FUN_PTR_SIZE == 2)
00913     #define QS_FUN(fun_)        QS_u16(QS_FUN_T, (uint16_t)(fun_))
00914 #elif (QS_FUN_PTR_SIZE == 4)
00915     #define QS_FUN(fun_)        QS_u32(QS_FUN_T, (uint32_t)(fun_))
00916 #elif (QS_FUN_PTR_SIZE == 8)
00917     #define QS_FUN(fun_)        QS_u64(QS_FUN_T, (uint64_t)(fun_))
00918 #else
00919 
00920     #define QS_FUN(fun_)        QS_u32(QS_FUN_T, (uint32_t)(fun_))
00921 #endif
00922 
00923 
00924 #if (Q_SIGNAL_SIZE == 1)
00925 
00929     #define QS_SIG(sig_, obj_) \
00930         QS_u8(QS_SIG_T, (sig_)); \
00931         QS_OBJ_(obj_)
00932 #elif (Q_SIGNAL_SIZE == 2)
00933     #define QS_SIG(sig_, obj_) \
00934         QS_u16(QS_SIG_T, (sig_)); \
00935         QS_OBJ_(obj_)
00936 #elif (Q_SIGNAL_SIZE == 4)
00937     #define QS_SIG(sig_, obj_) \
00938         QS_u32(QS_SIG_T, (sig_)); \
00939         QS_OBJ_(obj_)
00940 #endif
00941 
00982 #define QS_SIG_DICTIONARY(sig_, obj_) do { \
00983     if (((QS_glbFilter_[(uint8_t)QS_SIG_DIC >> 3] \
00984       & (uint8_t)(1U << ((uint8_t)QS_SIG_DIC & (uint8_t)7))) != (uint8_t)0)) \
00985     { \
00986         static char_t const Q_ROM Q_ROM_VAR sig_name__[] = #sig_; \
00987         QS_CRIT_STAT_ \
00988         QS_CRIT_ENTRY_(); \
00989         QS_begin((uint8_t)QS_SIG_DIC); \
00990         QS_SIG_((QSignal)sig_); \
00991         QS_OBJ_(obj_); \
00992         QS_STR_ROM_(sig_name__); \
00993         QS_end(); \
00994         QS_CRIT_EXIT_(); \
00995         QS_onFlush(); \
00996     } \
00997 } while (0)
00998 
01012 #define QS_OBJ_DICTIONARY(obj_) do { \
01013     if (((QS_glbFilter_[(uint8_t)QS_OBJ_DIC >> 3] \
01014       & (uint8_t)(1U << ((uint8_t)QS_OBJ_DIC & (uint8_t)7))) != (uint8_t)0)) \
01015     { \
01016         static char_t const Q_ROM Q_ROM_VAR obj_name__[] = #obj_; \
01017         QS_CRIT_STAT_ \
01018         QS_CRIT_ENTRY_(); \
01019         QS_begin((uint8_t)QS_OBJ_DIC); \
01020         QS_OBJ_(obj_); \
01021         QS_STR_ROM_(obj_name__); \
01022         QS_end(); \
01023         QS_CRIT_EXIT_(); \
01024         QS_onFlush(); \
01025     } \
01026 } while (0)
01027 
01040 #define QS_FUN_DICTIONARY(fun_) do { \
01041     if (((QS_glbFilter_[(uint8_t)QS_FUN_DIC >> 3] \
01042       & (uint8_t)(1U << ((uint8_t)QS_FUN_DIC & (uint8_t)7))) != (uint8_t)0)) \
01043     { \
01044         static char_t const Q_ROM Q_ROM_VAR fun_name__[] = #fun_; \
01045         QS_CRIT_STAT_ \
01046         QS_CRIT_ENTRY_(); \
01047         QS_begin((uint8_t)QS_FUN_DIC); \
01048         QS_FUN_(fun_); \
01049         QS_STR_ROM_(fun_name__); \
01050         QS_end(); \
01051         QS_CRIT_EXIT_(); \
01052         QS_onFlush(); \
01053     } \
01054 } while (0)
01055 
01056 
01064 #define QS_FLUSH()   QS_onFlush()
01065 
01067 #define QF_QS_CRIT_ENTRY() \
01068     QS_BEGIN_NOCRIT_(QS_QF_CRIT_ENTRY, (void *)0, (void *)0); \
01069         QS_TIME_(); \
01070         QS_U8_((uint8_t)(++QF_critNest_)); \
01071     QS_END_NOCRIT_()
01072 
01074 #define QF_QS_CRIT_EXIT() \
01075     QS_BEGIN_NOCRIT_(QS_QF_CRIT_EXIT, (void *)0, (void *)0); \
01076         QS_TIME_(); \
01077         QS_U8_((uint8_t)(QF_critNest_--)); \
01078     QS_END_NOCRIT_()
01079 
01081 #define QF_QS_ISR_ENTRY(isrnest_, prio_) \
01082     QS_BEGIN_NOCRIT_(QS_QF_ISR_ENTRY, (void *)0, (void *)0); \
01083         QS_TIME_(); \
01084         QS_U8_(isrnest_); \
01085         QS_U8_(prio_); \
01086     QS_END_NOCRIT_()
01087 
01089 #define QF_QS_ISR_EXIT(isrnest_, prio_) \
01090     QS_BEGIN_NOCRIT_(QS_QF_ISR_EXIT, (void *)0, (void *)0); \
01091         QS_TIME_(); \
01092         QS_U8_(isrnest_); \
01093         QS_U8_(prio_); \
01094     QS_END_NOCRIT_()
01095 
01097 #define QF_QS_ACTION(act_)      (act_)
01098 
01103 extern uint8_t QF_critNest_;
01104 
01105 #endif                                                             /* qs_h  */
01106