Skip to the content.

Trice user guide

_(Read this)

SORRY: This document is long and not 100% consistent. Hints or pull requests are welcome.

Table of Contents
    - [*Trice* user guide](#trice-user-guide) - [1. Project structure](#1-project-structure) - [2. Get started](#2-get-started) - [2.1. Get it](#21-get-it) - [2.2. Install It](#22-install-it) - [2.3. Try it](#23-try-it) - [2.4. Use It](#24-use-it) - [2.5. Port it](#25-port-it) - [2.5.1. Target Macros](#251-target-macros) - [2.5.2. Target Trice Stamps](#252-target-trice-stamps) - [2.5.3. Trice Checks](#253-trice-checks) - [2.5.4. Communication Ports](#254-communication-ports) - [2.5.5. Target Code Overview](#255-target-code-overview) - [2.5.6. User Code Adaption](#256-user-code-adaption) - [2.5.7. Limitations](#257-limitations) - [2.5.8. Trice (Time) Stamps](#258-trice-time-stamps) - [2.5.9. Trice Parameter Bit Widths](#259-trice-parameter-bit-widths) - [2.6. Avoid it](#26-avoid-it) - [2.6.1. Parser Limitation](#261-parser-limitation) - [2.6.2. Trice macros in header files](#262-trice-macros-in-header-files) - [2.6.3. Trice macros inside other macros](#263-trice-macros-inside-other-macros) - [3. Build `trice` tool from Go sources (you can skip that)](#3-build-trice-tool-from-go-sources-you-can-skip-that) - [4. Embedded system code configuration](#4--embedded-system-code-configuration) - [5. `trice` tool in logging action](#5-trice-tool-in-logging-action) - [6. Encryption](#6-encryption) - [7. CLI Options for `trice` tool](#7-cli-options-for-trice-tool) - [8. *Trice* command line examples](#8-trice-command-line-examples) - [8.1. Common information](#81-common-information) - [8.2. Further examples](#82-further-examples) - [8.2.1. Automated pre-build insert command example](#821-automated-pre-build-insert-command-example) - [8.2.2. Some Log examples](#822-some-log-examples) - [8.2.3. Logging over a display server](#823-logging-over-a-display-server) - [8.2.4. Logfile output](#824-logfile-output) - [8.2.5. Binary Logfile](#825-binary-logfile) - [8.2.6. TCP output](#826-tcp-output) - [8.2.7. TCP input](#827-tcp-input) - [8.2.8. Stimulate target with a user command over UART](#828-stimulate-target-with-a-user-command-over-uart) - [8.2.9. Explpore and modify channels and their colors](#829-explpore-and-modify-channels-and-their-colors) - [8.2.10. Location Information](#8210-location-information) - [9. Limitations](#9-limitations) - [9.1. Permanent Limitations](#91-permanent-limitations) - [9.1.1. Limitation TRICE in TRICE not possible](#911-limitation-trice-in-trice-not-possible) - [9.2. Current Limitations](#92-current-limitations) - [9.2.1. String Concatenation Within TRICE Macros Not Possible](#921-string-concatenation-within-trice-macros-not-possible) - [9.2.2. Limited Trice Parser Capabilities](#922-limited-trice-parser-capabilities) - [10. Additional hints](#10-additional-hints) - [10.1. Pre-built executables are available](#101-pre-built-executables-are-available) - [10.2. Configuration file `triceConfig.h`](#102-configuration-file-triceconfigh) - [10.3. Setting up the very first connection](#103-setting-up-the-very-first-connection) - [10.4. Avoid buffer overruns](#104-avoid-buffer-overruns) - [10.5. Buffer Macros](#105-buffer-macros) - [10.6. Logfile viewing](#106-logfile-viewing) - [10.7. Using the `trice` tool with 3rd party tools](#107-using-the-trice-tool-with-3rd-party-tools) - [10.8. Several targets at the same time](#108-several-targets-at-the-same-time) - [10.9. Executing `go test -race -count 100 ./...`](#109-executing-go-test--race--count-100-) - [10.10. Direct TRICE Out (TRICE\_MODE TRICE\_STACK\_BUFFER) could cause stack overflow with -o0 optimization](#1010-direct-trice-out-trice_mode-trice_stack_buffer-could-cause-stack-overflow-with--o0-optimization) - [10.11. Cycle Counter](#1011-cycle-counter) - [11. Switching *Trice* ON and OFF](#11-switching-trice-on-and-off) - [11.1. Target side compile-time *Trice* On-Off](#111-target-side-compile-time--trice-on-off) - [11.2. Host side *Trice* On-Off](#112-host-side-trice-on-off) - [12. Framing](#12-framing) - [13. Optional XTEA Encryption](#13-optional-xtea-encryption) - [14. Endianness](#14-endianness) - [15. `TRICE` (Time)Stamps](#15-trice-timestamps) - [16. Binary Encoding](#16-binary-encoding) - [16.1. Symbols](#161-symbols) - [16.2. Package Format](#162-package-format) - [17. Trice Decoding](#17-trice-decoding) - [17.1. *Trice* ID list `til.json`](#171-trice-id-list-tiljson) - [17.2. *Trice* location information file `li.json`](#172-trice-location-information-file-lijson) - [18. *Trice* ID Numbers](#18-trice-id-numbers) - [18.1. ID number selection](#181-id-number-selection) - [18.2. ID number usage and stability](#182-id-number-usage-and-stability) - [18.3. *Trice* ID 0](#183-trice-id-0) - [19. Trice ID management](#19-trice-id-management) - [19.1. *Trices* inside source code](#191-trices-inside-source-code) - [19.1.1. *Trices* in source code comments](#1911-trices-in-source-code-comments) - [19.1.2. Different IDs for same *Trices*](#1912-different-ids-for-same-trices) - [19.1.3. Same IDs for different *Trices*](#1913-same-ids-for-different-trices) - [20. ID reference list **til.json**](#20-id-reference-list-tiljson) - [20.1. **til.json** Version control](#201-tiljson-version-control) - [20.2. Long Time Availability](#202-long-time-availability) - [21. The `trice insert` Algorithm](#21-the-trice-insert-algorithm) - [21.1. Starting Conditions](#211-starting-conditions) - [21.2. Aims](#212-aims) - [21.3. Method](#213-method) - [21.3.1. `insert` Initialization](#2131-insert-initialization) - [21.4. User Code Patching (`trice insert`)](#214-user-code-patching-trice-insert) - [21.5. User Code Patching Examples](#215-user-code-patching-examples) - [21.6. User Code Un-Patching](#216-user-code-un-patching) - [21.7. ID Usage Options](#217-id-usage-options) - [21.8. General ID Management Information](#218-general-id-management-information) - [21.9. Option 1: Let the inserted Trice ID be a Part of the User Code](#219-option-1-let-the-inserted-trice-id-be-a-part-of-the-user-code) - [21.10. Option 2: Cleaning in a Post-build process](#2110-option-2-cleaning-in-a-post-build-process) - [21.11. Option 3: Cleaning on Repository Check-In](#2111-option-3-cleaning-on-repository-check-in) - [22. Changelog](#22-changelog)

1. Project structure

See FilesAndFolders.md

(back to top)

2. Get started

2.1. Get it

2.2. Install It

2.3. Try it

#include "trice.h"

int tryIt( void ){
    trice( "Hello! πŸ‘‹πŸ™‚\a\n" ); // A message with sound and without target timestamp.
}

You can also edit any of your existing project files accordingly. Just replace any printf with trice. (Handle float or double numbers and runtime-generated stings, according to TriceVsPrintfSimilaritiesAndDifferences.md. The file _test/testdata/triceCheck.c shows many usage examples. The uppercase TRICE macros are inlining the complete Trice code and the lowercase trice macros are function calls, so most probably you want use trice to keep the overall code size smaller.

You can use trice insert as pre- and trice clean as post-compile step, to not spoil your source code with IDs.

The optional Trice cache technique avoids un-edited file changes at all, what means no Trice releated build speed disadvantages.

See TriceCacheSpec.md for more details and examples/G1B1_inst/build.sh as example.

A quick setup is possible when using RTT as output channel. Otherwise you need to setup a serial port for Trice data transmission. Other output paths possible too using the auxilary interface.

2.4. Use It

(back to top)

2.5. Port it

Trice should be usable on any MCU with any compiler. On ARM MCUs the easiest way is to use SEGGER J-Link with RTT as output. Setting up UART transmission as alternative or additionally is also no big deal.

Compare folders of one of these folder groups:

Without Instrumentation With Trice Instrumentation
./examples/F030R8_gen ./examples/F030R8_inst
./examples/G0B1_gen ./examples/G0B1_inst
./examples/L432KC_gen_ad_toClang_ed ./examples/L432KC_gen_ad_toClang_ed_instr

This way you see in a quick way any needed adaptions for your target project to port trice to it.

The Readme.md files in the examples folder contain further helpful information.

2.5.1. Target Macros

The easiest and mostly sufficient way to use Trice on the target side is the Trice macro trice which you can mostly use as a printf replacement in legacy code. See TriceVsPrintfSimilaritiesAndDifferences.md for more details. Is uses the TRICE_DEFAULT_PARAMETER_BIT_WIDTH value (usually 32), which is equal for all values. If you wish target stamps use Trice for 16-bit ones or TRice for 32-bit ones.

The macros

are always usable and the number 8, 16, 32, 64 specifies the parameter width, which is equal for all values within one macro. They are partially disabled, when the value TRICE_SINGLE_MAX_SIZE is defined to be smaller than 104. For example with TRICE_SINGLE_MAX_SIZE == 8, TRice32 can have no parameter value (4 byte Trice header, 4 byte stamp) and trice8 can have up to 4 parameter values (4 byte Trice header, 4 byte values) That’s mainly to get compiler errors rather than runtime errors.

More examples:

Trice Header Stamp max. Values Trice Size
trice8 4 0 0 *1 byte 4
… … … … …
trice8 4 0 12 *1 byte 16
Trice8 4 2 0 *1 byte 6
… … … … …
Trice8 4 2 12 *1 byte 18
TRice8 4 4 0 *1 byte 8
… … … … …
TRice8 4 4 12 *1 byte 20
trice16 4 0 2 *2 byte 8
Trice16 4 2 1 *2 byte 8
trice32 4 0 1 *4 byte 8
Trice32 4 2 1 *4 byte 10
TRice32 4 4 2 *4 byte 16
trice64 4 0 1 *8 byte 12
TRice64 4 4 1 *8 byte 16
… … … … …
TRice64 4 4 12 *8 byte 104

The value TRICE_DEFAULT_PARAMETER_BIT_WIDTH is the parameter bit with for the macros trice, Trice, TRice (without number). It can make sense to set this value to 16 on smaller machines.

The full uppercase macro TRICE is a Trice macro only using inline code. Because the main design aim was speed, this was the original design. Then it became clear, that several hundred of TRICE macros increase the needed code amount too much and that it is better to have just a function call instead of having inline macros. If speed matters use TRICE(id(0), TRICE(Id(0), TRICE(ID(0) else use trice(iD(0), Trice(iD(0), TRice(iD(0) or mix usage as you like. The lower case macros internally use TRICE like code but each is only a function call and therefore needs less space.

2.5.2. Target Trice Stamps

Hint: I usually have the 32-bit timestamp as millisecond counter and the 16-bit timestamp as systick counter to measure short execution times.

2.5.3. Trice Checks

2.5.4. Communication Ports

2.5.5. Target Code Overview

File description
trice.h & trice.c trice runtime lib user interface, #include trice.h in project files, where to use TRICE macros. Add trice.c to your embedded device project. Add ./src to your compiler include path.
triceDefaultConfig.h This file contains the most probably settings and serves also as a reference for tuning your project triceConfig.h
File description
cobs.h message packaging, alternatively for tcobs
cobsEncode.c message encoding, alternatively for tcobs
cobsDecode.c message decoding, normally not needed
trice.h trice lib interface
trice.c trice core lib
trice8McuOrder.c trice MCU endianness lib
trice8McuReverse.c trice MCU reverse endianness lib
trice16McuOrder.c trice MCU endianness lib
trice16McuReverse.c trice MCU reverse endianness lib
trice32McuOrder.c trice MCU endianness lib
trice32McuReverse.c trice MCU reverse endianness lib
trice64McuOrder.c trice MCU endianness lib
trice64McuReverse.c trice MCU reverse endianness lib
SEGGER_RTT.h Segger RTT code interface
SEGGER_RTT.c Segger RTT code
tcobs.h message compression and packaging interface
tcobsv1Encode.c message encoding and packaging
tcobsv1Decode.c message decoding and packaging, normally not needed
tcobsv1Internal.h message decoding and packaging internal interface
trice8.h 8-bit trice code interface
trice8.c 8-bit trice code
trice16.h 16-bit trice code interface
trice16.c 16-bit trice code
trice32.h 32-bit trice code interface
trice32.c 32-bit trice code
trice64.h 64-bit trice code interface
trice64.c 64-bit trice code
triceAuxiliary.c trice code for auxiliary interfaces
triceDoubleBuffer.c trice runtime lib extension needed for fastest deferred mode
triceStackBuffer.c trice runtime lib extension needed for direct mode
triceRingBuffer.c trice runtime lib extension needed for recommended deferred mode
xtea.c XTEA message encryption/decryption interface
xtea.c XTEA message encryption/decryption code

(back to top)

2.5.6. User Code Adaption

The Trice macros are designed for maximal execution speed and therefore we have to pay the price for their limited capabilities.

2.5.7. Limitations

You should be aware that these parameter strings go into the target and slow down the execution. So, whenever a string is known at compile time it shuld be part of the Trice format string.

The Trice source code parser has very limited capabilities, so it cannot handle C-preprocessor string conatenation.

2.5.8. Trice (Time) Stamps

2.5.9. Trice Parameter Bit Widths

Hint: With the defaut TCOBS framing 8-bit values as 32-bit parameters typically occupy only 2-bytes during transmission.

2.6. Avoid it

2.6.1. Parser Limitation

Because the implemented source code parser for trice insert and trice clean is only a simple one, there is one important limitation:

trice( "hi 0" );
// An "allowed" example comment.
trice( "hi 1");
// An \" allowed example comment.
trice( "hi 2");
// A " NOT allowed example comment. This disrupts the parsing.
trice( "hi 3");
// A " NOT allowed example comment. This enables the parsing after a disruption.
trice( "hi 4");

2.6.2. Trice macros in header files

2.6.3. Trice macros inside other macros

(back to top)

3. Build trice tool from Go sources (you can skip that)

ms@DESKTOP-7POEGPB MINGW64 /c/repos/trice (master)
$ go clean -cache

ms@DESKTOP-7POEGPB MINGW64 /c/repos/trice (master)
$ go vet ./...

ms@DESKTOP-7POEGPB MINGW64 /c/repos/trice (master)
$ go test ./...
?       github.com/rokath/trice/cmd/cui [no test files]
ok      github.com/rokath/trice/cmd/stim        0.227s
ok      github.com/rokath/trice/cmd/trice       0.577s
ok      github.com/rokath/trice/internal/args   0.232s
ok      github.com/rokath/trice/internal/charDecoder    0.407s
ok      github.com/rokath/trice/internal/com    1.148s
ok      github.com/rokath/trice/internal/decoder        0.412s [no tests to run]
?       github.com/rokath/trice/internal/do     [no test files]
ok      github.com/rokath/trice/internal/dumpDecoder    0.388s
ok      github.com/rokath/trice/internal/emitter        0.431s
ok      github.com/rokath/trice/internal/id     0.421s
ok      github.com/rokath/trice/internal/keybcmd        0.431s
ok      github.com/rokath/trice/internal/link   0.404s
ok      github.com/rokath/trice/internal/receiver       0.409s
ok      github.com/rokath/trice/internal/tleDecoder     0.398s
?       github.com/rokath/trice/internal/translator     [no test files]
ok      github.com/rokath/trice/internal/trexDecoder    0.391s
ok      github.com/rokath/trice/pkg/cipher      0.377s
ok      github.com/rokath/trice/pkg/endian      0.302s
ok      github.com/rokath/trice/pkg/msg 0.299s
ok      github.com/rokath/trice/pkg/tst 0.406s

To execute the target code tests, you can run test.sh or cd into _test and run go test ./... from there. ATTENTION: These tests run a significant long time (many minutes depending on your machine), because the Go - C border is crossed very often. The last tests can last quite a while, depending on your machine.

ms@DESKTOP-7POEGPB MINGW64 /c/repos/trice (master)
$ go install ./cmd/trice/

Afterwards you should find an executable trice inside $GOPATH/bin/ and you can modify its source code.

(back to top)

4. Embedded system code configuration

Check comments inside triceDefaultConfig.h and adapt your project configuration like shown in triceConfig.h as example.

(back to top)


5. trice tool in logging action

With trice log -port COM12 you can visualize the trices on the PC, if for example COM12 is receiving the data from the embedded device at the 115200 default baudrate.

The following capture output comes from an (old) example project inside ../examples.

life.gif

See ../_test/testdata/triceCheck.c for reference. The Trices can come mixed from inside interrupts (light blue ISR:...) or from normal code. For usage with a RTOS, Trices are protected against breaks (TRICE_ENTER_CRITICAL_SECTION, TRICE_LEAVE_CRITICAL_SECTION). Regard the differences in the read SysTick values inside the GIF above These differences are the MCU clocks needed for one trice (~0,25Β΅s@48MHz).

Use the -color off switch for piping output in a file. More convenient is the -lf auto switch.

(back to top)

6. Encryption

(back to top)

7. CLI Options for trice tool

The trice tool is very easy to use even it has a plenty of options. Most of them normally not needed. The trice tool can be started in several modes (sub-commands), each with several mandatory or optional switches. Switches can have parameters or not.

trice sub-command -switch1 -switch2 parameter -switch3 ...

Which sub-command switches are usable for each sub-command is shown with trice help -all. This gives also information about their default values.

Info for a special sub-command is shown with trice h -l, trice h -z, … .

(back to top)

8. Trice command line examples

8.1. Common information

8.2. Further examples

8.2.1. Automated pre-build insert command example

trice i -v -i ../../../til.json -src ../src -src ../lib/src -src ./

This is a typical line you can add to your project as an automatic pre-compile step.

8.2.2. Some Log examples

trice log -i ./myProject/til.json -p=COM3
trice l -s COM3 -baud=9600

8.2.3. Logging over a display server

trice ds
trice l -ds -p COM3
trice sd -r 192.168.1.23:45678

8.2.4. Logfile output

trice l -p COM3 -logfile auto

This creates a new logfile 2022-05-16_2216-40_trice.log with the actual timestamp on each trice start.

trice l -p COM3 -logfile trice.log

This creates a new logfile trice.log on first start and appends to it on each next trice start.

Logfiles are text files one can see with 3rd party tools. Example: cat trice.log. They contain also the PC reception timestamps if where enabled.

8.2.5. Binary Logfile

trice l -p COM3 -binaryLogfile auto

This creates a new binary logfile 2022-05-16_2216-40_trice.bin with the actual timestamp on each trice start.

trice l -p COM3 -binaryLogfile trice.bin

This creates a new binary logfile trice.bin on first start and appends to it on each next trice start.

Binary logfiles store the trice messages as they come out of the target in binary form. They are much smaller than normal logfiles, but the trice tool with the til.json is needed for displaying them and the PC timestamps are the displaying time: trice l -p FILEBUFFER -args trice.log.

Binary logfiles are handy in the field for long data recordings.

When using RTT, the data are exchanged over a file interface. These binary logfiles are stored in the project [./temp] folder and accessable for later view: trice l -p FILEBUFFER -args ./temp/logfileName.bin. Of course the host timestamps are the playing time then.

8.2.6. TCP output

trice l -p COM3 -tcp 127.0.0.1:23

This additionally sends trice output to a 3rd party TCP listener, for example like Putty:

./ref/PuttyConfig1.PNG ./ref/PuttyConfig2.PNG ./ref/Putty.PNG

8.2.7. TCP input

trice l -p TCP4 -args "192.168.2.3:45678"

This expects a TCP4 server at IP address 192.168.2.3 with port number 45678 to read binary Trice data from.

8.2.8. Stimulate target with a user command over UART

Sometimes it is handy to stimulate the target during development. For that a 2nd screen is helpful what is possible using the display server option:

./ref/UARTCommandAnimation.gif

8.2.9. Explpore and modify channels and their colors

See file TriceColor.md

8.2.10. Location Information

When running trice insert, a file li.json is created, what you can control with the -li|locationInformation switch. During logging, when li.json is found, automatically the filename and line number is displayed in front of each log line, controllable with the -liFmt switch. This information is correct only with the right version of the li.json file. That is usually the case on the PC during development. Out in the field only the til.json reference is of importance. It serves as an accumulator of all firmware versions and usually the latest version of this file is the best fit. The li.json file should stay with the software developer only and needs no version control in the usual case because it is rebuild with each compilation, when trice i is a prebuild step. When trice clean is used, the file li.json should go into the version management too to secure that identical trices get the same ID back.

(back to top)

9. Limitations

9.1. Permanent Limitations

9.1.1. Limitation TRICE in TRICE not possible

int f0( void ){ TRICE( "msg:f0\n"); return 0; }
void f1( void ){ TRICE( "No; %d", f0() ); }

The reason is: When f1() gets active, the β€œNo” Trice header is created, than the f0() Trice is executed and afterwards the β€œNo” Trice tail is written. This works well during compile time but causes a mismatch during runtime.

int f0( void ){ TRICE( "msg:f0\n"); return 0; }
void f1( void ){ int x = f0(); TRICE( "Yes: %d", x ); }

9.2. Current Limitations

9.2.1. String Concatenation Within TRICE Macros Not Possible

String concatenation within TRICE macros does not work. The reason lays inside the way the trice tool parser works:

void f0( void ){ TRICE( "msg:" ## "Hello\n" ); } // ERROR!

To implement this would need to build a trice preprocessor or to run the C preprocessor first and to modify the preprocessor output with the trice tool. That would make things unneccessary complicate and fragile for now.

9.2.2. Limited Trice Parser Capabilities

The Trice tool internal parser has only limited capabilities. In works well in most cases, but could led to problems in some cases. The compiler run will for sure end up with some error messages in the following examples, so the developer can fix the code.

An example, provided by @KammutierSpule, is this:

void trice0_test() {
    Trice0( "OK");
    Trice( InvalidUse );
    Trice( "OK", Variable );
}
void trice0_test() {
    Trice0( iD(2740), "OK"); // ok, iD is added
    Trice( InvalidUse ); // no warning or error
    Trice( "OK", Variable ); // id is not added / inserted
}

As said, the compiler will complain about that in any case.

10. Additional hints

10.1. Pre-built executables are available

See https://github.com/rokath/trice/releases.

10.2. Configuration file triceConfig.h

10.3. Setting up the very first connection

If you see nothing in the beginning, what is normal ;-), add the -s (-showInputBytes) switch to see if any data arrive. There is also a switch -debug showing you the received packages, if you are interested in.

10.4. Avoid buffer overruns

It is your responsibility to produce less data than transmittable. If this is not guarantied, a data loss is not avoidable or you have to slow down the user application. The buffers have an optional overflow protection (TRICE_PROTECT), which is enabled by default. Recommendation: Make the buffer big and emit the maxDepth cyclically, every 10 or 1000 seconds. Then you know the needed size. It is influenced by the max Trice data burst and the buffer switch interval. See ./example/exampleData/triceLogDiagData.c for help.

If the target application produces more Trice data than transmittable, a buffer overrun can let the target crash, because for performance reasons no overflow check is implemented in versions before v0.65.0. Such a check is added now per default using TRICE_PROTECT, but the Trice code can only throw data away in such case. Of course you can disable this protection to get more speed.

Configuring the ring buffer option with TRICE_PROTECT == 0 makes buffer overruns not completely impossible, because due to partial Trice log overwrites, false data are not excluded anymore and overwriting the buffer boundaries is possible, because of wrong length information. Also losses will occur when producing more data than transmittable. This is detectable with the cycle counter. The internal 8-bit cycle counter is usually enabled. If Trice data are lost, the receiver side will detect that because the cycle counter is not as expected. There is a chance of 1/256 that the detection does not work for a single case. You can check the detection by unplugging the trice UART cable for a time. Also resetting the target during transmission should display a cycle error.

Gennerally it is recommended to enable TRICE_PROTECT during development and to disable it for performance, if you are 100% sure, that not more data are producable than transmittable.

Important to know: If the TRICE_PROTECT code inhibits the writing into a buffer, there will be later no cycle error because a non existing Trice cannot cause a cycle error. Therefore the TriceDirectOverflowCount and TriceDeferredOverflowCount values exist, which could be monitored.

10.5. Buffer Macros

(Examples in ../_test/testdata/triceCheck.c)

Macro Name Description Β  Β 
triceS |TriceS |TRiceS |TRICE_S Output of runtime generated 0-terminated strings. Β  Β 
triceN |TriceN |TRiceN |TRICE_N Is for byte buffer output as string until the specified size. It allows limiting the string size to a specific value and does not rely on a terminating 0. If for example len = 7 is given and β€œHello\0World\n” is in the buffer, the byte sequence β€œHello\0W” is transmitted but the trice tool probably shows only β€œHello”. Β  Β 
trice8B |Trice8B |TRice8B |TRICE8_B Is for byte buffer output according to the given format specifier for a single byte. Β  Β 
trice16B|Trice16B|TRice16B|TRICE16_B Is for 16-bit buffer output according to the given format specifier for a 16-bit value. Β  Β 
trice32B|Trice32B|TRice32B|TRICE32_B Is for 32-bit buffer output according to the given format specifier for a 32-bit value. Β  Β 
triceB |TriceB |TRiceB |TRICE_B Is buffer output according to the given format specifier for a default unit according to configuration (8 16 32-bit value).

10.6. Logfile viewing

Logfiles, trice tool generated with sub-command switch -color off, are normal ASCII files. If they are with color codes, these are ANSI escape sequences.

10.7. Using the trice tool with 3rd party tools

Parallel output as logfile, TCP or binary logfile is possible. See examples above.

10.8. Several targets at the same time

You can connect each target over its transmit channel with an own trice instance and integrate all transmissions line by line in an additional trice instance acting as display server. See https://github.com/rokath/trice#display-server-option.

10.9. Executing go test -race -count 100 ./...

The C-code is executed during some tests. Prerequisite is an installed GCC.

10.10. Direct TRICE Out (TRICE_MODE TRICE_STACK_BUFFER) could cause stack overflow with -o0 optimization

As discussed in issue #294 it can happen, that several TRICE macros within one function call increase the stack usage more than expected, when compiler optimization is totally switched off.

10.11. Cycle Counter

(back to top)

11. Switching Trice ON and OFF

11.1. Target side compile-time Trice On-Off

#define TRICE_OFF 1
#include "trice.h"
void fn(void) { 
    trice( iD(123), "Hi"); // Will generate code only, when TRICE_OFF == 0.
    trice( "Lo");          // Will generate code only, when TRICE_OFF == 0.
}

With #define TRICE_OFF 1 macros in this file are ignored completely by the compiler, but not by the trice tool. In case of re-constructing the Trice ID List these no code generating macros are regarded and go into (or stay inside) the ID reference list.

(back to top)

11.2. Host side Trice On-Off

(back to top)

12. Framing

(back to top)

13. Optional XTEA Encryption

(back to top)

14. Endianness

(back to top)

15. TRICE (Time)Stamps

It is up to the user to provide the functions TriceStamp16 and/or TriceStamp32. Normally they return a Β΅s or ms tick count but any values are allowed.

(back to top)

16. Binary Encoding

16.1. Symbols

Symbol Meaning
i ID bit
I iiiiiiii = ID byte
n number bit
z count selector bit
s stamp selector bit
N znnnnnnnn = count selector bit plus 7-bit number byte
c cycle counter bit
C z==0 ? cccccccc : nnnnnnnn = cycle counter byte or number byte extension
t (time)stamp bit
T tttttttt = (time)stamp byte
d data bit
D dddddddd = data byte
... 0 to 32767 data bytes
"..." format string
W bit width 8, 16, 32 or 64 (uW stands for u8, u16, or u64)
x unspecified bit
X =xxxxxxxx unspecified byte

16.2. Package Format

(back to top)

17. Trice Decoding

The 14-bit IDs are used to display the log strings. These IDs are pointing in two reference files.

17.1. Trice ID list til.json

17.2. Trice location information file li.json

(back to top)

18. Trice ID Numbers

18.1. ID number selection

18.2. ID number usage and stability

18.3. Trice ID 0

(back to top)

19. Trice ID management

19.1. Trices inside source code

19.1.1. Trices in source code comments

19.1.2. Different IDs for same Trices

19.1.3. Same IDs for different Trices

(back to top)

20. ID reference list til.json

20.1. til.json Version control

For the no-ids option deleting til.json should not not be done when the sources are without IDs. That would result in a loss of the complete ID history and a assignment of a complete new set of IDs.

20.2. Long Time Availability

(back to top)

21. The trice insert Algorithm

21.1. Starting Conditions

21.2. Aims

21.3. Method

21.3.1. insert Initialization

// insertIDsData holds the insert run specific data.
type insertIDsData struct {
    idToFmt    TriceIDLookUp     // idToFmt is a trice ID lookup map and is generated from existing til.json file at the begin of SubCmdIdInsert. This map is only extended during SubCmdIdInsert and goes back into til.json afterwards.
    fmtToId    triceFmtLookUp    // fmtToId is a trice fmt lookup map (reversed idToFmt for faster operation) and kept in sync with idToFmt. Each fmt can have several trice IDs (slice).
    idToLocRef TriceIDLookUpLI   // idToLocInf is the trice ID location information as reference generated from li.json (if exists) at the begin of SubCmdIdInsert and is not modified at all. At the end of SubCmdIdInsert a new li.json is generated from itemToId.
    itemToId   TriceItemLookUpID // itemToId is a trice item lookup ID map, extended from source tree during SubCmdIdInsert after each found and maybe modified trice item.
    idToItem   TriceIDLookupItem // idToItem is a trice ID lookup item map (reversed itemToId for faster operation) and kept in sync with itemToId.
}

Until here the algorithm seem to be ok.

21.4. User Code Patching (trice insert)

21.5. User Code Patching Examples

21.6. User Code Un-Patching

21.7. ID Usage Options

21.8. General ID Management Information

21.9. Option 1: Let the inserted Trice ID be a Part of the User Code

21.10. Option 2: Cleaning in a Post-build process

21.11. Option 3: Cleaning on Repository Check-In

(back to top)

22. Changelog

Details
    | Date | Version | Comment | | ----------- | ------- | ------------------------------------------------------------------------------------------------------------ | | 2022-MAR-15 | 0.0.0 | Initial Draft | | 2022-MAR-15 | 0.1.0 | Minor corrections applied. | | 2022-MAR-15 | 0.2.0 | Sigil byte encoding clarified. | | 2022-MAR-15 | 0.3.0 | Forward versus backward COBS encoding discussion inserted. | | 2022-MAR-15 | 0.4.0 | Forward versus backward COBS encoding reworked. Disruption detection added. | | 2022-MAR-15 | 0.5.0 | Minor corrections | | 2022-MAR-16 | 0.6.0 | TCOBS prime number comment added, simplified | | 2022-MAR-17 | 0.7.0 | TCOBS move into a separate [TCOBS Specification](/trice/docs/TCOBSSpecification.html), Framing more detailed. | | 2022-MAR-20 | 0.7.1 | Contributive *Trice* extension remark added. | | 2022-APR-12 | 0.8.0 | TREX mainstream format changed to timestamps immediate after ID. | | 2022-MAY-20 | 0.8.1 | Formatting, Spelling | | 2022-JUN-19 | 0.9.0 | Implementation hint added to chapter Framing. | | 2022-AUG-14 | 0.10.0 | Chapter ID Management added | | 2022-AUG-19 | 0.11.0 | Chapter Main Stream Logs changed/extended | | 2022-SEP-15 | 0.11.1 | TS32, TS16, NOTS, MOD7 added | | 2022-OCT-08 | 0.11.2 | S0...X3 added | | 2022-NOV-28 | 0.11.3 | +[#337](https://github.com/rokath/trice/issues/337) in [Framing](#Framing) | | 2022-DEC-11 | 0.12.0 | restructured | | 2022-DEC-13 | 0.13.0 | unneeded text removed, some clarifications | | 2023-JAN-14 | 0.14.0 | Formatting improved, [1. Trice User Interface - Quick Start](#1--trice-user-interface---quick-start) added. | | 2023-JAN-14 | 0.15.0 | [5.1. The `trice insert` algorithm](#51-the-trice-insert-algorithm) added | | 2023-JAN-21 | 0.15.1 | Corrections | | 2023-FEB-25 | 0.16.0 | Many parts reworked and restructured | | 2023-JUN-10 | 0.17.0 | trice insert algorithm refined | | 2023-AUG-03 | 0.18.0 | update ---> insert | | 2024-AUG-18 | 0.19.0 | Mainly updates to current Trice version v0.66.0 | | 2024-SEP-17 | 0.20.0 | TCP4 input hint added | | 2024-SEP-25 | 0.21.0 | Chapter "Target Macros" added | | 2024-NOV-11 | 0.22.0 | Whole document re-read aud updated. |

    (back to top)

<!–

_### 3. TREX (TRice EXtendable) encoding

(back to top)

_### 4. ID Management

TRICE( id(0), "...", ...); // a trice without stamp
TRICE( Id(0), "...", ...); // a trice with a 16-bit stamp
TRICE( ID(0), "...", ...); // a trice with a 32-bit stamp

For the implementation of the optional Trice extensions (see below), a til.json format extension is needed because several files are unhandy. Both til.json formats will be accepted in the future. –> <!–

(back to top)

_### 2. Compatibility

Possible better implementation: See issue #290

COBS: See #337

TRICE( S0, "...", ...); // a trice without stamp
TRICE( S2, "...", ...); // a trice with a 16-bit stamp
TRICE( S4, "...", ...); // a trice with a 32-bit stamp
TRICE( S8, "...", ...); // a trice with a 64-bit stamp
TRICE( X0, "...", ...); // an extended type 0 trice 
TRICE( X1, "...", ...); // an extended type 1 trice 
TRICE( X2, "...", ...); // an extended type 2 trice 
TRICE( X3, "...", ...); // an extended type 3 trice 
6.1. Trice format

_##### 3.2. Framing with TCOBS encoding