1. Build rtplot example
Download the example files using:
./scripts/download-examples.sh
Enable debug-link task in user/task/task.mk
# Uncomment the line
SRC += $(PROJ_ROOT)/user/tasks/debug_task.c
Rebuild the source code:
Install rtplot tool to the system:
cd tools/rtplot/
make install
2. Run rtplot example with QEMU
First, execute the following command to launch the Tenok with QEMU:
The output should be similar to the following:
char device redirected to /dev/pts/X (label serial1)
char device redirected to /dev/pts/Y (label serial2)
[ 0.001000000] Tenok RTOS (built time: 11:14:41 Nov 8 2023)
[ 0.001000000] Machine model: stm32f407
[ 0.006000000] chardev console: shell (alias: serial0)
[ 0.008000000] chardev mavlink: mavlink (alias: serial1)
[ 0.008000000] chardev dbglink: debug-link (alias: serial2)
[ 0.008000000] blkdev rom: romfs storage
type `help' for help
user@stm32f407:/$
According to the output, serial2 (debug-link) is redirceted to /dev/pts/Y.
Now open another terminal and execute the following command:
cd tools/rtplot/
make rtplot
After the rtplot window shows up, select /dev/pts/Y port, test message then click the connect button. The user should expect to see some real-time data plotting on the screen.

3. Define debug-link message
Tenok uses a metalanguage to define messages for debug visualization, this message prorocol is called the Debug-Link. All message files should named as *.msg and by default they should be placed in the msg/ directory.
To define a variable, the user can use the following syntax:
type variable "description"
For array, the syntax is:
type array[size] "description"
For example, in test.msg (provided by the ./scripts/download-examples.sh), the messages are defined as:
uint32_t
time "boot time"
float accel[3] "acceleration"
float q[4] "quaternion"
time_t time(time_t *tloc)
Return the time as the number of seconds since 1970-01-01 00:00:00 +0000 (UTC)
Definition: time.c:185
The supported types are:
- bool
- uint8_t
- int8_t
- uint16_t
- int16_t
- uint32_t
- int32_t
- uint64_t
- int64_t
- float
- double
The third description field of the message definition is optional, but it is recommended to not neglect it as it will show up in the real-time plotting graph.
When user execute make all to build the code, the Makefile target calls the msggen tool to generate C code and YAML files. The user should pack their on-board data with the generated C functions and send out the message to their computer via I/Os like USART, USB, etc. To visualize the messages, the user can then use another built-in tool called rtplot, which reads the message definitions from the generated YAML files.
The following code illustrates a basic C code implementation for sending message:
...
#include "debug_link_test_msg.h"
...
void debug_link_task(void)
{
int debug_link_fd =
open(
"/dev/serial2", O_RDWR);
...
debug_link_msg_test_t msg = {
.time = 0,
.accel = {1.0f, 2.0f, 3.0f},
.q = {1.0f, 0.0f, 0.0f, 0.0f}
};
uint8_t buf[100];
while(1) {
size_t size = pack_debug_link_test_msg(&msg, buf);
write(debug_link_fd, buf, size);
...
}
}
int open(const char *pathname, int flags,...)
Open the file specified by the pathname.
Definition: file.c:36
#define HOOK_USER_TASK(_task_func, _priority, _stacksize)
Register a user task to be launched at the start of the system.
Definition: task.h:25
void setprogname(const char *name)
Set the name of the running thread.
Definition: task.c:15
ssize_t write(int fd, const void *buf, size_t count)
Write up to count bytes from the buffer starting at buf to the file referred to by the file descripto...
Definition: file.c:132
int usleep(useconds_t usec)
Suspend execution of the calling thread for a given time in microseconds.
Definition: sched.c:64
The full example code can be found in user/task/debug/debug_task.c.