QP/C  6.8.1
qs.c
Go to the documentation of this file.
1 
40 #define QP_IMPL /* this is QP implementation */
41 #include "qs_port.h" /* QS port */
42 #include "qs_pkg.h" /* QS package-scope interface */
43 #include "qassert.h" /* QP embedded systems-friendly assertions */
44 
46 
47 /****************************************************************************/
48 QSPrivAttr QS_priv_; /* QS private attributes */
49 
50 /****************************************************************************/
75 void QS_initBuf(uint8_t sto[], uint_fast16_t stoSize) {
76  /* the provided buffer must be at least 8 bytes long */
77  Q_REQUIRE_ID(100, stoSize > 8U);
78 
79  /* all maskable filters off */
81 
82  QS_priv_.locFilter[SM_OBJ] = (void *)0;
83  QS_priv_.locFilter[AO_OBJ] = (void *)0;
84  QS_priv_.locFilter[MP_OBJ] = (void *)0;
85  QS_priv_.locFilter[EQ_OBJ] = (void *)0;
86  QS_priv_.locFilter[TE_OBJ] = (void *)0;
87  QS_priv_.locFilter[AP_OBJ] = (void *)0;
88 
89  QS_priv_.buf = &sto[0];
90  QS_priv_.end = (QSCtr)stoSize;
91  QS_priv_.head = 0U;
92  QS_priv_.tail = 0U;
93  QS_priv_.used = 0U;
94  QS_priv_.seq = 0U;
95  QS_priv_.chksum = 0U;
96  QS_priv_.critNest = 0U;
97 
98  /* produce an empty record to "flush" the QS trace buffer */
100  QS_endRec_();
101 
102  /* produce the reset record to inform QSPY of a new session */
103  QS_target_info_pre_(0xFFU); /* send Reset and Target info */
104 
105  /* wait with flushing after successfull initialization (see QS_INIT()) */
106 }
107 
108 /****************************************************************************/
122  if (rec == (uint_fast8_t)QS_ALL_RECORDS) {
123  uint_fast8_t i;
124  for (i = 0U; i < 15U; ++i) {
125  QS_priv_.glbFilter[i] = 0xFFU; /* set all bits */
126  }
127  /* never turn the last 3 records on (0x7D, 0x7E, 0x7F) */
128  QS_priv_.glbFilter[sizeof(QS_priv_.glbFilter) - 1U] = 0x1FU;
129  }
130  else if (rec == (uint_fast8_t)QS_SM_RECORDS) {
131  QS_priv_.glbFilter[0] |= 0xFEU;
132  QS_priv_.glbFilter[1] |= 0x03U;
133  QS_priv_.glbFilter[6] |= 0x80U;
134  QS_priv_.glbFilter[7] |= 0x03U;
135  }
136  else if (rec == (uint_fast8_t)QS_AO_RECORDS) {
137  QS_priv_.glbFilter[1] |= 0xFCU;
138  QS_priv_.glbFilter[2] |= 0x07U;
139  QS_priv_.glbFilter[5] |= 0x20U;
140  }
141  else if (rec == (uint_fast8_t)QS_EQ_RECORDS) {
142  QS_priv_.glbFilter[2] |= 0x78U;
143  QS_priv_.glbFilter[5] |= 0x40U;
144  }
145  else if (rec == (uint_fast8_t)QS_MP_RECORDS) {
146  QS_priv_.glbFilter[3] |= 0x03U;
147  QS_priv_.glbFilter[5] |= 0x80U;
148  }
149  else if (rec == (uint_fast8_t)QS_QF_RECORDS) {
150  QS_priv_.glbFilter[3] |= 0xFCU;
151  QS_priv_.glbFilter[4] |= 0xC0U;
152  QS_priv_.glbFilter[5] |= 0x1FU;
153  }
154  else if (rec == (uint_fast8_t)QS_TE_RECORDS) {
155  QS_priv_.glbFilter[4] |= 0x7FU;
156  }
157  else if (rec == (uint_fast8_t)QS_SC_RECORDS) {
158  QS_priv_.glbFilter[6] |= 0x7FU;
159  }
160  else if (rec == (uint_fast8_t)QS_U0_RECORDS) {
161  QS_priv_.glbFilter[12] |= 0xF0U;
162  QS_priv_.glbFilter[13] |= 0x01U;
163  }
164  else if (rec == (uint_fast8_t)QS_U1_RECORDS) {
165  QS_priv_.glbFilter[13] |= 0x1EU;
166  }
167  else if (rec == (uint_fast8_t)QS_U2_RECORDS) {
168  QS_priv_.glbFilter[13] |= 0xE0U;
169  QS_priv_.glbFilter[14] |= 0x03U;
170  }
171  else if (rec == (uint_fast8_t)QS_U3_RECORDS) {
172  QS_priv_.glbFilter[14] |= 0xF8U;
173  }
174  else if (rec == (uint_fast8_t)QS_U4_RECORDS) {
175  QS_priv_.glbFilter[15] |= 0x1FU;
176  }
177  else if (rec == (uint_fast8_t)QS_UA_RECORDS) {
178  QS_priv_.glbFilter[12] |= 0xF0U;
179  QS_priv_.glbFilter[13] |= 0xFFU;
180  QS_priv_.glbFilter[14] |= 0xFFU;
181  QS_priv_.glbFilter[15] |= 0x1FU;
182  }
183  else {
184  /* record numbers can't exceed QS_ESC, so they don't need escaping */
185  Q_ASSERT_ID(210, rec < QS_ESC);
186  QS_priv_.glbFilter[rec >> 3] |= (uint8_t)(1U << (rec & 7U));
187  }
188 }
189 
190 /****************************************************************************/
203  uint8_t tmp;
204 
205  if (rec == (uint_fast8_t)QS_ALL_RECORDS) {
206  /* first clear all global filters */
207  for (tmp = 15U; tmp > 0U; --tmp) {
208  QS_priv_.glbFilter[tmp] = 0x00U;
209  }
210  /* next leave the specific filters enabled */
211  QS_priv_.glbFilter[0] = 0x01U;
212  QS_priv_.glbFilter[7] = 0xFCU;
213  QS_priv_.glbFilter[8] = 0x3FU;
214  }
215  else if (rec == (uint_fast8_t)QS_SM_RECORDS) {
216  QS_priv_.glbFilter[0] &= ~(uint8_t)0xFEU;
217  QS_priv_.glbFilter[1] &= ~(uint8_t)0x03U;
218  QS_priv_.glbFilter[6] &= ~(uint8_t)0x80U;
219  QS_priv_.glbFilter[7] &= ~(uint8_t)0x03U;
220  }
221  else if (rec == (uint_fast8_t)QS_AO_RECORDS) {
222  QS_priv_.glbFilter[1] &= ~(uint8_t)0xFCU;
223  QS_priv_.glbFilter[2] &= ~(uint8_t)0x07U;
224  QS_priv_.glbFilter[5] &= ~(uint8_t)0x20U;
225  }
226  else if (rec == (uint_fast8_t)QS_EQ_RECORDS) {
227  QS_priv_.glbFilter[2] &= ~(uint8_t)0x78U;
228  QS_priv_.glbFilter[5] &= ~(uint8_t)0x40U;
229  }
230  else if (rec == (uint_fast8_t)QS_MP_RECORDS) {
231  QS_priv_.glbFilter[3] &= ~(uint8_t)0x03U;
232  QS_priv_.glbFilter[5] &= ~(uint8_t)0x80U;
233  }
234  else if (rec == (uint_fast8_t)QS_QF_RECORDS) {
235  QS_priv_.glbFilter[3] &= ~(uint8_t)0xFCU;
236  QS_priv_.glbFilter[4] &= ~(uint8_t)0xC0U;
237  QS_priv_.glbFilter[5] &= ~(uint8_t)0x1FU;
238  }
239  else if (rec == (uint_fast8_t)QS_TE_RECORDS) {
240  QS_priv_.glbFilter[4] &= ~(uint8_t)0x7FU;
241  }
242  else if (rec == (uint_fast8_t)QS_SC_RECORDS) {
243  QS_priv_.glbFilter[6] &= ~(uint8_t)0x7FU;
244  }
245  else if (rec == (uint_fast8_t)QS_U0_RECORDS) {
246  QS_priv_.glbFilter[12] &= ~(uint8_t)0xF0U;
247  QS_priv_.glbFilter[13] &= ~(uint8_t)0x01U;
248  }
249  else if (rec == (uint_fast8_t)QS_U1_RECORDS) {
250  QS_priv_.glbFilter[13] &= ~(uint8_t)0x1EU;
251  }
252  else if (rec == (uint_fast8_t)QS_U2_RECORDS) {
253  QS_priv_.glbFilter[13] &= ~(uint8_t)0xE0U;
254  QS_priv_.glbFilter[14] &= ~(uint8_t)0x03U;
255  }
256  else if (rec == (uint_fast8_t)QS_U3_RECORDS) {
257  QS_priv_.glbFilter[14] &= ~(uint8_t)0xF8U;
258  }
259  else if (rec == (uint_fast8_t)QS_U4_RECORDS) {
260  QS_priv_.glbFilter[15] &= 0x1FU;
261  }
262  else if (rec == (uint_fast8_t)QS_UA_RECORDS) {
263  QS_priv_.glbFilter[12] &= ~(uint8_t)0xF0U;
264  QS_priv_.glbFilter[13] = 0U;
265  QS_priv_.glbFilter[14] = 0U;
266  QS_priv_.glbFilter[15] &= ~(uint8_t)0x1FU;
267  }
268  else {
269  /* record IDs can't exceed QS_ESC, so they don't need escaping */
270  Q_ASSERT_ID(310, rec < (uint_fast8_t)QS_ESC);
271  tmp = (uint8_t)(1U << (rec & 0x07U));
272  tmp ^= 0xFFU; /* invert all bits */
273  QS_priv_.glbFilter[rec >> 3] &= tmp;
274  }
275 }
276 
277 /****************************************************************************/
286  uint8_t b = (uint8_t)(QS_priv_.seq + 1U);
287  uint8_t chksum = 0U; /* reset the checksum */
288  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
289  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
290  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
291 
292  QS_priv_.seq = b; /* store the incremented sequence num */
293  QS_priv_.used += 2U; /* 2 bytes about to be added */
294 
296 
297  chksum = (uint8_t)(chksum + rec); /* update checksum */
298  QS_INSERT_BYTE_((uint8_t)rec) /* rec byte does not need escaping */
299 
300  QS_priv_.head = head; /* save the head */
301  QS_priv_.chksum = chksum; /* save the checksum */
302 }
303 
304 /****************************************************************************/
312 void QS_endRec_(void) {
313  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
314  QSCtr head = QS_priv_.head;
315  QSCtr end = QS_priv_.end;
316  uint8_t b = QS_priv_.chksum;
317  b ^= 0xFFU; /* invert the bits in the checksum */
318 
319  QS_priv_.used += 2U; /* 2 bytes about to be added */
320 
321  if ((b != QS_FRAME) && (b != QS_ESC)) {
322  QS_INSERT_BYTE_(b)
323  }
324  else {
327  ++QS_priv_.used; /* account for the ESC byte */
328  }
329 
330  QS_INSERT_BYTE_(QS_FRAME) /* do not escape this QS_FRAME */
331 
332  QS_priv_.head = head; /* save the head */
333 
334  /* overrun over the old data? */
335  if (QS_priv_.used > end) {
336  QS_priv_.used = end; /* the whole buffer is used */
337  QS_priv_.tail = head; /* shift the tail to the old data */
338  }
339 }
340 
341 /****************************************************************************/
343  static uint8_t const ZERO = (uint8_t)'0';
344  static uint8_t const * const TIME = (uint8_t const *)&Q_BUILD_TIME[0];
345  static uint8_t const * const DATE = (uint8_t const *)&Q_BUILD_DATE[0];
346  uint8_t b;
347 
349  QS_U8_PRE_(isReset);
350  QS_U16_PRE_(QP_VERSION); /* two-byte version number */
351 
352  /* send the object sizes... */
354 
355 #ifdef QF_EQUEUE_CTR_SIZE
357 #else
359 #endif /* QF_EQUEUE_CTR_SIZE */
360 
361 #ifdef QF_MPOOL_CTR_SIZE
363 #else
364  QS_U8_PRE_(0U);
365 #endif /* QF_MPOOL_CTR_SIZE */
366 
369 
370  /* send the limits... */
372  QS_U8_PRE_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4));
373 
374  /* send the build time in three bytes (sec, min, hour)... */
375  QS_U8_PRE_((10U * (uint8_t)(TIME[6] - ZERO))
376  + (uint8_t)(TIME[7] - ZERO));
377  QS_U8_PRE_((10U * (uint8_t)(TIME[3] - ZERO))
378  + (uint8_t)(TIME[4] - ZERO));
379  if (Q_BUILD_TIME[0] == ' ') {
380  QS_U8_PRE_(TIME[1] - ZERO);
381  }
382  else {
383  QS_U8_PRE_((10U * (uint8_t)(TIME[0] - ZERO))
384  + (uint8_t)(TIME[1] - ZERO));
385  }
386 
387  /* send the build date in three bytes (day, month, year) ... */
388  if (Q_BUILD_DATE[4] == ' ') {
389  QS_U8_PRE_(DATE[5] - ZERO);
390  }
391  else {
392  QS_U8_PRE_((10U * (uint8_t)(DATE[4] - ZERO))
393  + (uint8_t)(DATE[5] - ZERO));
394  }
395  /* convert the 3-letter month to a number 1-12 ... */
396  switch (DATE[0] + DATE[1] + DATE[2]) {
397  case (int_t)'J' + (int_t)'a' + (int_t)'n':
398  b = 1U;
399  break;
400  case (int_t)'F' + (int_t)'e' + (int_t)'b':
401  b = 2U;
402  break;
403  case (int_t)'M' + (int_t)'a' + (int_t)'r':
404  b = 3U;
405  break;
406  case (int_t)'A' + (int_t)'p' + (int_t)'r':
407  b = 4U;
408  break;
409  case (int_t)'M' + (int_t)'a' + (int_t)'y':
410  b = 5U;
411  break;
412  case (int_t)'J' + (int_t)'u' + (int_t)'n':
413  b = 6U;
414  break;
415  case (int_t)'J' + (int_t)'u' + (int_t)'l':
416  b = 7U;
417  break;
418  case (int_t)'A' + (int_t)'u' + (int_t)'g':
419  b = 8U;
420  break;
421  case (int_t)'S' + (int_t)'e' + (int_t)'p':
422  b = 9U;
423  break;
424  case (int_t)'O' + (int_t)'c' + (int_t)'t':
425  b = 10U;
426  break;
427  case (int_t)'N' + (int_t)'o' + (int_t)'v':
428  b = 11U;
429  break;
430  case (int_t)'D' + (int_t)'e' + (int_t)'c':
431  b = 12U;
432  break;
433  default:
434  b = 0U;
435  break;
436  }
437  QS_U8_PRE_(b); /* store the month */
438  QS_U8_PRE_((10U * (uint8_t)(DATE[9] - ZERO))
439  + (uint8_t)(DATE[10] - ZERO));
440  QS_endRec_();
441 }
442 
443 /****************************************************************************/
449 void QS_u8_fmt_(uint8_t format, uint8_t d) {
450  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
451  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
452  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
453  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
454 
455  QS_priv_.used += 2U; /* 2 bytes about to be added */
456 
457  QS_INSERT_ESC_BYTE_(format)
459 
460  QS_priv_.head = head; /* save the head */
461  QS_priv_.chksum = chksum; /* save the checksum */
462 }
463 
464 /****************************************************************************/
470 void QS_u16_fmt_(uint8_t format, uint16_t d) {
471  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
472  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
473  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
474  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
475  uint8_t b = (uint8_t)d;
476 
477  QS_priv_.used += 3U; /* 3 bytes about to be added */
478 
479  QS_INSERT_ESC_BYTE_(format)
481  b = (uint8_t)(d >> 8);
483 
484  QS_priv_.head = head; /* save the head */
485  QS_priv_.chksum = chksum; /* save the checksum */
486 }
487 
488 /****************************************************************************/
493 void QS_u32_fmt_(uint8_t format, uint32_t d) {
494  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
495  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
496  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
497  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
498  uint32_t x = d;
499  uint_fast8_t i;
500 
501  QS_priv_.used += 5U; /* 5 bytes about to be added */
502  QS_INSERT_ESC_BYTE_(format) /* insert the format byte */
503 
504  /* insert 4 bytes... */
505  for (i = 4U; i != 0U; --i) {
507  x >>= 8;
508  }
509 
510  QS_priv_.head = head; /* save the head */
511  QS_priv_.chksum = chksum; /* save the checksum */
512 }
513 
514 /****************************************************************************/
520  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
521  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
522  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
523  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
524 
525  QS_priv_.used += 1U; /* 1 byte about to be added */
527 
528  QS_priv_.head = head; /* save the head */
529  QS_priv_.chksum = chksum; /* save the checksum */
530 }
531 
532 /****************************************************************************/
537  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
538  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
539  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
540  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
541 
542  QS_priv_.used += 2U; /* 2 bytes are about to be added */
545 
546  QS_priv_.head = head; /* save the head */
547  QS_priv_.chksum = chksum; /* save the checksum */
548 }
549 
550 /****************************************************************************/
556  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
557  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
558  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
559  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
560  uint16_t x = d;
561 
562  QS_priv_.used += 2U; /* 2 bytes are about to be added */
563 
565  x >>= 8;
567 
568  QS_priv_.head = head; /* save the head */
569  QS_priv_.chksum = chksum; /* save the checksum */
570 }
571 
572 /****************************************************************************/
577  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
578  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
579  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
580  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
581  uint32_t x = d;
582  uint_fast8_t i;
583 
584  QS_priv_.used += 4U; /* 4 bytes are about to be added */
585  for (i = 4U; i != 0U; --i) {
587  x >>= 8;
588  }
589 
590  QS_priv_.head = head; /* save the head */
591  QS_priv_.chksum = chksum; /* save the checksum */
592 }
593 
594 /****************************************************************************/
598 void QS_obj_raw_(void const * const obj) {
599 #if (QS_OBJ_PTR_SIZE == 1U)
600  QS_u8_raw_((uint8_t)obj);
601 #elif (QS_OBJ_PTR_SIZE == 2U)
602  QS_u16_raw_((uint16_t)obj);
603 #elif (QS_OBJ_PTR_SIZE == 4U)
604  QS_u32_raw_((uint32_t)obj);
605 #elif (QS_OBJ_PTR_SIZE == 8U)
606  QS_u64_raw_((uint64_t)obj);
607 #else
608  QS_u32_raw_((uint32_t)obj);
609 #endif
610 }
611 
612 /****************************************************************************/
617 void QS_str_raw_(char_t const *str) {
618  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
619  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
620  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
621  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
622  QSCtr used = QS_priv_.used; /* put in a temporary (register) */
623  char_t const *s;
624 
625  for (s = str; *s != '\0'; ++s) {
626  chksum += (uint8_t)*s; /* update checksum */
627  QS_INSERT_BYTE_((uint8_t)*s) /* ASCII char doesn't need escaping */
628  ++used;
629  }
630  QS_INSERT_BYTE_((uint8_t)'\0') /* zero-terminate the string */
631  ++used;
632 
633  QS_priv_.head = head; /* save the head */
634  QS_priv_.chksum = chksum; /* save the checksum */
635  QS_priv_.used = used; /* save # of used buffer space */
636 }
637 
638 /****************************************************************************/
650  uint16_t ret;
651  if (QS_priv_.used == 0U) {
652  ret = QS_EOD; /* set End-Of-Data */
653  }
654  else {
655  uint8_t const *buf = QS_priv_.buf; /* put in a temporary */
656  QSCtr tail = QS_priv_.tail; /* put in a temporary (register) */
657  ret = (uint16_t)buf[tail]; /* set the byte to return */
658  ++tail; /* advance the tail */
659  if (tail == QS_priv_.end) { /* tail wrap around? */
660  tail = 0U;
661  }
662  QS_priv_.tail = tail; /* update the tail */
663  --QS_priv_.used; /* one less byte used */
664  }
665  return ret; /* return the byte or EOD */
666 }
667 
668 /****************************************************************************/
691 uint8_t const *QS_getBlock(uint16_t *pNbytes) {
692  QSCtr used = QS_priv_.used; /* put in a temporary (register) */
693  uint8_t const *buf;
694 
695  /* any bytes used in the ring buffer? */
696  if (used != 0U) {
697  QSCtr tail = QS_priv_.tail; /* put in a temporary (register) */
698  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
699  QSCtr n = (QSCtr)(end - tail);
700  if (n > used) {
701  n = used;
702  }
703  if (n > (QSCtr)(*pNbytes)) {
704  n = (QSCtr)(*pNbytes);
705  }
706  *pNbytes = (uint16_t)n; /* n-bytes available */
707  buf = &QS_priv_.buf[tail]; /* the bytes are at the tail */
708 
709  QS_priv_.used = (QSCtr)(used - n);
710  tail += n;
711  if (tail == end) {
712  tail = 0U;
713  }
714  QS_priv_.tail = tail;
715  }
716 
717  else { /* no bytes available */
718  *pNbytes = 0U; /* no bytes available right now */
719  buf = (uint8_t *)0; /* no bytes available right now */
720  }
721  return buf;
722 }
723 
724 /****************************************************************************/
727 void QS_sig_dict_pre_(enum_t const sig, void const * const obj,
728  char_t const *name)
729 {
731 
732  QS_CRIT_ENTRY_();
734  QS_SIG_PRE_(sig);
735  QS_OBJ_PRE_(obj);
736  QS_str_raw_((*name == (char_t)'&') ? &name[1] : name);
737  QS_endRec_();
738  QS_CRIT_EXIT_();
739  QS_onFlush();
740 }
741 
742 /****************************************************************************/
745 void QS_obj_dict_pre_(void const * const obj,
746  char_t const *name)
747 {
749 
750  QS_CRIT_ENTRY_();
752  QS_OBJ_PRE_(obj);
753  QS_str_raw_((*name == (char_t)'&') ? &name[1] : name);
754  QS_endRec_();
755  QS_CRIT_EXIT_();
756  QS_onFlush();
757 }
758 
759 /****************************************************************************/
762 void QS_fun_dict_pre_(void (* const fun)(void), char_t const *name) {
764 
765  QS_CRIT_ENTRY_();
767  QS_FUN_PRE_(fun);
768  QS_str_raw_((*name == (char_t)'&') ? &name[1] : name);
769  QS_endRec_();
770  QS_CRIT_EXIT_();
771  QS_onFlush();
772 }
773 
774 /****************************************************************************/
777 void QS_usr_dict_pre_(enum_t const rec,
778  char_t const * const name)
779 {
781 
782  QS_CRIT_ENTRY_();
784  QS_u8_raw_((uint8_t)rec);
785  QS_str_raw_(name);
786  QS_endRec_();
787  QS_CRIT_EXIT_();
788  QS_onFlush();
789 }
790 
791 /****************************************************************************/
795 void QS_mem_fmt_(uint8_t const *blk, uint8_t size) {
796  uint8_t chksum = QS_priv_.chksum;
797  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
798  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
799  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
800  uint8_t const *pb = blk;
801  uint8_t len;
802 
803  QS_priv_.used += ((QSCtr)size + 2U); /* size+2 bytes to be added */
804 
806  chksum += (uint8_t)QS_MEM_T;
807 
808  QS_INSERT_ESC_BYTE_(size)
809  /* output the 'size' number of bytes */
810  for (len = size; len > 0U; --len) {
812  ++pb;
813  }
814 
815  QS_priv_.head = head; /* save the head */
816  QS_priv_.chksum = chksum; /* save the checksum */
817 }
818 
819 /****************************************************************************/
824 void QS_str_fmt_(char_t const *str) {
825  uint8_t chksum = QS_priv_.chksum;
826  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
827  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
828  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
829  QSCtr used = QS_priv_.used; /* put in a temporary (register) */
830  char_t const *s;
831 
832  used += 2U; /* account for the format byte and the terminating-0 */
834  chksum += (uint8_t)QS_STR_T;
835 
836  for (s = str; *s != '\0'; ++s) {
837  QS_INSERT_BYTE_((uint8_t)*s) /* ASCII char doesn't need escaping */
838  chksum += (uint8_t)*s; /* update checksum */
839  ++used;
840  }
841  QS_INSERT_BYTE_(0U) /* zero-terminate the string */
842 
843  QS_priv_.head = head; /* save the head */
844  QS_priv_.chksum = chksum; /* save the checksum */
845  QS_priv_.used = used; /* save # of used buffer space */
846 }
847 
848 /****************************************************************************/
850 void QS_ASSERTION(char_t const * const module,
851  int_t const loc,
852  uint32_t delay)
853 {
854  uint32_t volatile delay_ctr;
855 
856  QS_BEGIN_NOCRIT_PRE_(QS_ASSERT_FAIL, (void *)0, (void *)0)
857  QS_TIME_PRE_();
858  QS_U16_PRE_(loc);
859  QS_STR_PRE_((module != (char_t *)0) ? module : "?");
861  QS_onFlush();
862  for (delay_ctr = delay; delay_ctr > 0U; --delay_ctr) {
863  }
864  QS_onCleanup();
865 }
866 
867 /****************************************************************************/
868 /* Output the critical section entry/exit
869 */
870 void QF_QS_CRIT_ENTRY(void) {
871  QS_BEGIN_NOCRIT_PRE_(QS_QF_CRIT_ENTRY, (void *)0, (void *)0)
872  QS_TIME_PRE_();
873  ++QS_priv_.critNest;
876 }
877 
878 void QF_QS_CRIT_EXIT(void) {
879  QS_BEGIN_NOCRIT_PRE_(QS_QF_CRIT_EXIT, (void *)0, (void *)0)
880  QS_TIME_PRE_();
882  --QS_priv_.critNest;
884 }
885 
886 /****************************************************************************/
887 /* Output the ISR entry/exit
888 */
889 void QF_QS_ISR_ENTRY(uint8_t const isrnest, uint8_t const prio) {
890  QS_BEGIN_NOCRIT_PRE_(QS_QF_ISR_ENTRY, (void *)0, (void *)0)
891  QS_TIME_PRE_();
892  QS_2u8_raw_(isrnest, prio);
894 }
895 
896 void QF_QS_ISR_EXIT(uint8_t const isrnest, uint8_t const prio) {
897  QS_BEGIN_NOCRIT_PRE_(QS_QF_ISR_EXIT, (void *)0, (void *)0)
898  QS_TIME_PRE_();
899  QS_2u8_raw_(isrnest, prio);
901 }
902 
QSPrivAttr::tail
QSCtr tail
offset of where next byte will be extracted
Definition: qs.h:991
QS_BEGIN_NOCRIT_PRE_
#define QS_BEGIN_NOCRIT_PRE_(rec_, objFilter_, obj_)
Internal macro to begin a predefined QS record without entering critical section.
Definition: qs_pkg.h:76
QS_priv_
QSPrivAttr QS_priv_
Definition: qs.c:48
QS_filterOn_
void QS_filterOn_(uint_fast8_t rec)
Turn the global Filter on for a given record type rec.
Definition: qs.c:121
uint8_t
unsigned char uint8_t
exact-width 8-bit unsigned int
Definition: 16bit/stdint.h:29
QF_QS_ISR_EXIT
void QF_QS_ISR_EXIT(uint8_t const isrnest, uint8_t const prio)
Output the interrupt exit record.
Definition: qs.c:896
QS_u8_fmt_
void QS_u8_fmt_(uint8_t format, uint8_t d)
Output uint8_t data element with format information.
Definition: qs.c:449
SM_OBJ
@ SM_OBJ
state machine object
Definition: qs.h:971
QS_onCleanup
void QS_onCleanup(void)
Callback to cleanup the QS facility.
QS_U4_RECORDS
@ QS_U4_RECORDS
User Group 120-124 records.
Definition: qs.h:212
QS_U8_PRE_
#define QS_U8_PRE_(data_)
Internal QS macro to output a predefined uint8_t data element.
Definition: qs_pkg.h:93
QP_VERSION
#define QP_VERSION
The current QP version as a decimal constant XXYZ, where XX is a 2-digit major version number,...
Definition: qep.h:48
QS_TE_RECORDS
@ QS_TE_RECORDS
Time Events QS records.
Definition: qs.h:205
QS_sig_dict_pre_
void QS_sig_dict_pre_(enum_t const sig, void const *const obj, char_t const *name)
Output predefined signal-dictionary record.
Definition: qs.c:727
QS_ASSERT_FAIL
@ QS_ASSERT_FAIL
assertion failed in the code
Definition: qs.h:160
QS_u32_fmt_
void QS_u32_fmt_(uint8_t format, uint32_t d)
Output uint32_t data element with format information.
Definition: qs.c:493
QF_TIMEEVT_CTR_SIZE
#define QF_TIMEEVT_CTR_SIZE
The size (in bytes) of the time event-counter representation in the QTimeEvt struct.
Definition: qk/qf_port.h:188
QS_FUN_PRE_
#define QS_FUN_PRE_(fun_)
Internal macro to output an unformatted function pointer.
Definition: qs_pkg.h:136
QF_QS_CRIT_ENTRY
void QF_QS_CRIT_ENTRY(void)
Output the critical section entry.
Definition: qs.c:870
AP_OBJ
@ AP_OBJ
generic Application-specific object
Definition: qs.h:976
QS_FUN_PTR_SIZE
#define QS_FUN_PTR_SIZE
Definition: qs_port.h:50
QSPrivAttr::locFilter
const void * locFilter[MAX_OBJ]
local QS filters
Definition: qs.h:987
QS_TIME_PRE_
#define QS_TIME_PRE_()
Definition: qs.h:241
MP_OBJ
@ MP_OBJ
event pool object
Definition: qs.h:973
QS_STR_PRE_
#define QS_STR_PRE_(msg_)
Internal QS macro to output a predefined zero-terminated string element.
Definition: qs_pkg.h:106
QF_EVENT_SIZ_SIZE
#define QF_EVENT_SIZ_SIZE
The size (in bytes) of the event-size representation in the QF.
Definition: qk/qf_port.h:99
Q_DEFINE_THIS_MODULE
#define Q_DEFINE_THIS_MODULE(name_)
Define the user-specified module name for assertions in this file.
Definition: qassert.h:120
QSPrivAttr::seq
uint8_t seq
the record sequence number
Definition: qs.h:993
QSPrivAttr::glbFilter
uint8_t glbFilter[16]
global on/off QS filter
Definition: qs.h:986
uint64_t
unsigned long long uint64_t
exact-width 64-bit unsigned int
Definition: 16bit/stdint.h:32
QS_U2_RECORDS
@ QS_U2_RECORDS
User Group 110-114 records.
Definition: qs.h:210
qassert.h
Customizable and memory-efficient assertions for embedded systems.
QS_obj_dict_pre_
void QS_obj_dict_pre_(void const *const obj, char_t const *name)
Output predefined object-dictionary record.
Definition: qs.c:745
QS_INSERT_ESC_BYTE_
#define QS_INSERT_ESC_BYTE_(b_)
Internal QS macro to insert an escaped byte into the QS buffer.
Definition: qs_pkg.h:226
QS_EMPTY
@ QS_EMPTY
QS record for cleanly starting a session.
Definition: qs.h:64
QS_STR_T
@ QS_STR_T
zero-terminated ASCII string format
Definition: qs.h:664
QS_ASSERTION
void QS_ASSERTION(char_t const *const module, int_t const loc, uint32_t delay)
Output the assertion failure trace record.
Definition: qs.c:850
QS_FRAME
#define QS_FRAME
Frame character of the QS output protocol.
Definition: qs_pkg.h:239
QS_target_info_pre_
void QS_target_info_pre_(uint8_t isReset)
send the predefined target info trace record (object sizes, build time-stamp, QP version)
Definition: qs.c:342
uint16_t
unsigned int uint16_t
exact-width 16-bit unsigned int
Definition: 16bit/stdint.h:30
QS_filterOff_
void QS_filterOff_(uint_fast8_t rec)
Turn the global Filter off for a given record type rec.
Definition: qs.c:202
QS_AO_RECORDS
@ QS_AO_RECORDS
Active Object QS records.
Definition: qs.h:202
QS_MP_RECORDS
@ QS_MP_RECORDS
Memory Pools QS records.
Definition: qs.h:204
QSCtr
uint_fast16_t QSCtr
QS ring buffer counter and offset type.
Definition: qs.h:967
QS_UA_RECORDS
@ QS_UA_RECORDS
All User records.
Definition: qs.h:213
QS_CRIT_EXIT_
#define QS_CRIT_EXIT_()
This is an internal macro for exiting a critical section.
Definition: qs.h:820
uint_fast8_t
unsigned int uint_fast8_t
fast at-least 8-bit unsigned int
Definition: 16bit/stdint.h:36
QF_MAX_EPOOL
#define QF_MAX_EPOOL
The maximum number of event pools in the application.
Definition: qk/qf_port.h:78
QS_QF_RECORDS
@ QS_QF_RECORDS
QF QS records.
Definition: qs.h:206
QS_USR_DICT
@ QS_USR_DICT
user QS record dictionary entry
Definition: qs.h:154
QS_U16_PRE_
#define QS_U16_PRE_(data_)
Internal QS macro to output an predefined uint16_t data element.
Definition: qs_pkg.h:100
QS_QF_CRIT_ENTRY
@ QS_QF_CRIT_ENTRY
critical section was entered
Definition: qs.h:118
QS_fun_dict_pre_
void QS_fun_dict_pre_(void(*const fun)(void), char_t const *name)
Output predefined function-dictionary record.
Definition: qs.c:762
QS_ESC
#define QS_ESC
Escape character of the QS output protocol.
Definition: qs_pkg.h:243
QF_MPOOL_CTR_SIZE
#define QF_MPOOL_CTR_SIZE
The size (in bytes) of the block-counter representation in the native QF event pool.
Definition: qk/qf_port.h:167
QS_QF_CRIT_EXIT
@ QS_QF_CRIT_EXIT
critical section was exited
Definition: qs.h:119
QSPrivAttr::chksum
uint8_t chksum
the checksum of the current record
Definition: qs.h:994
Q_SIGNAL_SIZE
#define Q_SIGNAL_SIZE
The size (in bytes) of the signal of an event.
Definition: qep.h:113
QF_QS_CRIT_EXIT
void QF_QS_CRIT_EXIT(void)
Output the critical section exit.
Definition: qs.c:878
QS_str_fmt_
void QS_str_fmt_(char_t const *str)
Output zero-terminated ASCII string element with format information.
Definition: qs.c:824
QS_usr_dict_pre_
void QS_usr_dict_pre_(enum_t const rec, char_t const *const name)
Output predefined user-dictionary record.
Definition: qs.c:777
QS_ESC_XOR
#define QS_ESC_XOR
Escape modifier of the QS output protocol.
Definition: qs_pkg.h:256
QS_getBlock
const uint8_t * QS_getBlock(uint16_t *pNbytes)
Block-oriented interface to the QS data buffer.
Definition: qs.c:691
QS_str_raw_
void QS_str_raw_(char_t const *str)
Output raw zero-terminated string element (without format information)
Definition: qs.c:617
QS_OBJ_PRE_
#define QS_OBJ_PRE_(obj_)
Definition: qs_pkg.h:121
QS_ALL_RECORDS
@ QS_ALL_RECORDS
all maskable QS records
Definition: qs.h:200
qs_pkg.h
Internal (package scope) QS/C interface.
QS_OBJ_PTR_SIZE
#define QS_OBJ_PTR_SIZE
Definition: qs_port.h:47
QS_onFlush
void QS_onFlush(void)
Callback to flush the QS trace data to the host.
TE_OBJ
@ TE_OBJ
time event object
Definition: qs.h:975
QS_INSERT_BYTE_
#define QS_INSERT_BYTE_(b_)
Internal QS macro to insert an un-escaped byte into the QS buffer.
Definition: qs_pkg.h:217
QSPrivAttr::critNest
uint8_t critNest
critical section nesting level
Definition: qs.h:996
AO_OBJ
@ AO_OBJ
active object
Definition: qs.h:972
QF_MPOOL_SIZ_SIZE
#define QF_MPOOL_SIZ_SIZE
The size (in bytes) of the block-size representation in the native QF event pool.
Definition: qk/qf_port.h:145
QS_getByte
uint16_t QS_getByte(void)
Byte-oriented interface to the QS data buffer.
Definition: qs.c:649
QS_EOD
#define QS_EOD
Constant for End-Of-Data condition returned from QS_getByte()
Definition: qs.h:330
QF_QS_ISR_ENTRY
void QF_QS_ISR_ENTRY(uint8_t const isrnest, uint8_t const prio)
Output the interrupt entry record.
Definition: qs.c:889
QS_CRIT_ENTRY_
#define QS_CRIT_ENTRY_()
This is an internal macro for entering a critical section.
Definition: qs.h:808
Q_BUILD_DATE
const char Q_BUILD_DATE[12]
the calendar date of the last translation of the form: "Mmm dd yyyy"
Definition: qstamp.c:16
QS_FUN_DICT
@ QS_FUN_DICT
function dictionary entry
Definition: qs.h:153
QS_endRec_
void QS_endRec_(void)
Mark the end of a QS record rec.
Definition: qs.c:312
QS_mem_fmt_
void QS_mem_fmt_(uint8_t const *blk, uint8_t size)
Output memory block of up to 255-bytes with format information.
Definition: qs.c:795
QS_EQ_RECORDS
@ QS_EQ_RECORDS
Event Queues QS records.
Definition: qs.h:203
char_t
char char_t
typedef for character strings.
Definition: qassert.h:77
QS_u32_raw_
void QS_u32_raw_(uint32_t d)
Output raw uint32_t data element (without format information)
Definition: qs.c:576
QS_u16_fmt_
void QS_u16_fmt_(uint8_t format, uint16_t d)
output uint16_t data element with format information
Definition: qs.c:470
QF_EQUEUE_CTR_SIZE
#define QF_EQUEUE_CTR_SIZE
The size (in bytes) of the ring-buffer counters used in the native QF event queue implementation.
Definition: qk/qf_port.h:121
QS_TIME_SIZE
#define QS_TIME_SIZE
Definition: qs_port.h:44
QSPrivAttr::used
QSCtr used
number of bytes currently in the ring buffer
Definition: qs.h:992
QS_SC_RECORDS
@ QS_SC_RECORDS
Scheduler QS records.
Definition: qs.h:207
Q_ASSERT_ID
#define Q_ASSERT_ID(id_, test_)
General purpose assertion with user-specified assertion-id.
Definition: qassert.h:155
QS_2u8_raw_
void QS_2u8_raw_(uint8_t d1, uint8_t d2)
output two raw uint8_t data elements (without format information)
Definition: qs.c:536
QS_U0_RECORDS
@ QS_U0_RECORDS
User Group 100-104 records.
Definition: qs.h:208
QS_u16_raw_
void QS_u16_raw_(uint16_t d)
Output raw uint16_t data element (without format information)
Definition: qs.c:555
EQ_OBJ
@ EQ_OBJ
raw queue object
Definition: qs.h:974
Q_REQUIRE_ID
#define Q_REQUIRE_ID(id_, test_)
Assertion for checking preconditions with user-specified assertion-id.
Definition: qassert.h:279
QS_MEM_T
@ QS_MEM_T
up to 255-bytes memory block format
Definition: qs.h:665
QS_U1_RECORDS
@ QS_U1_RECORDS
User Group 105-109 records.
Definition: qs.h:209
QS_obj_raw_
void QS_obj_raw_(void const *const obj)
Output obj pointer data element without format information.
Definition: qs.c:598
QSPrivAttr::buf
uint8_t * buf
pointer to the start of the ring buffer
Definition: qs.h:988
QSPrivAttr::head
QSCtr head
offset to where next byte will be inserted
Definition: qs.h:990
QS_OBJ_DICT
@ QS_OBJ_DICT
object dictionary entry
Definition: qs.h:152
QS_u8_raw_
void QS_u8_raw_(uint8_t d)
output uint8_t data element without format information
Definition: qs.c:519
QS_SIG_DICT
@ QS_SIG_DICT
signal dictionary entry
Definition: qs.h:151
QS_U3_RECORDS
@ QS_U3_RECORDS
User Group 115-119 records.
Definition: qs.h:211
QSPrivAttr::end
QSCtr end
offset of the end of the ring buffer
Definition: qs.h:989
enum_t
int enum_t
typedef for enumerations used for event signals
Definition: qep.h:79
int_t
int int_t
typedef for assertions-ids and line numbers in assertions.
Definition: qassert.h:86
QSPrivAttr
Private QS attributes to keep track of the filters and the trace buffer.
Definition: qs.h:985
QS_CRIT_STAT_
#define QS_CRIT_STAT_
This is an internal macro for defining the critical section status type.
Definition: qs.h:796
QS_END_NOCRIT_PRE_
#define QS_END_NOCRIT_PRE_()
Internal QS macro to end a predefined QS record without exiting critical section.
Definition: qs_pkg.h:90
QF_MAX_ACTIVE
#define QF_MAX_ACTIVE
The maximum number of active objects in the application.
Definition: qk/qf_port.h:58
QS_QF_ISR_ENTRY
@ QS_QF_ISR_ENTRY
an ISR was entered
Definition: qs.h:120
QS_beginRec_
void QS_beginRec_(uint_fast8_t rec)
Mark the begin of a QS record rec.
Definition: qs.c:285
QS_SM_RECORDS
@ QS_SM_RECORDS
State Machine QS records.
Definition: qs.h:201
QS_initBuf
void QS_initBuf(uint8_t sto[], uint_fast16_t stoSize)
Initialize the QS data buffer.
Definition: qs.c:75
QS_QF_ISR_EXIT
@ QS_QF_ISR_EXIT
an ISR was exited
Definition: qs.h:121
uint32_t
unsigned long int uint32_t
exact-width 32-bit unsigned int
Definition: 16bit/stdint.h:31
uint_fast16_t
unsigned int uint_fast16_t
fast at-least 16-bit unsigned int
Definition: 16bit/stdint.h:38
QS_TARGET_INFO
@ QS_TARGET_INFO
reports the Target information
Definition: qs.h:155
Q_BUILD_TIME
const char Q_BUILD_TIME[9]
the time of the last translation of the form: "hh:mm:ss"
Definition: qstamp.c:19