Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: HelloWorld_CCA01M1 HelloWorld_CCA02M1 CI-data-logger-server HelloWorld_CCA02M1 ... more
This is a fork of the events subdirectory of https://github.com/ARMmbed/mbed-os.
Note, you must import this library with import name: events!!!
README.md@201:dd058cec5f28, 2016-10-03 (annotated)
- Committer:
- Seppo Takalo
- Date:
- Mon Oct 03 14:40:33 2016 +0300
- Revision:
- 201:dd058cec5f28
Squashed 'features/FEATURE_COMMON_PAL/mbed-trace/' content from commit b17e969
git-subtree-dir: features/FEATURE_COMMON_PAL/mbed-trace
git-subtree-split: b17e96970777cdc61ba143bdd6ffc7b640aa6311
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Seppo Takalo |
201:dd058cec5f28 | 1 | # mbed-trace |
| Seppo Takalo |
201:dd058cec5f28 | 2 | |
| Seppo Takalo |
201:dd058cec5f28 | 3 | A general purpose tracing abstraction library for mbed devices. |
| Seppo Takalo |
201:dd058cec5f28 | 4 | |
| Seppo Takalo |
201:dd058cec5f28 | 5 | ## Description |
| Seppo Takalo |
201:dd058cec5f28 | 6 | |
| Seppo Takalo |
201:dd058cec5f28 | 7 | The purpose of the library is to provide a light, simple and general tracing solution for mbed devices. By default, it prints traces to `stdout` (usually, a serial port), but the output can also be redirected to other targets. The library was developed using ANSI C language, but it can be used with C++ as well. Currently, there is no C++ wrapper available, but it can be created easily on top of this library. |
| Seppo Takalo |
201:dd058cec5f28 | 8 | |
| Seppo Takalo |
201:dd058cec5f28 | 9 | ## Philosophy |
| Seppo Takalo |
201:dd058cec5f28 | 10 | |
| Seppo Takalo |
201:dd058cec5f28 | 11 | * The library needs to be light, fast, simple and abstract. |
| Seppo Takalo |
201:dd058cec5f28 | 12 | * Dependencies must be minimal. |
| Seppo Takalo |
201:dd058cec5f28 | 13 | * The memory space required by the library is allocated at the initialization only once during the application lifetime. |
| Seppo Takalo |
201:dd058cec5f28 | 14 | * No new malloc/free are needed when running the library. |
| Seppo Takalo |
201:dd058cec5f28 | 15 | * The trace methods must be as fast as possible. |
| Seppo Takalo |
201:dd058cec5f28 | 16 | * After a trace method call, the trace function needs to release the required resources. |
| Seppo Takalo |
201:dd058cec5f28 | 17 | * A trace method call produces a single line containing `<level>`, `<group>` and `<message>` |
| Seppo Takalo |
201:dd058cec5f28 | 18 | * It must be possible to filter messages on the fly. Compile time filtering is not fully supported yet. |
| Seppo Takalo |
201:dd058cec5f28 | 19 | |
| Seppo Takalo |
201:dd058cec5f28 | 20 | ## Compromises |
| Seppo Takalo |
201:dd058cec5f28 | 21 | |
| Seppo Takalo |
201:dd058cec5f28 | 22 | * The traces are stored as ASCII arrays in the flash memory (pretty high memory consumption). Therefore, it is not necessary to: |
| Seppo Takalo |
201:dd058cec5f28 | 23 | * encode/decode the trace messages on the fly (this may take too much CPU time) or |
| Seppo Takalo |
201:dd058cec5f28 | 24 | * have external dev-env dependencies to encode the traces compile time and an external application to decode the traces. |
| Seppo Takalo |
201:dd058cec5f28 | 25 | * The group name length is limited to four characters. This makes the lines cleaner and it is enough for most use cases for separating the module names. The group name length may not be suitable for a clean human readable format, but still four characters is enough for unique module names. |
| Seppo Takalo |
201:dd058cec5f28 | 26 | * The trace function uses `stdout` as the default output target because it goes directly to serial port when initialized. |
| Seppo Takalo |
201:dd058cec5f28 | 27 | * The trace function produces traces like: `[<levl>][grp ]: msg`. This provides an easy way to detect trace prints and separate traces from normal prints (for example with _regex_). |
| Seppo Takalo |
201:dd058cec5f28 | 28 | * This approach requires a `sprintf` implementation (`stdio.h`). The memory consumption is pretty high, but it allows an efficient way to format traces. |
| Seppo Takalo |
201:dd058cec5f28 | 29 | * The solution is not Interrupt safe. (PRs are more than welcome.) |
| Seppo Takalo |
201:dd058cec5f28 | 30 | * The solution is not Thread safe by default. Thread safety for the actual trace calls can be enabled by providing wait and release callback functions that use mutexes defined by the application. |
| Seppo Takalo |
201:dd058cec5f28 | 31 | |
| Seppo Takalo |
201:dd058cec5f28 | 32 | ## Examples of traces |
| Seppo Takalo |
201:dd058cec5f28 | 33 | |
| Seppo Takalo |
201:dd058cec5f28 | 34 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 35 | [DBG ][abc ]: This is a debug message from module abc<cr><lf> |
| Seppo Takalo |
201:dd058cec5f28 | 36 | [ERR ][abc ]: Something goes wrong in module abc<cr><lf> |
| Seppo Takalo |
201:dd058cec5f28 | 37 | [WARN][br ]: Oh no, br warning occurs!<cr><lf> |
| Seppo Takalo |
201:dd058cec5f28 | 38 | [INFO][br ]: Hi there.<cr><lf> |
| Seppo Takalo |
201:dd058cec5f28 | 39 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 40 | |
| Seppo Takalo |
201:dd058cec5f28 | 41 | ## Usage |
| Seppo Takalo |
201:dd058cec5f28 | 42 | |
| Seppo Takalo |
201:dd058cec5f28 | 43 | ### Prerequisites |
| Seppo Takalo |
201:dd058cec5f28 | 44 | |
| Seppo Takalo |
201:dd058cec5f28 | 45 | * Initialize the serial port so that `stdout` works. You can verify that the serial port works using the `printf()` function. |
| Seppo Takalo |
201:dd058cec5f28 | 46 | * if you want to redirect the traces somewhere else, see the [trace API](https://github.com/ARMmbed/mbed-trace/blob/master/mbed-trace/mbed_trace.h#L170). |
| Seppo Takalo |
201:dd058cec5f28 | 47 | * To enable the tracing API: |
| Seppo Takalo |
201:dd058cec5f28 | 48 | * With yotta: set `YOTTA_CFG_MBED_TRACE` to 1 or true. Setting the flag to 0 or false disables tracing. |
| Seppo Takalo |
201:dd058cec5f28 | 49 | * [With mbed OS 5](#enabling-the-tracing-api-in-mbed-os-5) |
| Seppo Takalo |
201:dd058cec5f28 | 50 | * By default, trace uses 1024 bytes buffer for trace lines, but you can change it by yotta with: `YOTTA_CFG_MBED_TRACE_LINE_LENGTH`. |
| Seppo Takalo |
201:dd058cec5f28 | 51 | * To disable the IPv6 conversion, set `YOTTA_CFG_MBED_TRACE_FEA_IPV6 = 0`. |
| Seppo Takalo |
201:dd058cec5f28 | 52 | * If thread safety is needed, configure the wait and release callback functions before initialization to enable the protection. Usually, this needs to be done only once in the application's lifetime. |
| Seppo Takalo |
201:dd058cec5f28 | 53 | * Call the trace initialization (`mbed_trace_init`) once before using any other APIs. It allocates the trace buffer and initializes the internal variables. |
| Seppo Takalo |
201:dd058cec5f28 | 54 | * Define `TRACE_GROUP` in your source code (not in the header!) to use traces. It is a 1-4 characters long char-array (for example `#define TRACE_GROUP "APPL"`). This will be printed on every trace line. |
| Seppo Takalo |
201:dd058cec5f28 | 55 | |
| Seppo Takalo |
201:dd058cec5f28 | 56 | ### Enabling the tracing API in mbed OS 5 |
| Seppo Takalo |
201:dd058cec5f28 | 57 | |
| Seppo Takalo |
201:dd058cec5f28 | 58 | * Add the feature COMMON_PAL into the build |
| Seppo Takalo |
201:dd058cec5f28 | 59 | * Set `MBED_CONF_MBED_TRACE_ENABLE` to 1 or true |
| Seppo Takalo |
201:dd058cec5f28 | 60 | |
| Seppo Takalo |
201:dd058cec5f28 | 61 | To do so, add the following to your mbed_app.json: |
| Seppo Takalo |
201:dd058cec5f28 | 62 | |
| Seppo Takalo |
201:dd058cec5f28 | 63 | ```json |
| Seppo Takalo |
201:dd058cec5f28 | 64 | { |
| Seppo Takalo |
201:dd058cec5f28 | 65 | "target_overrides": { |
| Seppo Takalo |
201:dd058cec5f28 | 66 | "*": { |
| Seppo Takalo |
201:dd058cec5f28 | 67 | "target.features_add": ["COMMON_PAL"], |
| Seppo Takalo |
201:dd058cec5f28 | 68 | "mbed-trace.enable": 1 |
| Seppo Takalo |
201:dd058cec5f28 | 69 | } |
| Seppo Takalo |
201:dd058cec5f28 | 70 | } |
| Seppo Takalo |
201:dd058cec5f28 | 71 | } |
| Seppo Takalo |
201:dd058cec5f28 | 72 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 73 | |
| Seppo Takalo |
201:dd058cec5f28 | 74 | Don't forget to fulfill the other [prerequisites](#prerequisites)! |
| Seppo Takalo |
201:dd058cec5f28 | 75 | |
| Seppo Takalo |
201:dd058cec5f28 | 76 | ([Click here for more information on the configuration system](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md)) |
| Seppo Takalo |
201:dd058cec5f28 | 77 | |
| Seppo Takalo |
201:dd058cec5f28 | 78 | ### Traces |
| Seppo Takalo |
201:dd058cec5f28 | 79 | |
| Seppo Takalo |
201:dd058cec5f28 | 80 | When you want to print traces, use the `tr_<level>` macros. The macros behave like `printf()`. For example, `tr_debug("hello %s", "trace")` produces the following trace line: `[DBG ][APPL] hello trace<cr><lf>`. |
| Seppo Takalo |
201:dd058cec5f28 | 81 | |
| Seppo Takalo |
201:dd058cec5f28 | 82 | Available levels: |
| Seppo Takalo |
201:dd058cec5f28 | 83 | |
| Seppo Takalo |
201:dd058cec5f28 | 84 | * debug |
| Seppo Takalo |
201:dd058cec5f28 | 85 | * warning |
| Seppo Takalo |
201:dd058cec5f28 | 86 | * error |
| Seppo Takalo |
201:dd058cec5f28 | 87 | * info |
| Seppo Takalo |
201:dd058cec5f28 | 88 | * cmdline (special behavior, should not be used) |
| Seppo Takalo |
201:dd058cec5f28 | 89 | |
| Seppo Takalo |
201:dd058cec5f28 | 90 | For the thread safety, set the mutex wait and release functions. You need do this before the initialization to have the functions available right away: |
| Seppo Takalo |
201:dd058cec5f28 | 91 | |
| Seppo Takalo |
201:dd058cec5f28 | 92 | ```c |
| Seppo Takalo |
201:dd058cec5f28 | 93 | mbed_trace_mutex_wait_function_set(my_mutex_wait); |
| Seppo Takalo |
201:dd058cec5f28 | 94 | mbed_trace_mutex_release_function_set(my_mutex_release); |
| Seppo Takalo |
201:dd058cec5f28 | 95 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 96 | |
| Seppo Takalo |
201:dd058cec5f28 | 97 | Initialization (once in application's lifetime): |
| Seppo Takalo |
201:dd058cec5f28 | 98 | |
| Seppo Takalo |
201:dd058cec5f28 | 99 | ```c |
| Seppo Takalo |
201:dd058cec5f28 | 100 | int mbed_trace_init(void); |
| Seppo Takalo |
201:dd058cec5f28 | 101 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 102 | |
| Seppo Takalo |
201:dd058cec5f28 | 103 | Set the output function, `printf` by default: |
| Seppo Takalo |
201:dd058cec5f28 | 104 | |
| Seppo Takalo |
201:dd058cec5f28 | 105 | ```c |
| Seppo Takalo |
201:dd058cec5f28 | 106 | mbed_trace_print_function_set(printf) |
| Seppo Takalo |
201:dd058cec5f28 | 107 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 108 | |
| Seppo Takalo |
201:dd058cec5f28 | 109 | ### Helping functions |
| Seppo Takalo |
201:dd058cec5f28 | 110 | |
| Seppo Takalo |
201:dd058cec5f28 | 111 | The purpose of the helping functions is to provide simple conversions, for example from an array to C string, so that you can print everything to single trace line. They must be called inside the actual trace calls, for example: |
| Seppo Takalo |
201:dd058cec5f28 | 112 | |
| Seppo Takalo |
201:dd058cec5f28 | 113 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 114 | tr_debug("My IP6 address: %s", mbed_trace_ipv6(addr)); |
| Seppo Takalo |
201:dd058cec5f28 | 115 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 116 | |
| Seppo Takalo |
201:dd058cec5f28 | 117 | Available conversion functions: |
| Seppo Takalo |
201:dd058cec5f28 | 118 | |
| Seppo Takalo |
201:dd058cec5f28 | 119 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 120 | char *mbed_trace_ipv6(const void *addr_ptr) |
| Seppo Takalo |
201:dd058cec5f28 | 121 | char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len) |
| Seppo Takalo |
201:dd058cec5f28 | 122 | char *mbed_trace_array(const uint8_t *buf, uint16_t len) |
| Seppo Takalo |
201:dd058cec5f28 | 123 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 124 | |
| Seppo Takalo |
201:dd058cec5f28 | 125 | See more in [mbed_trace.h](https://github.com/ARMmbed/mbed-trace/blob/master/mbed-trace/mbed_trace.h). |
| Seppo Takalo |
201:dd058cec5f28 | 126 | |
| Seppo Takalo |
201:dd058cec5f28 | 127 | |
| Seppo Takalo |
201:dd058cec5f28 | 128 | ## Usage example: |
| Seppo Takalo |
201:dd058cec5f28 | 129 | |
| Seppo Takalo |
201:dd058cec5f28 | 130 | ```c++ |
| Seppo Takalo |
201:dd058cec5f28 | 131 | #define YOTTA_CFG_MBED_TRACE 1 //this can be defined also in the yotta configuration file config.json |
| Seppo Takalo |
201:dd058cec5f28 | 132 | #include "mbed-trace/mbed_trace.h" |
| Seppo Takalo |
201:dd058cec5f28 | 133 | #define TRACE_GROUP "main" |
| Seppo Takalo |
201:dd058cec5f28 | 134 | |
| Seppo Takalo |
201:dd058cec5f28 | 135 | // These are necessary only if thread safety is needed |
| Seppo Takalo |
201:dd058cec5f28 | 136 | static Mutex MyMutex; |
| Seppo Takalo |
201:dd058cec5f28 | 137 | static void my_mutex_wait() |
| Seppo Takalo |
201:dd058cec5f28 | 138 | { |
| Seppo Takalo |
201:dd058cec5f28 | 139 | MyMutex.lock(); |
| Seppo Takalo |
201:dd058cec5f28 | 140 | } |
| Seppo Takalo |
201:dd058cec5f28 | 141 | static void my_mutex_release() |
| Seppo Takalo |
201:dd058cec5f28 | 142 | { |
| Seppo Takalo |
201:dd058cec5f28 | 143 | MyMutex.unlock(); |
| Seppo Takalo |
201:dd058cec5f28 | 144 | } |
| Seppo Takalo |
201:dd058cec5f28 | 145 | |
| Seppo Takalo |
201:dd058cec5f28 | 146 | int main(void){ |
| Seppo Takalo |
201:dd058cec5f28 | 147 | mbed_trace_mutex_wait_function_set( my_mutex_wait ); // only if thread safety is needed |
| Seppo Takalo |
201:dd058cec5f28 | 148 | mbed_trace_mutex_release_function_set( my_mutex_release ); // only if thread safety is needed |
| Seppo Takalo |
201:dd058cec5f28 | 149 | mbed_trace_init(); // initialize the trace library |
| Seppo Takalo |
201:dd058cec5f28 | 150 | tr_debug("this is debug msg"); //-> "[DBG ][main]: this is a debug msg" |
| Seppo Takalo |
201:dd058cec5f28 | 151 | tr_err("this is error msg"); //-> "[ERR ][main]: this is an error msg" |
| Seppo Takalo |
201:dd058cec5f28 | 152 | tr_warn("this is warning msg"); //-> "[WARN][main]: this is a warning msg" |
| Seppo Takalo |
201:dd058cec5f28 | 153 | tr_info("this is info msg"); //-> "[INFO][main]: this is an info msg" |
| Seppo Takalo |
201:dd058cec5f28 | 154 | char arr[] = {30, 31, 32}; |
| Seppo Takalo |
201:dd058cec5f28 | 155 | tr_debug("printing array: %s", mbed_trace_array(arr, 3)); //-> "[DBG ][main]: printing array: 01:02:03" |
| Seppo Takalo |
201:dd058cec5f28 | 156 | return 0; |
| Seppo Takalo |
201:dd058cec5f28 | 157 | } |
| Seppo Takalo |
201:dd058cec5f28 | 158 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 159 | |
| Seppo Takalo |
201:dd058cec5f28 | 160 | ## Unit tests |
| Seppo Takalo |
201:dd058cec5f28 | 161 | |
| Seppo Takalo |
201:dd058cec5f28 | 162 | To run unit tests: |
| Seppo Takalo |
201:dd058cec5f28 | 163 | |
| Seppo Takalo |
201:dd058cec5f28 | 164 | * In Linux |
| Seppo Takalo |
201:dd058cec5f28 | 165 | |
| Seppo Takalo |
201:dd058cec5f28 | 166 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 167 | yotta target x86-linux-native |
| Seppo Takalo |
201:dd058cec5f28 | 168 | yotta test mbed_trace_test |
| Seppo Takalo |
201:dd058cec5f28 | 169 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 170 | |
| Seppo Takalo |
201:dd058cec5f28 | 171 | * In Windows |
| Seppo Takalo |
201:dd058cec5f28 | 172 | |
| Seppo Takalo |
201:dd058cec5f28 | 173 | ``` |
| Seppo Takalo |
201:dd058cec5f28 | 174 | yotta target x86-windows-native |
| Seppo Takalo |
201:dd058cec5f28 | 175 | yotta test mbed_trace_test |
| Seppo Takalo |
201:dd058cec5f28 | 176 | ``` |