Logging Library
Overview
Ameba SDK provides a unified tag-based logging system available across ROM, bootloader, and application firmware stages. Log output is controlled at two independent layers:
Compile-time filtering via
COMPIL_LOG_LEVEL: log calls that exceed this level are removed entirely by the preprocessor, producing zero code or data overhead.Runtime filtering via
rtk_log_level_set(): controls which compiled-in logs are actually printed, without affecting binary size.
Log Levels
Log levels are defined by the enumeration rtk_log_level_t:
typedef enum {
RTK_LOG_NONE, /* 0 */
RTK_LOG_ALWAYS, /* 1 */
RTK_LOG_ERROR, /* 2 */
RTK_LOG_WARN, /* 3 */
RTK_LOG_INFO, /* 4 */
RTK_LOG_DEBUG /* 5 */
} rtk_log_level_t;
Level |
Value |
Letter |
Description |
|---|---|---|---|
RTK_LOG_NONE |
0 |
— |
Disable all output. |
RTK_LOG_ALWAYS |
1 |
|
Critical information that must always be shown, but does not indicate a warning or error. |
RTK_LOG_ERROR |
2 |
|
Error messages, such as incorrect API usage. |
RTK_LOG_WARN |
3 |
|
Inappropriate configuration that still works, or situations that may lead to errors. |
RTK_LOG_INFO |
4 |
|
Normal and necessary operational messages (default level). |
RTK_LOG_DEBUG |
5 |
|
Diagnostic information for faults, such as pointer values and memory contents. |
To change the compile-time or runtime log level, see the Log Level Configuration section.
Log Format
Output format
The output format depends on the tag argument passed to the macro.
With tag prefix (normal call):
[TAG-X] message content
Without tag prefix (passing
NOTAG):message content
where X is the level letter (A, E, W, I, or D). No newline is appended
automatically; a trailing \n must be included in every format string. NOTAG is intended
for cases where a repeated prefix is not needed, such as continuation lines inside a loop.
Tag naming rules
Each module identifies itself with a tag string. The rules are:
Define the tag as a
const char *pointer, typically at file scope.All files within the same component, or a single file acting as its own module, share one tag as a unique identifier.
The tag string must be all uppercase, at most 9 characters, and contain only digits, letters, or underscores. Hyphens are not allowed.
The tag variable should be named with a
TAG_prefix (e.g.TAG_WIFI).
static const char *TAG_APP = "APP";
Logging macros
Ameba SDK provides two macro families to suit different use cases.
1. Standard macros (RTK_LOGx)
These macros use the DiagPrintf backend and support all format specifiers except floating-point.
The log level is encoded in the macro name, making them suitable for general task contexts:
RTK_LOGA(tag, format, ...) /* RTK_LOG_ALWAYS */
RTK_LOGE(tag, format, ...) /* RTK_LOG_ERROR */
RTK_LOGW(tag, format, ...) /* RTK_LOG_WARN */
RTK_LOGI(tag, format, ...) /* RTK_LOG_INFO */
RTK_LOGD(tag, format, ...) /* RTK_LOG_DEBUG */
tag: module tag string, or
NOTAGto suppress the prefix.format: a
printf-style format string.
2. Lightweight macro (RTK_LOGS)
RTK_LOGS uses the DiagPrintfNano backend. It has a smaller stack footprint and limited
format specifier support, making it suitable for interrupt handlers (ISR) or stack-constrained tasks:
RTK_LOGS(tag, level, format, ...)
tag: module tag string, or
NOTAGto suppress the prefix.level: one of the
rtk_log_level_tvalues.format: a
printf-style format string.
Usage example
#include "log.h"
static const char *TAG_APP = "APP";
void app_init(void)
{
int err = 1;
/* Recommended: nano backend, lower stack usage */
RTK_LOGS(TAG_APP, RTK_LOG_INFO, "version %d\n", 1);
RTK_LOGS(TAG_APP, RTK_LOG_ERROR, "open failed, ret=%d\n", err);
/* Print a header line, then loop items without repeating the prefix */
RTK_LOGI(TAG_APP, "command list start\n");
for (int i = 0; i < count; i++) {
RTK_LOGI(NOTAG, " [%d] %s\n", i, cmd_table[i].name);
}
RTK_LOGI(TAG_APP, "command list end\n");
}
Expected output:
[APP-I] version 1
[APP-E] open failed, ret=1
[APP-I] command list start
[0] help
[1] reset
[APP-I] command list end
Log Level Configuration
Compile-Time Log Level Setting
The macro COMPIL_LOG_LEVEL is a global definition that determines which log levels are compiled into the image.
Any call whose level exceeds COMPIL_LOG_LEVEL is eliminated at the preprocessing stage and occupies no flash or RAM.
Default log level is RTK_LOG_INFO (DEBUG stripped by default, set in log.h).
To change the compile level for a single file or an entire component, see the override methods below.
Per-file override
Define COMPIL_LOG_LEVEL before including the header. This overrides the default for that translation unit only:
#define COMPIL_LOG_LEVEL RTK_LOG_ERROR
#include "log.h"
static const char *TAG_FOO = "FOO";
/* Only ALWAYS and ERROR calls survive compilation in this file. */
RTK_LOGE(TAG_FOO, "error code: %d\n", err);
RTK_LOGD(TAG_FOO, "debug value: %08x\n", val); /* compiled out */
Per-component override
To change the compile level for all files in a component, append the definition to private_definitions
in the component’s CMakeLists.txt:
ameba_list_append(private_definitions COMPIL_LOG_LEVEL=RTK_LOG_DEBUG)
This is equivalent to passing -DCOMPIL_LOG_LEVEL=RTK_LOG_DEBUG to the compiler for every source file
in that component.
Note
COMPIL_LOG_LEVEL is the compile-time ceiling. A log call that was not compiled into the image cannot
be enabled at runtime, regardless of the level set by rtk_log_level_set(). The runtime level can
only suppress output further — it cannot recover logs that were removed at compile time.
Runtime Log Level Setting
At runtime the log level can be adjusted per-tag or globally without affecting binary size.
rtk_log_level_set
Items |
Description |
|---|---|
Introduction |
Set the log output level for a specific module tag, or set the global default level. |
Parameter |
|
Return |
|
rtk_log_level_get
Items |
Description |
|---|---|
Introduction |
Query the effective log level for a module tag. |
Parameter |
|
Return |
The level registered for the tag if found in the cache; otherwise
the global default level ( |
rtk_log_array_clear
Items |
Description |
|---|---|
Introduction |
Clear all per-tag level entries from the cache and reset the entry counter to zero. |
Parameter |
None |
Return |
None |
rtk_log_array_print
Items |
Description |
|---|---|
Introduction |
Print all tag/level entries currently stored in the cache. |
Parameter |
|
Return |
|
Global level and per-module level
The runtime log level operates on two independent dimensions:
Global default level (
rtk_log_default_level): set viartk_log_level_set("*", level); applies to all modules that do not have an individually registered entry in the tag cache.Per-module level: set via
rtk_log_level_set(tag, level)for a specific tag and stored in the tag cache. When a tag has a cached entry, that value is returned directly byrtk_log_level_getand the global default level has no effect on it.
The two dimensions are fully independent. Updating the global default level does not affect tags that have a cached per-module entry; updating a per-module level does not affect the global default or any other module.
Tag Cache Management
The tag cache holds at most LOG_TAG_CACHE_ARRAY_SIZE (4) entries for
per-module level storage. When the cache is full and a new tag is written,
the slot at index count % 4 is overwritten following a ring policy.
The wildcard "*" does not consume a cache slot; it only updates the
global default level variable.
Usage example
/* Suppress DEBUG globally */
rtk_log_level_set("*", RTK_LOG_INFO);
/* Enable DEBUG for the WiFi module only */
rtk_log_level_set("WIFI", RTK_LOG_DEBUG);
/* Query effective level */
rtk_log_level_t lvl = rtk_log_level_get("WIFI"); /* RTK_LOG_DEBUG */
/* Inspect the cache */
rtk_log_array_print(rtk_log_tag_array);
/* Clear all per-tag settings */
rtk_log_array_clear();
AT command
The runtime log level can also be controlled over AT commands. See AT+LOG for the
full AT+LOG command reference.
Print Backend
Each log macro call passes through two filtering stages before reaching the actual print backend, as shown in the following diagram.
The two filtering stages are:
Compile-time filter (
COMPIL_LOG_LEVEL): any call whose level exceeds this value is removed by the preprocessor and generates no code.Runtime filter (
rtk_log_level_get): checks the effective level for the tag against the current call level. If the tag has been individually registered viartk_log_level_set(), that level is used; otherwise the global default (rtk_log_default_level) applies.
Two print backends are available:
DiagPrintfNano: lower stack usage, suitable for interrupt handlers and small-stack tasks; limited format specifier support.DiagPrintf: supports format specifiers except floating-point (%f,%g, etc.), suitable for general use.
Performance Overhead
The two macro families differ in stack usage and format specifier support:
RTK_LOGScall chain:RTK_LOGS->rtk_log_write_nano()->DiagPrintfNano/DiagVprintfNano. Typical stack usage is ~136 B; limited format specifier support.RTK_LOGxcall chain:RTK_LOGx->rtk_log_write()->DiagPrintf/DiagVprintf. Typical stack usage is ~252 B; supports format specifiers except floating-point.
Macro |
Backend function |
Stack (typical) |
Format support |
|---|---|---|---|
RTK_LOGS |
DiagVprintfNano |
~136 B |
Limited specifiers |
RTK_LOGx |
DiagVprintf |
~252 B |
Except floating-point |
Selection guidance:
Use
RTK_LOGSin interrupt handlers or stack-constrained tasks.Use
RTK_LOGxwhen long integer format specifiers such as%lldor%luare needed.Floating-point specifiers (
%f,%g, etc.) are not supported by either macro family.
Memory Dump
Three helper functions produce hex dumps of a memory region to log output.
rtk_log_memory_dump_word
Items |
Description |
|---|---|
Introduction |
Dump a memory region as 32-bit words, 8 words per line. |
Parameter |
|
Return |
None |
Example output:
[200447b4] 20015e08 00000000 20000674 000055d9 0c002763 20000749 0c0067f4 00000000
rtk_log_memory_dump_byte
Items |
Description |
|---|---|
Introduction |
Dump a memory region as bytes, 8 bytes per line. |
Parameter |
|
Return |
None |
Example output:
[200447b4] 08 5e 01 20 00 00 00 00
rtk_log_memory_dump2char
Items |
Description |
|---|---|
Introduction |
Dump a memory region in combined hex and printable-ASCII format, 16 bytes per line. |
Parameter |
|
Return |
None |
Example output:
[0xe005263] 7c 03 f0 7f 03 23 74 cf e7 07 25 cd e7 a1 69 30 ||....#t...%...i0|
API Reference
Include log.h before using any of the following APIs.
API / Macro |
Description |
|---|---|
|
Log with nano backend (recommended) |
|
Log at ALWAYS level |
|
Log at ERROR level |
|
Log at WARN level |
|
Log at INFO level |
|
Log at DEBUG level |
|
Set runtime level for a tag or global default |
|
Get runtime level for a tag |
|
Clear tag level cache |
|
Print tag level cache |
|
Hex dump: 32-bit words |
|
Hex dump: bytes |
|
Hex dump: bytes + ASCII |
|
Init log mutex (RTL8730E only) |