-
Notifications
You must be signed in to change notification settings - Fork 163
/
Copy pathqs.h
975 lines (800 loc) · 34.1 KB
/
qs.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
//$file${include::qs.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//
// Model: qpc.qm
// File: ${include::qs.h}
//
// This code has been generated by QM 5.3.0 <www.state-machine.com/qm>.
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following QP license:
// License # : LicenseRef-QL-dual
// Issued to : Any user of the QP/C real-time embedded framework
// Framework(s) : qpc
// Support ends : 2024-12-31
// License scope:
//
// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
//
// This software is dual-licensed under the terms of the open source GNU
// General Public License version 3 (or any later version), or alternatively,
// under the terms of one of the closed source Quantum Leaps commercial
// licenses.
//
// The terms of the open source GNU General Public License version 3
// can be found at: <www.gnu.org/licenses/gpl-3.0>
//
// The terms of the closed source Quantum Leaps commercial licenses
// can be found at: <www.state-machine.com/licensing>
//
// Redistributions in source code must retain this top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//
//$endhead${include::qs.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#ifndef QS_H_
#define QS_H_
#ifndef Q_SPY
#error "Q_SPY must be defined to include qs.h"
#endif
//============================================================================
//! @cond INTERNAL
#ifndef QS_CTR_SIZE
#define QS_CTR_SIZE 2U
#endif
#ifndef QS_TIME_SIZE
#define QS_TIME_SIZE 4U
#endif
//! @endcond
//============================================================================
//$declare${QS::types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::types::QS} ...........................................................
//! @class QS
typedef struct QS {
//! @cond INTERNAL
uint8_t dummy;
//! @endcond
} QS;
//${QS::types::QSpyPre} ......................................................
//! @static @public @memberof QS
//! pre-defined QS record IDs
enum QSpyPre {
// [0] QS session (not maskable)
QS_EMPTY, //!< QS record for cleanly starting a session
// [1] SM records
QS_QEP_STATE_ENTRY, //!< a state was entered
QS_QEP_STATE_EXIT, //!< a state was exited
QS_QEP_STATE_INIT, //!< an initial transition was taken in a state
QS_QEP_INIT_TRAN, //!< the top-most initial transition was taken
QS_QEP_INTERN_TRAN, //!< an internal transition was taken
QS_QEP_TRAN, //!< a regular transition was taken
QS_QEP_IGNORED, //!< an event was ignored (silently discarded)
QS_QEP_DISPATCH, //!< an event was dispatched (begin of RTC step)
QS_QEP_UNHANDLED, //!< an event was un-handled due to a guard
// [10] Active Object (AO) records
QS_QF_ACTIVE_DEFER, //!< AO deferred an event
QS_QF_ACTIVE_RECALL, //!< AO recalled an event
QS_QF_ACTIVE_SUBSCRIBE, //!< an AO subscribed to an event
QS_QF_ACTIVE_UNSUBSCRIBE, //!< an AO unsubscribed to an event
QS_QF_ACTIVE_POST, //!< an event was posted (FIFO) directly to AO
QS_QF_ACTIVE_POST_LIFO, //!< an event was posted (LIFO) directly to AO
QS_QF_ACTIVE_GET, //!< AO got an event and its queue is not empty
QS_QF_ACTIVE_GET_LAST,//!< AO got an event and its queue is empty
QS_QF_ACTIVE_RECALL_ATTEMPT, //!< AO attempted to recall an event
// [19] Event Queue (EQ) records
QS_QF_EQUEUE_POST, //!< an event was posted (FIFO) to a raw queue
QS_QF_EQUEUE_POST_LIFO, //!< an event was posted (LIFO) to a raw queue
QS_QF_EQUEUE_GET, //!< get an event and queue still not empty
QS_QF_EQUEUE_GET_LAST,//!< get the last event from the queue
// [23] Framework (QF) records
QS_QF_NEW_ATTEMPT, //!< an attempt to allocate an event failed
// [24] Memory Pool (MP) records
QS_QF_MPOOL_GET, //!< a memory block was removed from memory pool
QS_QF_MPOOL_PUT, //!< a memory block was returned to memory pool
// [26] Additional Framework (QF) records
QS_QF_PUBLISH, //!< an event was published to active objects
QS_QF_NEW_REF, //!< new event reference was created
QS_QF_NEW, //!< new event was created
QS_QF_GC_ATTEMPT, //!< garbage collection attempt
QS_QF_GC, //!< garbage collection
QS_QF_TICK, //!< QTimeEvt tick was called
// [32] Time Event (TE) records
QS_QF_TIMEEVT_ARM, //!< a time event was armed
QS_QF_TIMEEVT_AUTO_DISARM, //!< a time event expired and was disarmed
QS_QF_TIMEEVT_DISARM_ATTEMPT,//!< attempt to disarm a disarmed QTimeEvt
QS_QF_TIMEEVT_DISARM, //!< true disarming of an armed time event
QS_QF_TIMEEVT_REARM, //!< rearming of a time event
QS_QF_TIMEEVT_POST, //!< a time event posted itself directly to an AO
// [38] Additional Framework (QF) records
QS_QF_DELETE_REF, //!< an event reference is about to be deleted
QS_QF_CRIT_ENTRY, //!< critical section was entered
QS_QF_CRIT_EXIT, //!< critical section was exited
QS_QF_ISR_ENTRY, //!< an ISR was entered
QS_QF_ISR_EXIT, //!< an ISR was exited
QS_QF_INT_DISABLE, //!< interrupts were disabled
QS_QF_INT_ENABLE, //!< interrupts were enabled
// [45] Additional Active Object (AO) records
QS_QF_ACTIVE_POST_ATTEMPT,//!< attempt to post an evt to AO failed
// [46] Additional Event Queue (EQ) records
QS_QF_EQUEUE_POST_ATTEMPT,//!< attempt to post evt to QEQueue failed
// [47] Additional Memory Pool (MP) records
QS_QF_MPOOL_GET_ATTEMPT, //!< attempt to get a memory block failed
// [48] Scheduler (SC) records
QS_SCHED_PREEMPT, //!< scheduler asynchronously preempted a task
QS_SCHED_RESTORE, //!< scheduler restored preempted task
QS_SCHED_LOCK, //!< scheduler was locked
QS_SCHED_UNLOCK, //!< scheduler was unlocked
QS_SCHED_NEXT, //!< scheduler started next task
QS_SCHED_IDLE, //!< scheduler restored the idle task
// [54] Miscellaneous QS records (not maskable)
QS_ENUM_DICT, //!< enumeration dictionary entry
// [55] Additional QEP records
QS_QEP_TRAN_HIST, //!< a tran to history was taken
QS_QEP_TRAN_EP, //!< a tran to entry point into a submachine
QS_QEP_TRAN_XP, //!< a tran to exit point out of a submachine
// [58] Miscellaneous QS records (not maskable)
QS_TEST_PAUSED, //!< test has been paused
QS_TEST_PROBE_GET, //!< reports that Test-Probe has been used
QS_SIG_DICT, //!< signal dictionary entry
QS_OBJ_DICT, //!< object dictionary entry
QS_FUN_DICT, //!< function dictionary entry
QS_USR_DICT, //!< user QS record dictionary entry
QS_TARGET_INFO, //!< reports the Target information
QS_TARGET_DONE, //!< reports completion of a user callback
QS_RX_STATUS, //!< reports QS data receive status
QS_QUERY_DATA, //!< reports the data from "current object" query
QS_PEEK_DATA, //!< reports the data from the PEEK query
QS_ASSERT_FAIL, //!< assertion failed in the code
QS_QF_RUN, //!< QF_run() was entered
// [71] Semaphore (SEM) records
QS_SEM_TAKE, //!< a semaphore was taken by a thread
QS_SEM_BLOCK, //!< a semaphore blocked a thread
QS_SEM_SIGNAL, //!< a semaphore was signaled
QS_SEM_BLOCK_ATTEMPT, //!< a semaphore blocked was attempted
// [75] Mutex (MTX) records
QS_MTX_LOCK, //!< a mutex was locked
QS_MTX_BLOCK, //!< a mutex blocked a thread
QS_MTX_UNLOCK, //!< a mutex was unlocked
QS_MTX_LOCK_ATTEMPT, //!< a mutex lock was attempted
QS_MTX_BLOCK_ATTEMPT, //!< a mutex blocking was attempted
QS_MTX_UNLOCK_ATTEMPT,//!< a mutex unlock was attempted
// [81]
QS_PRE_MAX //!< the # predefined signals
};
//${QS::types::QSpyGroups} ...................................................
//! @static @public @memberof QS
//! QS-TX record groups for QS_GLB_FILTER()
enum QSpyGroups {
QS_ALL_RECORDS = 0xF0,//!< all maskable QS records
QS_SM_RECORDS, //!< State Machine QS records
QS_AO_RECORDS, //!< Active Object QS records
QS_EQ_RECORDS, //!< Event Queues QS records
QS_MP_RECORDS, //!< Memory Pools QS records
QS_TE_RECORDS, //!< Time Events QS records
QS_QF_RECORDS, //!< QF QS records
QS_SC_RECORDS, //!< Scheduler QS records
QS_SEM_RECORDS, //!< Semaphore QS records
QS_MTX_RECORDS, //!< Mutex QS records
QS_U0_RECORDS, //!< User Group 100-104 records
QS_U1_RECORDS, //!< User Group 105-109 records
QS_U2_RECORDS, //!< User Group 110-114 records
QS_U3_RECORDS, //!< User Group 115-119 records
QS_U4_RECORDS, //!< User Group 120-124 records
QS_UA_RECORDS //!< All User records
};
//${QS::types::QSpyUserOffsets} ..............................................
//! @static @public @memberof QS
//! QS user record group offsets for QS_GLB_FILTER()
enum QSpyUserOffsets {
QS_USER = 100, //!< the first record available to QS users
QS_USER0 = QS_USER, //!< offset for User Group 0
QS_USER1 = (enum_t)QS_USER0 + 5, //!< offset for User Group 1
QS_USER2 = (enum_t)QS_USER1 + 5, //!< offset for User Group 2
QS_USER3 = (enum_t)QS_USER2 + 5, //!< offset for User Group 3
QS_USER4 = (enum_t)QS_USER3 + 5 //!< offset for User Group 4
};
//${QS::types::QSpyIdOffsets} ................................................
//! @static @public @memberof QS
//! QS ID offsets for QS_LOC_FILTER()
enum QSpyIdOffsets {
QS_AO_ID = 0, //!< offset for AO priorities
QS_EP_ID = 64, //!< offset for event-pool IDs
QS_EQ_ID = 80, //!< offset for event-queue IDs
QS_AP_ID = 96 //!< offset for Application-specific IDs
};
//${QS::types::QSpyIdGroups} .................................................
//! @static @public @memberof QS
//! QS ID groups for QS_LOC_FILTER()
enum QSpyIdGroups {
QS_ALL_IDS = 0xF0, //!< all QS IDs
QS_AO_IDS = 0x80 + (enum_t)QS_AO_ID, //!< AO IDs (priorities)
QS_EP_IDS = 0x80 + (enum_t)QS_EP_ID, //!< event-pool IDs
QS_EQ_IDS = 0x80 + (enum_t)QS_EQ_ID, //!< event-queue IDs
QS_AP_IDS = 0x80 + (enum_t)QS_AP_ID //!< Application-specific IDs
};
//${QS::types::QSpyId} .......................................................
//! @struct QSpyId
typedef struct { uint8_t prio; } QSpyId;
//${QS::types::QSpyFunPtr} ...................................................
//! @static @private @memberof QS
typedef void (* QSpyFunPtr )(void);
//${QS::types::QSCtr} ........................................................
#if (QS_CTR_SIZE == 2U)
typedef uint16_t QSCtr;
#endif // (QS_CTR_SIZE == 2U)
//${QS::types::QSCtr} ........................................................
#if (QS_CTR_SIZE == 4U)
typedef uint32_t QSCtr;
#endif // (QS_CTR_SIZE == 4U)
//${QS::types::QSTimeCtr} ....................................................
#if (QS_TIME_SIZE == 2U)
typedef uint16_t QSTimeCtr;
#endif // (QS_TIME_SIZE == 2U)
//${QS::types::QSTimeCtr} ....................................................
#if (QS_TIME_SIZE == 4U)
typedef uint32_t QSTimeCtr;
#endif // (QS_TIME_SIZE == 4U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 2U)
typedef uint16_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 2U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 4U)
typedef uint32_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 4U)
//${QS::types::QSFun} ........................................................
#if (QS_FUN_PTR_SIZE == 8U)
typedef uint64_t QSFun;
#endif // (QS_FUN_PTR_SIZE == 8U)
//$enddecl${QS::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::filters::Filter} .....................................................
//! @struct QS_Filter
typedef struct {
// public:
uint8_t glb[16];
uint8_t loc[16];
} QS_Filter;
//${QS::filters::filt_} ......................................................
//! @static @private @memberof QS
extern QS_Filter QS_filt_;
//$enddecl${QS::filters} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QS-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS-macros::QS_INIT} ......................................................
#define QS_INIT(arg_) (QS_onStartup(arg_))
//${QS-macros::QS_EXIT} ......................................................
#define QS_EXIT() (QS_onCleanup())
//${QS-macros::QS_OUTPUT} ....................................................
#define QS_OUTPUT() (QS_output())
//${QS-macros::QS_RX_INPUT} ..................................................
#define QS_RX_INPUT() (QS_rx_input())
//${QS-macros::QS_GLB_FILTER} ................................................
#define QS_GLB_FILTER(rec_) (QS_glbFilter_((int_fast16_t)(rec_)))
//${QS-macros::QS_LOC_FILTER} ................................................
#define QS_LOC_FILTER(qs_id_) (QS_locFilter_((int_fast16_t)(qs_id_)))
//${QS-macros::QS_BEGIN_ID} ..................................................
#define QS_BEGIN_ID(rec_, qs_id_) \
if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
QS_CRIT_STAT \
QS_CRIT_ENTRY(); \
QS_MEM_SYS(); \
QS_beginRec_((uint_fast8_t)(rec_)); \
QS_TIME_PRE_(); {
//${QS-macros::QS_END} .......................................................
#define QS_END() } \
QS_endRec_(); \
QS_MEM_APP(); \
QS_CRIT_EXIT(); \
}
//${QS-macros::QS_FLUSH} .....................................................
#define QS_FLUSH() (QS_onFlush())
//${QS-macros::QS_BEGIN_INCRIT} ..............................................
#define QS_BEGIN_INCRIT(rec_, qs_id_) \
if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
QS_beginRec_((uint_fast8_t)(rec_)); \
QS_TIME_PRE_(); {
//${QS-macros::QS_END_INCRIT} ................................................
#define QS_END_INCRIT() } \
QS_endRec_(); \
}
//${QS-macros::QS_GLB_CHECK_} ................................................
#define QS_GLB_CHECK_(rec_) \
(((uint_fast8_t)QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \
& ((uint_fast8_t)1U << ((uint_fast8_t)(rec_) & 7U))) != 0U)
//${QS-macros::QS_LOC_CHECK_} ................................................
#define QS_LOC_CHECK_(qs_id_) \
(((uint_fast8_t)QS_filt_.loc[(uint_fast8_t)(qs_id_) >> 3U] \
& ((uint_fast8_t)1U << ((uint_fast8_t)(qs_id_) & 7U))) != 0U)
//${QS-macros::QS_REC_DONE} ..................................................
#ifndef QS_REC_DONE
#define QS_REC_DONE() ((void)0)
#endif // ndef QS_REC_DONE
//${QS-macros::QS_I8} ........................................................
#define QS_I8(width_, data_) \
(QS_u8_fmt_((uint8_t)(((width_) << 4U) & 0x7U) | (uint8_t)QS_I8_ENUM_T, \
(data_)))
//${QS-macros::QS_U8} ........................................................
#define QS_U8(width_, data_) \
(QS_u8_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_)))
//${QS-macros::QS_I16} .......................................................
#define QS_I16(width_, data_) \
(QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_)))
//${QS-macros::QS_U16} .......................................................
#define QS_U16(width_, data_) \
(QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_)))
//${QS-macros::QS_I32} .......................................................
#define QS_I32(width_, data_) \
(QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_)))
//${QS-macros::QS_U32} .......................................................
#define QS_U32(width_, data_) \
(QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_)))
//${QS-macros::QS_I64} .......................................................
#define QS_I64(width_, data_) \
(QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_)))
//${QS-macros::QS_U64} .......................................................
#define QS_U64(width_, data_) \
(QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_)))
//${QS-macros::QS_F32} .......................................................
#define QS_F32(width_, data_) \
(QS_f32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_)))
//${QS-macros::QS_F64} .......................................................
#define QS_F64(width_, data_) \
(QS_f64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_)))
//${QS-macros::QS_STR} .......................................................
#define QS_STR(str_) (QS_str_fmt_((str_)))
//${QS-macros::QS_MEM} .......................................................
#define QS_MEM(mem_, size_) (QS_mem_fmt_((mem_), (size_)))
//${QS-macros::QS_ENUM} ......................................................
#define QS_ENUM(group_, value_) \
(QS_u8_fmt_((uint8_t)(0x80U | ((group_) << 4U)) | (uint8_t)QS_I8_ENUM_T,\
(uint8_t)(value_)))
//${QS-macros::QS_TIME_PRE_} .................................................
#if (QS_TIME_SIZE == 2U)
#define QS_TIME_PRE_() (QS_u16_raw_(QS_onGetTime()))
#endif // (QS_TIME_SIZE == 2U)
//${QS-macros::QS_TIME_PRE_} .................................................
#if (QS_TIME_SIZE == 4U)
#define QS_TIME_PRE_() (QS_u32_raw_(QS_onGetTime()))
#endif // (QS_TIME_SIZE == 4U)
//${QS-macros::QS_OBJ} .......................................................
#if (QS_OBJ_PTR_SIZE == 2U)
#define QS_OBJ(obj_) (QS_u16_fmt_(QS_OBJ_T, (uint16_t)(obj_)))
#endif // (QS_OBJ_PTR_SIZE == 2U)
//${QS-macros::QS_OBJ} .......................................................
#if (QS_OBJ_PTR_SIZE == 4U)
#define QS_OBJ(obj_) (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_)))
#endif // (QS_OBJ_PTR_SIZE == 4U)
//${QS-macros::QS_OBJ} .......................................................
#if (QS_OBJ_PTR_SIZE == 8U)
#define QS_OBJ(obj_) (QS_u64_fmt_(QS_OBJ_T, (uint64_t)(obj_)))
#endif // (QS_OBJ_PTR_SIZE == 8U)
//${QS-macros::QS_FUN} .......................................................
#if (QS_FUN_PTR_SIZE == 2U)
#define QS_FUN(fun_) (QS_u16_fmt_(QS_FUN_T, (uint16_t)(fun_)))
#endif // (QS_FUN_PTR_SIZE == 2U)
//${QS-macros::QS_FUN} .......................................................
#if (QS_FUN_PTR_SIZE == 4U)
#define QS_FUN(fun_) (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_)))
#endif // (QS_FUN_PTR_SIZE == 4U)
//${QS-macros::QS_FUN} .......................................................
#if (QS_FUN_PTR_SIZE == 8U)
#define QS_FUN(fun_) (QS_u64_fmt_(QS_FUN_T, (uint64_t)(fun_)))
#endif // (QS_FUN_PTR_SIZE == 8U)
//${QS-macros::QS_SIG} .......................................................
#if (Q_SIGNAL_SIZE == 1U)
#define QS_SIG(sig_, obj_) \
QS_u8_fmt_(QS_SIG_T, (sig_)); \
QS_obj_raw_(obj_)
#endif // (Q_SIGNAL_SIZE == 1U)
//${QS-macros::QS_SIG} .......................................................
#if (Q_SIGNAL_SIZE == 2U)
#define QS_SIG(sig_, obj_) \
QS_u16_fmt_(QS_SIG_T, (sig_)); \
QS_obj_raw_(obj_)
#endif // (Q_SIGNAL_SIZE == 2U)
//${QS-macros::QS_SIG} .......................................................
#if (Q_SIGNAL_SIZE == 4U)
#define QS_SIG(sig_, obj_) \
QS_u32_fmt_(QS_SIG_T, (sig_)); \
QS_obj_raw_(obj_)
#endif // (Q_SIGNAL_SIZE == 4U)
//${QS-macros::QS_SIG_DICTIONARY} ............................................
#define QS_SIG_DICTIONARY(sig_, obj_) \
(QS_sig_dict_pre_((QSignal)(sig_), (obj_), #sig_))
//${QS-macros::QS_OBJ_DICTIONARY} ............................................
#define QS_OBJ_DICTIONARY(obj_) \
(QS_obj_dict_pre_((obj_), #obj_))
//${QS-macros::QS_OBJ_ARR_DICTIONARY} ........................................
#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \
(QS_obj_arr_dict_pre_((obj_), (idx_), #obj_))
//${QS-macros::QS_FUN_DICTIONARY} ............................................
#define QS_FUN_DICTIONARY(fun_) \
(QS_fun_dict_pre_((void (*)(void))(fun_), #fun_))
//${QS-macros::QS_USR_DICTIONARY} ............................................
#define QS_USR_DICTIONARY(rec_) \
(QS_usr_dict_pre_((rec_), #rec_))
//${QS-macros::QS_ENUM_DICTIONARY} ...........................................
#define QS_ENUM_DICTIONARY(value_, group_) \
(QS_enum_dict_pre_((value_), (group_), #value_))
//${QS-macros::QS_RX_PUT} ....................................................
#define QS_RX_PUT(b_) (QS_rxPut((b_)))
//${QS-macros::QS_TR_CRIT_ENTRY} .............................................
#define QS_TR_CRIT_ENTRY()
//${QS-macros::QS_TR_CRIT_EXIT} ..............................................
#define QS_TR_CRIT_EXIT()
//${QS-macros::QS_TR_ISR_ENTRY} ..............................................
#define QS_TR_ISR_ENTRY(isrnest, prio) do { \
QS_BEGIN_PRE_(QS_QF_ISR_ENTRY, 0U) \
QS_TIME_PRE_(); \
QS_2u8_raw_(isrnest, prio); \
QS_END_PRE_() \
}
//${QS-macros::QS_TR_ISR_EXIT} ...............................................
void QS_TR_ISR_EXIT(
uint_fast8_t isrnest,
uint_fast8_t prio);
//${QS-macros::QS_ONLY} ......................................................
#define QS_ONLY(code_) (code_)
//${QS-macros::QS_ASSERTION} .................................................
#define QS_ASSERTION(module_, id_, delay_) \
(QS_assertion_pre_((module_), (id_), (delay_)))
//${QS-macros::QS_EOD} .......................................................
#define QS_EOD ((uint16_t)0xFFFFU)
//${QS-macros::QS_CMD} .......................................................
#define QS_CMD ((uint8_t)7U)
//${QS-macros::QS_HEX_FMT} ...................................................
#define QS_HEX_FMT ((uint8_t)0x0FU)
//${QS-macros::QS_CRIT_STAT} .................................................
#ifndef QS_CRIT_STAT
#define QS_CRIT_STAT QF_CRIT_STAT
#endif // ndef QS_CRIT_STAT
//${QS-macros::QS_CRIT_ENTRY} ................................................
#ifndef QS_CRIT_ENTRY
#define QS_CRIT_ENTRY() QF_CRIT_ENTRY()
#endif // ndef QS_CRIT_ENTRY
//${QS-macros::QS_CRIT_EXIT} .................................................
#ifndef QS_CRIT_EXIT
#define QS_CRIT_EXIT() QF_CRIT_EXIT()
#endif // ndef QS_CRIT_EXIT
//${QS-macros::QS_MEM_SYS} ...................................................
#ifndef QS_MEM_SYS
#define QS_MEM_SYS() QF_MEM_SYS()
#endif // ndef QS_MEM_SYS
//${QS-macros::QS_MEM_APP} ...................................................
#ifndef QS_MEM_APP
#define QS_MEM_APP() QF_MEM_APP()
#endif // ndef QS_MEM_APP
//$enddecl${QS-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//============================================================================
//! @cond INTERNAL
typedef struct {
void const * locFilter_AP; //!< @deprecated
uint8_t * buf;
QSCtr end;
QSCtr volatile head;
QSCtr volatile tail;
QSCtr volatile used;
uint8_t volatile seq;
uint8_t volatile chksum;
uint8_t volatile critNest;
uint8_t flags;
} QS_Attr;
extern QS_Attr QS_priv_;
void QS_glbFilter_(int_fast16_t const filter);
void QS_locFilter_(int_fast16_t const filter);
void QS_beginRec_(uint_fast8_t const rec);
void QS_endRec_(void);
void QS_u8_raw_(uint8_t const d);
void QS_2u8_raw_(
uint8_t const d1,
uint8_t const d2);
void QS_u16_raw_(uint16_t const d);
void QS_u32_raw_(uint32_t const d);
void QS_u64_raw_(uint64_t const d);
void QS_obj_raw_(void const * const obj);
void QS_str_raw_(char const * const str);
void QS_u8_fmt_(
uint8_t const format,
uint8_t const d);
void QS_u16_fmt_(
uint8_t const format,
uint16_t const d);
void QS_u32_fmt_(
uint8_t const format,
uint32_t const d);
void QS_u64_fmt_(
uint8_t const format,
uint64_t const d);
void QS_f32_fmt_(
uint8_t const format,
float32_t const f);
void QS_f64_fmt_(
uint8_t const format,
float64_t const d);
void QS_str_fmt_(char const * const str);
void QS_mem_fmt_(
uint8_t const * const blk,
uint8_t const size);
void QS_sig_dict_pre_(
QSignal const sig,
void const * const obj,
char const * const name);
void QS_obj_dict_pre_(
void const * const obj,
char const * const name);
void QS_obj_arr_dict_pre_(
void const * const obj,
uint_fast16_t const idx,
char const * const name);
void QS_fun_dict_pre_(
QSpyFunPtr const fun,
char const * const name);
void QS_usr_dict_pre_(
enum_t const rec,
char const * const name);
void QS_enum_dict_pre_(
enum_t const value,
uint8_t const group,
char const * const name);
void QS_assertion_pre_(
char const * const module,
int_t const id,
uint32_t const delay);
void QS_target_info_pre_(uint8_t const isReset);
//! @endcond
//============================================================================
//$declare${QS::QS-TX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::QS-TX::preType} ......................................................
//! Enumerates data elements for app-specific trace records
enum QS_preType {
QS_I8_ENUM_T, //!< signed 8-bit integer or enum format
QS_U8_T, //!< unsigned 8-bit integer format
QS_I16_T, //!< signed 16-bit integer format
QS_U16_T, //!< unsigned 16-bit integer format
QS_I32_T, //!< signed 32-bit integer format
QS_U32_T, //!< unsigned 32-bit integer format
QS_F32_T, //!< 32-bit floating point format
QS_F64_T, //!< 64-bit floating point format
QS_STR_T, //!< zero-terminated ASCII string format
QS_MEM_T, //!< up to 255-bytes memory block format
QS_SIG_T, //!< event signal format
QS_OBJ_T, //!< object pointer format
QS_FUN_T, //!< function pointer format
QS_I64_T, //!< signed 64-bit integer format
QS_U64_T //!< unsigned 64-bit integer format
};
//${QS::QS-TX::initBuf} ......................................................
//! @static @public @memberof QS
void QS_initBuf(
uint8_t * const sto,
uint_fast32_t const stoSize);
//${QS::QS-TX::getByte} ......................................................
//! @static @public @memberof QS
uint16_t QS_getByte(void);
//${QS::QS-TX::getBlock} .....................................................
//! @static @public @memberof QS
uint8_t const * QS_getBlock(uint16_t * const pNbytes);
//${QS::QS-TX::doOutput} .....................................................
//! @static @public @memberof QS
void QS_doOutput(void);
//${QS::QS-TX::onStartup} ....................................................
//! @static @public @memberof QS
uint8_t QS_onStartup(void const * arg);
//${QS::QS-TX::onCleanup} ....................................................
//! @static @public @memberof QS
void QS_onCleanup(void);
//${QS::QS-TX::onFlush} ......................................................
//! @static @public @memberof QS
void QS_onFlush(void);
//${QS::QS-TX::onGetTime} ....................................................
//! @static @public @memberof QS
QSTimeCtr QS_onGetTime(void);
//$enddecl${QS::QS-TX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//============================================================================
//! @cond INTERNAL
typedef struct {
void * currObj[8];
uint8_t * buf;
QSCtr end;
QSCtr volatile head;
QSCtr volatile tail;
#ifdef Q_UTEST
bool inTestLoop;
#endif
} QS_RxAttr;
//! @static @private @memberof QS
extern QS_RxAttr QS_rxPriv_;
//! @endcond
//============================================================================
//$declare${QS::QS-RX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::QS-RX::QSpyObjKind} ..................................................
//! @static @public @memberof QS
//! Kinds of objects used in QS-RX
enum QS_QSpyObjKind {
SM_OBJ, //!< state machine object
AO_OBJ, //!< active object
MP_OBJ, //!< event pool object
EQ_OBJ, //!< raw queue object
TE_OBJ, //!< time event object
AP_OBJ, //!< generic Application-specific object
MAX_OBJ
};
//${QS::QS-RX::OSpyObjComb} ..................................................
//! @static @public @memberof QS
//! Object combinations for QS-RX
enum QS_OSpyObjComb {
SM_AO_OBJ = (enum_t)MAX_OBJ //!< combination of SM and AO
};
//${QS::QS-RX::rxInitBuf} ....................................................
//! @static @public @memberof QS
void QS_rxInitBuf(
uint8_t * const sto,
uint16_t const stoSize);
//${QS::QS-RX::rxPut} ........................................................
//! @static @public @memberof QS
static inline bool QS_rxPut(uint8_t const b) {
// NOTE: does not need critical section
// But requires system-level memory access (QF_MEM_SYS()).
QSCtr head = QS_rxPriv_.head + 1U;
if (head == QS_rxPriv_.end) {
head = 0U;
}
if (head != QS_rxPriv_.tail) { // buffer NOT full?
QS_rxPriv_.buf[QS_rxPriv_.head] = b;
QS_rxPriv_.head = head; // update the head to a *valid* index
return true; // byte placed in the buffer
}
else {
return false; // byte NOT placed in the buffer
}
}
//${QS::QS-RX::rxParse} ......................................................
//! @static @public @memberof QS
void QS_rxParse(void);
//${QS::QS-RX::rxGetNfree} ...................................................
//! @static @public @memberof QS
uint16_t QS_rxGetNfree(void);
//${QS::QS-RX::doInput} ......................................................
//! @static @public @memberof QS
void QS_doInput(void);
//${QS::QS-RX::onReset} ......................................................
//! @static @public @memberof QS
void QS_onReset(void);
//${QS::QS-RX::onCommand} ....................................................
//! @static @public @memberof QS
void QS_onCommand(
uint8_t cmdId,
uint32_t param1,
uint32_t param2,
uint32_t param3);
//$enddecl${QS::QS-RX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//============================================================================
#ifdef Q_UTEST
//$declare${QS::QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::QUTest::TProbe} ......................................................
// @struct TProbe
struct QS_TProbe {
QSFun addr;
uint32_t data;
uint8_t idx;
};
//${QS::QUTest::onTestSetup} .................................................
//! @static @public @memberof QS
void QS_onTestSetup(void);
//${QS::QUTest::onTestTeardown} ..............................................
//! @static @public @memberof QS
void QS_onTestTeardown(void);
//${QS::QUTest::onTestEvt} ...................................................
//! @static @public @memberof QS
void QS_onTestEvt(QEvt * e);
//${QS::QUTest::onTestPost} ..................................................
//! @static @public @memberof QS
void QS_onTestPost(
void const * sender,
QActive * recipient,
QEvt const * e,
bool status);
//${QS::QUTest::onTestLoop} ..................................................
//! @static @public @memberof QS
void QS_onTestLoop(void);
//$enddecl${QS::QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#define QUTEST_ON_POST 124
//============================================================================
//! @cond INTERNAL
typedef struct {
struct QS_TProbe tpBuf[16];
uint8_t tpNum;
QSTimeCtr testTime;
QPSet readySet;
QPSet readySet_dis;
uint_fast8_t intLock;
} QSTestAttr;
extern QSTestAttr QS_tstPriv_;
void QS_test_pause_(void);
uint32_t QS_getTestProbe_(QSpyFunPtr const api);
//! @endcond
//============================================================================
// QP-stub for QUTest
// NOTE: The QP-stub is needed for unit testing QP applications,
// but might NOT be needed for testing QP itself.
#if (Q_UTEST != 0)
//$declare${QS::QUTest-stub::QHsmDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::QUTest-stub::QHsmDummy} ..............................................
//! @class QHsmDummy
//! @extends QHsm
typedef struct {
// protected:
QAsm super;
} QHsmDummy;
// public:
//! @public @memberof QHsmDummy
void QHsmDummy_ctor(QHsmDummy * const me);
//! @private @memberof QHsmDummy
void QHsmDummy_init_(
QAsm * const me,
void const * const par,
uint_fast8_t const qs_id);
// private:
//! @private @memberof QHsmDummy
void QHsmDummy_dispatch_(
QAsm * const me,
QEvt const * const e,
uint_fast8_t const qs_id);
//$enddecl${QS::QUTest-stub::QHsmDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QS::QUTest-stub::QActiveDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QS::QUTest-stub::QActiveDummy} ...........................................
//! @class QActiveDummy
//! @extends QActive
typedef struct {
// protected:
QActive super;
} QActiveDummy;
// public:
//! @public @memberof QActiveDummy
void QActiveDummy_ctor(QActiveDummy * const me);
// private:
//! @private @memberof QActiveDummy
void QActiveDummy_init_(
QAsm * const me,
void const * const par,
uint_fast8_t const qs_id);
//! @private @memberof QActiveDummy
void QActiveDummy_dispatch_(
QAsm * const me,
QEvt const * const e,
uint_fast8_t const qs_id);
//! @private @memberof QActiveDummy
bool QActiveDummy_fakePost_(
QActive * const me,
QEvt const * const e,
uint_fast16_t const margin,
void const * const sender);
//! @private @memberof QActiveDummy
void QActiveDummy_fakePostLIFO_(
QActive * const me,
QEvt const * const e);
//$enddecl${QS::QUTest-stub::QActiveDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif // Q_UTEST != 0
#define QS_TEST_PROBE_DEF(fun_) \
uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_));
#define QS_TEST_PROBE(code_) \
if (qs_tp_ != 0U) { code_ }
#define QS_TEST_PROBE_ID(id_, code_) \
if (qs_tp_ == (uint32_t)(id_)) { code_ }
#define QS_TEST_PAUSE() (QS_test_pause_())
#else // Q_UTEST not defined
// dummy definitions when not building for QUTEST
#define QS_TEST_PROBE_DEF(fun_)
#define QS_TEST_PROBE(code_)
#define QS_TEST_PROBE_ID(id_, code_)
#define QS_TEST_PAUSE() ((void)0)
#endif // Q_UTEST
#endif // QS_H_