qs.h 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707
  1. /*$file${include::qs.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  2. /*
  3. * Model: qpc.qm
  4. * File: ${include::qs.h}
  5. *
  6. * This code has been generated by QM 5.2.5 <www.state-machine.com/qm>.
  7. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
  8. *
  9. * This code is covered by the following QP license:
  10. * License # : LicenseRef-QL-dual
  11. * Issued to : Any user of the QP/C real-time embedded framework
  12. * Framework(s) : qpc
  13. * Support ends : 2023-12-31
  14. * License scope:
  15. *
  16. * Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
  17. *
  18. * SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
  19. *
  20. * This software is dual-licensed under the terms of the open source GNU
  21. * General Public License version 3 (or any later version), or alternatively,
  22. * under the terms of one of the closed source Quantum Leaps commercial
  23. * licenses.
  24. *
  25. * The terms of the open source GNU General Public License version 3
  26. * can be found at: <www.gnu.org/licenses/gpl-3.0>
  27. *
  28. * The terms of the closed source Quantum Leaps commercial licenses
  29. * can be found at: <www.state-machine.com/licensing>
  30. *
  31. * Redistributions in source code must retain this top-level comment block.
  32. * Plagiarizing this software to sidestep the license obligations is illegal.
  33. *
  34. * Contact information:
  35. * <www.state-machine.com/licensing>
  36. * <info@state-machine.com>
  37. */
  38. /*$endhead${include::qs.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  39. /*! @file
  40. * @brief QS/C platform-independent public interface.
  41. */
  42. #ifndef QS_H_
  43. #define QS_H_
  44. #ifndef Q_SPY
  45. #error "Q_SPY must be defined to include qs.h"
  46. #endif
  47. /*==========================================================================*/
  48. /*$declare${QS-config} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  49. /*${QS-config::QS_CTR_SIZE} ................................................*/
  50. #ifndef QS_CTR_SIZE
  51. /*! The size [bytes] of the internal QS buffer-counters. Valid values: 2U or 4U;
  52. * default 2U.
  53. *
  54. * @details
  55. * This macro can be defined in the QS port file (qs_port.h) to
  56. * configure the ::QSCtr type. Here the macro is not defined so the
  57. * default of 2 byte is chosen.
  58. */
  59. #define QS_CTR_SIZE 2U
  60. #endif /* ndef QS_CTR_SIZE */
  61. /*${QS-config::QS_CTR_SIZE defined incorrectly,~} ..........................*/
  62. #if (QS_CTR_SIZE != 2U) && (QS_CTR_SIZE != 4U)
  63. #error QS_CTR_SIZE defined incorrectly, expected 2U or 4U;
  64. #endif /* (QS_CTR_SIZE != 2U) && (QS_CTR_SIZE != 4U) */
  65. /*${QS-config::QS_TIME_SIZE} ...............................................*/
  66. #ifndef QS_TIME_SIZE
  67. /*! The size [bytes] of the QS time stamp. Valid values: 1U, 2U, or 4U;
  68. * default 4U.
  69. *
  70. * @details
  71. * This macro can be defined in the QS port file (qs_port.h) to
  72. * configure the ::QSTimeCtr type. Here the macro is not defined so the
  73. * default of 4 byte is chosen.
  74. */
  75. #define QS_TIME_SIZE 4U
  76. #endif /* ndef QS_TIME_SIZE */
  77. /*${QS-config::QS_TIME_SIZE defined incorrectly~} ..........................*/
  78. #if (QS_TIME_SIZE != 1U) && (QS_TIME_SIZE != 2U) && (QS_TIME_SIZE != 4U)
  79. #error QS_TIME_SIZE defined incorrectly, expected 1U, 2U, or 4U;
  80. #endif /* (QS_TIME_SIZE != 1U) && (QS_TIME_SIZE != 2U) && (QS_TIME_SIZE != 4U) */
  81. /*$enddecl${QS-config} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  82. /*==========================================================================*/
  83. /*$declare${QS} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  84. /*${QS::QSCtr} .............................................................*/
  85. #if (QS_CTR_SIZE == 2U)
  86. /*! QS ring buffer counter and offset type */
  87. typedef uint_fast16_t QSCtr;
  88. #endif /* (QS_CTR_SIZE == 2U) */
  89. /*${QS::QSCtr} .............................................................*/
  90. #if (QS_CTR_SIZE == 4U)
  91. typedef uint_fast32_t QSCtr;
  92. #endif /* (QS_CTR_SIZE == 4U) */
  93. /*${QS::QSTimeCtr} .........................................................*/
  94. #if (QS_TIME_SIZE == 4U)
  95. /*! QS time stamp type, which determines the dynamic range of QS time stamps */
  96. typedef uint32_t QSTimeCtr;
  97. #endif /* (QS_TIME_SIZE == 4U) */
  98. /*${QS::QSTimeCtr} .........................................................*/
  99. #if (QS_TIME_SIZE == 2U)
  100. typedef uint16_t QSTimeCtr;
  101. #endif /* (QS_TIME_SIZE == 2U) */
  102. /*${QS::QSTimeCtr} .........................................................*/
  103. #if (QS_TIME_SIZE == 1U)
  104. typedef uint8_t QSTimeCtr;
  105. #endif /* (QS_TIME_SIZE == 1U) */
  106. /*${QS::QSFun} .............................................................*/
  107. #if (QS_FUN_PTR_SIZE == 4U)
  108. /*! QS function pointer type (for serializing function pointers) */
  109. typedef uint32_t QSFun;
  110. #endif /* (QS_FUN_PTR_SIZE == 4U) */
  111. /*${QS::QSFun} .............................................................*/
  112. #if (QS_FUN_PTR_SIZE == 8U)
  113. typedef uint64_t QSFun;
  114. #endif /* (QS_FUN_PTR_SIZE == 8U) */
  115. /*${QS::QSFun} .............................................................*/
  116. #if (QS_FUN_PTR_SIZE == 2U)
  117. typedef uint16_t QSFun;
  118. #endif /* (QS_FUN_PTR_SIZE == 2U) */
  119. /*${QS::QSFun} .............................................................*/
  120. #if (QS_FUN_PTR_SIZE == 1U)
  121. typedef uint8_t QSFun;
  122. #endif /* (QS_FUN_PTR_SIZE == 1U) */
  123. /*${QS::QSpyPre} ...........................................................*/
  124. /*! QS pre-defined record types (TX channel)
  125. * @static @public @memberof QS
  126. *
  127. * @details
  128. * This enumeration specifies the record types used in the QP components.
  129. * You can specify your own record types starting from ::QS_USER offset.
  130. * Currently, the maximum of all records cannot exceed 125.
  131. *
  132. * @note
  133. * The QS records labeled as "not maskable" are always enabled and cannot
  134. * be turend off with the QS_GLB_FILTER() macro. Other QS trace records
  135. * can be disabled by means of the "global filters"
  136. *
  137. * @sa QS_GLB_FILTER() macro
  138. */
  139. enum QSpyPre {
  140. /* [0] QS session (not maskable) */
  141. QS_EMPTY, /*!< QS record for cleanly starting a session */
  142. /* [1] SM records */
  143. QS_QEP_STATE_ENTRY, /*!< a state was entered */
  144. QS_QEP_STATE_EXIT, /*!< a state was exited */
  145. QS_QEP_STATE_INIT, /*!< an initial transition was taken in a state */
  146. QS_QEP_INIT_TRAN, /*!< the top-most initial transition was taken */
  147. QS_QEP_INTERN_TRAN, /*!< an internal transition was taken */
  148. QS_QEP_TRAN, /*!< a regular transition was taken */
  149. QS_QEP_IGNORED, /*!< an event was ignored (silently discarded) */
  150. QS_QEP_DISPATCH, /*!< an event was dispatched (begin of RTC step) */
  151. QS_QEP_UNHANDLED, /*!< an event was un-handled due to a guard */
  152. /* [10] Active Object (AO) records */
  153. QS_QF_ACTIVE_DEFER, /*!< AO deferred an event */
  154. QS_QF_ACTIVE_RECALL, /*!< AO recalled an event */
  155. QS_QF_ACTIVE_SUBSCRIBE, /*!< an AO subscribed to an event */
  156. QS_QF_ACTIVE_UNSUBSCRIBE, /*!< an AO unsubscribed to an event */
  157. QS_QF_ACTIVE_POST, /*!< an event was posted (FIFO) directly to AO */
  158. QS_QF_ACTIVE_POST_LIFO, /*!< an event was posted (LIFO) directly to AO */
  159. QS_QF_ACTIVE_GET, /*!< AO got an event and its queue is not empty */
  160. QS_QF_ACTIVE_GET_LAST,/*!< AO got an event and its queue is empty */
  161. QS_QF_ACTIVE_RECALL_ATTEMPT, /*!< AO attempted to recall an event */
  162. /* [19] Event Queue (EQ) records */
  163. QS_QF_EQUEUE_POST, /*!< an event was posted (FIFO) to a raw queue */
  164. QS_QF_EQUEUE_POST_LIFO, /*!< an event was posted (LIFO) to a raw queue */
  165. QS_QF_EQUEUE_GET, /*!< get an event and queue still not empty */
  166. QS_QF_EQUEUE_GET_LAST,/*!< get the last event from the queue */
  167. /* [23] Framework (QF) records */
  168. QS_QF_NEW_ATTEMPT, /*!< an attempt to allocate an event failed */
  169. /* [24] Memory Pool (MP) records */
  170. QS_QF_MPOOL_GET, /*!< a memory block was removed from memory pool */
  171. QS_QF_MPOOL_PUT, /*!< a memory block was returned to memory pool */
  172. /* [26] Additional Framework (QF) records */
  173. QS_QF_PUBLISH, /*!< an event was published to active objects */
  174. QS_QF_NEW_REF, /*!< new event reference was created */
  175. QS_QF_NEW, /*!< new event was created */
  176. QS_QF_GC_ATTEMPT, /*!< garbage collection attempt */
  177. QS_QF_GC, /*!< garbage collection */
  178. QS_QF_TICK, /*!< QTimeEvt_tick_() was called */
  179. /* [32] Time Event (TE) records */
  180. QS_QF_TIMEEVT_ARM, /*!< a time event was armed */
  181. QS_QF_TIMEEVT_AUTO_DISARM, /*!< a time event expired and was disarmed */
  182. QS_QF_TIMEEVT_DISARM_ATTEMPT,/*!< attempt to disarm a disarmed QTimeEvt */
  183. QS_QF_TIMEEVT_DISARM, /*!< true disarming of an armed time event */
  184. QS_QF_TIMEEVT_REARM, /*!< rearming of a time event */
  185. QS_QF_TIMEEVT_POST, /*!< a time event posted itself directly to an AO */
  186. /* [38] Additional Framework (QF) records */
  187. QS_QF_DELETE_REF, /*!< an event reference is about to be deleted */
  188. QS_QF_CRIT_ENTRY, /*!< critical section was entered */
  189. QS_QF_CRIT_EXIT, /*!< critical section was exited */
  190. QS_QF_ISR_ENTRY, /*!< an ISR was entered */
  191. QS_QF_ISR_EXIT, /*!< an ISR was exited */
  192. QS_QF_INT_DISABLE, /*!< interrupts were disabled */
  193. QS_QF_INT_ENABLE, /*!< interrupts were enabled */
  194. /* [45] Additional Active Object (AO) records */
  195. QS_QF_ACTIVE_POST_ATTEMPT,/*!< attempt to post an evt to AO failed */
  196. /* [46] Additional Event Queue (EQ) records */
  197. QS_QF_EQUEUE_POST_ATTEMPT,/*!< attempt to post evt to QEQueue failed */
  198. /* [47] Additional Memory Pool (MP) records */
  199. QS_QF_MPOOL_GET_ATTEMPT, /*!< attempt to get a memory block failed */
  200. /* [48] Scheduler (SC) records */
  201. QS_SCHED_PREEMPT, /*!< scheduler asynchronously preempted a task */
  202. QS_SCHED_RESTORE, /*!< scheduler restored preempted task */
  203. QS_SCHED_LOCK, /*!< scheduler was locked */
  204. QS_SCHED_UNLOCK, /*!< scheduler was unlocked */
  205. QS_SCHED_NEXT, /*!< scheduler started new task */
  206. QS_SCHED_IDLE, /*!< scheduler restored the idle task */
  207. /* [54] Miscellaneous QS records (not maskable) */
  208. QS_ENUM_DICT, /*!< enumeration dictionary entry */
  209. /* [55] Additional QEP records */
  210. QS_QEP_TRAN_HIST, /*!< a tran to history was taken */
  211. QS_QEP_TRAN_EP, /*!< a tran to entry point into a submachine */
  212. QS_QEP_TRAN_XP, /*!< a tran to exit point out of a submachine */
  213. /* [58] Miscellaneous QS records (not maskable) */
  214. QS_TEST_PAUSED, /*!< test has been paused */
  215. QS_TEST_PROBE_GET, /*!< reports that Test-Probe has been used */
  216. QS_SIG_DICT, /*!< signal dictionary entry */
  217. QS_OBJ_DICT, /*!< object dictionary entry */
  218. QS_FUN_DICT, /*!< function dictionary entry */
  219. QS_USR_DICT, /*!< user QS record dictionary entry */
  220. QS_TARGET_INFO, /*!< reports the Target information */
  221. QS_TARGET_DONE, /*!< reports completion of a user callback */
  222. QS_RX_STATUS, /*!< reports QS data receive status */
  223. QS_QUERY_DATA, /*!< reports the data from "current object" query */
  224. QS_PEEK_DATA, /*!< reports the data from the PEEK query */
  225. QS_ASSERT_FAIL, /*!< assertion failed in the code */
  226. QS_QF_RUN, /*!< QF_run() was entered */
  227. /* [71] Semaphore (SEM) records */
  228. QS_SEM_TAKE, /*!< a semaphore was taken by a thread */
  229. QS_SEM_BLOCK, /*!< a semaphore blocked a thread */
  230. QS_SEM_SIGNAL, /*!< a semaphore was signaled */
  231. QS_SEM_BLOCK_ATTEMPT, /*!< a semaphore blocked was attempted */
  232. /* [75] Mutex (MTX) records */
  233. QS_MTX_LOCK, /*!< a mutex was locked */
  234. QS_MTX_BLOCK, /*!< a mutex blocked a thread */
  235. QS_MTX_UNLOCK, /*!< a mutex was unlocked */
  236. QS_MTX_LOCK_ATTEMPT, /*!< a mutex lock was attempted */
  237. QS_MTX_BLOCK_ATTEMPT, /*!< a mutex blocking was attempted */
  238. QS_MTX_UNLOCK_ATTEMPT,/*!< a mutex unlock was attempted */
  239. /* [81] */
  240. QS_PRE_MAX /*!< the number of predefined signals */
  241. };
  242. /*${QS::QSpyGroups} ........................................................*/
  243. /*! QS record groups for QS_GLB_FILTER()
  244. * @static @public @memberof QS
  245. */
  246. enum QSpyGroups {
  247. QS_ALL_RECORDS = 0xF0,/*!< all maskable QS records */
  248. QS_SM_RECORDS, /*!< State Machine QS records */
  249. QS_AO_RECORDS, /*!< Active Object QS records */
  250. QS_EQ_RECORDS, /*!< Event Queues QS records */
  251. QS_MP_RECORDS, /*!< Memory Pools QS records */
  252. QS_TE_RECORDS, /*!< Time Events QS records */
  253. QS_QF_RECORDS, /*!< QF QS records */
  254. QS_SC_RECORDS, /*!< Scheduler QS records */
  255. QS_SEM_RECORDS, /*!< Semaphore QS records */
  256. QS_MTX_RECORDS, /*!< Mutex QS records */
  257. QS_U0_RECORDS, /*!< User Group 100-104 records */
  258. QS_U1_RECORDS, /*!< User Group 105-109 records */
  259. QS_U2_RECORDS, /*!< User Group 110-114 records */
  260. QS_U3_RECORDS, /*!< User Group 115-119 records */
  261. QS_U4_RECORDS, /*!< User Group 120-124 records */
  262. QS_UA_RECORDS /*!< All User records */
  263. };
  264. /*${QS::QSpyUserOffsets} ...................................................*/
  265. /*! QS user record group offsets for QS_GLB_FILTER()
  266. * @static @public @memberof QS
  267. */
  268. enum QSpyUserOffsets {
  269. QS_USER = 100, /*!< the first record available to QS users */
  270. QS_USER0 = (enum_t)QS_USER, /*!< offset for User Group 0 */
  271. QS_USER1 = (enum_t)QS_USER0 + 5, /*!< offset for User Group 1 */
  272. QS_USER2 = (enum_t)QS_USER1 + 5, /*!< offset for User Group 2 */
  273. QS_USER3 = (enum_t)QS_USER2 + 5, /*!< offset for User Group 3 */
  274. QS_USER4 = (enum_t)QS_USER3 + 5 /*!< offset for User Group 4 */
  275. };
  276. /*${QS::QSpyIdOffsets} .....................................................*/
  277. /*! QS ID offsets for QS_LOC_FILTER()
  278. * @static @public @memberof QS
  279. */
  280. enum QSpyIdOffsets {
  281. QS_AO_ID = 0, /*!< offset for AO priorities */
  282. QS_EP_ID = 64, /*!< offset for event-pool IDs */
  283. QS_EQ_ID = 80, /*!< offset for event-queue IDs */
  284. QS_AP_ID = 96 /*!< offset for Application-specific IDs */
  285. };
  286. /*${QS::QSpyIdGroups} ......................................................*/
  287. /*! QS ID groups for QS_LOC_FILTER()
  288. * @static @public @memberof QS
  289. */
  290. enum QSpyIdGroups {
  291. QS_ALL_IDS = 0xF0, /*!< all QS IDs */
  292. QS_AO_IDS = (0x80 + (enum_t)QS_AO_ID), /*!< AO IDs (priorities) */
  293. QS_EP_IDS = (0x80 + (enum_t)QS_EP_ID), /*!< event-pool IDs */
  294. QS_EQ_IDS = (0x80 + (enum_t)QS_EQ_ID), /*!< event-queue IDs */
  295. QS_AP_IDS = (0x80 + (enum_t)QS_AP_ID) /*!< Application-specific IDs */
  296. };
  297. /*${QS::QSpyFunPtr} ........................................................*/
  298. /*! function pointer type for QS_fun_dict_pre_()
  299. * @static @private @memberof QS
  300. */
  301. typedef void (* QSpyFunPtr )(void);
  302. /*${QS::QSpyId} ............................................................*/
  303. /*! @brief QS ID type for applying local filtering
  304. * @static @public @memberof QS
  305. */
  306. typedef struct { uint8_t prio; } QSpyId;
  307. /*${QS::QS-tx::tx} .........................................................*/
  308. /*! @brief Software tracing, output (QS-TX)
  309. * @class QS
  310. *
  311. * @details
  312. * This class groups together QS services.
  313. */
  314. typedef struct {
  315. /* public: */
  316. /*! global on/off QS filter */
  317. uint8_t glbFilter[16];
  318. /*! local on/off QS filter */
  319. uint8_t locFilter[16];
  320. /*! @deprecated old local QS filter */
  321. void const * locFilter_AP;
  322. /*! pointer to the start of the QS-TX ring buffer */
  323. uint8_t * buf;
  324. /*! offset of the end of the ring buffer */
  325. QSCtr end;
  326. /*! offset to where next byte will be inserted */
  327. QSCtr volatile head;
  328. /*! offset of where next record will be extracted */
  329. QSCtr volatile tail;
  330. /*! number of bytes currently in the ring buffer */
  331. QSCtr volatile used;
  332. /*! sequence number of the last inserted QS record */
  333. uint8_t volatile seq;
  334. /*! checksum of the currently inserted record */
  335. uint8_t volatile chksum;
  336. /*! critical section nesting level */
  337. uint8_t volatile critNest;
  338. /* flags for internal use */
  339. uint8_t flags;
  340. } QS_tx;
  341. /*${QS::QS-tx::preType} ....................................................*/
  342. /*! Enumerates data elements for app-specific trace records */
  343. enum QS_preType {
  344. QS_I8_ENUM_T, /*!< signed 8-bit integer or enum format */
  345. QS_U8_T, /*!< unsigned 8-bit integer format */
  346. QS_I16_T, /*!< signed 16-bit integer format */
  347. QS_U16_T, /*!< unsigned 16-bit integer format */
  348. QS_I32_T, /*!< signed 32-bit integer format */
  349. QS_U32_T, /*!< unsigned 32-bit integer format */
  350. QS_F32_T, /*!< 32-bit floating point format */
  351. QS_F64_T, /*!< 64-bit floating point format */
  352. QS_STR_T, /*!< zero-terminated ASCII string format */
  353. QS_MEM_T, /*!< up to 255-bytes memory block format */
  354. QS_SIG_T, /*!< event signal format */
  355. QS_OBJ_T, /*!< object pointer format */
  356. QS_FUN_T, /*!< function pointer format */
  357. QS_I64_T, /*!< signed 64-bit integer format */
  358. QS_U64_T /*!< unsigned 64-bit integer format */
  359. };
  360. /*${QS::QS-tx::priv_} ......................................................*/
  361. /*! the only instance of the QS-TX object (Singleton) */
  362. extern QS_tx QS_priv_;
  363. /*${QS::QS-tx::initBuf} ....................................................*/
  364. /*! Initialize the QS-TX data buffer
  365. * @static @public @memberof QS_tx
  366. *
  367. * @details
  368. * This function should be called from QS_onStartup() to provide
  369. * QS with the data buffer. The first argument `sto` is the address
  370. * of the memory block, and the second argument `stoSize` is the size
  371. * of this block [in bytes]. Currently the size of the QS buffer cannot
  372. * exceed 64KB.
  373. *
  374. * @param[in] sto pointer to the storage for the transmit buffer
  375. * @param[in] stoSize size in [bytes] of the storage buffer
  376. *
  377. * @remark
  378. * QS can work with quite small data buffers, but you will start losing
  379. * data if the buffer is too small for the bursts of tracing activity.
  380. * The right size of the buffer depends on the data production rate and
  381. * the data output rate. QS offers flexible filtering to reduce the data
  382. * production rate.
  383. *
  384. * @note
  385. * If the data output rate cannot keep up with the production rate,
  386. * QS will start overwriting the older data with newer data. This is
  387. * consistent with the "last-is-best" QS policy. The record sequence
  388. * counters and check sums on each record allow the QSPY host utility
  389. * to easily detect any data loss.
  390. */
  391. void QS_initBuf(
  392. uint8_t * const sto,
  393. uint_fast32_t const stoSize);
  394. /*${QS::QS-tx::getByte} ....................................................*/
  395. /*! Byte-oriented interface to the QS-TX data buffer
  396. * @static @public @memberof QS_tx
  397. *
  398. * @details
  399. * This function delivers one byte at a time from the QS data buffer.
  400. *
  401. * @returns
  402. * the byte in the least-significant 8-bits of the 16-bit return
  403. * value if the byte is available. If no more data is available at the
  404. * time, the function returns ::QS_EOD (End-Of-Data).
  405. *
  406. * @note
  407. * QS_getByte() is NOT protected with a critical section.
  408. */
  409. uint16_t QS_getByte(void);
  410. /*${QS::QS-tx::getBlock} ...................................................*/
  411. /*! Block-oriented interface to the QS-TX data buffer
  412. * @static @public @memberof QS_tx
  413. *
  414. * @details
  415. * This function delivers a contiguous block of data from the QS data
  416. * buffer. The function returns the pointer to the beginning of the
  417. * block, and writes the number of bytes in the block to the location
  418. * pointed to by `pNbytes`. The argument `pNbytes` is also used as
  419. * input to provide the maximum size of the data block that the caller
  420. * can accept.
  421. *
  422. * @param[in,out] pNbytes pointer to the number of bytes to send.
  423. * On input, `pNbytes` specifies the maximum number
  424. * of bytes that the function can provide.
  425. * On output, `pNbytes` contains the actual number
  426. * of bytes available.
  427. * @returns
  428. * if data is available, the function returns pointer to the
  429. * contiguous block of data and sets the value pointed to by `pNbytes`
  430. * to the # available bytes. If data is available at the time the
  431. * function is called, the function returns NULL pointer and sets the
  432. * value pointed to by `pNbytes` to zero.
  433. *
  434. * @note
  435. * Only the NULL return from QS_getBlock() indicates that the QS
  436. * buffer is empty at the time of the call. The non-NULL return often
  437. * means that the block is at the end of the buffer and you need to call
  438. * QS_getBlock() again to obtain the rest of the data that
  439. * "wrapped around" to the beginning of the QS data buffer.
  440. *
  441. * @note QS_getBlock() is **not** protected with a critical section.
  442. */
  443. uint8_t const * QS_getBlock(uint16_t * const pNbytes);
  444. /*${QS::QS-tx::glbFilter_} .................................................*/
  445. /*! Set/clear the global Filter for a given QS record or a group
  446. * of records
  447. * @static @public @memberof QS_tx
  448. *
  449. * @details
  450. * This function sets up the QS filter to enable record types specified
  451. * in the `filter` parameter. The value #QS_ALL_RECORDS specifies to
  452. * filter-in all records. This function should be called indirectly
  453. * through the macro QS_GLB_FILTER()
  454. *
  455. * @param[in] filter the QS record-d or group to enable in the filter,
  456. * if positive or disable, if negative. The record-id
  457. * numbers must be in the range -127..127.
  458. * @note
  459. * Filtering based on the record-type is only the first layer of
  460. * filtering. The second layer is based on the object-type. Both filter
  461. * layers must be enabled for the QS record to be inserted in the
  462. * QS buffer.
  463. *
  464. * @sa QS_locFilter_()
  465. */
  466. void QS_glbFilter_(int_fast16_t const filter);
  467. /*${QS::QS-tx::locFilter_} .................................................*/
  468. /*! Set/clear the local Filter for a given object-id
  469. * or a group of object-ids
  470. * @static @public @memberof QS_tx
  471. *
  472. * @details
  473. * This function sets up the local QS filter to enable or disable the
  474. * given QS object-id or a group of object-ids @a filter.
  475. * This function should be called indirectly through the macro
  476. * QS_LOC_FILTER()
  477. *
  478. * @param[in] filter the QS object-id or group to enable in the filter,
  479. * if positive or disable, if negative. The qs_id numbers
  480. * must be in the range 1..127.
  481. * @note
  482. * Filtering based on the object-id (local filter) is the second layer
  483. * of filtering. The first layer is based on the QS record-type (global
  484. * filter). Both filter layers must be enabled for the QS record to be
  485. * inserted into the QS buffer.
  486. *
  487. * @sa QS_glbFilter_()
  488. */
  489. void QS_locFilter_(int_fast16_t const filter);
  490. /*${QS::QS-tx::doOutput} ...................................................*/
  491. /*! Perform the QS-TX output (implemented in some QS ports)
  492. * @static @public @memberof QS_tx
  493. */
  494. void QS_doOutput(void);
  495. /*${QS::QS-tx::beginRec_} ..................................................*/
  496. /*! Mark the begin of a QS record `rec`
  497. * @static @private @memberof QS_tx
  498. *
  499. * @details
  500. * This function must be called at the beginning of each QS record.
  501. * This function should be called indirectly through the macro QS_BEGIN_ID(),
  502. * or QS_BEGIN_NOCRIT(), depending if it's called in a normal code or from
  503. * a critical section.
  504. */
  505. void QS_beginRec_(uint_fast8_t const rec);
  506. /*${QS::QS-tx::endRec_} ....................................................*/
  507. /*! Mark the end of a QS record `rec`
  508. * @static @private @memberof QS_tx
  509. *
  510. * @details
  511. * This function must be called at the end of each QS record.
  512. * This function should be called indirectly through the macro QS_END(),
  513. * or QS_END_NOCRIT(), depending if it's called in a normal code or from
  514. * a critical section.
  515. */
  516. void QS_endRec_(void);
  517. /*${QS::QS-tx::u8_raw_} ....................................................*/
  518. /*! output uint8_t data element without format information
  519. * @static @private @memberof QS_tx
  520. */
  521. void QS_u8_raw_(uint8_t const d);
  522. /*${QS::QS-tx::2u8_raw_} ...................................................*/
  523. /*! output two uint8_t data elements without format information
  524. * @static @private @memberof QS_tx
  525. */
  526. void QS_2u8_raw_(
  527. uint8_t const d1,
  528. uint8_t const d2);
  529. /*${QS::QS-tx::u16_raw_} ...................................................*/
  530. /*! output uint16_t data element without format information
  531. * @static @private @memberof QS_tx
  532. */
  533. void QS_u16_raw_(uint16_t const d);
  534. /*${QS::QS-tx::u32_raw_} ...................................................*/
  535. /*! output uint32_t data element without format information
  536. * @static @private @memberof QS_tx
  537. */
  538. void QS_u32_raw_(uint32_t const d);
  539. /*${QS::QS-tx::obj_raw_} ...................................................*/
  540. /*! Output obj pointer data element without format information
  541. * @static @private @memberof QS_tx
  542. *
  543. * @note This function is only to be used through macros, never in the
  544. * client code directly.
  545. */
  546. void QS_obj_raw_(void const * const obj);
  547. /*${QS::QS-tx::str_raw_} ...................................................*/
  548. /*! Output raw zero-terminated string element (without format information)
  549. * @static @private @memberof QS_tx
  550. *
  551. * @note This function is only to be used through macros, never in the
  552. * client code directly.
  553. */
  554. void QS_str_raw_(char const * const str);
  555. /*${QS::QS-tx::u8_fmt_} ....................................................*/
  556. /*! Output uint8_t data element with format information
  557. * @static @private @memberof QS_tx
  558. *
  559. * @details
  560. * @note This function is only to be used through macros, never in the
  561. * client code directly.
  562. */
  563. void QS_u8_fmt_(
  564. uint8_t const format,
  565. uint8_t const d);
  566. /*${QS::QS-tx::u16_fmt_} ...................................................*/
  567. /*! output uint16_t data element with format information
  568. * @static @private @memberof QS_tx
  569. *
  570. * @details
  571. * This function is only to be used through macros, never in the
  572. * client code directly.
  573. */
  574. void QS_u16_fmt_(
  575. uint8_t const format,
  576. uint16_t const d);
  577. /*${QS::QS-tx::u32_fmt_} ...................................................*/
  578. /*! Output uint32_t data element with format information
  579. * @static @private @memberof QS_tx
  580. *
  581. * @note This function is only to be used through macros, never in the
  582. * client code directly.
  583. */
  584. void QS_u32_fmt_(
  585. uint8_t const format,
  586. uint32_t const d);
  587. /*${QS::QS-tx::str_fmt_} ...................................................*/
  588. /*! Output formatted zero-terminated ASCII string to the QS record
  589. * @static @private @memberof QS_tx
  590. */
  591. void QS_str_fmt_(char const * const str);
  592. /*${QS::QS-tx::mem_fmt_} ...................................................*/
  593. /*! Output formatted memory block of up to 255 bytes to the QS record
  594. * @static @private @memberof QS_tx
  595. */
  596. void QS_mem_fmt_(
  597. uint8_t const * const blk,
  598. uint8_t const size);
  599. /*${QS::QS-tx::sig_dict_pre_} ..............................................*/
  600. /*! Output predefined signal-dictionary record
  601. * @static @private @memberof QS_tx
  602. *
  603. * @note This function is only to be used through macro QS_SIG_DICTIONARY()
  604. */
  605. void QS_sig_dict_pre_(
  606. enum_t const sig,
  607. void const * const obj,
  608. char const * const name);
  609. /*${QS::QS-tx::obj_dict_pre_} ..............................................*/
  610. /*! Output predefined object-dictionary record
  611. * @static @private @memberof QS_tx
  612. *
  613. * @note This function is only to be used through macro QS_OBJ_DICTIONARY()
  614. */
  615. void QS_obj_dict_pre_(
  616. void const * const obj,
  617. char const * const name);
  618. /*${QS::QS-tx::obj_arr_dict_pre_} ..........................................*/
  619. /*! Output predefined object-array dictionary record
  620. * @static @private @memberof QS_tx
  621. *
  622. * @note This function is only to be used through macro QS_OBJ_ARR_DICTIONARY()
  623. */
  624. void QS_obj_arr_dict_pre_(
  625. void const * const obj,
  626. uint_fast16_t const idx,
  627. char const * const name);
  628. /*${QS::QS-tx::fun_dict_pre_} ..............................................*/
  629. /*! Output predefined function-dictionary record
  630. * @static @private @memberof QS_tx
  631. *
  632. * @note This function is only to be used through macro QS_FUN_DICTIONARY()
  633. */
  634. void QS_fun_dict_pre_(
  635. QSpyFunPtr const fun,
  636. char const * const name);
  637. /*${QS::QS-tx::usr_dict_pre_} ..............................................*/
  638. /*! Output predefined user-dictionary record
  639. * @static @private @memberof QS_tx
  640. *
  641. * @note This function is only to be used through macro QS_USR_DICTIONARY()
  642. */
  643. void QS_usr_dict_pre_(
  644. enum_t const rec,
  645. char const * const name);
  646. /*${QS::QS-tx::enum_dict_pre_} .............................................*/
  647. /*! Output predefined enum-dictionary record
  648. * @static @private @memberof QS_tx
  649. *
  650. * @note This function is only to be used through macro QS_ENUM_DICTIONARY()
  651. */
  652. void QS_enum_dict_pre_(
  653. enum_t const value,
  654. uint8_t const group,
  655. char const * const name);
  656. /*${QS::QS-tx::ASSERTION} ..................................................*/
  657. /*! Output the predefined assertion failure trace record
  658. * @static @public @memberof QS_tx
  659. *
  660. * @details
  661. * This trace record is intended to use from the Q_onAssert() callback.
  662. */
  663. void QS_ASSERTION(
  664. char const * const module,
  665. int_t const loc,
  666. uint32_t const delay);
  667. /*${QS::QS-tx::target_info_pre_} ...........................................*/
  668. /*! Helper function to output the predefined Target-info trace record
  669. * @static @private @memberof QS_tx
  670. */
  671. void QS_target_info_pre_(uint8_t const isReset);
  672. /*${QS::QS-tx::onStartup} ..................................................*/
  673. /*! Callback to startup the QS facility
  674. * @static @public @memberof QS_tx
  675. */
  676. uint8_t QS_onStartup(void const * arg);
  677. /*${QS::QS-tx::onCleanup} ..................................................*/
  678. /*! Callback to cleanup the QS facility
  679. * @static @public @memberof QS_tx
  680. */
  681. void QS_onCleanup(void);
  682. /*${QS::QS-tx::onFlush} ....................................................*/
  683. /*! Callback to flush the QS trace data to the host
  684. * @static @public @memberof QS_tx
  685. */
  686. void QS_onFlush(void);
  687. /*${QS::QS-tx::onGetTime} ..................................................*/
  688. /*! Callback to obtain a timestamp for a QS record
  689. * @static @public @memberof QS_tx
  690. */
  691. QSTimeCtr QS_onGetTime(void);
  692. /*${QS::QS-tx-64bit::u64_raw_} .............................................*/
  693. /*! Output uint64_t data element without format information
  694. * @static @private @memberof QS_tx
  695. */
  696. void QS_u64_raw_(uint64_t d);
  697. /*${QS::QS-tx-64bit::u64_fmt_} .............................................*/
  698. /*! Output uint64_t data element with format information
  699. * @static @private @memberof QS_tx
  700. *
  701. * @sa QS_U64(), QS_I64()
  702. */
  703. void QS_u64_fmt_(
  704. uint8_t format,
  705. uint64_t d);
  706. /*${QS::QS-tx-fp::f32_fmt_} ................................................*/
  707. /*! Output 32-bit floating point data element with format information
  708. * @static @private @memberof QS_tx
  709. *
  710. * @sa QS_F32()
  711. */
  712. void QS_f32_fmt_(
  713. uint8_t const format,
  714. float32_t const d);
  715. /*${QS::QS-tx-fp::f64_fmt_} ................................................*/
  716. /*! Output 64-bit floating point data element with format information
  717. * @static @private @memberof QS_tx
  718. *
  719. * @sa QS_F64()
  720. */
  721. void QS_f64_fmt_(
  722. uint8_t const format,
  723. float64_t const d);
  724. /*${QS::QS-rx::rx} .........................................................*/
  725. /*! @brief QS software tracing parameters for QS input (QS-RX)
  726. * @class QS_rx
  727. */
  728. typedef struct {
  729. /* public: */
  730. void * currObj[8];
  731. uint8_t * buf;
  732. QSCtr end;
  733. QSCtr volatile head;
  734. QSCtr volatile tail;
  735. #ifdef Q_UTEST
  736. bool inTestLoop;
  737. #endif /* def Q_UTEST */
  738. } QS_rx;
  739. /*${QS::QS-rx::rxPriv_} ....................................................*/
  740. /*! the only instance of the QS-RX object (Singleton)
  741. * @static @private @memberof QS_rx
  742. */
  743. extern QS_rx QS_rxPriv_;
  744. /*${QS::QS-rx::QSpyObjKind} ................................................*/
  745. /*! Kinds of objects used in QS_setCurrObj() and QS_queryCurrObj()
  746. * @static @public @memberof QS_rx
  747. */
  748. enum QS_QSpyObjKind {
  749. SM_OBJ, /*!< state machine object */
  750. AO_OBJ, /*!< active object */
  751. MP_OBJ, /*!< event pool object */
  752. EQ_OBJ, /*!< raw queue object */
  753. TE_OBJ, /*!< time event object */
  754. AP_OBJ, /*!< generic Application-specific object */
  755. MAX_OBJ
  756. };
  757. /*${QS::QS-rx::OSpyObjCombnation} ..........................................*/
  758. /*! Object combinations for QS_setCurrObj() and QS_queryCurrObj()
  759. * @static @public @memberof QS_rx
  760. */
  761. enum QS_OSpyObjCombnation {
  762. SM_AO_OBJ = (enum_t)MAX_OBJ /*!< combination of SM and AO */
  763. };
  764. /*${QS::QS-rx::rxInitBuf} ..................................................*/
  765. /*! Initialize the QS-RX data buffer
  766. * @static @public @memberof QS_rx
  767. *
  768. * @details
  769. * This function should be called from QS::onStartup() to provide QS-RX
  770. * with the receive data buffer.
  771. *
  772. * @param[in] sto pointer to the memory block for input buffer
  773. * @param[in] stoSize the size of this block [bytes]. The size of the
  774. * QS-RX buffer cannot exceed 64KB.
  775. *
  776. * @note
  777. * QS-RX can work with quite small data buffers, but you will start
  778. * losing data if the buffer is not drained fast enough (e.g., in the
  779. * idle task).
  780. *
  781. * @note
  782. * If the data input rate exceeds the QS-RX processing rate, the data
  783. * will be lost, but the QS protocol will notice that:
  784. * (1) that the checksum in the incomplete QS records will fail; and
  785. * (2) the sequence counter in QS records will show discontinuities.
  786. *
  787. * The QS-RX channel will report any data errors by sending the
  788. * QS_RX_DATA_ERROR trace record.
  789. */
  790. void QS_rxInitBuf(
  791. uint8_t * const sto,
  792. uint16_t const stoSize);
  793. /*${QS::QS-rx::rxPut} ......................................................*/
  794. /*! Put one byte into the QS-RX lock-free buffer
  795. * @static @public @memberof QS_rx
  796. */
  797. static inline bool QS_rxPut(uint8_t const b) {
  798. QSCtr head = QS_rxPriv_.head + 1U;
  799. if (head == QS_rxPriv_.end) {
  800. head = 0U;
  801. }
  802. if (head != QS_rxPriv_.tail) { /* buffer NOT full? */
  803. QS_rxPriv_.buf[QS_rxPriv_.head] = b;
  804. QS_rxPriv_.head = head; /* update the head to a *valid* index */
  805. return true; /* byte placed in the buffer */
  806. }
  807. else {
  808. return false; /* byte NOT placed in the buffer */
  809. }
  810. }
  811. /*${QS::QS-rx::rxGetNfree} .................................................*/
  812. /*! Obtain the number of free bytes in the QS-RX data buffer
  813. * @static @public @memberof QS_rx
  814. *
  815. * @details
  816. * This function is intended to be called from the ISR that reads the
  817. * QS-RX bytes from the QSPY application. The function returns the
  818. * conservative number of free bytes currently available in the buffer,
  819. * assuming that the head pointer is not being moved concurrently.
  820. * The tail pointer might be moving, meaning that bytes can be
  821. * concurrently removed from the buffer.
  822. */
  823. uint16_t QS_rxGetNfree(void);
  824. /*${QS::QS-rx::doInput} ....................................................*/
  825. /*! Perform the QS-RX input (implemented in some QS ports)
  826. * @static @public @memberof QS_rx
  827. */
  828. void QS_doInput(void);
  829. /*${QS::QS-rx::setCurrObj} .................................................*/
  830. /*! Set the "current object" in the Target
  831. * @static @public @memberof QS_rx
  832. *
  833. * @details
  834. * This function sets the "current object" in the Target.
  835. */
  836. void QS_setCurrObj(
  837. uint8_t const obj_kind,
  838. void * const obj_ptr);
  839. /*${QS::QS-rx::queryCurrObj} ...............................................*/
  840. /*! Query the "current object" in the Target
  841. * @static @public @memberof QS_rx
  842. *
  843. * @details
  844. * This function programmatically generates the response to the query for
  845. * a "current object".
  846. */
  847. void QS_queryCurrObj(uint8_t const obj_kind);
  848. /*${QS::QS-rx::rxParse} ....................................................*/
  849. /*! Parse all bytes present in the QS-RX data buffer
  850. * @static @public @memberof QS_rx
  851. */
  852. void QS_rxParse(void);
  853. /*${QS::QS-rx::rxHandleGoodFrame_} .........................................*/
  854. /*! internal function to handle incoming (QS-RX) packet
  855. * @static @private @memberof QS_rx
  856. */
  857. void QS_rxHandleGoodFrame_(uint8_t const state);
  858. /*${QS::QS-rx::onReset} ....................................................*/
  859. /*! callback function to reset the Target (to be implemented in the BSP)
  860. * @static @public @memberof QS_rx
  861. */
  862. void QS_onReset(void);
  863. /*${QS::QS-rx::onCommand} ..................................................*/
  864. /*! Callback function to execute user commands (to be implemented in BSP)
  865. * @static @public @memberof QS_rx
  866. */
  867. void QS_onCommand(
  868. uint8_t cmdId,
  869. uint32_t param1,
  870. uint32_t param2,
  871. uint32_t param3);
  872. /*${QS::QS-rx::RX_PUT} .....................................................*/
  873. /*! Put one byte into the QS RX lock-free buffer
  874. * @static @public @memberof QS_rx
  875. */
  876. bool QS_RX_PUT(uint8_t const b);
  877. /*$enddecl${QS} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  878. /*==========================================================================*/
  879. /*$declare${QS-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  880. /*${QS-macros::QS_INIT} ....................................................*/
  881. /*! Initialize the QS facility
  882. *
  883. * @details
  884. * This macro provides an indirection layer to invoke the QS initialization
  885. * routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.
  886. * @sa QS_onStartup(), example of setting up a QS filter in
  887. * QS_GLB_FILTER()
  888. */
  889. #define QS_INIT(arg_) (QS_onStartup(arg_))
  890. /*${QS-macros::QS_EXIT} ....................................................*/
  891. /*! Cleanup the QS facility
  892. *
  893. * @details
  894. * This macro provides an indirection layer to invoke the QS cleanup
  895. * routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.
  896. * @sa QS_onCleanup()
  897. */
  898. #define QS_EXIT() (QS_onCleanup())
  899. /*${QS-macros::QS_OUTPUT} ..................................................*/
  900. /*! macro to handle the QS output from the application
  901. *
  902. * @note
  903. * If this macro is used, the application must define QS_output().
  904. */
  905. #define QS_OUTPUT() (QS_output())
  906. /*${QS-macros::QS_RX_INPUT} ................................................*/
  907. /*! macro to handle the QS-RX input to the application
  908. *
  909. * @note
  910. * If this macro is used, the application must define QS_doInput().
  911. */
  912. #define QS_RX_INPUT() (QS_rx_input())
  913. /*${QS-macros::QS_GLB_FILTER} ..............................................*/
  914. /*! Global Filter ON for a given record type `rec_`
  915. *
  916. * @details
  917. * This macro provides an indirection layer to call QS_filterOn()
  918. * if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.
  919. *
  920. * @sa
  921. * - enum QSpyGroups - QS record groups that can be used as `rec_`
  922. * - enum QSpyPre - predefined QS records that can be used as `rec_`
  923. *
  924. * @usage
  925. * The following example shows how to use QS filters:
  926. * @include qs_filter.c
  927. */
  928. #define QS_GLB_FILTER(rec_) (QS_glbFilter_((int_fast16_t)(rec_)))
  929. /*${QS-macros::QS_LOC_FILTER} ..............................................*/
  930. /*! Local Filter for a given state machine object `qs_id`
  931. *
  932. * @details
  933. * This macro provides an indirection layer to call QS_locFilter_()
  934. * if #Q_SPY is defined, or do nothing if #Q_SPY is not defined.
  935. *
  936. * @sa
  937. * - enum QSpyIdGroups - QS ID groups that can be used as `qs_id_`
  938. * - enum QSpyIdOffsets - QS ID offsets for `qs_id_` (e.g., QS_AP_IDS + 5)
  939. *
  940. * The following example shows how to use QS filters:
  941. * @include qs_filter.c
  942. */
  943. #define QS_LOC_FILTER(qs_id_) (QS_locFilter_((int_fast16_t)(qs_id_)))
  944. /*${QS-macros::QS_BEGIN_ID} ................................................*/
  945. /*! Begin an application-specific QS record with entering critical section
  946. *
  947. * @details
  948. * The following example shows how to build a user QS record using the
  949. * macros QS_BEGIN_ID(), QS_END(), and the formatted output macros:
  950. * QS_U8(), QS_STR(), etc.
  951. *
  952. * @note
  953. * Must always be used in pair with QS_END()
  954. *
  955. * @include qs_ap.c
  956. */
  957. #define QS_BEGIN_ID(rec_, qs_id_) \
  958. if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
  959. QS_CRIT_STAT_ \
  960. QS_CRIT_E_(); \
  961. QS_beginRec_((uint_fast8_t)(rec_)); \
  962. QS_TIME_PRE_(); {
  963. /*${QS-macros::QS_END} .....................................................*/
  964. /*! End an application-specific QS record with exiting critical section.
  965. *
  966. * @sa example for QS_BEGIN_ID()
  967. * @note Must always be used in pair with QS_BEGIN_ID()
  968. */
  969. #define QS_END() } \
  970. QS_endRec_(); \
  971. QS_CRIT_X_(); \
  972. }
  973. /*${QS-macros::QS_FLUSH} ...................................................*/
  974. /*! Flush the QS trace data to the host
  975. *
  976. * @details
  977. * This macro invokes the QS_flush() platform-dependent callback
  978. * function to flush the QS trace buffer to the host. The function
  979. * typically busy-waits until all the data in the buffer is sent to
  980. * the host. This is acceptable only in the initial transient.
  981. */
  982. #define QS_FLUSH() (QS_onFlush())
  983. /*${QS-macros::QS_BEGIN_NOCRIT} ............................................*/
  984. /*! Begin an application-specific QS record WITHOUT entering critical section */
  985. #define QS_BEGIN_NOCRIT(rec_, qs_id_) \
  986. if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
  987. QS_beginRec_((uint_fast8_t)(rec_)); \
  988. QS_TIME_PRE_(); {
  989. /*${QS-macros::QS_END_NOCRIT} ..............................................*/
  990. /*! End an application-specific QS record WITHOUT exiting critical section */
  991. #define QS_END_NOCRIT() } \
  992. QS_endRec_();\
  993. }
  994. /*${QS-macros::QS_GLB_CHECK_} ..............................................*/
  995. /*! Helper macro for checking the global QS filter */
  996. #define QS_GLB_CHECK_(rec_) \
  997. (((uint_fast8_t)QS_priv_.glbFilter[(uint_fast8_t)(rec_) >> 3U] \
  998. & ((uint_fast8_t)1U << ((uint_fast8_t)(rec_) & 7U))) != 0U)
  999. /*${QS-macros::QS_LOC_CHECK_} ..............................................*/
  1000. /*! Helper macro for checking the local QS filter */
  1001. #define QS_LOC_CHECK_(qs_id_) \
  1002. (((uint_fast8_t)QS_priv_.locFilter[(uint_fast8_t)(qs_id_) >> 3U] \
  1003. & ((uint_fast8_t)1U << ((uint_fast8_t)(qs_id_) & 7U))) != 0U)
  1004. /*${QS-macros::QS_REC_DONE} ................................................*/
  1005. #ifndef QS_REC_DONE
  1006. /*! Macro to execute user code when a QS record is produced
  1007. *
  1008. * @note
  1009. * This is a dummy definition in case this macro is undefined.
  1010. */
  1011. #define QS_REC_DONE() ((void)0)
  1012. #endif /* ndef QS_REC_DONE */
  1013. /*${QS-macros::QS_I8} ......................................................*/
  1014. /*! Output formatted int8_t to the QS record */
  1015. #define QS_I8(width_, data_) \
  1016. (QS_u8_fmt_((uint8_t)(((width_) << 4U) & 0x7U) | (uint8_t)QS_I8_ENUM_T, \
  1017. (data_)))
  1018. /*${QS-macros::QS_U8} ......................................................*/
  1019. /*! Output formatted uint8_t to the QS record */
  1020. #define QS_U8(width_, data_) \
  1021. (QS_u8_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_)))
  1022. /*${QS-macros::QS_I16} .....................................................*/
  1023. /*! Output formatted int16_t to the QS record */
  1024. #define QS_I16(width_, data_) \
  1025. (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_)))
  1026. /*${QS-macros::QS_U16} .....................................................*/
  1027. /*! Output formatted uint16_t to the QS record */
  1028. #define QS_U16(width_, data_) \
  1029. (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_)))
  1030. /*${QS-macros::QS_I32} .....................................................*/
  1031. /*! Output formatted int32_t to the QS record */
  1032. #define QS_I32(width_, data_) \
  1033. (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_)))
  1034. /*${QS-macros::QS_U32} .....................................................*/
  1035. /*! Output formatted uint32_t to the QS record */
  1036. #define QS_U32(width_, data_) \
  1037. (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_)))
  1038. /*${QS-macros::QS_I64} .....................................................*/
  1039. /*! Output formatted int64_t to the QS record */
  1040. #define QS_I64(width_, data_) \
  1041. (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_)))
  1042. /*${QS-macros::QS_U64} .....................................................*/
  1043. /*! Output formatted uint64_t to the QS record */
  1044. #define QS_U64(width_, data_) \
  1045. (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_)))
  1046. /*${QS-macros::QS_F32} .....................................................*/
  1047. /*! Output formatted 32-bit floating point number to the QS record */
  1048. #define QS_F32(width_, data_) \
  1049. (QS_f32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_)))
  1050. /*${QS-macros::QS_F64} .....................................................*/
  1051. /*! Output formatted 64-bit floating point number to the QS record */
  1052. #define QS_F64(width_, data_) \
  1053. (QS_f64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_)))
  1054. /*${QS-macros::QS_STR} .....................................................*/
  1055. /*! Output formatted zero-terminated ASCII string to the QS record */
  1056. #define QS_STR(str_) (QS_str_fmt_((str_)))
  1057. /*${QS-macros::QS_MEM} .....................................................*/
  1058. /*! Output formatted memory block of up to 255 bytes to the QS record */
  1059. #define QS_MEM(mem_, size_) (QS_mem_fmt_((mem_), (size_)))
  1060. /*${QS-macros::QS_ENUM} ....................................................*/
  1061. /*! Output formatted enumeration to the QS record */
  1062. #define QS_ENUM(group_, value_) \
  1063. (QS_u8_fmt_((uint8_t)(0x80U | ((group_) << 4U)) | (uint8_t)QS_I8_ENUM_T,\
  1064. (uint8_t)(value_)))
  1065. /*${QS-macros::QS_TIME_PRE_} ...............................................*/
  1066. #if (QS_TIME_SIZE == 4U)
  1067. /*! Output time stamp to a QS record (used in predefined
  1068. * and application-specific trace records)
  1069. */
  1070. #define QS_TIME_PRE_() (QS_u32_raw_(QS_onGetTime()))
  1071. #endif /* (QS_TIME_SIZE == 4U) */
  1072. /*${QS-macros::QS_TIME_PRE_} ...............................................*/
  1073. #if (QS_TIME_SIZE == 2U)
  1074. #define QS_TIME_PRE_() (QS_u16_raw_(QS_onGetTime()))
  1075. #endif /* (QS_TIME_SIZE == 2U) */
  1076. /*${QS-macros::QS_TIME_PRE_} ...............................................*/
  1077. #if (QS_TIME_SIZE == 1U)
  1078. #define QS_TIME_PRE_() (QS_u8_raw_(QS_onGetTime()))
  1079. #endif /* (QS_TIME_SIZE == 1U) */
  1080. /*${QS-macros::QS_OBJ} .....................................................*/
  1081. #if (QS_OBJ_PTR_SIZE == 4U)
  1082. /*! Output formatted object pointer to the QS record */
  1083. #define QS_OBJ(obj_) (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_)))
  1084. #endif /* (QS_OBJ_PTR_SIZE == 4U) */
  1085. /*${QS-macros::QS_OBJ} .....................................................*/
  1086. #if (QS_OBJ_PTR_SIZE == 2U)
  1087. #define QS_OBJ(obj_) (QS_u16_fmt_(QS_OBJ_T, (uint16_t)(obj_)))
  1088. #endif /* (QS_OBJ_PTR_SIZE == 2U) */
  1089. /*${QS-macros::QS_OBJ} .....................................................*/
  1090. #if (QS_OBJ_PTR_SIZE == 1U)
  1091. #define QS_OBJ(obj_) (QS_u8_fmt_(QS_OBJ_T, (uint8_t)(obj_)))
  1092. #endif /* (QS_OBJ_PTR_SIZE == 1U) */
  1093. /*${QS-macros::QS_OBJ} .....................................................*/
  1094. #if (QS_OBJ_PTR_SIZE == 8U)
  1095. #define QS_OBJ(obj_) (QS_u64_fmt_(QS_OBJ_T, (uint64_t)(obj_)))
  1096. #endif /* (QS_OBJ_PTR_SIZE == 8U) */
  1097. /*${QS-macros::QS_FUN} .....................................................*/
  1098. #if (QS_FUN_PTR_SIZE == 4U)
  1099. /* Output formatted function pointer to the QS record */
  1100. #define QS_FUN(fun_) (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_)))
  1101. #endif /* (QS_FUN_PTR_SIZE == 4U) */
  1102. /*${QS-macros::QS_FUN} .....................................................*/
  1103. #if (QS_FUN_PTR_SIZE == 2U)
  1104. #define QS_FUN(fun_) (QS_u16_fmt_(QS_FUN_T, (uint16_t)(fun_)))
  1105. #endif /* (QS_FUN_PTR_SIZE == 2U) */
  1106. /*${QS-macros::QS_FUN} .....................................................*/
  1107. #if (QS_FUN_PTR_SIZE == 1U)
  1108. #define QS_FUN(fun_) (QS_u8_fmt_(QS_FUN_T, (uint8_t)(fun_)))
  1109. #endif /* (QS_FUN_PTR_SIZE == 1U) */
  1110. /*${QS-macros::QS_FUN} .....................................................*/
  1111. #if (QS_FUN_PTR_SIZE == 8U)
  1112. #define QS_FUN(fun_) (QS_u64_fmt_(QS_FUN_T, (uint64_t)(fun_)))
  1113. #endif /* (QS_FUN_PTR_SIZE == 8U) */
  1114. /*${QS-macros::QS_SIG} .....................................................*/
  1115. #if (Q_SIGNAL_SIZE == 4U)
  1116. /*! Output formatted event signal (of type ::QSignal) and
  1117. * the state machine object to the user QS record
  1118. */
  1119. #define QS_SIG(sig_, obj_) \
  1120. QS_u32_fmt_(QS_SIG_T, (sig_)); \
  1121. QS_obj_raw_(obj_)
  1122. #endif /* (Q_SIGNAL_SIZE == 4U) */
  1123. /*${QS-macros::QS_SIG} .....................................................*/
  1124. #if (Q_SIGNAL_SIZE == 2U)
  1125. #define QS_SIG(sig_, obj_) \
  1126. QS_u16_fmt_(QS_SIG_T, (sig_)); \
  1127. QS_obj_raw_(obj_)
  1128. #endif /* (Q_SIGNAL_SIZE == 2U) */
  1129. /*${QS-macros::QS_SIG} .....................................................*/
  1130. #if (Q_SIGNAL_SIZE == 1U)
  1131. #define QS_SIG(sig_, obj_) \
  1132. QS_u8_fmt_(QS_SIG_T, (sig_)); \
  1133. QS_obj_raw_(obj_)
  1134. #endif /* (Q_SIGNAL_SIZE == 1U) */
  1135. /*${QS-macros::QS_SIG_DICTIONARY} ..........................................*/
  1136. /*! Output QS signal dictionary record
  1137. *
  1138. * @details
  1139. * A signal dictionary record associates the numerical value of the signal
  1140. * and the binary address of the state machine that consumes that signal
  1141. * with the human-readable name of the signal.
  1142. *
  1143. * @param[in] sig_ event signal (typically enumerated, e.g. `TIMEOUT_SIG`)
  1144. * @param[in] obj_ pointer to the associated state machine object
  1145. * (might be `(void*)0` for globally recognized signals)
  1146. *
  1147. * A signal dictionary entry is associated with both the signal value `sig_`
  1148. * and the state machine `obj_`, because signals are required to be unique
  1149. * only within a given state machine and therefore the same numerical values
  1150. * can represent different signals in different state machines.
  1151. *
  1152. * For the "global" signals that have the same meaning in many state machines
  1153. * (such as globally published signals), you can specify a signal dictionary
  1154. * entry with the `obj_` parameter set to `(void*)0`.
  1155. *
  1156. * The following example shows the definition of signal dictionary entries
  1157. * in the initial transition of the Table active object. Please note that
  1158. * signals HUNGRY_SIG and DONE_SIG are associated with the Table state
  1159. * machine only ("me" `obj_` pointer). The EAT_SIG signal, on the other
  1160. * hand, is global (0 `obj_` pointer):
  1161. * @include qs_sigDic.c
  1162. *
  1163. * The following QSpy log example shows the signal dictionary records
  1164. * generated from the Table initial transition and subsequent records that
  1165. * show human-readable names of the signals:
  1166. * @include qs_sigLog.txt
  1167. */
  1168. #define QS_SIG_DICTIONARY(sig_, obj_) \
  1169. (QS_sig_dict_pre_((sig_), (obj_), #sig_))
  1170. /*${QS-macros::QS_OBJ_DICTIONARY} ..........................................*/
  1171. /*! Output object dictionary record
  1172. *
  1173. * @details
  1174. * An object dictionary record associates the binary address of an object
  1175. * in the target's memory with the human-readable name of the object.
  1176. *
  1177. * @param[in] obj_ pointer to the object (any object)
  1178. *
  1179. * The following example shows the definition of object dictionary entry
  1180. * for the Table active object:
  1181. * @include qs_objDic.c
  1182. */
  1183. #define QS_OBJ_DICTIONARY(obj_) \
  1184. (QS_obj_dict_pre_((obj_), #obj_))
  1185. /*${QS-macros::QS_OBJ_ARR_DICTIONARY} ......................................*/
  1186. /*! Output object-array dictionary record
  1187. *
  1188. * @details
  1189. * An object array dictionary record associates the binary address of the
  1190. * object element in the target's memory with the human-readable name
  1191. * of the object.
  1192. *
  1193. * @param[in] obj_ pointer to the object (any object)
  1194. * @param[in] idx_ array index
  1195. *
  1196. * The following example shows the definition of object array dictionary
  1197. * for `Philo::inst[n]` and `Philo::inst[n].m_timeEvt`:
  1198. * @include qs_objArrDic.c
  1199. */
  1200. #define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \
  1201. (QS_obj_arr_dict_pre_((obj_), (idx_), #obj_))
  1202. /*${QS-macros::QS_FUN_DICTIONARY} ..........................................*/
  1203. /*! Output function dictionary record
  1204. *
  1205. * @details
  1206. * A function dictionary record associates the binary address of a function
  1207. * in the target's memory with the human-readable name of the function.
  1208. *
  1209. * Providing a function dictionary QS record can vastly improve readability
  1210. * of the QS log, because instead of dealing with cryptic machine addresses
  1211. * the QSpy host utility can display human-readable function names.
  1212. *
  1213. * The example from #QS_SIG_DICTIONARY shows the definition of a function
  1214. * dictionary.
  1215. */
  1216. #define QS_FUN_DICTIONARY(fun_) \
  1217. (QS_fun_dict_pre_((void (*)(void))(fun_), #fun_))
  1218. /*${QS-macros::QS_USR_DICTIONARY} ..........................................*/
  1219. /*! Output user QS record dictionary record
  1220. *
  1221. * @details
  1222. * A user QS record dictionary record associates the numerical value of a
  1223. * user record with the human-readable identifier.
  1224. */
  1225. #define QS_USR_DICTIONARY(rec_) \
  1226. (QS_usr_dict_pre_((rec_), #rec_))
  1227. /*${QS-macros::QS_ENUM_DICTIONARY} .........................................*/
  1228. /*! Output enumeration dictionary record
  1229. *
  1230. * @details
  1231. * An enum QS record dictionary record associates the numerical value of
  1232. * an enumeration with the human-readable identifier.
  1233. */
  1234. #define QS_ENUM_DICTIONARY(value_, group_) \
  1235. (QS_enum_dict_pre_((value_), (group_), #value_))
  1236. /*${QS-macros::QF_QS_CRIT_ENTRY} ...........................................*/
  1237. /*! Output the critical section entry record */
  1238. void QF_QS_CRIT_ENTRY(void);
  1239. /*${QS-macros::QF_QS_CRIT_EXIT} ............................................*/
  1240. /*! Output the critical section exit record */
  1241. void QF_QS_CRIT_EXIT(void);
  1242. /*${QS-macros::QF_QS_ISR_ENTRY} ............................................*/
  1243. /*! Output the interrupt entry record */
  1244. void QF_QS_ISR_ENTRY(
  1245. uint_fast8_t const isrnest,
  1246. uint_fast8_t const prio_);
  1247. /*${QS-macros::QF_QS_ISR_EXIT} .............................................*/
  1248. /*! Output the ISR exit trace record */
  1249. void QF_QS_ISR_EXIT(
  1250. uint_fast8_t isrnest,
  1251. uint_fast8_t prio);
  1252. /*${QS-macros::QF_QS_ACTION} ...............................................*/
  1253. /*! Execute an action that is only necessary for QS output */
  1254. #define QF_QS_ACTION(act_) (act_)
  1255. /*${QS-macros::QS_EOD} .....................................................*/
  1256. /*! Constant representing End-Of-Data condition returned from the
  1257. * QS_getByte() function.
  1258. */
  1259. #define QS_EOD ((uint16_t)0xFFFFU)
  1260. /*${QS-macros::QS_CMD} .....................................................*/
  1261. /*! Constant representing command enumeration group
  1262. * in QS_ENUM_DICTIONARY() and QS_ENUM()
  1263. * @sa QS_onCommand()
  1264. */
  1265. #define QS_CMD ((uint8_t)7U)
  1266. /*${QS-macros::QS_HEX_FMT} .................................................*/
  1267. /*! Constant representing HEX format for the "width" filed
  1268. * in QS_U8(), QS_U16(), QS_U32(), and QS_U64().
  1269. */
  1270. #define QS_HEX_FMT ((uint8_t)0x0FU)
  1271. /*$enddecl${QS-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1272. /*==========================================================================*/
  1273. /* Facilities for QS critical section */
  1274. /* QS-specific critical section */
  1275. #ifdef QS_CRIT_ENTRY /* separate QS critical section defined? */
  1276. #ifndef QS_CRIT_STAT_TYPE
  1277. #define QS_CRIT_STAT_
  1278. #define QS_CRIT_E_() QS_CRIT_ENTRY(dummy)
  1279. #define QS_CRIT_X_() QS_CRIT_EXIT(dummy); QS_REC_DONE()
  1280. #else
  1281. #define QS_CRIT_STAT_ QS_CRIT_STAT_TYPE critStat_;
  1282. #define QS_CRIT_E_() QS_CRIT_ENTRY(critStat_)
  1283. #define QS_CRIT_X_() QS_CRIT_EXIT(critStat_); QS_REC_DONE()
  1284. #endif /* QS_CRIT_STAT_TYPE */
  1285. #else /* separate QS critical section not defined--use the QF definition */
  1286. #ifndef QF_CRIT_STAT_TYPE
  1287. /*! This is an internal macro for defining the critical section
  1288. * status type.
  1289. * @details
  1290. * The purpose of this macro is to enable writing the same code for the
  1291. * case when critical section status type is defined and when it is not.
  1292. * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
  1293. * provides the definition of the critical section status variable.
  1294. * Otherwise this macro is empty.
  1295. * @sa #QF_CRIT_STAT_TYPE
  1296. */
  1297. #define QS_CRIT_STAT_
  1298. /*! This is an internal macro for entering a critical section.
  1299. * @details
  1300. * The purpose of this macro is to enable writing the same code for the
  1301. * case when critical section status type is defined and when it is not.
  1302. * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
  1303. * invokes QF_CRIT_ENTRY() passing the key variable as the parameter.
  1304. * Otherwise QF_CRIT_ENTRY() is invoked with a dummy parameter.
  1305. * @sa QF_CRIT_ENTRY()
  1306. */
  1307. #define QS_CRIT_E_() QF_CRIT_ENTRY(dummy)
  1308. /*! This is an internal macro for exiting a critical section.
  1309. * @details
  1310. * The purpose of this macro is to enable writing the same code for the
  1311. * case when critical section status type is defined and when it is not.
  1312. * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro
  1313. * invokes QF_CRIT_EXIT() passing the key variable as the parameter.
  1314. * Otherwise QF_CRIT_EXIT() is invoked with a dummy parameter.
  1315. * @sa QF_CRIT_EXIT()
  1316. */
  1317. #define QS_CRIT_X_() QF_CRIT_EXIT(dummy); QS_REC_DONE()
  1318. #elif (!defined QS_CRIT_STAT_)
  1319. #define QS_CRIT_STAT_ QF_CRIT_STAT_TYPE critStat_;
  1320. #define QS_CRIT_E_() QF_CRIT_ENTRY(critStat_)
  1321. #define QS_CRIT_X_() QF_CRIT_EXIT(critStat_); QS_REC_DONE()
  1322. #endif /* simple unconditional interrupt disabling used */
  1323. #endif /* separate QS critical section not defined */
  1324. /*==========================================================================*/
  1325. /* Macros for use in QUTest only */
  1326. #ifdef Q_UTEST
  1327. /*$declare${QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  1328. /*${QUTest::QS::TProbe} ....................................................*/
  1329. /*! @brief Test Probe attributes */
  1330. struct QS_TProbe {
  1331. QSFun addr;
  1332. uint32_t data;
  1333. uint8_t idx;
  1334. };
  1335. /*${QUTest::QS::TestData} ..................................................*/
  1336. /*! @brief QUTest data */
  1337. struct QS_TestData {
  1338. struct QS_TProbe tpBuf[16]; /*!< buffer of Test-Probes received so far */
  1339. uint8_t tpNum; /*!< current number of Test-Probes */
  1340. QSTimeCtr testTime; /*!< test time (tick counter) */
  1341. };
  1342. /*${QUTest::QS::testData} ..................................................*/
  1343. /*! QUTest data */
  1344. extern struct QS_TestData QS_testData;
  1345. /*${QUTest::QS::test_pause_} ...............................................*/
  1346. /*! internal function to pause test and enter the test event loop */
  1347. void QS_test_pause_(void);
  1348. /*${QUTest::QS::getTestProbe_} .............................................*/
  1349. /*! get the test probe data for the given API */
  1350. uint32_t QS_getTestProbe_(QSpyFunPtr const api);
  1351. /*${QUTest::QS::onTestSetup} ...............................................*/
  1352. /*! callback to setup a unit test inside the Target */
  1353. void QS_onTestSetup(void);
  1354. /*${QUTest::QS::onTestTeardown} ............................................*/
  1355. /*! callback to teardown after a unit test inside the Target */
  1356. void QS_onTestTeardown(void);
  1357. /*${QUTest::QS::onTestEvt} .................................................*/
  1358. /*! callback to "massage" the test event before dispatching/posting it */
  1359. void QS_onTestEvt(QEvt * e);
  1360. /*${QUTest::QS::onTestPost} ................................................*/
  1361. /*! callback to examine an event that is about to be posted */
  1362. void QS_onTestPost(
  1363. void const * sender,
  1364. QActive * recipient,
  1365. QEvt const * e,
  1366. bool status);
  1367. /*${QUTest::QS::onTestLoop} ................................................*/
  1368. /*! callback to run the test loop */
  1369. void QS_onTestLoop(void);
  1370. /*${QUTest::QUTEST_ON_POST} ................................................*/
  1371. /*! record-ID for posting events */
  1372. #define QUTEST_ON_POST 124
  1373. /*$enddecl${QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1374. /*--------------------------------------------------------------------------*/
  1375. /* QP-stub for QUTest
  1376. * NOTE: The QP-stub is needed for unit testing QP applications,
  1377. * but might NOT be needed for testing QP itself.
  1378. */
  1379. #if Q_UTEST != 0
  1380. /*$declare${QUTest-stub::QS} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  1381. /*${QUTest-stub::QS::processTestEvts_} .....................................*/
  1382. /*! internal function to process posted events during test */
  1383. void QS_processTestEvts_(void);
  1384. /*$enddecl${QUTest-stub::QS} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1385. /*$declare${QUTest-stub::QHsmDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  1386. /*${QUTest-stub::QHsmDummy} ................................................*/
  1387. /*! @brief QHsmDummy class
  1388. * @class QHsmDummy
  1389. * @extends QHsm
  1390. *
  1391. * @details
  1392. * ::QHsmDummy is a test double for the role of "Orthogonal Components"
  1393. * HSM objects in QUTest unit testing.
  1394. */
  1395. typedef struct {
  1396. /* protected: */
  1397. QHsm super;
  1398. } QHsmDummy;
  1399. /* public: */
  1400. /*! Constructor of the QHsmDummy HSM class
  1401. * @public @memberof QHsmDummy
  1402. */
  1403. void QHsmDummy_ctor(QHsmDummy * const me);
  1404. /*! override for QHsm_init_()
  1405. * @private @memberof QHsmDummy
  1406. */
  1407. void QHsmDummy_init_(
  1408. QHsm * const me,
  1409. void const * const par,
  1410. uint_fast8_t const qs_id);
  1411. /*! override for QHsm_dispatch_()
  1412. * @private @memberof QHsmDummy
  1413. */
  1414. void QHsmDummy_dispatch_(
  1415. QHsm * const me,
  1416. QEvt const * const e,
  1417. uint_fast8_t const qs_id);
  1418. /*$enddecl${QUTest-stub::QHsmDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1419. /*$declare${QUTest-stub::QActiveDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  1420. /*${QUTest-stub::QActiveDummy} .............................................*/
  1421. /*! @brief QActiveDummy Object class
  1422. * @class QActiveDummy
  1423. * @extends QActive
  1424. *
  1425. * @details
  1426. * QActiveDummy is a test double for the role of collaborating active
  1427. * objects in QUTest unit testing.
  1428. */
  1429. typedef struct {
  1430. /* protected: */
  1431. QActive super;
  1432. } QActiveDummy;
  1433. /* public: */
  1434. /*! Constructor of the QActiveDummy Active Object class
  1435. * @public @memberof QActiveDummy
  1436. */
  1437. void QActiveDummy_ctor(QActiveDummy * const me);
  1438. /*! override for QHsm_init_()
  1439. * @private @memberof QActiveDummy
  1440. */
  1441. void QActiveDummy_init_(
  1442. QHsm * const me,
  1443. void const * const par,
  1444. uint_fast8_t const qs_id);
  1445. /*! override for QHsm_dispatch_()
  1446. * @private @memberof QActiveDummy
  1447. */
  1448. void QActiveDummy_dispatch_(
  1449. QHsm * const me,
  1450. QEvt const * const e,
  1451. uint_fast8_t const qs_id);
  1452. /*! override for QActive_start_()
  1453. * @private @memberof QActiveDummy
  1454. */
  1455. void QActiveDummy_start_(
  1456. QActive * const me,
  1457. QPrioSpec const prioSpec,
  1458. QEvt const * * const qSto,
  1459. uint_fast16_t const qLen,
  1460. void * const stkSto,
  1461. uint_fast16_t const stkSize,
  1462. void const * const par);
  1463. /*! override for QActive_post_()
  1464. * @private @memberof QActiveDummy
  1465. */
  1466. bool QActiveDummy_post_(
  1467. QActive * const me,
  1468. QEvt const * const e,
  1469. uint_fast16_t const margin,
  1470. void const * const sender);
  1471. /*! override for QActive_postLIFO_()
  1472. * @private @memberof QActiveDummy
  1473. */
  1474. void QActiveDummy_postLIFO_(
  1475. QActive * const me,
  1476. QEvt const * const e);
  1477. /*$enddecl${QUTest-stub::QActiveDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1478. #endif /* Q_UTEST != 0 */
  1479. /*! QS macro to define the Test-Probe for a given `fun_` */
  1480. #define QS_TEST_PROBE_DEF(fun_) \
  1481. uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_));
  1482. /*! QS macro to apply a Test-Probe */
  1483. #define QS_TEST_PROBE(code_) \
  1484. if (qs_tp_ != 0U) { code_ }
  1485. /*! QS macro to apply a Test-Probe */
  1486. #define QS_TEST_PROBE_ID(id_, code_) \
  1487. if (qs_tp_ == (uint32_t)(id_)) { code_ }
  1488. /*! QS macro to pause test execution and enter the test event-loop */
  1489. #define QS_TEST_PAUSE() (QS_test_pause_())
  1490. #else /* Q_UTEST not defined */
  1491. /* dummy definitions when not building for QUTEST */
  1492. #define QS_TEST_PROBE_DEF(fun_)
  1493. #define QS_TEST_PROBE(code_)
  1494. #define QS_TEST_PROBE_ID(id_, code_)
  1495. #define QS_TEST_PAUSE() ((void)0)
  1496. #endif /* Q_UTEST */
  1497. #endif /* QS_H_ */