QP/C  6.5.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 /****************************************************************************/
49 extern char_t const Q_BUILD_DATE[12];
50 extern char_t const Q_BUILD_TIME[9];
51 
52 /****************************************************************************/
53 QSPriv QS_priv_; /* QS private data */
54 
55 /****************************************************************************/
80 void QS_initBuf(uint8_t sto[], uint_fast16_t stoSize) {
81  /* the provided buffer must be at least 8 bytes long */
82  Q_REQUIRE_ID(100, stoSize > (uint_fast16_t)8);
83 
84  QS_filterOff((uint_fast8_t)QS_ALL_RECORDS); /* all maskable filters off */
85 
86  QS_priv_.locFilter[SM_OBJ] = (void *)0;
87  QS_priv_.locFilter[AO_OBJ] = (void *)0;
88  QS_priv_.locFilter[MP_OBJ] = (void *)0;
89  QS_priv_.locFilter[EQ_OBJ] = (void *)0;
90  QS_priv_.locFilter[TE_OBJ] = (void *)0;
91  QS_priv_.locFilter[AP_OBJ] = (void *)0;
92 
93  QS_priv_.buf = &sto[0];
94  QS_priv_.end = (QSCtr)stoSize;
95  QS_priv_.head = (QSCtr)0;
96  QS_priv_.tail = (QSCtr)0;
97  QS_priv_.used = (QSCtr)0;
98  QS_priv_.seq = (uint8_t)0;
99  QS_priv_.chksum = (uint8_t)0;
101 
102  /* produce an empty record to "flush" the QS trace buffer */
104  QS_endRec();
105 
106  /* produce the reset record to inform QSPY of a new session */
107  QS_target_info_((uint8_t)0xFF); /* send Reset and Target info */
108 
109  /* wait with flushing after successfull initialization (see QS_INIT()) */
110 }
111 
112 /****************************************************************************/
126  if (rec == (uint_fast8_t)QS_ALL_RECORDS) {
127  uint_fast8_t i;
128  for (i = (uint_fast8_t)0; i < (uint_fast8_t)15; ++i) {
129  QS_priv_.glbFilter[i] = (uint8_t)0xFFU; /* set all bits */
130  }
131  /* never turn the last 3 records on (0x7D, 0x7E, 0x7F) */
132  QS_priv_.glbFilter[sizeof(QS_priv_.glbFilter) - 1U] = (uint8_t)0x1FU;
133  }
134  else if (rec == (uint_fast8_t)QS_SM_RECORDS) {
135  QS_priv_.glbFilter[0] |= (uint8_t)0xFEU;
136  QS_priv_.glbFilter[1] |= (uint8_t)0x03U;
137  QS_priv_.glbFilter[6] |= (uint8_t)0x80U;
138  QS_priv_.glbFilter[7] |= (uint8_t)0x03U;
139  }
140  else if (rec == (uint_fast8_t)QS_AO_RECORDS) {
141  QS_priv_.glbFilter[1] |= (uint8_t)0xFCU;
142  QS_priv_.glbFilter[2] |= (uint8_t)0x07U;
143  QS_priv_.glbFilter[5] |= (uint8_t)0x20U;
144  }
145  else if (rec == (uint_fast8_t)QS_EQ_RECORDS) {
146  QS_priv_.glbFilter[2] |= (uint8_t)0x78U;
147  QS_priv_.glbFilter[5] |= (uint8_t)0x40U;
148  }
149  else if (rec == (uint_fast8_t)QS_MP_RECORDS) {
150  QS_priv_.glbFilter[3] |= (uint8_t)0x03U;
151  QS_priv_.glbFilter[5] |= (uint8_t)0x80U;
152  }
153  else if (rec == (uint_fast8_t)QS_QF_RECORDS) {
154  QS_priv_.glbFilter[3] |= (uint8_t)0xFCU;
155  QS_priv_.glbFilter[4] |= (uint8_t)0xC0U;
156  QS_priv_.glbFilter[5] |= (uint8_t)0x1FU;
157  }
158  else if (rec == (uint_fast8_t)QS_TE_RECORDS) {
159  QS_priv_.glbFilter[4] |= (uint8_t)0x7FU;
160  }
161  else if (rec == (uint_fast8_t)QS_SC_RECORDS) {
162  QS_priv_.glbFilter[6] |= (uint8_t)0x7FU;
163  }
164  else if (rec == (uint_fast8_t)QS_U0_RECORDS) {
165  QS_priv_.glbFilter[8] |= (uint8_t)0xC0U;
166  QS_priv_.glbFilter[9] |= (uint8_t)0xFFU;
167  }
168  else if (rec == (uint_fast8_t)QS_U1_RECORDS) {
169  QS_priv_.glbFilter[10] |= (uint8_t)0xFFU;
170  QS_priv_.glbFilter[11] |= (uint8_t)0x03U;
171  }
172  else if (rec == (uint_fast8_t)QS_U2_RECORDS) {
173  QS_priv_.glbFilter[11] |= (uint8_t)0xFCU;
174  QS_priv_.glbFilter[12] |= (uint8_t)0x0FU;
175  }
176  else if (rec == (uint_fast8_t)QS_U3_RECORDS) {
177  QS_priv_.glbFilter[12] |= (uint8_t)0xF0U;
178  QS_priv_.glbFilter[13] |= (uint8_t)0x3FU;
179  }
180  else if (rec == (uint_fast8_t)QS_U4_RECORDS) {
181  QS_priv_.glbFilter[13] |= (uint8_t)0xC0U;
182  QS_priv_.glbFilter[14] |= (uint8_t)0xFFU;
183  QS_priv_.glbFilter[15] |= (uint8_t)0x1FU;
184  }
185  else if (rec == (uint_fast8_t)QS_UA_RECORDS) {
186  QS_priv_.glbFilter[8] |= (uint8_t)0xC0U;
187  QS_priv_.glbFilter[9] |= (uint8_t)0xFFU;
188  QS_priv_.glbFilter[10] |= (uint8_t)0xFFU;
189  QS_priv_.glbFilter[11] |= (uint8_t)0xFFU;
190  QS_priv_.glbFilter[12] |= (uint8_t)0xFFU;
191  QS_priv_.glbFilter[13] |= (uint8_t)0xFFU;
192  QS_priv_.glbFilter[14] |= (uint8_t)0xFFU;
193  QS_priv_.glbFilter[15] |= (uint8_t)0x1FU;
194  }
195  else {
196  /* record numbers can't exceed QS_ESC, so they don't need escaping */
197  Q_ASSERT_ID(210, rec < (uint_fast8_t)QS_ESC);
198  QS_priv_.glbFilter[rec >> 3] |=
199  (uint8_t)(1U << (rec & (uint_fast8_t)7U));
200  }
201 }
202 
203 /****************************************************************************/
216  uint8_t tmp;
217 
218  if (rec == (uint_fast8_t)QS_ALL_RECORDS) {
219  /* first clear all global filters */
220  for (tmp = (uint8_t)15; tmp > (uint8_t)0; --tmp) {
221  QS_priv_.glbFilter[tmp] = (uint8_t)0;
222  }
223  /* next leave the specific filters enabled */
224  QS_priv_.glbFilter[0] = (uint8_t)0x01U;
225  QS_priv_.glbFilter[7] = (uint8_t)0xFCU;
226  QS_priv_.glbFilter[8] = (uint8_t)0x3FU;
227  }
228  else if (rec == (uint_fast8_t)QS_SM_RECORDS) {
229  QS_priv_.glbFilter[0] &= (uint8_t)(~0xFEU);
230  QS_priv_.glbFilter[1] &= (uint8_t)(~0x03U);
231  QS_priv_.glbFilter[6] &= (uint8_t)(~0x80U);
232  QS_priv_.glbFilter[7] &= (uint8_t)(~0x03U);
233  }
234  else if (rec == (uint_fast8_t)QS_AO_RECORDS) {
235  QS_priv_.glbFilter[1] &= (uint8_t)(~0xFCU);
236  QS_priv_.glbFilter[2] &= (uint8_t)(~0x07U);
237  QS_priv_.glbFilter[5] &= (uint8_t)(~0x20U);
238  }
239  else if (rec == (uint_fast8_t)QS_EQ_RECORDS) {
240  QS_priv_.glbFilter[2] &= (uint8_t)(~0x78U);
241  QS_priv_.glbFilter[5] &= (uint8_t)(~0x40U);
242  }
243  else if (rec == (uint_fast8_t)QS_MP_RECORDS) {
244  QS_priv_.glbFilter[3] &= (uint8_t)(~0x03U);
245  QS_priv_.glbFilter[5] &= (uint8_t)(~0x80U);
246  }
247  else if (rec == (uint_fast8_t)QS_QF_RECORDS) {
248  QS_priv_.glbFilter[3] &= (uint8_t)(~0xFCU);
249  QS_priv_.glbFilter[4] &= (uint8_t)(~0xC0U);
250  QS_priv_.glbFilter[5] &= (uint8_t)(~0x1FU);
251  }
252  else if (rec == (uint_fast8_t)QS_TE_RECORDS) {
253  QS_priv_.glbFilter[4] &= (uint8_t)(~0x7FU);
254  }
255  else if (rec == (uint_fast8_t)QS_SC_RECORDS) {
256  QS_priv_.glbFilter[6] &= (uint8_t)(~0x7FU);
257  }
258  else if (rec == (uint_fast8_t)QS_U0_RECORDS) {
259  QS_priv_.glbFilter[8] &= (uint8_t)(~0xC0U);
260  QS_priv_.glbFilter[9] = (uint8_t)0;
261  }
262  else if (rec == (uint_fast8_t)QS_U1_RECORDS) {
263  QS_priv_.glbFilter[10] = (uint8_t)0;
264  QS_priv_.glbFilter[11] &= (uint8_t)(~0x03U);
265  }
266  else if (rec == (uint_fast8_t)QS_U2_RECORDS) {
267  QS_priv_.glbFilter[11] &= (uint8_t)(~0xFCU);
268  QS_priv_.glbFilter[12] &= (uint8_t)(~0x0FU);
269  }
270  else if (rec == (uint_fast8_t)QS_U3_RECORDS) {
271  QS_priv_.glbFilter[12] &= (uint8_t)(~0xF0U);
272  QS_priv_.glbFilter[13] &= (uint8_t)(~0x3FU);
273  }
274  else if (rec == (uint_fast8_t)QS_U4_RECORDS) {
275  QS_priv_.glbFilter[13] &= (uint8_t)(~0xC0U);
276  QS_priv_.glbFilter[14] = (uint8_t)0;
277  QS_priv_.glbFilter[15] &= (uint8_t)(~0x1FU);
278  }
279  else if (rec == (uint_fast8_t)QS_UA_RECORDS) {
280  QS_priv_.glbFilter[8] &= (uint8_t)(~0xC0U);
281  QS_priv_.glbFilter[9] = (uint8_t)0;
282  QS_priv_.glbFilter[10] = (uint8_t)0;
283  QS_priv_.glbFilter[11] = (uint8_t)0;
284  QS_priv_.glbFilter[12] = (uint8_t)0;
285  QS_priv_.glbFilter[13] = (uint8_t)0;
286  QS_priv_.glbFilter[14] = (uint8_t)0;
287  QS_priv_.glbFilter[15] &= (uint8_t)(~0x1FU);
288  }
289  else {
290  /* record IDs can't exceed QS_ESC, so they don't need escaping */
291  Q_ASSERT_ID(310, rec < (uint_fast8_t)QS_ESC);
292  tmp = (uint8_t)(1U << (rec & (uint_fast8_t)0x07U));
293  tmp ^= (uint8_t)0xFFU; /* invert all bits */
294  QS_priv_.glbFilter[rec >> 3] &= tmp;
295  }
296 }
297 
298 /****************************************************************************/
307  uint8_t b = (uint8_t)(QS_priv_.seq + (uint8_t)1);
308  uint8_t chksum = (uint8_t)0; /* reset the checksum */
309  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
310  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
311  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
312 
313  QS_priv_.seq = b; /* store the incremented sequence num */
314  QS_priv_.used += (QSCtr)2; /* 2 bytes about to be added */
315 
317 
318  chksum = (uint8_t)(chksum + (uint8_t)rec); /* update checksum */
319  QS_INSERT_BYTE((uint8_t)rec) /* rec byte does not need escaping */
320 
321  QS_priv_.head = head; /* save the head */
322  QS_priv_.chksum = chksum; /* save the checksum */
323 }
324 
325 /****************************************************************************/
333 void QS_endRec(void) {
334  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
335  QSCtr head = QS_priv_.head;
336  QSCtr end = QS_priv_.end;
337  uint8_t b = QS_priv_.chksum;
338  b ^= (uint8_t)0xFFU; /* invert the bits in the checksum */
339 
340  QS_priv_.used += (QSCtr)2; /* 2 bytes about to be added */
341 
342  if ((b != QS_FRAME) && (b != QS_ESC)) {
343  QS_INSERT_BYTE(b)
344  }
345  else {
348  ++QS_priv_.used; /* account for the ESC byte */
349  }
350 
351  QS_INSERT_BYTE(QS_FRAME) /* do not escape this QS_FRAME */
352 
353  QS_priv_.head = head; /* save the head */
354 
355  /* overrun over the old data? */
356  if (QS_priv_.used > end) {
357  QS_priv_.used = end; /* the whole buffer is used */
358  QS_priv_.tail = head; /* shift the tail to the old data */
359  }
360 }
361 
362 /****************************************************************************/
363 void QS_target_info_(uint8_t isReset) {
364  uint8_t b;
365 
367  QS_U8_(isReset);
368 
369  QS_U16_(QP_VERSION); /* two-byte version number */
370 
371  /* send the object sizes... */
373  | (uint8_t)((uint8_t)QF_EVENT_SIZ_SIZE << 4));
374 
375 #ifdef QF_EQUEUE_CTR_SIZE
377  | (uint8_t)((uint8_t)QF_TIMEEVT_CTR_SIZE << 4));
378 #else
380 #endif /* QF_EQUEUE_CTR_SIZE */
381 
382 #ifdef QF_MPOOL_CTR_SIZE
384  | (uint8_t)((uint8_t)QF_MPOOL_CTR_SIZE << 4));
385 #else
386  QS_U8_((uint8_t)0);
387 #endif /* QF_MPOOL_CTR_SIZE */
388 
390  | (uint8_t)((uint8_t)QS_FUN_PTR_SIZE << 4));
392 
393  /* send the limits... */
396  | (uint8_t)((uint8_t)QF_MAX_TICK_RATE << 4));
397 
398  /* send the build time in three bytes (sec, min, hour)... */
400  - (uint8_t)'0'))
401  + ((uint8_t)Q_BUILD_TIME[7] - (uint8_t)'0'));
403  - (uint8_t)'0'))
404  + ((uint8_t)Q_BUILD_TIME[4] - (uint8_t)'0'));
405  if ((uint8_t)Q_BUILD_TIME[0] == (uint8_t)' ') {
406  QS_U8_((uint8_t)Q_BUILD_TIME[1] - (uint8_t)'0');
407  }
408  else {
410  - (uint8_t)'0'))
411  + ((uint8_t)Q_BUILD_TIME[1] - (uint8_t)'0'));
412  }
413 
414  /* send the build date in three bytes (day, month, year) ... */
415  if ((uint8_t)Q_BUILD_DATE[4] == (uint8_t)' ') {
416  QS_U8_((uint8_t)Q_BUILD_DATE[5] - (uint8_t)'0');
417  }
418  else {
420  - (uint8_t)'0'))
421  + ((uint8_t)Q_BUILD_DATE[5] - (uint8_t)'0'));
422  }
423  /* convert the 3-letter month to a number 1-12 ... */
424  switch ((int_t)Q_BUILD_DATE[0]
425  + (int_t)Q_BUILD_DATE[1]
426  + (int_t)Q_BUILD_DATE[2])
427  {
428  case (int_t)'J' + (int_t)'a' + (int_t)'n':
429  b = (uint8_t)1;
430  break;
431  case (int_t)'F' + (int_t)'e' + (int_t)'b':
432  b = (uint8_t)2;
433  break;
434  case (int_t)'M' + (int_t)'a' + (int_t)'r':
435  b = (uint8_t)3;
436  break;
437  case (int_t)'A' + (int_t)'p' + (int_t)'r':
438  b = (uint8_t)4;
439  break;
440  case (int_t)'M' + (int_t)'a' + (int_t)'y':
441  b = (uint8_t)5;
442  break;
443  case (int_t)'J' + (int_t)'u' + (int_t)'n':
444  b = (uint8_t)6;
445  break;
446  case (int_t)'J' + (int_t)'u' + (int_t)'l':
447  b = (uint8_t)7;
448  break;
449  case (int_t)'A' + (int_t)'u' + (int_t)'g':
450  b = (uint8_t)8;
451  break;
452  case (int_t)'S' + (int_t)'e' + (int_t)'p':
453  b = (uint8_t)9;
454  break;
455  case (int_t)'O' + (int_t)'c' + (int_t)'t':
456  b = (uint8_t)10;
457  break;
458  case (int_t)'N' + (int_t)'o' + (int_t)'v':
459  b = (uint8_t)11;
460  break;
461  case (int_t)'D' + (int_t)'e' + (int_t)'c':
462  b = (uint8_t)12;
463  break;
464  default:
465  b = (uint8_t)0;
466  break;
467  }
468  QS_U8_(b); /* store the month */
470  - (uint8_t)'0'))
471  + ((uint8_t)Q_BUILD_DATE[10] - (uint8_t)'0'));
472  QS_endRec();
473 }
474 
475 /****************************************************************************/
481 void QS_u8(uint8_t format, uint8_t d) {
482  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
483  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
484  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
485  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
486 
487  QS_priv_.used += (QSCtr)2; /* 2 bytes about to be added */
488 
489  QS_INSERT_ESC_BYTE(format)
491 
492  QS_priv_.head = head; /* save the head */
493  QS_priv_.chksum = chksum; /* save the checksum */
494 }
495 
496 /****************************************************************************/
502 void QS_u16(uint8_t format, uint16_t d) {
503  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
504  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
505  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
506  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
507 
508  QS_priv_.used += (QSCtr)3; /* 3 bytes about to be added */
509 
510  QS_INSERT_ESC_BYTE(format)
511 
512  format = (uint8_t)d;
513  QS_INSERT_ESC_BYTE(format)
514 
515  d >>= 8;
516  format = (uint8_t)d;
517  QS_INSERT_ESC_BYTE(format)
518 
519  QS_priv_.head = head; /* save the head */
520  QS_priv_.chksum = chksum; /* save the checksum */
521 }
522 
523 /****************************************************************************/
528 void QS_u32(uint8_t format, uint32_t d) {
529  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
530  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
531  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
532  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
533  int_fast8_t i;
534 
535  QS_priv_.used += (QSCtr)5; /* 5 bytes about to be added */
536  QS_INSERT_ESC_BYTE(format) /* insert the format byte */
537 
538  /* insert 4 bytes... */
539  for (i = (int_fast8_t)4; i != (int_fast8_t)0; --i) {
540  format = (uint8_t)d;
541  QS_INSERT_ESC_BYTE(format)
542  d >>= 8;
543  }
544 
545  QS_priv_.head = head; /* save the head */
546  QS_priv_.chksum = chksum; /* save the checksum */
547 }
548 
549 /****************************************************************************/
554 void QS_u8_(uint8_t d) {
555  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
556  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
557  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
558  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
559 
560  ++QS_priv_.used; /* 1 byte about to be added */
562 
563  QS_priv_.head = head; /* save the head */
564  QS_priv_.chksum = chksum; /* save the checksum */
565 }
566 
567 /****************************************************************************/
571 void QS_u8u8_(uint8_t d1, uint8_t d2) {
572  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
573  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
574  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
575  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
576 
577  QS_priv_.used += (QSCtr)2; /* 2 bytes are about to be added */
580 
581  QS_priv_.head = head; /* save the head */
582  QS_priv_.chksum = chksum; /* save the checksum */
583 }
584 
585 /****************************************************************************/
590 void QS_u16_(uint16_t d) {
591  uint8_t b = (uint8_t)d;
592  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
593  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
594  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
595  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
596 
597  QS_priv_.used += (QSCtr)2; /* 2 bytes are about to be added */
598 
600 
601  d >>= 8;
602  b = (uint8_t)d;
604 
605  QS_priv_.head = head; /* save the head */
606  QS_priv_.chksum = chksum; /* save the checksum */
607 }
608 
609 /****************************************************************************/
613 void QS_u32_(uint32_t d) {
614  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
615  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
616  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
617  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
618  int_fast8_t i;
619 
620  QS_priv_.used += (QSCtr)4; /* 4 bytes are about to be added */
621  for (i = (int_fast8_t)4; i != (int_fast8_t)0; --i) {
622  uint8_t b = (uint8_t)d;
624  d >>= 8;
625  }
626 
627  QS_priv_.head = head; /* save the head */
628  QS_priv_.chksum = chksum; /* save the checksum */
629 }
630 
631 /****************************************************************************/
636 void QS_str_(char_t const *s) {
637  uint8_t b = (uint8_t)(*s);
638  uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */
639  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
640  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
641  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
642  QSCtr used = QS_priv_.used; /* put in a temporary (register) */
643 
644  while (b != (uint8_t)(0)) {
645  chksum = (uint8_t)(chksum + b); /* update checksum */
646  QS_INSERT_BYTE(b) /* ASCII characters don't need escaping */
647  QS_PTR_INC_(s);
648  b = (uint8_t)(*s);
649  ++used;
650  }
651  QS_INSERT_BYTE((uint8_t)0) /* zero-terminate the string */
652  ++used;
653 
654  QS_priv_.head = head; /* save the head */
655  QS_priv_.chksum = chksum; /* save the checksum */
656  QS_priv_.used = used; /* save # of used buffer space */
657 }
658 
659 /****************************************************************************/
671  uint16_t ret;
672  if (QS_priv_.used == (QSCtr)0) {
673  ret = QS_EOD; /* set End-Of-Data */
674  }
675  else {
676  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
677  QSCtr tail = QS_priv_.tail; /* put in a temporary (register) */
678  ret = (uint16_t)(QS_PTR_AT_(buf, tail)); /* set the byte to return */
679  ++tail; /* advance the tail */
680  if (tail == QS_priv_.end) { /* tail wrap around? */
681  tail = (QSCtr)0;
682  }
683  QS_priv_.tail = tail; /* update the tail */
684  --QS_priv_.used; /* one less byte used */
685  }
686  return ret; /* return the byte or EOD */
687 }
688 
689 /****************************************************************************/
712 uint8_t const *QS_getBlock(uint16_t *pNbytes) {
713  QSCtr used = QS_priv_.used; /* put in a temporary (register) */
714  uint8_t *buf;
715 
716  /* any bytes used in the ring buffer? */
717  if (used != (QSCtr)0) {
718  QSCtr tail = QS_priv_.tail; /* put in a temporary (register) */
719  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
720  QSCtr n = (QSCtr)(end - tail);
721  if (n > used) {
722  n = used;
723  }
724  if (n > (QSCtr)(*pNbytes)) {
725  n = (QSCtr)(*pNbytes);
726  }
727  *pNbytes = (uint16_t)n; /* n-bytes available */
728  buf = &QS_PTR_AT_(QS_priv_.buf, tail); /* the bytes are at the tail */
729 
730  QS_priv_.used = (QSCtr)(used - n);
731  tail += n;
732  if (tail == end) {
733  tail = (QSCtr)0;
734  }
735  QS_priv_.tail = tail;
736  }
737 
738  else { /* no bytes available */
739  *pNbytes = (uint16_t)0; /* no bytes available right now */
740  buf = (uint8_t *)0; /* no bytes available right now */
741  }
742  return buf;
743 }
744 
745 /****************************************************************************/
748 void QS_sig_dict(enum_t const sig, void const * const obj,
749  char_t const *name)
750 {
752 
753  if (*name == (char_t)'&') {
754  QS_PTR_INC_(name);
755  }
756  QS_CRIT_ENTRY_();
758  QS_SIG_((QSignal)sig);
759  QS_OBJ_(obj);
760  QS_STR_(name);
761  QS_endRec();
762  QS_CRIT_EXIT_();
763  QS_onFlush();
764 }
765 
766 /****************************************************************************/
769 void QS_obj_dict(void const * const obj,
770  char_t const *name)
771 {
773 
774  if (*name == (char_t)'&') {
775  QS_PTR_INC_(name);
776  }
777  QS_CRIT_ENTRY_();
779  QS_OBJ_(obj);
780  QS_STR_(name);
781  QS_endRec();
782  QS_CRIT_EXIT_();
783  QS_onFlush();
784 }
785 
786 /****************************************************************************/
789 void QS_fun_dict(void (* const fun)(void), char_t const *name) {
791 
792  if (*name == (char_t)'&') {
793  QS_PTR_INC_(name);
794  }
795  QS_CRIT_ENTRY_();
797  QS_FUN_(fun);
798  QS_STR_(name);
799  QS_endRec();
800  QS_CRIT_EXIT_();
801  QS_onFlush();
802 }
803 
804 /****************************************************************************/
807 void QS_usr_dict(enum_t const rec,
808  char_t const * const name)
809 {
811 
812  QS_CRIT_ENTRY_();
814  QS_U8_((uint8_t)rec);
815  QS_STR_(name);
816  QS_endRec();
817  QS_CRIT_EXIT_();
818  QS_onFlush();
819 }
820 
821 /****************************************************************************/
825 void QS_mem(uint8_t const *blk, uint8_t size) {
826  uint8_t b = (uint8_t)(QS_MEM_T);
827  uint8_t chksum = (uint8_t)(QS_priv_.chksum + b);
828  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
829  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
830  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
831 
832  QS_priv_.used += ((QSCtr)size + (QSCtr)2); /* size+2 bytes to be added */
833 
834  QS_INSERT_BYTE(b)
835  QS_INSERT_ESC_BYTE(size)
836 
837  /* output the 'size' number of bytes */
838  while (size != (uint8_t)0) {
839  b = *blk;
841  QS_PTR_INC_(blk);
842  --size;
843  }
844 
845  QS_priv_.head = head; /* save the head */
846  QS_priv_.chksum = chksum; /* save the checksum */
847 }
848 
849 /****************************************************************************/
854 void QS_str(char_t const *s) {
855  uint8_t b = (uint8_t)(*s);
857  uint8_t *buf = QS_priv_.buf; /* put in a temporary (register) */
858  QSCtr head = QS_priv_.head; /* put in a temporary (register) */
859  QSCtr end = QS_priv_.end; /* put in a temporary (register) */
860  QSCtr used = QS_priv_.used; /* put in a temporary (register) */
861 
862  used += (QSCtr)2; /* account for the format byte and the terminating-0 */
864  while (b != (uint8_t)(0)) {
865  /* ASCII characters don't need escaping */
866  chksum = (uint8_t)(chksum + b); /* update checksum */
867  QS_INSERT_BYTE(b)
868  QS_PTR_INC_(s);
869  b = (uint8_t)(*s);
870  ++used;
871  }
872  QS_INSERT_BYTE((uint8_t)0) /* zero-terminate the string */
873 
874  QS_priv_.head = head; /* save the head */
875  QS_priv_.chksum = chksum; /* save the checksum */
876  QS_priv_.used = used; /* save # of used buffer space */
877 }
878 
#define QF_MPOOL_SIZ_SIZE
macro to override the default QMPoolSize size.
Definition: qmpool.h:48
void QS_u8_(uint8_t d)
output uint8_t data element without format information
Definition: qs.c:554
signed int int_fast8_t
fast at-least 8-bit signed int
Definition: stdint.h:35
void QS_target_info_(uint8_t isReset)
send the Target info (object sizes, build time-stamp, QP version)
Definition: qs.c:363
generic Application-specific object
Definition: qs.h:1085
void QS_onFlush(void)
Callback to flush the QS trace data to the host.
User Group 90-99 records.
Definition: qs.h:181
#define QS_TIME_SIZE
The size (in bytes) of the QS time stamp.
Definition: qs.h:207
uint8_t const * QS_getBlock(uint16_t *pNbytes)
Block-oriented interface to the QS data buffer.
Definition: qs.c:712
QF QS records.
Definition: qs.h:177
User Group 100-109 records.
Definition: qs.h:182
#define QS_PTR_AT_(base_, i_)
access element at index i_ from the base pointer base_
Definition: qs.h:234
void QS_u32_(uint32_t d)
Output uint32_t data element without format information.
Definition: qs.c:613
zero-terminated ASCII string format
Definition: qs.h:805
void QS_str_(char_t const *s)
Output zero-terminated ASCII string element without format information.
Definition: qs.c:636
void QS_fun_dict(void(*const fun)(void), char_t const *name)
Output function dictionary record.
Definition: qs.c:789
void QS_initBuf(uint8_t sto[], uint_fast16_t stoSize)
Initialize the QS data buffer.
Definition: qs.c:80
#define QS_FRAME
Frame character of the QS output protocol.
Definition: qs_pkg.h:73
#define QF_EVENT_SIZ_SIZE
Default value of the macro configurable value in qf_port.h.
Definition: qf.h:50
void QS_u32(uint8_t format, uint32_t d)
Output uint32_t data element with format information.
Definition: qs.c:528
Memory Pools QS records.
Definition: qs.h:175
char_t const Q_BUILD_TIME[9]
object dictionary entry
Definition: qs.h:155
#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
unsigned short uint16_t
exact-width 16-bit unsigned int
Definition: stdint.h:30
uint16_t QS_getByte(void)
Byte-oriented interface to the QS data buffer.
Definition: qs.c:670
#define Q_DEFINE_THIS_MODULE(name_)
Define the user-specified module name for assertions in this file.
Definition: qassert.h:120
void QS_u8u8_(uint8_t d1, uint8_t d2)
output two uint8_t data elements without format information
Definition: qs.c:571
unsigned char uint8_t
exact-width 8-bit unsigned int
Definition: stdint.h:29
Scheduler QS records.
Definition: qs.h:178
event pool object
Definition: qs.h:1082
#define QS_ESC_XOR
Escape modifier of the QS output protocol.
Definition: qs_pkg.h:87
#define QS_FUN_PTR_SIZE
Definition: qs_port.h:50
User Group 110-124 records.
Definition: qs.h:183
#define QS_FUN_(fun_)
Internal macro to output an unformatted function pointer.
Definition: qs.h:784
#define QS_CRIT_EXIT_()
This is an internal macro for exiting a critical section.
Definition: qs.h:635
Event Queues QS records.
Definition: qs.h:174
void QS_obj_dict(void const *const obj, char_t const *name)
Output object dictionary record.
Definition: qs.c:769
#define QF_MPOOL_CTR_SIZE
macro to override the default QMPoolCtr size.
Definition: qmpool.h:75
void QS_mem(uint8_t const *blk, uint8_t size)
Output memory block of up to 255-bytes with format information.
Definition: qs.c:825
State Machine QS records.
Definition: qs.h:172
#define Q_SIGNAL_SIZE
The size (in bytes) of the signal of an event.
Definition: qep.h:115
uint8_t critNest
critical section nesting level
Definition: qs.h:1105
Time Events QS records.
Definition: qs.h:176
unsigned int uint_fast8_t
fast at-least 8-bit unsigned int
Definition: stdint.h:36
#define QS_U16_(data_)
Internal QS macro to output an unformatted uint16_t data element.
Definition: qs.h:730
void QS_u16(uint8_t format, uint16_t d)
output uint16_t data element with format information
Definition: qs.c:502
QSCtr used
number of bytes currently in the ring buffer
Definition: qs.h:1101
int enum_t
typedef for enumerations used for event signals
Definition: qep.h:76
uint16_t QSignal
QSignal represents the signal of an event.
Definition: qep.h:130
#define QF_TIMEEVT_CTR_SIZE
macro to override the default QTimeEvtCtr size.
Definition: qf.h:86
state machine object
Definition: qs.h:1080
all maskable QS records
Definition: qs.h:171
#define QS_ESC
Escape character of the QS output protocol.
Definition: qs_pkg.h:76
#define QS_PTR_INC_(ptr_)
Internal QS macro to increment the given pointer parameter ptr_.
Definition: qs_pkg.h:70
QSPriv QS_priv_
Definition: qs.c:53
unsigned long uint32_t
exact-width 32-bit unsigned int
Definition: stdint.h:31
char char_t
typedef for character strings.
Definition: qassert.h:77
raw queue object
Definition: qs.h:1083
void QS_filterOff(uint_fast8_t rec)
Turn the global Filter off for a given record type rec.
Definition: qs.c:215
#define Q_ASSERT_ID(id_, test_)
General purpose assertion with user-specified assertion-id.
Definition: qassert.h:155
void QS_sig_dict(enum_t const sig, void const *const obj, char_t const *name)
Output signal dictionary record.
Definition: qs.c:748
void const * locFilter[MAX_OBJ]
local QS filters
Definition: qs.h:1096
void QS_str(char_t const *s)
Output zero-terminated ASCII string element with format information.
Definition: qs.c:854
active object
Definition: qs.h:1081
void QS_usr_dict(enum_t const rec, char_t const *const name)
Output user dictionary record.
Definition: qs.c:807
void QS_filterOn(uint_fast8_t rec)
Turn the global Filter on for a given record type rec.
Definition: qs.c:125
void QS_beginRec(uint_fast8_t rec)
Mark the begin of a QS record rec.
Definition: qs.c:306
char_t const Q_BUILD_DATE[12]
unsigned int uint_fast16_t
fast at-least 16-bit unsigned int
Definition: stdint.h:38
QS record for cleanly starting a session.
Definition: qs.h:67
User Group 70-79 records.
Definition: qs.h:179
#define QF_MAX_ACTIVE
The maximum number of active objects in the application.
Definition: qk/qf_port.h:58
function dictionary entry
Definition: qs.h:156
Customizable and memory-efficient assertions for embedded systems.
#define Q_REQUIRE_ID(id_, test_)
Assertion for checking preconditions with user-specified assertion-id.
Definition: qassert.h:273
Internal (package scope) QS/C interface.
Private QS data to keep track of the filters and the trace buffer.
Definition: qs.h:1094
All User records.
Definition: qs.h:184
#define QS_OBJ_(obj_)
Internal macro to output an unformatted object pointer data element.
Definition: qs.h:766
reports the Target information
Definition: qs.h:158
uint8_t seq
the record sequence number
Definition: qs.h:1102
uint8_t glbFilter[16]
global on/off QS filter
Definition: qs.h:1095
uint8_t * buf
pointer to the start of the ring buffer
Definition: qs.h:1097
signal dictionary entry
Definition: qs.h:154
uint_fast16_t QSCtr
QS ring buffer counter and offset type.
Definition: qs.h:1076
#define QF_MAX_EPOOL
Default value of the macro configurable value in qf_port.h.
Definition: qf.h:70
#define QF_MAX_TICK_RATE
Default value of the macro configurable value in qf_port.h.
Definition: qf.h:77
User Group 80-89 records.
Definition: qs.h:180
void QS_u16_(uint16_t d)
Output uint16_t data element without format information.
Definition: qs.c:590
#define QF_EQUEUE_CTR_SIZE
The size (in bytes) of the ring-buffer counters used in the native QF event queue implementation.
Definition: qequeue.h:65
int int_t
typedef for assertions-ids and line numbers in assertions.
Definition: qassert.h:86
Active Object QS records.
Definition: qs.h:173
#define QS_EOD
Constant for End-Of-Data condition returned from QS_getByte()
Definition: qs.h:321
#define QS_U8_(data_)
Internal QS macro to output an unformatted uint8_t data element.
Definition: qs.h:724
uint8_t chksum
the checksum of the current record
Definition: qs.h:1103
up to 255-bytes memory block format
Definition: qs.h:806
void QS_endRec(void)
Mark the end of a QS record rec.
Definition: qs.c:333
QSCtr head
offset to where next byte will be inserted
Definition: qs.h:1099
time event object
Definition: qs.h:1084
QSCtr tail
offset of where next byte will be extracted
Definition: qs.h:1100
user QS record dictionary entry
Definition: qs.h:157
void QS_u8(uint8_t format, uint8_t d)
Output uint8_t data element with format information.
Definition: qs.c:481
#define QS_INSERT_ESC_BYTE(b_)
Internal QS macro to insert an escaped byte into the QS buffer.
Definition: qs_pkg.h:53
#define QS_CRIT_STAT_
This is an internal macro for defining the critical section status type.
Definition: qs.h:611
#define QS_INSERT_BYTE(b_)
Internal QS macro to insert an un-escaped byte into the QS buffer.
Definition: qs_pkg.h:45
#define QS_CRIT_ENTRY_()
This is an internal macro for entering a critical section.
Definition: qs.h:623
QSCtr end
offset of the end of the ring buffer
Definition: qs.h:1098
#define QS_STR_(msg_)
Internal QS macro to output a zero-terminated ASCII string element.
Definition: qs.h:736
#define QS_OBJ_PTR_SIZE
Definition: qs_port.h:47