Repository: try-fork-it-twice/scanf
Pull request #8: Add SCANF_CONFIG_TraceMessage #4
Author: login: ivatolm
Created: 2025-05-04T22:43:56Z | Merged: 2025-05-19T09:58:19Z



Diff:
diff --git a/.gitignore b/.gitignore
index d163863..ee41cb1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-build/
\ No newline at end of file
+build/
+a.out
\ No newline at end of file
diff --git a/samples/example.c b/samples/example.c
index 0371ae7..4ad06a7 100644
--- a/samples/example.c
+++ b/samples/example.c
@@ -1,19 +1,57 @@
 #include <FreeRTOS.h>
 #include <assert.h>
 #include <queue.h>
+#include <scanf.h>
 #include <semphr.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <task.h>
 #include <timers.h>
 
-#include <scanf.h>
-
 static void exampleTask(void* parameters) __attribute__((noreturn));
 
 static void exampleTask(void* parameters) {
+    size_t i = 0;
+    for (;;) {
+        printf("Tick 0\n");
+        for (size_t j = 0; j < 10000; j++) {
+            printf("1\n");
+        }
+        vTaskDelay(1);
+
+        if (i++ == 100) {
+            SCANF_Tracelog* tl = scanf_get_tracelog();
+            printf("Saving trace log. Trace log size %d\n", tl->size);
+            scanf_stop_tracing();
+            scanf_save_tracelog("data.bin");
+            exit(0);
+        }
+    }
+}
+
+static void exampleTask1(void* parameters) __attribute__((noreturn));
+
+static void exampleTask1(void* parameters) {
+    size_t i = 0;
+    for (;;) {
+        printf("Tick 1\n");
+        for (size_t j = 0; j < 50000; j++) {
+            printf("2\n");
+        }
+        vTaskDelay(5);
+    }
+}
+
+static void exampleTask2(void* parameters) __attribute__((noreturn));
+
+static void exampleTask2(void* parameters) {
+    size_t i = 0;
     for (;;) {
-        printf("Tick\n");
-        vTaskDelay(100);
+        printf("Tick 2\n");
+        for (size_t j = 0; j < 100000; j++) {
+            printf("3\n");
+        }
+        vTaskDelay(10);
     }
 }
 
