Using the Debug Message API

The Debug Message API allows an application to send customizable messages to the Message Viewer without impacting real-time application performance. This is possible because the computationally intensive string interpolation is performed by the Message Viewer in Windows, not performed by the real-time application. See String Messages.

There are three types of messages: Basic, Standard, and Trace. Each message type resides in its corresponding channel: Basic, Standard, and Trace, respectively. The Basic message channel carries basic messages, while the Standard and Trace message channels are designed for messages with special formatting.

Message Channel

Three message channels are available:

Available APIs: RtdbgCloseBasicChannel, RtdbgGetBasicCategoryName, RtdbgGetBasicMessage, RtdbgGetSeverityFilter, RtdbgOpenBasicChannel, RtdbgSendBasicMessage, RtdbgSetBasicCategoryName, RtdbgSetSeverityFilter

Available APIs: RtdbgCloseChannel, RtdbgCreateStandardChannel, RtdbgGetMessage, RtdbgGetSourceFilter, RtdbgGetTypeFilter, RtdbgSendMessage, RtdbgSetSourceFilter, RtdbgSetTypeFilter

Available APIs: RtdbgCloseChannel, RtdbgCreateTraceChannel, RtdbgGetMessage, RtdbgGetIndexFilter, RtdbgGetSourceFilter, RtdbgGetTypeFilter, RtdbgSendMessage, RtdbgSetIndexFilter, RtdbgSetSourceFilter, RtdbgSetTypeFilter

For larger applications that require sending messages with specialized formats, the Standard and Trace message channels are ideal. You can define these channels using the Channel Editor in the Message Viewer. These channels are identified with the combination of VendorId, ProductCode, ChannelId, and channel type.

Note: The VendorId should correspond to the CustomerId of the wRTOS SDK license used to build the program.

Message formats are defined per channel and identified by the combination of MessageType and MessageFormat. The console can filter messages by MessageType or Source. Valid ranges for message types and sources are between 0 and 31.

Basic Message Channel

The Basic message API, RtdbgSendBasicMessage, sends a message to the console with four optional values. The values are formatted into the message by the console not the library to avoid printf performance issues. The console uses standard .NET string formatting to insert the values in the message text.

Messages can be filtered by category and severity. User applications must define category names using RtdbgSetBasicCategoryName. The category names can be retrieved using RtdbgGetBasicCategoryName.

To send messages, enable the Basic message channel using RtdbgOpenBasicChannel, and then send messages with RtdbgSendBasicMessage. Close this channel at the end of your application (using RtdbgCloseBasicChannel) to release its resources.

Basic Message Channel Example:

Copy
int i = 0;
INT Failed = ERROR_SUCCESS;
Failed = RtdbgOpenBasicChannel();
if (Failed) {
        RtPrintf("Failed to open basic channel: %d\n", Failed);
        return;
}
Failed = RtdbgSetBasicCategoryName(1, L"MyMessages");
if (Failed) {
        RtPrintf("Failed to set category name: %d\n", Failed);
}
for (i = 0; i < 10; i++) {
        Failed = RtdbgSendBasicMessage(1, MsgInfo, L"Message number: {0}", FALSE, i, 0, 0, 0);
        if (Failed) {
                RtPrintf("Failed to send the message: %d\n", Failed);
                break;
        }
}
Failed = RtdbgCloseBasicChannel();
if (Failed) {
        RtPrintf("Failed to close basic channel: %d\n", Failed);
        return;
}

Standard Message Channel

Standard message channels are created using RtdbgCreateStandardChannel. To effectively display these messages in Message Viewer, you must define these channels using the console's Channel Editor.

The application continuously sends messages to the Standard message channel using RtdbgSendMessage. The Message Viewer periodically reads the channel's content in batches. The channel's length is configurable. To prevent the console from not being able to read messages in time due to Windows lag, it's recommended to set the default buffer length to 10,000.

The standard message channels have a default message filter parameter to allow some messages to be logged even if the console is not started. This allows users to get basic debug information when they start the console after an issue has occurred.

Standard Message Channel Example:

Copy
int i = 0;
INT Failed = ERROR_SUCCESS;
RTDBG_CHANNEL Channel = NULL;
byte Data[64] = { 0 };
Failed = RtdbgCreateStandardChannel(&Channel, 123456, 0, 0, 0x1, 10000, 64, 8);
if (Failed) {
        RtPrintf("Failed to open channel: %d\n", Failed);
        return;
}
for (i = 0; i < 10; i++) {
        Failed = RtdbgSendMessage(Channel, 0, 0, 0, 0, 0, L"Test Message", 2, Data);
        if (Failed) {
                RtPrintf("Failed to set category name: %d\n", Failed);
        }
}
Failed = RtdbgCloseChannel(Channel);
if (Failed) {
        RtPrintf("Failed to close channel: %d\n", Failed);
        return;
}

Trace Message Channel

Trace message channels are created using RtdbgCreateTraceChannel. To effectively display these messages in Message Viewer, you must define these channels using the console's Channel Editor.

Since applications print multiple trace messages, Trace message channels have an additional SourceIndex filter. This allows the queue to only take messages from specific indexes of specific sources. For example, if you define two source types, device and axis, you can then filter messages to receive them from all devices but only from axes 1 and 2. See Source index filter.

Index filtering can enable all indexes for a source or up to 4 specific indexes for that source. Index values must be between 0 and 31.

Trace Message Channel Example:

Copy
int i = 0;
INT Failed = ERROR_SUCCESS;
RTDBG_CHANNEL Channel = NULL;
byte Data[64] = { 0 };
Failed = RtdbgCreateTraceChannel(&Channel, 123456, 0, 0, 10000, 1, 64, 8);
if (Failed) {
        RtPrintf("Failed to open channel: %d\n", Failed);
        return;
}
for (i = 0; i < 10; i++) {
        Failed = RtdbgSendMessage(Channel, 0, 0, 0, 0, 0, L"Test Message", 2, Data);
        if (Failed) {
                RtPrintf("Failed to set category name: %d\n", Failed);
        }
}
Failed = RtdbgCloseChannel(Channel);
if (Failed) {
        RtPrintf("Failed to close channel: %d\n", Failed);
        return;
}