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:
- Basic message channel: for sending basic messages from your application. There is only one Basic message channel.
Available APIs: RtdbgCloseBasicChannel, RtdbgGetBasicCategoryName, RtdbgGetBasicMessage, RtdbgGetSeverityFilter, RtdbgOpenBasicChannel, RtdbgSendBasicMessage, RtdbgSetBasicCategoryName, RtdbgSetSeverityFilter
- Standard message channel: for messages sent occasionally, such as startup, information, errors and warnings. This channel allows for customizable message data and filtering.
Available APIs: RtdbgCloseChannel, RtdbgCreateStandardChannel, RtdbgGetMessage, RtdbgGetSourceFilter, RtdbgGetTypeFilter, RtdbgSendMessage, RtdbgSetSourceFilter, RtdbgSetTypeFilter
- Trace message channel: similar to the Standard message channel; however, this channel allows you to send massive and customized messages in a short period. For example, 10,000 messages in one second.
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:
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:
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:
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;
}