@@ -21,6 +59,12 @@ int main(void) {
     static StaticTask_t exampleTaskTCB;
     static StackType_t exampleTaskStack[configMINIMAL_STACK_SIZE];
 
+    static StaticTask_t exampleTask1TCB;
+    static StackType_t exampleTask1Stack[configMINIMAL_STACK_SIZE];
+
+    static StaticTask_t exampleTask2TCB;
+    static StackType_t exampleTask2Stack[configMINIMAL_STACK_SIZE];
+
     printf("Example FreeRTOS Project\n");
 
     const int BUFFER_SIZE = 1024;
@@ -34,12 +78,14 @@ int main(void) {
 
     scanf_start_tracing();
 
-    xTaskCreateStatic(exampleTask, "example", configMINIMAL_STACK_SIZE, NULL,
-        configMAX_PRIORITIES - 1U, &(exampleTaskStack[0]), &(exampleTaskTCB));
+    xTaskCreateStatic(exampleTask, "task0", configMINIMAL_STACK_SIZE, NULL,
+                      configMAX_PRIORITIES - 1U, &(exampleTaskStack[0]), &(exampleTaskTCB));
 
-    scanf_stop_tracing();
+    xTaskCreateStatic(exampleTask1, "task1", configMINIMAL_STACK_SIZE, NULL,
+                      configMAX_PRIORITIES - 1U, &(exampleTask1Stack[0]), &(exampleTask1TCB));
 
-    scanf_save_tracelog("data.bin");
+    xTaskCreateStatic(exampleTask2, "task2", configMINIMAL_STACK_SIZE, NULL,
+                      configMAX_PRIORITIES - 1U, &(exampleTask2Stack[0]), &(exampleTask2TCB));
 
     vTaskStartScheduler();
     assert(0 && "Should not reach here.");
diff --git a/src/messages.h b/src/messages.h
index 4ffcf7e..13f34c2 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -6,12 +6,25 @@
 #define SCANF_MAX_TASK_NAME_LEN 64
 
 typedef enum __attribute__((__packed__)) {
-    SCANF_TASK_CREATE = 0,
+    SCANF_CONFIG = 0,
+    SCANF_TASK_CREATE,
     SCANF_TASK_SWITCHED_IN,
     SCANF_TASK_SWITCHED_OUT
 } SCANF_EventType;
 static_assert(sizeof(SCANF_EventType) == 1, "sizeof(SCANF_EventType) > 1");
 
+typedef struct __attribute__((__packed__)) {
+    uint8_t major;
+    uint8_t minor;
+    uint8_t patch;
+} SCANF_Version;
+
+typedef struct __attribute__((__packed__)) {
+    SCANF_EventType event_type;
+    SCANF_Version version;
+    uint8_t config_max_task_name_len;
+} SCANF_CONFIG_TraceMessage;
+
 typedef struct __attribute__((__packed__)) {
     SCANF_EventType event_type;
     uint32_t timestamp;
diff --git a/src/scanf.c b/src/scanf.c
index 59d067f..c3208ba 100644
--- a/src/scanf.c
+++ b/src/scanf.c
@@ -1,49 +1,50 @@
 #include "scanf.h"
 
 #include <FreeRTOS.h>
-#include <task.h>
-
-#include <stddef.h>
+#include <errno.h>
 #include <stdbool.h>
-#include <string.h>
+#include <stddef.h>
 #include <stdio.h>
-#include <errno.h>
+#include <string.h>
+#include <task.h>
 
 static SCANF_Tracelog *_tracelog = NULL;
 static bool _is_tracing = false;
 
-void scanf_init(SCANF_Tracelog *tracelog)
-{
+void scanf_init(SCANF_Tracelog *tracelog) {
     if (!tracelog) return;
     _tracelog = tracelog;
+    scanf_reset();
 }
 
-SCANF_Tracelog *scanf_get_tracelog()
-{
-    return _tracelog;
-}
+SCANF_Tracelog *scanf_get_tracelog() { return _tracelog; }
 
-void scanf_reset()
-{
+void scanf_reset() {
     if (!_tracelog) return;
     _tracelog->size = 0;
-}
 
-void scanf_start_tracing()
-{
+    static SCANF_CONFIG_TraceMessage config_message;
+    config_message.event_type = SCANF_CONFIG;
+    // TODO: Pass version through CMake
+    config_message.version.major = 0;
+    config_message.version.minor = 2;
+    config_message.version.patch = 0;
+    config_message.config_max_task_name_len = SCANF_MAX_TASK_NAME_LEN;
+
+    bool prev_is_tracing = _is_tracing;
     _is_tracing = true;
+    _scanf_save_trace((void *)&config_message, sizeof(config_message));
+    _is_tracing = prev_is_tracing;
 }
 
-void scanf_stop_tracing()
-{
-    _is_tracing = false;
-}
+void scanf_start_tracing() { _is_tracing = true; }
+
+void scanf_stop_tracing() { _is_tracing = false; }
 
-int scanf_save_tracelog(const char *filepath)
-{
+int scanf_save_tracelog(const char *filepath) {
     if (!_tracelog) return -EINVAL;
     if (_is_tracing) return -EBUSY;
-    FILE *file = fopen(filepath, "ab");
+    FILE *file = fopen(filepath, "wb");
     if (!file) {
         return -EINVAL;
     }
@@ -56,8 +57,7 @@ int scanf_save_tracelog(const char *filepath)
     return 0;
 }
 
-void _scanf_save_trace(const void *message, uint32_t message_size)
-{
+void _scanf_save_trace(const void *message, uint32_t message_size) {
     if (!_tracelog) return;
     if (!_is_tracing) return;
     if ((_tracelog->size + message_size) >= _tracelog->capacity) return;
@@ -65,7 +65,4 @@ void _scanf_save_trace(const void *message, uint32_t message_size)
     _tracelog->size += message_size;
 }
 
-uint32_t _scanf_get_timestamp()
-{
-    return (xTaskGetTickCount() * 1000000) / configTICK_RATE_HZ;
-}
+uint32_t _scanf_get_timestamp() { return (xTaskGetTickCount() * 1000000) / configTICK_RATE_HZ; }
diff --git a/src/scanf_hooks.h b/src/scanf_hooks.h
index 344bea2..730858a 100644
--- a/src/scanf_hooks.h
+++ b/src/scanf_hooks.h
@@ -13,32 +13,32 @@ extern "C" {
 void _scanf_save_trace(const void *message, uint32_t size);
 uint32_t _scanf_get_timestamp();
 
-#define traceTASK_CREATE(pxNewTCB)                              \
-    do {                                                        \
-        SCANF_TASK_CREATE_TraceMessage message;                 \
-        message.event_type = SCANF_TASK_CREATE;                 \
-        message.timestamp = _scanf_get_timestamp();             \
-        message.task_number = (uint32_t)pxNewTCB->uxTaskNumber; \
-        strcpy(message.task_name, pxNewTCB->pcTaskName);        \
-        _scanf_save_trace(&message, sizeof(message));           \
+#define traceTASK_CREATE(pxNewTCB)                             \
+    do {                                                       \
+        SCANF_TASK_CREATE_TraceMessage message;                \
+        message.event_type = SCANF_TASK_CREATE;                \
+        message.timestamp = _scanf_get_timestamp();            \
+        message.task_number = (uint32_t)pxNewTCB->uxTCBNumber; \
+        strcpy(message.task_name, pxNewTCB->pcTaskName);       \
+        _scanf_save_trace(&message, sizeof(message));          \
     } while (0)
 
-#define traceTASK_SWITCHED_IN()                                     \
-    do {                                                            \
-        SCANF_TASK_SWITCHED_IN_TraceMessage message;                \
-        message.event_type = SCANF_TASK_SWITCHED_IN;                \
-        message.timestamp = _scanf_get_timestamp();                 \
-        message.task_number = (uint32_t)pxCurrentTCB->uxTaskNumber; \
-        _scanf_save_trace(&message, sizeof(message));               \
+#define traceTASK_SWITCHED_IN()                                    \
+    do {                                                           \
+        SCANF_TASK_SWITCHED_IN_TraceMessage message;               \
+        message.event_type = SCANF_TASK_SWITCHED_IN;               \
+        message.timestamp = _scanf_get_timestamp();                \
+        message.task_number = (uint32_t)pxCurrentTCB->uxTCBNumber; \
+        _scanf_save_trace(&message, sizeof(message));              \
     } while (0)
 
-#define traceTASK_SWITCHED_OUT()                                    \
-    do {                                                            \
-        SCANF_TASK_SWITCHED_OUT_TraceMessage message;               \
-        message.event_type = SCANF_TASK_SWITCHED_OUT;               \
-        message.timestamp = _scanf_get_timestamp();                 \
-        message.task_number = (uint32_t)pxCurrentTCB->uxTaskNumber; \
-        _scanf_save_trace(&message, sizeof(message));               \
+#define traceTASK_SWITCHED_OUT()                                   \
+    do {                                                           \
+        SCANF_TASK_SWITCHED_OUT_TraceMessage message;              \
+        message.event_type = SCANF_TASK_SWITCHED_OUT;              \
+        message.timestamp = _scanf_get_timestamp();                \
+        message.task_number = (uint32_t)pxCurrentTCB->uxTCBNumber; \
+        _scanf_save_trace(&message, sizeof(message));              \
     } while (0)
 
 #ifdef __cplusplus
diff --git a/test.c b/test.c
new file mode 100644
index 0000000..667defb
--- /dev/null
+++ b/test.c
@@ -0,0 +1,115 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define SCANF_MAX_TASK_NAME_LEN 64
+
+typedef enum __attribute__((__packed__)) {
+    SCANF_CONFIG = 0,
+    SCANF_TASK_CREATE,
+    SCANF_TASK_SWITCHED_IN,
+    SCANF_TASK_SWITCHED_OUT
+} SCANF_EventType;
+static_assert(sizeof(SCANF_EventType) == 1, "sizeof(SCANF_EventType) > 1");
+
+typedef struct __attribute__((__packed__)) {
+    uint8_t major;
+    uint8_t minor;
+    uint8_t patch;
+} SCANF_Version;
+
+typedef struct __attribute__((__packed__)) {
+    SCANF_EventType event_type;
+    SCANF_Version version;
+    uint8_t config_max_task_name_len;
+} SCANF_CONFIG_TraceMessage;
+
+typedef struct __attribute__((__packed__)) {
+    SCANF_EventType event_type;
+    uint32_t timestamp;
+} SCANF_TraceMessage;
+
+typedef struct __attribute__((__packed__)) {
+    SCANF_EventType event_type;
+    uint32_t timestamp;
+    uint32_t task_number;
+    char task_name[SCANF_MAX_TASK_NAME_LEN];
+} SCANF_TASK_CREATE_TraceMessage;
+
+typedef struct __attribute__((__packed__)) {
+    SCANF_EventType event_type;
+    uint32_t timestamp;
+    uint32_t task_number;
+} SCANF_TASK_SWITCHED_IN_TraceMessage;
+
+typedef struct __attribute__((__packed__)) {
+    SCANF_EventType event_type;
+    uint32_t timestamp;
+    uint32_t task_number;
+} SCANF_TASK_SWITCHED_OUT_TraceMessage;
+
+int main(int argc, char** argv) {
+    if (argc != 2) {
+        printf("Usage: %s <tracelog_file>\n", argv[0]);
+        return 1;
+    }
+
+    FILE* fd = fopen(argv[1], "r");
+    char buf[1024];
+    size_t size = fread(buf, 1, sizeof(buf), fd);
+    if (size == 0 && ferror(fd)) {
+        fprintf(stderr, "fread() failed: %zu\n", size);
+        exit(EXIT_FAILURE);
+    }
+
+    size_t i = 0;
+    printf("[\n");
+    while (i < size) {
+        printf("  {\n");
+        SCANF_EventType* message_type = (SCANF_EventType*)(&buf[i]);
+        switch (*message_type) {
+            case SCANF_CONFIG: {
+                SCANF_CONFIG_TraceMessage* message = (SCANF_CONFIG_TraceMessage*)(&buf[i]);
+                printf("    \"event_type:\": \"SCANF_CONFIG\",\n");
+                printf("    \"version:\": \"%d.%d.%d\",\n", message->version.major,
+                       message->version.minor, message->version.patch);
+                printf("    \"config_max_task_name_len:\": %d\n",
+                       message->config_max_task_name_len);
+                i += sizeof(SCANF_CONFIG_TraceMessage);
+            } break;
+            case SCANF_TASK_CREATE: {
+                SCANF_TASK_CREATE_TraceMessage* message =
+                    (SCANF_TASK_CREATE_TraceMessage*)(&buf[i]);
+                printf("    \"event_type:\": \"SCANF_TASK_CREATE\",\n");
+                printf("    \"timestamp:\": %d,\n", message->timestamp);
+                printf("    \"task_number:\": %d,\n", message->task_number);
+                printf("    \"task_name:\": \"%.64s\"\n", message->task_name);
+                i += sizeof(SCANF_TASK_CREATE_TraceMessage);
+            } break;
+            case SCANF_TASK_SWITCHED_IN: {
+                SCANF_TASK_SWITCHED_IN_TraceMessage* message =
+                    (SCANF_TASK_SWITCHED_IN_TraceMessage*)(&buf[i]);
+                printf("    \"event_type:\": \"SCANF_TASK_SWITCHED_IN\",\n");
+                printf("    \"timestamp:\": %d,\n", message->timestamp);
+                printf("    \"task_number:\": %d\n", message->task_number);
+                i += sizeof(SCANF_TASK_SWITCHED_IN_TraceMessage);
+            } break;
+            case SCANF_TASK_SWITCHED_OUT: {
+                SCANF_TASK_SWITCHED_OUT_TraceMessage* message =
+                    (SCANF_TASK_SWITCHED_OUT_TraceMessage*)(&buf[i]);
+                printf("    \"event_type:\": \"SCANF_TASK_SWITCHED_OUT\",\n");
+                printf("    \"timestamp:\": %d,\n", message->timestamp);
+                printf("    \"task_number:\": %d\n", message->task_number);
+                i += sizeof(SCANF_TASK_SWITCHED_OUT_TraceMessage);
+            } break;
+            default: {
+                printf("unreachable\n");
+                return 1;
+            };
+        }
+        printf("  },\n");
+    }
+    printf("]\n");
+    return 0;
+}
\ No newline at end of file


Reviews:
user: login: butvinm
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T01:51:39Z
user: login: butvinm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T08:13:05Z
user: login: butvinm
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T09:58:12Z

Review comments:
diff_hunk: @@ -1,46 +1,43 @@
 #include "scanf.h"
 
 #include <FreeRTOS.h>
-#include <task.h>
-
-#include <stddef.h>
+#include <errno.h>
 #include <stdbool.h>
-#include <string.h>
+#include <stddef.h>
 #include <stdio.h>
-#include <errno.h>
+#include <string.h>
+#include <task.h>
 
 static SCANF_Tracelog *_tracelog = NULL;
 static bool _is_tracing = false;
 
-void scanf_init(SCANF_Tracelog *tracelog)
-{
+void scanf_init(SCANF_Tracelog *tracelog) {
     if (!tracelog) return;
     _tracelog = tracelog;
+    scanf_reset();
 }
 
-SCANF_Tracelog *scanf_get_tracelog()
-{
-    return _tracelog;
-}
+SCANF_Tracelog *scanf_get_tracelog() { return _tracelog; }
 
-void scanf_reset()
-{
+void scanf_reset() {
     if (!_tracelog) return;
     _tracelog->size = 0;
-}
 
-void scanf_start_tracing()
-{
-    _is_tracing = true;
+    static SCANF_CONFIG_TraceMessage config_message;
+    config_message.event_type = SCANF_CONFIG;
+    // TODO: Pass version through CMake
+    config_message.version.major = 0;
+    config_message.version.minor = 2;
+    config_message.version.patch = 0;
+    config_message.config_max_task_name_len = SCANF_MAX_TASK_NAME_LEN;
+    _scanf_save_trace((void *)&config_message, sizeof(config_message));
path: src/scanf.c
user: login: butvinm
body: When you call `scanf_reset` first time `_is_tracing` is false, so `_scanf_save_trace` does not append message to tracelog and SCANF_CONFIG is not being saved
created_at: 2025-05-12T01:51:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,52 +1,54 @@
 #include "scanf.h"
 
 #include <FreeRTOS.h>
-#include <task.h>
-
-#include <stddef.h>
+#include <errno.h>
 #include <stdbool.h>
-#include <string.h>
+#include <stddef.h>
 #include <stdio.h>
-#include <errno.h>
+#include <string.h>
+#include <task.h>
 
 static SCANF_Tracelog *_tracelog = NULL;
 static bool _is_tracing = false;
 
-void scanf_init(SCANF_Tracelog *tracelog)
-{
+void scanf_init(SCANF_Tracelog *tracelog) {
     if (!tracelog) return;
     _tracelog = tracelog;
+    scanf_reset();
 }
 
-SCANF_Tracelog *scanf_get_tracelog()
-{
-    return _tracelog;
-}
+SCANF_Tracelog *scanf_get_tracelog() { return _tracelog; }
 
-void scanf_reset()
-{
+void scanf_reset() {
     if (!_tracelog) return;
     _tracelog->size = 0;
-}
 
-void scanf_start_tracing()
-{
+    static SCANF_CONFIG_TraceMessage config_message;
+    config_message.event_type = SCANF_CONFIG;
+    // TODO: Pass version through CMake
+    config_message.version.major = 0;
+    config_message.version.minor = 2;
+    config_message.version.patch = 0;
+    config_message.config_max_task_name_len = SCANF_MAX_TASK_NAME_LEN;
+
+    bool prev_is_tracing = _is_tracing;
     _is_tracing = true;
+    _scanf_save_trace((void *)&config_message, sizeof(config_message));
+    _is_tracing = prev_is_tracing;
 }
 
-void scanf_stop_tracing()
-{
-    _is_tracing = false;
-}
+void scanf_start_tracing() { _is_tracing = true; }
+
+void scanf_stop_tracing() { _is_tracing = false; }
 
-int scanf_save_tracelog(const char *filepath)
-{
+int scanf_save_tracelog(const char *filepath) {
     if (!_tracelog) return -EINVAL;
     if (_is_tracing) return -EBUSY;
-    FILE *file = fopen(filepath, "ab");
+    FILE *file = fopen(filepath, "wb");
     if (!file) {
         return -EINVAL;
     }
+    printf("here!\n");
path: src/scanf.c
user: login: butvinm
body: I assume it was for debug, should we now remove it?
created_at: 2025-05-19T08:13:05Z
author_association: CONTRIBUTOR

PR comments:
user: login: ivatolm
created_at: 2025-05-04T22:45:22Z
body: Not tested, because I failed to configure printf 
author_association: CONTRIBUTOR
user: login: butvinm
created_at: 2025-05-12T01:52:55Z
body: @ivatolm This is the script I use to introspect the binary log. Maybe would be useful for you during development


```c
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>


#define SCANF_MAX_TASK_NAME_LEN 64

typedef enum __attribute__((__packed__)) {
    SCANF_CONFIG = 0,
    SCANF_TASK_CREATE,
    SCANF_TASK_SWITCHED_IN,
    SCANF_TASK_SWITCHED_OUT
} SCANF_EventType;
static_assert(sizeof(SCANF_EventType) == 1, "sizeof(SCANF_EventType) > 1");

typedef struct __attribute__((__packed__)) {
    uint8_t major;
    uint8_t minor;
    uint8_t patch;
} SCANF_Version;

typedef struct __attribute__((__packed__)) {
    SCANF_EventType event_type;
    SCANF_Version version;
    uint8_t config_max_task_name_len;
} SCANF_CONFIG_TraceMessage;

typedef struct __attribute__((__packed__)) {
    SCANF_EventType event_type;
    uint32_t timestamp;
} SCANF_TraceMessage;

typedef struct __attribute__((__packed__)) {
    SCANF_EventType event_type;
    uint32_t timestamp;
    uint32_t task_number;
    char task_name[SCANF_MAX_TASK_NAME_LEN];
} SCANF_TASK_CREATE_TraceMessage;

typedef struct __attribute__((__packed__)) {
    SCANF_EventType event_type;
    uint32_t timestamp;
    uint32_t task_number;
} SCANF_TASK_SWITCHED_IN_TraceMessage;

typedef struct __attribute__((__packed__)) {
    SCANF_EventType event_type;
    uint32_t timestamp;
    uint32_t task_number;
} SCANF_TASK_SWITCHED_OUT_TraceMessage;

int main(int argc, char** argv) {
    if (argc != 2) {
        printf("Usage: %s <tracelog_file>\n", argv[0]);
        return 1;
    }

    FILE* fd = fopen(argv[1], "r");
    char buf[1024];
    size_t size = fread(buf, 1, sizeof(buf), fd);
    if (size == 0 && ferror(fd)) {
        fprintf(stderr, "fread() failed: %zu\n", size);
        exit(EXIT_FAILURE);
    }

    size_t i = 0;
    printf("[\n");
    while (i < size) {
        printf("  {\n");
        SCANF_EventType* message_type = (SCANF_EventType*)(&buf[i]);
        switch (*message_type) {
            case SCANF_CONFIG: {
                SCANF_CONFIG_TraceMessage* message = (SCANF_CONFIG_TraceMessage*)(&buf[i]);
                printf("    \"event_type:\": \"SCANF_CONFIG\",\n");
                printf("    \"version:\": \"%d.%d.%d\",\n",
                    message->version.major,
                    message->version.minor,
                    message->version.patch);
                printf("    \"config_max_task_name_len:\": %d\n", message->config_max_task_name_len);
                i += sizeof(SCANF_CONFIG_TraceMessage);
            } break;
            case SCANF_TASK_CREATE: {
                SCANF_TASK_CREATE_TraceMessage* message = (SCANF_TASK_CREATE_TraceMessage*)(&buf[i]);
                printf("    \"event_type:\": \"SCANF_TASK_CREATE\",\n");
                printf("    \"timestamp:\": %d,\n", message->timestamp);
                printf("    \"task_number:\": %d,\n", message->task_number);
                printf("    \"task_name:\": \"%.64s\"\n", message->task_name);
                i += sizeof(SCANF_TASK_CREATE_TraceMessage);
            } break;
            case SCANF_TASK_SWITCHED_IN: {
                SCANF_TASK_SWITCHED_IN_TraceMessage* message = (SCANF_TASK_SWITCHED_IN_TraceMessage*)(&buf[i]);
                printf("    \"event_type:\": \"SCANF_TASK_SWITCHED_IN\",\n");
                printf("    \"timestamp:\": %d,\n", message->timestamp);
                printf("    \"task_number:\": %d\n", message->task_number);
                i += sizeof(SCANF_TASK_SWITCHED_IN_TraceMessage);
            } break;
            case SCANF_TASK_SWITCHED_OUT: {
                SCANF_TASK_SWITCHED_OUT_TraceMessage* message = (SCANF_TASK_SWITCHED_OUT_TraceMessage*)(&buf[i]);
                printf("    \"event_type:\": \"SCANF_TASK_SWITCHED_OUT\",\n");
                printf("    \"timestamp:\": %d,\n", message->timestamp);
                printf("    \"task_number:\": %d\n", message->task_number);
                i += sizeof(SCANF_TASK_SWITCHED_OUT_TraceMessage);
            } break;
            default: {
                printf("unreachable\n");
                return 1;
            };
        }
        printf("  },\n");
    }
    printf("]\n");
    return 0;
}
```
author_association: CONTRIBUTOR
user: login: butvinm
created_at: 2025-05-12T01:54:55Z
body: @ivatolm And lets also change the file open mode from `ab` to `wb` to not get insane again debugging accidentally merged tracelog files
author_association: CONTRIBUTOR
user: login: butvinm
created_at: 2025-05-19T03:18:08Z
body: @ivatolm  Just remembered - we need to replace `uxTaskNumber` with `uxTCBNumber`, lets also make it in this PR so we can produce the full valid tracelog to test
author_association: CONTRIBUTOR