QP/C  7.0.0
Real-Time Embedded Framework
qs_rx.c
Go to the documentation of this file.
1/*============================================================================
2* QP/C Real-Time Embedded Framework (RTEF)
3* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
4*
5* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
6*
7* This software is dual-licensed under the terms of the open source GNU
8* General Public License version 3 (or any later version), or alternatively,
9* under the terms of one of the closed source Quantum Leaps commercial
10* licenses.
11*
12* The terms of the open source GNU General Public License version 3
13* can be found at: <www.gnu.org/licenses/gpl-3.0>
14*
15* The terms of the closed source Quantum Leaps commercial licenses
16* can be found at: <www.state-machine.com/licensing>
17*
18* Redistributions in source code must retain this top-level comment block.
19* Plagiarizing this software to sidestep the license obligations is illegal.
20*
21* Contact information:
22* <www.state-machine.com>
23* <info@state-machine.com>
24============================================================================*/
32#define QP_IMPL /* this is QP implementation */
33#include "qs_port.h" /* QS port */
34#include "qs_pkg.h" /* QS package-scope interface */
35#include "qassert.h" /* QP embedded systems-friendly assertions */
36
38
39/*==========================================================================*/
40QSrxPrivAttr QS_rxPriv_; /* QS-RX private attributes */
41
42/*==========================================================================*/
43#if (QS_OBJ_PTR_SIZE == 1U)
44 typedef uint8_t QSObj;
45#elif (QS_OBJ_PTR_SIZE == 2U)
46 typedef uint16_t QSObj;
47#elif (QS_OBJ_PTR_SIZE == 4U)
48 typedef uint32_t QSObj;
49#elif (QS_OBJ_PTR_SIZE == 8U)
50 typedef uint64_t QSObj;
51#endif
52
57typedef struct {
58 uint32_t param1;
59 uint32_t param2;
60 uint32_t param3;
61 uint8_t idx;
62 uint8_t cmdId;
63} CmdVar;
64
65typedef struct {
66 uint_fast8_t rate;
67} TickVar;
68
69typedef struct {
70 uint16_t offs;
71 uint8_t size;
72 uint8_t num;
73 uint8_t idx;
74} PeekVar;
75
76typedef struct {
77 uint32_t data;
78 uint16_t offs;
79 uint8_t size;
80 uint8_t num;
81 uint8_t idx;
82 uint8_t fill;
83} PokeVar;
84
85typedef struct {
86 uint8_t data[16];
87 uint8_t idx;
88 int8_t recId; /* global/local */
89} FltVar;
90
91typedef struct {
92 QSObj addr;
93 uint8_t idx;
94 uint8_t kind; /* see qs.h, enum QSpyObjKind */
95 int8_t recId;
96} ObjVar;
97
98typedef struct {
99 QEvt *e;
100 uint8_t *p;
101 QSignal sig;
102 uint16_t len;
103 uint8_t prio;
104 uint8_t idx;
105} EvtVar;
106
107#ifdef Q_UTEST
108
109 #if (QS_FUN_PTR_SIZE == 1U)
110 typedef uint8_t QSFun;
111 #elif (QS_FUN_PTR_SIZE == 2U)
112 typedef uint16_t QSFun;
113 #elif (QS_FUN_PTR_SIZE == 4U)
114 typedef uint32_t QSFun;
115 #elif (QS_FUN_PTR_SIZE == 8U)
116 typedef uint64_t QSFun;
117 #endif
118
119 typedef struct {
120 QSFun addr;
121 uint32_t data;
122 uint8_t idx;
123 } TPVar; /* Test-Probe */
124
125 static struct {
126 TPVar tpBuf[16]; /* buffer of Test-Probes received so far */
127 uint8_t tpNum; /* current number of Test-Probes */
128 QSTimeCtr testTime; /* test time (tick counter) */
129 } l_testData;
130
131#endif /* Q_UTEST */
132
133/* extended-state variables for the current state */
134static struct {
135 union Variant {
136 CmdVar cmd;
137 TickVar tick;
138 PeekVar peek;
139 PokeVar poke;
140 FltVar flt;
141 ObjVar obj;
142 EvtVar evt;
143#ifdef Q_UTEST
144 TPVar tp;
145#endif /* Q_UTEST */
146 } var;
147 uint8_t state;
148 uint8_t esc;
149 uint8_t seq;
150 uint8_t chksum;
151} l_rx;
152
153enum {
154 ERROR_STATE,
155 WAIT4_SEQ,
156 WAIT4_REC,
157 WAIT4_INFO_FRAME,
158 WAIT4_CMD_ID,
159 WAIT4_CMD_PARAM1,
160 WAIT4_CMD_PARAM2,
161 WAIT4_CMD_PARAM3,
162 WAIT4_CMD_FRAME,
163 WAIT4_RESET_FRAME,
164 WAIT4_TICK_RATE,
165 WAIT4_TICK_FRAME,
166 WAIT4_PEEK_OFFS,
167 WAIT4_PEEK_SIZE,
168 WAIT4_PEEK_NUM,
169 WAIT4_PEEK_FRAME,
170 WAIT4_POKE_OFFS,
171 WAIT4_POKE_SIZE,
172 WAIT4_POKE_NUM,
173 WAIT4_POKE_DATA,
174 WAIT4_POKE_FRAME,
175 WAIT4_FILL_DATA,
176 WAIT4_FILL_FRAME,
177 WAIT4_FILTER_LEN,
178 WAIT4_FILTER_DATA,
179 WAIT4_FILTER_FRAME,
180 WAIT4_OBJ_KIND,
181 WAIT4_OBJ_ADDR,
182 WAIT4_OBJ_FRAME,
183 WAIT4_QUERY_KIND,
184 WAIT4_QUERY_FRAME,
185 WAIT4_EVT_PRIO,
186 WAIT4_EVT_SIG,
187 WAIT4_EVT_LEN,
188 WAIT4_EVT_PAR,
189 WAIT4_EVT_FRAME,
190
191#ifdef Q_UTEST
192 WAIT4_TEST_SETUP_FRAME,
193 WAIT4_TEST_TEARDOWN_FRAME,
194 WAIT4_TEST_PROBE_DATA,
195 WAIT4_TEST_PROBE_ADDR,
196 WAIT4_TEST_PROBE_FRAME,
197 WAIT4_TEST_CONTINUE_FRAME,
198#endif /* Q_UTEST */
199};
200
201/* static helper functions... */
202static void QS_rxParseData_(uint8_t b);
203static void QS_rxHandleGoodFrame_(uint8_t state);
204static void QS_rxHandleBadFrame_(uint8_t state);
205static void QS_rxReportAck_(int8_t recId);
206static void QS_rxReportError_(int8_t code);
207static void QS_rxReportDone_(int8_t recId);
208static void QS_rxPoke_(void);
209
211#define QS_RX_TRAN_(target_) (l_rx.state = (uint8_t)(target_))
212
215/*==========================================================================*/
236void QS_rxInitBuf(uint8_t sto[], uint16_t stoSize) {
237 QS_rxPriv_.buf = &sto[0];
238 QS_rxPriv_.end = (QSCtr)stoSize;
239 QS_rxPriv_.head = 0U;
240 QS_rxPriv_.tail = 0U;
241
242 QS_rxPriv_.currObj[SM_OBJ] = (void *)0;
243 QS_rxPriv_.currObj[AO_OBJ] = (void *)0;
244 QS_rxPriv_.currObj[MP_OBJ] = (void *)0;
245 QS_rxPriv_.currObj[EQ_OBJ] = (void *)0;
246 QS_rxPriv_.currObj[TE_OBJ] = (void *)0;
247 QS_rxPriv_.currObj[AP_OBJ] = (void *)0;
248
249 QS_RX_TRAN_(WAIT4_SEQ);
250 l_rx.esc = 0U;
251 l_rx.seq = 0U;
252 l_rx.chksum = 0U;
253
254 QS_beginRec_((uint_fast8_t)QS_OBJ_DICT);
256 QS_STR_PRE_("QS_RX");
257 QS_endRec_();
258 /* no QS_REC_DONE(), because QS is not running yet */
259
260#ifdef Q_UTEST
261 l_testData.tpNum = 0U;
262 l_testData.testTime = 0U;
263#endif /* Q_UTEST */
264}
265
266/*==========================================================================*/
268bool QS_RX_PUT(uint8_t const b) {
269 QSCtr head = QS_rxPriv_.head + 1U;
270 if (head == QS_rxPriv_.end) {
271 head = 0U;
272 }
273 if (head != QS_rxPriv_.tail) { /* buffer NOT full? */
275 QS_rxPriv_.head = head; /* update the head to a *valid* index */
276 return true; /* byte placed in the buffer */
277 }
278 else {
279 return false; /* byte NOT placed in the buffer */
280 }
281}
282
283/*==========================================================================*/
292uint16_t QS_rxGetNfree(void) {
293 QSCtr const head = QS_rxPriv_.head;
294 if (head == QS_rxPriv_.tail) { /* buffer empty? */
295 return (uint16_t)(QS_rxPriv_.end - 1U);
296 }
297 else if (head < QS_rxPriv_.tail) {
298 return (uint16_t)(QS_rxPriv_.tail - (head + 1U));
299 }
300 else {
301 return (uint16_t)(QS_rxPriv_.end + QS_rxPriv_.tail - (head + 1U));
302 }
303}
304
305/*==========================================================================*/
310void QS_setCurrObj(uint8_t obj_kind, void *obj_ptr) {
311 Q_REQUIRE_ID(100, obj_kind < Q_DIM(QS_rxPriv_.currObj));
312 QS_rxPriv_.currObj[obj_kind] = obj_ptr;
313}
314
315/*==========================================================================*/
321void QS_queryCurrObj(uint8_t obj_kind) {
322 if (QS_rxPriv_.currObj[obj_kind] != (void *)0) {
324 QS_CRIT_E_();
325 QS_beginRec_((uint_fast8_t)QS_QUERY_DATA);
326 QS_TIME_PRE_(); /* timestamp */
327 QS_U8_PRE_(obj_kind); /* object kind */
328 QS_OBJ_PRE_(QS_rxPriv_.currObj[obj_kind]);
329 switch (obj_kind) {
330 case SM_OBJ: /* intentionally fall through */
331 case AO_OBJ:
332 QS_FUN_PRE_((*((QHsm *)QS_rxPriv_.currObj[obj_kind])->vptr
333 ->getStateHandler)(
334 ((QHsm *)QS_rxPriv_.currObj[obj_kind])));
335 break;
336 case MP_OBJ:
337 QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind])
338 ->nFree);
339 QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind])
340 ->nMin);
341 break;
342 case EQ_OBJ:
344 ->nFree);
346 ->nMin);
347 break;
348 case TE_OBJ:
350 ->act);
352 ->ctr);
354 ->interval);
356 ->super.sig);
357 QS_U8_PRE_ (((QTimeEvt *)QS_rxPriv_.currObj[obj_kind])
358 ->super.refCtr_);
359 break;
360 default:
361 /* intentionally empty */
362 break;
363 }
364 QS_endRec_();
365 QS_CRIT_X_();
366
367 QS_REC_DONE(); /* user callback (if defined) */
368 }
369 else {
371 }
372}
373
374/*==========================================================================*/
375void QS_rxParse(void) {
376 QSCtr tail = QS_rxPriv_.tail;
377 while (QS_rxPriv_.head != tail) { /* QS-RX buffer NOT empty? */
378 uint8_t b = QS_rxPriv_.buf[tail];
379
380 ++tail;
381 if (tail == QS_rxPriv_.end) {
382 tail = 0U;
383 }
384 QS_rxPriv_.tail = tail; /* update the tail to a *valid* index */
385
386 if (l_rx.esc != 0U) { /* escaped byte arrived? */
387 l_rx.esc = 0U;
388 b ^= QS_ESC_XOR;
389
390 l_rx.chksum += b;
392 }
393 else if (b == QS_ESC) {
394 l_rx.esc = 1U;
395 }
396 else if (b == QS_FRAME) {
397 /* get ready for the next frame */
398 b = l_rx.state; /* save the current state in b */
399 l_rx.esc = 0U;
400 QS_RX_TRAN_(WAIT4_SEQ);
401
402 if (l_rx.chksum == QS_GOOD_CHKSUM) {
403 l_rx.chksum = 0U;
405 }
406 else { /* bad checksum */
407 l_rx.chksum = 0U;
408 QS_rxReportError_(0x41);
410 }
411 }
412 else {
413 l_rx.chksum += b;
415 }
416 }
417}
418
419/*==========================================================================*/
420static void QS_rxParseData_(uint8_t b) {
421 switch (l_rx.state) {
422 case WAIT4_SEQ: {
423 ++l_rx.seq;
424 if (l_rx.seq != b) {
425 QS_rxReportError_(0x42);
426 l_rx.seq = b; /* update the sequence */
427 }
428 QS_RX_TRAN_(WAIT4_REC);
429 break;
430 }
431 case WAIT4_REC: {
432 switch (b) {
433 case QS_RX_INFO:
434 QS_RX_TRAN_(WAIT4_INFO_FRAME);
435 break;
436 case QS_RX_COMMAND:
437 QS_RX_TRAN_(WAIT4_CMD_ID);
438 break;
439 case QS_RX_RESET:
440 QS_RX_TRAN_(WAIT4_RESET_FRAME);
441 break;
442 case QS_RX_TICK:
443 QS_RX_TRAN_(WAIT4_TICK_RATE);
444 break;
445 case QS_RX_PEEK:
446 if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) {
447 l_rx.var.peek.offs = 0U;
448 l_rx.var.peek.idx = 0U;
449 QS_RX_TRAN_(WAIT4_PEEK_OFFS);
450 }
451 else {
453 QS_RX_TRAN_(ERROR_STATE);
454 }
455 break;
456 case QS_RX_POKE: /* intentionally fall-through */
457 case QS_RX_FILL:
458 l_rx.var.poke.fill =
459 ((b == (uint8_t)QS_RX_FILL) ? 1U : 0U);
460 if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) {
461 l_rx.var.poke.offs = 0U;
462 l_rx.var.poke.idx = 0U;
463 QS_RX_TRAN_(WAIT4_POKE_OFFS);
464 }
465 else {
466 QS_rxReportError_((l_rx.var.poke.fill != 0U)
467 ? (int8_t)QS_RX_FILL
468 : (int8_t)QS_RX_POKE);
469 QS_RX_TRAN_(ERROR_STATE);
470 }
471 break;
472 case QS_RX_GLB_FILTER: /* intentionally fall-through */
473 case QS_RX_LOC_FILTER:
474 l_rx.var.flt.recId = (int8_t)b;
475 QS_RX_TRAN_(WAIT4_FILTER_LEN);
476 break;
477 case QS_RX_AO_FILTER: /* intentionally fall-through */
478 case QS_RX_CURR_OBJ:
479 l_rx.var.obj.recId = (int8_t)b;
480 QS_RX_TRAN_(WAIT4_OBJ_KIND);
481 break;
482 case QS_RX_QUERY_CURR:
483 l_rx.var.obj.recId = (int8_t)QS_RX_QUERY_CURR;
484 QS_RX_TRAN_(WAIT4_QUERY_KIND);
485 break;
486 case QS_RX_EVENT:
487 QS_RX_TRAN_(WAIT4_EVT_PRIO);
488 break;
489
490#ifdef Q_UTEST
491 case QS_RX_TEST_SETUP:
492 QS_RX_TRAN_(WAIT4_TEST_SETUP_FRAME);
493 break;
495 QS_RX_TRAN_(WAIT4_TEST_TEARDOWN_FRAME);
496 break;
498 QS_RX_TRAN_(WAIT4_TEST_CONTINUE_FRAME);
499 break;
500 case QS_RX_TEST_PROBE:
501 if (l_testData.tpNum
502 < (uint8_t)(sizeof(l_testData.tpBuf)
503 / sizeof(l_testData.tpBuf[0])))
504 {
505 l_rx.var.tp.data = 0U;
506 l_rx.var.tp.idx = 0U;
507 QS_RX_TRAN_(WAIT4_TEST_PROBE_DATA);
508 }
509 else { /* the number of Test-Probes exceeded */
511 QS_RX_TRAN_(ERROR_STATE);
512 }
513 break;
514#endif /* Q_UTEST */
515
516 default:
517 QS_rxReportError_(0x43);
518 QS_RX_TRAN_(ERROR_STATE);
519 break;
520 }
521 break;
522 }
523 case WAIT4_INFO_FRAME: {
524 /* keep ignoring the data until a frame is collected */
525 break;
526 }
527 case WAIT4_CMD_ID: {
528 l_rx.var.cmd.cmdId = b;
529 l_rx.var.cmd.idx = 0U;
530 l_rx.var.cmd.param1 = 0U;
531 l_rx.var.cmd.param2 = 0U;
532 l_rx.var.cmd.param3 = 0U;
533 QS_RX_TRAN_(WAIT4_CMD_PARAM1);
534 break;
535 }
536 case WAIT4_CMD_PARAM1: {
537 l_rx.var.cmd.param1 |= ((uint32_t)b << l_rx.var.cmd.idx);
538 l_rx.var.cmd.idx += 8U;
539 if (l_rx.var.cmd.idx == (8U * 4U)) {
540 l_rx.var.cmd.idx = 0U;
541 QS_RX_TRAN_(WAIT4_CMD_PARAM2);
542 }
543 break;
544 }
545 case WAIT4_CMD_PARAM2: {
546 l_rx.var.cmd.param2 |= ((uint32_t)b << l_rx.var.cmd.idx);
547 l_rx.var.cmd.idx += 8U;
548 if (l_rx.var.cmd.idx == (8U * 4U)) {
549 l_rx.var.cmd.idx = 0U;
550 QS_RX_TRAN_(WAIT4_CMD_PARAM3);
551 }
552 break;
553 }
554 case WAIT4_CMD_PARAM3: {
555 l_rx.var.cmd.param3 |= ((uint32_t)b << l_rx.var.cmd.idx);
556 l_rx.var.cmd.idx += 8U;
557 if (l_rx.var.cmd.idx == (8U * 4U)) {
558 l_rx.var.cmd.idx = 0U;
559 QS_RX_TRAN_(WAIT4_CMD_FRAME);
560 }
561 break;
562 }
563 case WAIT4_CMD_FRAME: {
564 /* keep ignoring the data until a frame is collected */
565 break;
566 }
567 case WAIT4_RESET_FRAME: {
568 /* keep ignoring the data until a frame is collected */
569 break;
570 }
571 case WAIT4_TICK_RATE: {
572 l_rx.var.tick.rate = (uint_fast8_t)b;
573 QS_RX_TRAN_(WAIT4_TICK_FRAME);
574 break;
575 }
576 case WAIT4_TICK_FRAME: {
577 /* keep ignoring the data until a frame is collected */
578 break;
579 }
580 case WAIT4_PEEK_OFFS: {
581 if (l_rx.var.peek.idx == 0U) {
582 l_rx.var.peek.offs = (uint16_t)b;
583 l_rx.var.peek.idx += 8U;
584 }
585 else {
586 l_rx.var.peek.offs |= (uint16_t)((uint16_t)b << 8U);
587 QS_RX_TRAN_(WAIT4_PEEK_SIZE);
588 }
589 break;
590 }
591 case WAIT4_PEEK_SIZE: {
592 if ((b == 1U) || (b == 2U) || (b == 4U)) {
593 l_rx.var.peek.size = b;
594 QS_RX_TRAN_(WAIT4_PEEK_NUM);
595 }
596 else {
598 QS_RX_TRAN_(ERROR_STATE);
599 }
600 break;
601 }
602 case WAIT4_PEEK_NUM: {
603 l_rx.var.peek.num = b;
604 QS_RX_TRAN_(WAIT4_PEEK_FRAME);
605 break;
606 }
607 case WAIT4_PEEK_FRAME: {
608 /* keep ignoring the data until a frame is collected */
609 break;
610 }
611 case WAIT4_POKE_OFFS: {
612 if (l_rx.var.poke.idx == 0U) {
613 l_rx.var.poke.offs = (uint16_t)b;
614 l_rx.var.poke.idx = 1U;
615 }
616 else {
617 l_rx.var.poke.offs |= (uint16_t)((uint16_t)b << 8U);
618 QS_RX_TRAN_(WAIT4_POKE_SIZE);
619 }
620 break;
621 }
622 case WAIT4_POKE_SIZE: {
623 if ((b == 1U) || (b == 2U) || (b == 4U)) {
624 l_rx.var.poke.size = b;
625 QS_RX_TRAN_(WAIT4_POKE_NUM);
626 }
627 else {
628 QS_rxReportError_((l_rx.var.poke.fill != 0U)
629 ? (int8_t)QS_RX_FILL
630 : (int8_t)QS_RX_POKE);
631 QS_RX_TRAN_(ERROR_STATE);
632 }
633 break;
634 }
635 case WAIT4_POKE_NUM: {
636 if (b > 0U) {
637 l_rx.var.poke.num = b;
638 l_rx.var.poke.data = 0U;
639 l_rx.var.poke.idx = 0U;
640 QS_RX_TRAN_((l_rx.var.poke.fill != 0U)
641 ? WAIT4_FILL_DATA
642 : WAIT4_POKE_DATA);
643 }
644 else {
645 QS_rxReportError_((l_rx.var.poke.fill != 0U)
646 ? (int8_t)QS_RX_FILL
647 : (int8_t)QS_RX_POKE);
648 QS_RX_TRAN_(ERROR_STATE);
649 }
650 break;
651 }
652 case WAIT4_FILL_DATA: {
653 l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx);
654 l_rx.var.poke.idx += 8U;
655 if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) {
656 QS_RX_TRAN_(WAIT4_FILL_FRAME);
657 }
658 break;
659 }
660 case WAIT4_POKE_DATA: {
661 l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx);
662 l_rx.var.poke.idx += 8U;
663 if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) {
664 QS_rxPoke_();
665 --l_rx.var.poke.num;
666 if (l_rx.var.poke.num == 0U) {
667 QS_RX_TRAN_(WAIT4_POKE_FRAME);
668 }
669 }
670 break;
671 }
672 case WAIT4_FILL_FRAME: {
673 /* keep ignoring the data until a frame is collected */
674 break;
675 }
676 case WAIT4_POKE_FRAME: {
677 /* keep ignoring the data until a frame is collected */
678 break;
679 }
680 case WAIT4_FILTER_LEN: {
681 if (b == sizeof(l_rx.var.flt.data)) {
682 l_rx.var.flt.idx = 0U;
683 QS_RX_TRAN_(WAIT4_FILTER_DATA);
684 }
685 else {
686 QS_rxReportError_(l_rx.var.flt.recId);
687 QS_RX_TRAN_(ERROR_STATE);
688 }
689 break;
690 }
691 case WAIT4_FILTER_DATA: {
692 l_rx.var.flt.data[l_rx.var.flt.idx] = b;
693 ++l_rx.var.flt.idx;
694 if (l_rx.var.flt.idx == sizeof(l_rx.var.flt.data)) {
695 QS_RX_TRAN_(WAIT4_FILTER_FRAME);
696 }
697 break;
698 }
699 case WAIT4_FILTER_FRAME: {
700 /* keep ignoring the data until a frame is collected */
701 break;
702 }
703 case WAIT4_OBJ_KIND: {
704 if (b <= (uint8_t)SM_AO_OBJ) {
705 l_rx.var.obj.kind = b;
706 l_rx.var.obj.addr = 0U;
707 l_rx.var.obj.idx = 0U;
708 QS_RX_TRAN_(WAIT4_OBJ_ADDR);
709 }
710 else {
711 QS_rxReportError_(l_rx.var.obj.recId);
712 QS_RX_TRAN_(ERROR_STATE);
713 }
714 break;
715 }
716 case WAIT4_OBJ_ADDR: {
717 l_rx.var.obj.addr |= ((QSObj)b << l_rx.var.obj.idx);
718 l_rx.var.obj.idx += 8U;
719 if (l_rx.var.obj.idx == (uint8_t)(8U * QS_OBJ_PTR_SIZE)) {
720 QS_RX_TRAN_(WAIT4_OBJ_FRAME);
721 }
722 break;
723 }
724 case WAIT4_OBJ_FRAME: {
725 /* keep ignoring the data until a frame is collected */
726 break;
727 }
728 case WAIT4_QUERY_KIND: {
729 if (b < (uint8_t)MAX_OBJ) {
730 l_rx.var.obj.kind = b;
731 QS_RX_TRAN_(WAIT4_QUERY_FRAME);
732 }
733 else {
734 QS_rxReportError_(l_rx.var.obj.recId);
735 QS_RX_TRAN_(ERROR_STATE);
736 }
737 break;
738 }
739 case WAIT4_QUERY_FRAME: {
740 /* keep ignoring the data until a frame is collected */
741 break;
742 }
743 case WAIT4_EVT_PRIO: {
744 l_rx.var.evt.prio = b;
745 l_rx.var.evt.sig = 0U;
746 l_rx.var.evt.idx = 0U;
747 QS_RX_TRAN_(WAIT4_EVT_SIG);
748 break;
749 }
750 case WAIT4_EVT_SIG: {
751 l_rx.var.evt.sig |= (QSignal)((uint32_t)b << l_rx.var.evt.idx);
752 l_rx.var.evt.idx += 8U;
753 if (l_rx.var.evt.idx == (uint8_t)(8U * Q_SIGNAL_SIZE)) {
754 l_rx.var.evt.len = 0U;
755 l_rx.var.evt.idx = 0U;
756 QS_RX_TRAN_(WAIT4_EVT_LEN);
757 }
758 break;
759 }
760 case WAIT4_EVT_LEN: {
761 l_rx.var.evt.len |= (uint16_t)((uint32_t)b << l_rx.var.evt.idx);
762 l_rx.var.evt.idx += 8U;
763 if (l_rx.var.evt.idx == (8U * 2U)) {
764 if ((l_rx.var.evt.len + sizeof(QEvt)) <=
766 {
767 /* report Ack before generating any other QS records */
769
770 l_rx.var.evt.e = QF_newX_(
771 ((uint_fast16_t)l_rx.var.evt.len + sizeof(QEvt)),
772 0U, /* margin */
773 (enum_t)l_rx.var.evt.sig);
774 if (l_rx.var.evt.e != (QEvt *)0) { /* evt allocated? */
775 l_rx.var.evt.p = (uint8_t *)l_rx.var.evt.e;
776 l_rx.var.evt.p = &l_rx.var.evt.p[sizeof(QEvt)];
777 if (l_rx.var.evt.len > 0U) {
778 QS_RX_TRAN_(WAIT4_EVT_PAR);
779 }
780 else {
781 QS_RX_TRAN_(WAIT4_EVT_FRAME);
782 }
783 }
784 else {
786 QS_RX_TRAN_(ERROR_STATE);
787 }
788 }
789 else {
791 QS_RX_TRAN_(ERROR_STATE);
792 }
793 }
794 break;
795 }
796 case WAIT4_EVT_PAR: { /* event parameters */
797 *l_rx.var.evt.p = b;
798 ++l_rx.var.evt.p;
799 --l_rx.var.evt.len;
800 if (l_rx.var.evt.len == 0U) {
801 QS_RX_TRAN_(WAIT4_EVT_FRAME);
802 }
803 break;
804 }
805 case WAIT4_EVT_FRAME: {
806 /* keep ignoring the data until a frame is collected */
807 break;
808 }
809
810#ifdef Q_UTEST
811 case WAIT4_TEST_SETUP_FRAME: {
812 /* keep ignoring the data until a frame is collected */
813 break;
814 }
815 case WAIT4_TEST_TEARDOWN_FRAME: {
816 /* keep ignoring the data until a frame is collected */
817 break;
818 }
819 case WAIT4_TEST_CONTINUE_FRAME: {
820 /* keep ignoring the data until a frame is collected */
821 break;
822 }
823 case WAIT4_TEST_PROBE_DATA: {
824 l_rx.var.tp.data |= ((uint32_t)b << l_rx.var.tp.idx);
825 l_rx.var.tp.idx += 8U;
826 if (l_rx.var.tp.idx == (uint8_t)(8U * sizeof(uint32_t))) {
827 l_rx.var.tp.addr = 0U;
828 l_rx.var.tp.idx = 0U;
829 QS_RX_TRAN_(WAIT4_TEST_PROBE_ADDR);
830 }
831 break;
832 }
833 case WAIT4_TEST_PROBE_ADDR: {
834 l_rx.var.tp.addr |= ((QSFun)b << l_rx.var.tp.idx);
835 l_rx.var.tp.idx += 8U;
836 if (l_rx.var.tp.idx == (uint8_t)(8U * QS_FUN_PTR_SIZE)) {
837 QS_RX_TRAN_(WAIT4_TEST_PROBE_FRAME);
838 }
839 break;
840 }
841 case WAIT4_TEST_PROBE_FRAME: {
842 /* keep ignoring the data until a frame is collected */
843 break;
844 }
845#endif /* Q_UTEST */
846
847 case ERROR_STATE: {
848 /* keep ignoring the data until a good frame is collected */
849 break;
850 }
851 default: { /* unexpected or unimplemented state */
852 QS_rxReportError_(0x45);
853 QS_RX_TRAN_(ERROR_STATE);
854 break;
855 }
856 }
857}
858
859/*==========================================================================*/
860static void QS_rxHandleGoodFrame_(uint8_t state) {
861 uint8_t i;
862 uint8_t *ptr;
864
865 switch (state) {
866 case WAIT4_INFO_FRAME: {
867 /* no need to report Ack or Done */
868 QS_CRIT_E_();
869 QS_target_info_pre_(0U); /* send only Target info */
870 QS_CRIT_X_();
871 break;
872 }
873 case WAIT4_RESET_FRAME: {
874 /* no need to report Ack or Done, because Target resets */
875 QS_onReset(); /* reset the Target */
876 break;
877 }
878 case WAIT4_CMD_PARAM1: /* intentionally fall-through */
879 case WAIT4_CMD_PARAM2: /* intentionally fall-through */
880 case WAIT4_CMD_PARAM3: /* intentionally fall-through */
881 case WAIT4_CMD_FRAME: {
883 QS_onCommand(l_rx.var.cmd.cmdId, l_rx.var.cmd.param1,
884 l_rx.var.cmd.param2, l_rx.var.cmd.param3);
885#ifdef Q_UTEST
886 QS_processTestEvts_(); /* process all events produced */
887#endif
889 break;
890 }
891 case WAIT4_TICK_FRAME: {
893#ifdef Q_UTEST
894 QS_tickX_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_);
895 QS_processTestEvts_(); /* process all events produced */
896#else
897 QF_tickX_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_);
898#endif
900 break;
901 }
902 case WAIT4_PEEK_FRAME: {
903
904 /* no need to report Ack or Done */
905 QS_CRIT_E_();
906 QS_beginRec_((uint_fast8_t)QS_PEEK_DATA);
907 ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ];
908 ptr = &ptr[l_rx.var.peek.offs];
909 QS_TIME_PRE_(); /* timestamp */
910 QS_U16_PRE_(l_rx.var.peek.offs); /* data offset */
911 QS_U8_PRE_(l_rx.var.peek.size); /* data size */
912 QS_U8_PRE_(l_rx.var.peek.num); /* number of data items */
913 for (i = 0U; i < l_rx.var.peek.num; ++i) {
914 switch (l_rx.var.peek.size) {
915 case 1:
916 QS_U8_PRE_(ptr[i]);
917 break;
918 case 2:
919 QS_U16_PRE_(((uint16_t *)ptr)[i]);
920 break;
921 case 4:
922 QS_U32_PRE_(((uint32_t *)ptr)[i]);
923 break;
924 default:
925 /* intentionally empty */
926 break;
927 }
928 }
929 QS_endRec_();
930 QS_CRIT_X_();
931
932 QS_REC_DONE(); /* user callback (if defined) */
933 break;
934 }
935 case WAIT4_POKE_DATA: {
936 /* received less than expected poke data items */
938 break;
939 }
940 case WAIT4_POKE_FRAME: {
942 /* no need to report done */
943 break;
944 }
945 case WAIT4_FILL_FRAME: {
947 ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ];
948 ptr = &ptr[l_rx.var.poke.offs];
949 for (i = 0U; i < l_rx.var.poke.num; ++i) {
950 switch (l_rx.var.poke.size) {
951 case 1:
952 ptr[i] = (uint8_t)l_rx.var.poke.data;
953 break;
954 case 2:
955 ((uint16_t *)ptr)[i]
956 = (uint16_t)l_rx.var.poke.data;
957 break;
958 case 4:
959 ((uint32_t *)ptr)[i] = l_rx.var.poke.data;
960 break;
961 default:
962 /* intentionally empty */
963 break;
964 }
965 }
966 break;
967 }
968 case WAIT4_FILTER_FRAME: {
969 QS_rxReportAck_(l_rx.var.flt.recId);
970
971 /* apply the received filters */
972 if (l_rx.var.flt.recId == (int8_t)QS_RX_GLB_FILTER) {
973 for (i = 0U; i < Q_DIM(QS_priv_.glbFilter); ++i) {
974 QS_priv_.glbFilter[i] = l_rx.var.flt.data[i];
975 }
976 /* leave the "not maskable" filters enabled,
977 * see qs.h, Miscellaneous QS records (not maskable)
978 */
979 QS_priv_.glbFilter[0] |= 0x01U;
980 QS_priv_.glbFilter[7] |= 0xFCU;
981 QS_priv_.glbFilter[8] |= 0x7FU;
982
983 /* never enable the last 3 records (0x7D, 0x7E, 0x7F) */
984 QS_priv_.glbFilter[15] &= 0x1FU;
985 }
986 else if (l_rx.var.flt.recId == (int8_t)QS_RX_LOC_FILTER) {
987 for (i = 0U; i < Q_DIM(QS_priv_.locFilter); ++i) {
988 QS_priv_.locFilter[i] = l_rx.var.flt.data[i];
989 }
990 /* leave QS_ID == 0 always on */
991 QS_priv_.locFilter[0] |= 0x01U;
992 }
993 else {
994 QS_rxReportError_(l_rx.var.flt.recId);
995 }
996 /* no need to report Done */
997 break;
998 }
999 case WAIT4_OBJ_FRAME: {
1000 i = l_rx.var.obj.kind;
1001 if (i < (uint8_t)MAX_OBJ) {
1002 if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) {
1003 QS_rxPriv_.currObj[i] = (void *)l_rx.var.obj.addr;
1005 }
1006 else if (l_rx.var.obj.recId == (int8_t)QS_RX_AO_FILTER) {
1007 if (l_rx.var.obj.addr != 0U) {
1008 int_fast16_t const filter =
1009 (int_fast16_t)((QActive *)l_rx.var.obj.addr)->prio;
1010 QS_locFilter_((i == 0U)
1011 ? filter
1012 :-filter);
1014 }
1015 else {
1017 }
1018 }
1019 else {
1020 QS_rxReportError_(l_rx.var.obj.recId);
1021 }
1022 }
1023 /* both SM and AO */
1024 else if (i == (uint8_t)SM_AO_OBJ) {
1025 if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) {
1026 QS_rxPriv_.currObj[SM_OBJ] = (void *)l_rx.var.obj.addr;
1027 QS_rxPriv_.currObj[AO_OBJ] = (void *)l_rx.var.obj.addr;
1028 }
1029 QS_rxReportAck_(l_rx.var.obj.recId);
1030 }
1031 else {
1032 QS_rxReportError_(l_rx.var.obj.recId);
1033 }
1034 break;
1035 }
1036 case WAIT4_QUERY_FRAME: {
1037 QS_queryCurrObj(l_rx.var.obj.kind);
1038 break;
1039 }
1040 case WAIT4_EVT_FRAME: {
1041 /* NOTE: Ack was already reported in the WAIT4_EVT_LEN state */
1042#ifdef Q_UTEST
1043 QS_onTestEvt(l_rx.var.evt.e); /* adjust the event, if needed */
1044#endif /* Q_UTEST */
1045 i = 0U; /* use 'i' as status, 0 == success,no-recycle */
1046
1047 if (l_rx.var.evt.prio == 0U) { /* publish */
1048 QF_publish_(l_rx.var.evt.e, &QS_rxPriv_, 0U);
1049 }
1050 else if (l_rx.var.evt.prio < QF_MAX_ACTIVE) {
1051 if (!QACTIVE_POST_X(QF_active_[l_rx.var.evt.prio],
1052 l_rx.var.evt.e,
1053 0U, /* margin */
1054 &QS_rxPriv_))
1055 {
1056 /* failed QACTIVE_POST() recycles the event */
1057 i = 0x80U; /* failure status, no recycle */
1058 }
1059 }
1060 else if (l_rx.var.evt.prio == 255U) { /* special prio */
1061 /* dispatch to the current SM object */
1062 if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) {
1063 /* increment the ref-ctr to simulate the situation
1064 * when the event is just retreived from a queue.
1065 * This is expected for the following QF_gc() call.
1066 */
1067 ++l_rx.var.evt.e->refCtr_;
1068
1070 l_rx.var.evt.e, 0U);
1071 i = 0x01U; /* success status, recycle needed */
1072 }
1073 else {
1074 i = 0x81U; /* failure status, recycle needed */
1075 }
1076 }
1077 else if (l_rx.var.evt.prio == 254U) { /* special prio */
1078 /* init the current SM object" */
1079 if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) {
1080 /* increment the ref-ctr to simulate the situation
1081 * when the event is just retreived from a queue.
1082 * This is expected for the following QF_gc() call.
1083 */
1084 ++l_rx.var.evt.e->refCtr_;
1085
1087 l_rx.var.evt.e, 0U);
1088 i = 0x01U; /* success status, recycle needed */
1089 }
1090 else {
1091 i = 0x81U; /* failure status, recycle needed */
1092 }
1093 }
1094 else if (l_rx.var.evt.prio == 253U) { /* special prio */
1095 /* post to the current AO */
1096 if (QS_rxPriv_.currObj[AO_OBJ] != (void *)0) {
1097 if (!QACTIVE_POST_X(
1099 l_rx.var.evt.e,
1100 0U, /* margin */
1101 &QS_rxPriv_))
1102 {
1103 /* failed QACTIVE_POST() recycles the event */
1104 i = 0x80U; /* failure status, no recycle */
1105 }
1106 }
1107 else {
1108 i = 0x81U; /* failure status, recycle needed */
1109 }
1110 }
1111 else {
1112 i = 0x81U; /* failure status, recycle needed */
1113 }
1114
1115 if ((i & 0x01U) != 0U) { /* recycle needed? */
1116 QF_gc(l_rx.var.evt.e);
1117 }
1118
1119 if ((i & 0x80U) != 0U) { /* failure? */
1121 }
1122 else {
1123#ifdef Q_UTEST
1124 QS_processTestEvts_(); /* process all events produced */
1125#endif
1127 }
1128 break;
1129 }
1130
1131#ifdef Q_UTEST
1132 case WAIT4_TEST_SETUP_FRAME: {
1134 l_testData.tpNum = 0U; /* clear the Test-Probes */
1135 l_testData.testTime = 0U; /* clear the time tick */
1136 /* don't clear current objects */
1137 QS_onTestSetup(); /* application-specific test setup */
1138 /* no need to report Done */
1139 break;
1140 }
1141 case WAIT4_TEST_TEARDOWN_FRAME: {
1143 QS_onTestTeardown(); /* application-specific test teardown */
1144 /* no need to report Done */
1145 break;
1146 }
1147 case WAIT4_TEST_CONTINUE_FRAME: {
1149 QS_rxPriv_.inTestLoop = false; /* exit the QUTest loop */
1150 /* no need to report Done */
1151 break;
1152 }
1153 case WAIT4_TEST_PROBE_FRAME: {
1155 Q_ASSERT_ID(815, l_testData.tpNum
1156 < (sizeof(l_testData.tpBuf) / sizeof(l_testData.tpBuf[0])));
1157 l_testData.tpBuf[l_testData.tpNum] = l_rx.var.tp;
1158 ++l_testData.tpNum;
1159 /* no need to report Done */
1160 break;
1161 }
1162#endif /* Q_UTEST */
1163
1164 case ERROR_STATE: {
1165 /* keep ignoring all bytes until new frame */
1166 break;
1167 }
1168 default: {
1169 QS_rxReportError_(0x47);
1170 break;
1171 }
1172 }
1173}
1174
1175/*==========================================================================*/
1176static void QS_rxHandleBadFrame_(uint8_t state) {
1177 QS_rxReportError_(0x50); /* report error for all bad frames */
1178 switch (state) {
1179 case WAIT4_EVT_FRAME: {
1180 Q_ASSERT_ID(910, l_rx.var.evt.e != (QEvt *)0);
1181 QF_gc(l_rx.var.evt.e); /* don't leak an allocated event */
1182 break;
1183 }
1184 default: {
1185 /* intentionally empty */
1186 break;
1187 }
1188 }
1189}
1190
1191/*==========================================================================*/
1192static void QS_rxReportAck_(int8_t recId) {
1194 QS_CRIT_E_();
1195 QS_beginRec_((uint_fast8_t)QS_RX_STATUS);
1196 QS_U8_PRE_(recId); /* record ID */
1197 QS_endRec_();
1198 QS_CRIT_X_();
1199
1200 QS_REC_DONE(); /* user callback (if defined) */
1201}
1202
1203/*==========================================================================*/
1204static void QS_rxReportError_(int8_t code) {
1206 QS_CRIT_E_();
1207 QS_beginRec_((uint_fast8_t)QS_RX_STATUS);
1208 QS_U8_PRE_(0x80U | (uint8_t)code); /* error code */
1209 QS_endRec_();
1210 QS_CRIT_X_();
1211
1212 QS_REC_DONE(); /* user callback (if defined) */
1213}
1214
1215/*==========================================================================*/
1216static void QS_rxReportDone_(int8_t recId) {
1218 QS_CRIT_E_();
1219 QS_beginRec_((uint_fast8_t)QS_TARGET_DONE);
1220 QS_TIME_PRE_(); /* timestamp */
1221 QS_U8_PRE_(recId); /* record ID */
1222 QS_endRec_();
1223 QS_CRIT_X_();
1224
1225 QS_REC_DONE(); /* user callback (if defined) */
1226}
1227
1228/*==========================================================================*/
1229static void QS_rxPoke_(void) {
1230 uint8_t *ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ];
1231 ptr = &ptr[l_rx.var.poke.offs];
1232 switch (l_rx.var.poke.size) {
1233 case 1:
1234 *ptr = (uint8_t)l_rx.var.poke.data;
1235 break;
1236 case 2:
1237 *(uint16_t *)ptr = (uint16_t)l_rx.var.poke.data;
1238 break;
1239 case 4:
1240 *(uint32_t *)ptr = l_rx.var.poke.data;
1241 break;
1242 default:
1243 Q_ERROR_ID(900);
1244 break;
1245 }
1246
1247 l_rx.var.poke.data = 0U;
1248 l_rx.var.poke.idx = 0U;
1249 l_rx.var.poke.offs += (uint16_t)l_rx.var.poke.size;
1250}
1251
1252/*==========================================================================*/
1253#ifdef Q_UTEST
1254
1255/*==========================================================================*/
1268uint32_t QS_getTestProbe_(void (* const api)(void)) {
1269 uint32_t data = 0U;
1270 uint_fast8_t i;
1271 for (i = 0U; i < l_testData.tpNum; ++i) {
1272 uint_fast8_t j;
1273
1274 if (l_testData.tpBuf[i].addr == (QSFun)api) {
1276
1277 data = l_testData.tpBuf[i].data;
1278
1279 QS_CRIT_E_();
1280 QS_beginRec_((uint_fast8_t)QS_TEST_PROBE_GET);
1281 QS_TIME_PRE_(); /* timestamp */
1282 QS_FUN_PRE_(api); /* the calling API */
1283 QS_U32_PRE_(data); /* the Test-Probe data */
1284 QS_endRec_();
1285 QS_CRIT_X_();
1286
1287 QS_REC_DONE(); /* user callback (if defined) */
1288
1289 --l_testData.tpNum; /* one less Test-Probe */
1290 /* move all remaining entries in the buffer up by one */
1291 for (j = i; j < l_testData.tpNum; ++j) {
1292 l_testData.tpBuf[j] = l_testData.tpBuf[j + 1U];
1293 }
1294 break; /* we are done (Test-Probe retreived) */
1295 }
1296 }
1297 return data;
1298}
1299
1300/*==========================================================================*/
1302 return (++l_testData.testTime);
1303}
1304
1305#endif /* Q_UTEST */
Customizable and memory-efficient assertions for embedded systems.
#define Q_DEFINE_THIS_MODULE(name_)
Definition: qassert.h:102
#define Q_ASSERT_ID(id_, test_)
Definition: qassert.h:135
#define Q_REQUIRE_ID(id_, test_)
Definition: qassert.h:252
#define Q_DIM(array_)
Definition: qassert.h:307
#define Q_ERROR_ID(id_)
Definition: qassert.h:187
#define QHSM_INIT(me_, par_, qs_id_)
Definition: qep.h:296
#define QHSM_DISPATCH(me_, e_, qs_id_)
Definition: qep.h:330
uint16_t QSignal
Definition: qep.h:97
signed int enum_t
Definition: qep.h:60
#define Q_SIGNAL_SIZE
Definition: qep.h:83
#define QACTIVE_POST_X(me_, e_, margin_, sender_)
Definition: qf.h:275
QSPrivAttr QS_priv_
Definition: qs.c:41
@ SM_AO_OBJ
Definition: qs.h:906
#define QS_CRIT_STAT_
Definition: qs.h:509
#define QS_TIME_PRE_()
Definition: qs.h:220
#define QS_REC_DONE()
Definition: qs.h:559
void QS_onTestSetup(void)
#define QS_CRIT_X_()
Definition: qs.h:531
#define QS_CRIT_E_()
Definition: qs.h:520
uint8_t glbFilter[16]
Definition: qs.h:911
uint8_t QSTimeCtr
Definition: qs.h:219
@ SM_OBJ
Definition: qs.h:896
@ EQ_OBJ
Definition: qs.h:899
@ AO_OBJ
Definition: qs.h:897
@ TE_OBJ
Definition: qs.h:900
@ MAX_OBJ
Definition: qs.h:902
@ AP_OBJ
Definition: qs.h:901
@ MP_OBJ
Definition: qs.h:898
uint_fast16_t QSCtr
Definition: qs.h:892
uint8_t locFilter[16]
Definition: qs.h:912
@ QS_TEST_PROBE_GET
Definition: qs.h:142
@ QS_TARGET_DONE
Definition: qs.h:148
@ QS_OBJ_DICT
Definition: qs.h:144
@ QS_RX_STATUS
Definition: qs.h:149
@ QS_QUERY_DATA
Definition: qs.h:150
@ QS_PEEK_DATA
Definition: qs.h:151
Internal (package scope) QS/C interface.
void * currObj[MAX_OBJ]
Definition: qs_pkg.h:93
#define QS_U8_PRE_(data_)
Definition: qs_pkg.h:151
#define QS_OBJ_PRE_(obj_)
Definition: qs_pkg.h:179
#define QS_FUN_PRE_(fun_)
Definition: qs_pkg.h:182
#define QS_MPC_PRE_(ctr_)
Definition: qs_pkg.h:249
uint8_t * buf
Definition: qs_pkg.h:94
#define QS_ESC
Definition: qs_pkg.h:70
#define QS_TEC_PRE_(ctr_)
Definition: qs_pkg.h:264
#define QS_U16_PRE_(data_)
Definition: qs_pkg.h:158
QSCtr volatile tail
Definition: qs_pkg.h:97
#define QS_ESC_XOR
Definition: qs_pkg.h:81
#define QS_SIG_PRE_(sig_)
Definition: qs_pkg.h:172
#define QS_EQC_PRE_(ctr_)
Definition: qs_pkg.h:205
bool inTestLoop
Definition: qs_pkg.h:100
QSCtr end
Definition: qs_pkg.h:95
@ QS_RX_RESET
Definition: qs_pkg.h:48
@ QS_RX_EVENT
Definition: qs_pkg.h:62
@ QS_RX_LOC_FILTER
Definition: qs_pkg.h:57
@ QS_RX_FILL
Definition: qs_pkg.h:52
@ QS_RX_AO_FILTER
Definition: qs_pkg.h:58
@ QS_RX_TICK
Definition: qs_pkg.h:49
@ QS_RX_PEEK
Definition: qs_pkg.h:50
@ QS_RX_CURR_OBJ
Definition: qs_pkg.h:59
@ QS_RX_GLB_FILTER
Definition: qs_pkg.h:56
@ QS_RX_POKE
Definition: qs_pkg.h:51
@ QS_RX_INFO
Definition: qs_pkg.h:46
@ QS_RX_TEST_TEARDOWN
Definition: qs_pkg.h:54
@ QS_RX_TEST_PROBE
Definition: qs_pkg.h:55
@ QS_RX_TEST_SETUP
Definition: qs_pkg.h:53
@ QS_RX_COMMAND
Definition: qs_pkg.h:47
@ QS_RX_TEST_CONTINUE
Definition: qs_pkg.h:60
@ QS_RX_QUERY_CURR
Definition: qs_pkg.h:61
#define QS_GOOD_CHKSUM
Definition: qs_pkg.h:73
QSCtr volatile head
Definition: qs_pkg.h:96
#define QS_FRAME
Definition: qs_pkg.h:67
#define QS_U32_PRE_(data_)
Definition: qs_pkg.h:161
#define QS_STR_PRE_(msg_)
Definition: qs_pkg.h:164
static void QS_rxReportDone_(int8_t recId)
Definition: qs_rx.c:1216
static void QS_rxParseData_(uint8_t b)
Definition: qs_rx.c:420
static void QS_rxReportAck_(int8_t recId)
Definition: qs_rx.c:1192
static void QS_rxHandleBadFrame_(uint8_t state)
Definition: qs_rx.c:1176
static void QS_rxPoke_(void)
Definition: qs_rx.c:1229
static void QS_rxReportError_(int8_t code)
Definition: qs_rx.c:1204
static void QS_rxHandleGoodFrame_(uint8_t state)
Definition: qs_rx.c:860
QSrxPrivAttr QS_rxPriv_
Definition: qs_rx.c:40
#define QF_MAX_ACTIVE
#define QS_FUN_PTR_SIZE
#define QS_OBJ_PTR_SIZE
Definition: qf.h:107
Definition: qep.h:119
QActive * QF_active_[QF_MAX_ACTIVE+1U]
Definition: qf_act.c:48
void QF_publish_(QEvt const *const e, void const *const sender, uint_fast8_t const qs_id)
Definition: qf_ps.c:119
void QF_gc(QEvt const *const e)
Definition: qf_dyn.c:241
uint_fast16_t QF_poolGetMaxBlockSize(void)
Definition: qf_dyn.c:362
void QF_tickX_(uint_fast8_t const tickRate, void const *const sender)
Definition: qf_time.c:86
QEvt * QF_newX_(uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig)
Definition: qf_dyn.c:160
Definition: qep.h:253
Definition: qmpool.h:105
void QS_locFilter_(int_fast16_t const filter)
Definition: qs.c:308
void QS_onReset(void)
void QS_endRec_(void)
Definition: qs.c:399
void QS_queryCurrObj(uint8_t obj_kind)
Definition: qs_rx.c:321
void QS_tickX_(uint_fast8_t const tickRate, void const *const sender)
Definition: qutest.c:371
void QS_rxParse(void)
Definition: qs_rx.c:375
uint32_t QS_getTestProbe_(void(*const api)(void))
Definition: qs_rx.c:1268
void QS_target_info_pre_(uint8_t isReset)
Definition: qs.c:430
void QS_processTestEvts_(void)
Definition: qutest.c:339
bool QS_RX_PUT(uint8_t const b)
Definition: qs_rx.c:268
void QS_beginRec_(uint_fast8_t rec)
Definition: qs.c:371
void QS_rxInitBuf(uint8_t sto[], uint16_t stoSize)
Definition: qs_rx.c:236
QSTimeCtr QS_onGetTime(void)
Definition: qs_rx.c:1301
void QS_onTestTeardown(void)
void QS_setCurrObj(uint8_t obj_kind, void *obj_ptr)
Definition: qs_rx.c:310
void QS_onTestEvt(QEvt *e)
uint16_t QS_rxGetNfree(void)
Definition: qs_rx.c:292
void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3)
Definition: qf.h:456