NPR Tutorial >> Writing A Plugin | TOC |
Earlier, the page NPR Tutorial => Writing A Plugin => Quick Start described how to turn on debugging messages in the mycount plugin so that we would get a message displayed each time a packet was received by the plugin. This page describes how to write code to display those debug messages using the onl_api_int2str() and onl_api_debug_message() functions and what happens when you call these functions.
The plugin framework provides a very simple mechanism for sending messages from a plugin to the RLI. This section describes two of the most basic debug message functions: onl_api_int2str() and onl_api_debug_message(). In the mycount plugin, the handle_pkt_user() function uses these two functions in the following way:
void handle_pkt_user() { 1 __declspec(local_mem) char dbgmsg[28] = "got pkt x"; 2 __declspec(local_mem) char pkt_count_str[9]; 3 ++pkt_count; 4 if( debug_on ) { 5 onl_api_int2str( pkt_count, pkt_count_str ); 6 strcat_lmem(dbgmsg, pkt_count_str); 7 onl_api_debug_message(msgNextBlock, dbgmsg); 8 } 9 onl_api_plugin_cntr_inc(pluginId, 0); }
In NPR Tutorial => Writing A Plugin => Quick Start, we said the function onl_api_int2str() converts the value of pkt_count from its internal binary representation to a hexadecimal ASCII string. For example, if the value of pkt_count is 20 decimal, pkt_count_str will contain "14". Line 6 will append "14" to the string "got pkt x" to produce the debug message "got pkt x14". Then, the onl_api_debug_message() function in Line 7 will put the contents of dbgmsg into a control message input ring for the NPR's Xscale Control Processor; and a daemon running on the Xscale will write the message to your debug message file (if one has been specified).
Debug messages are inserted into the same SRAM rings that plugins use for control reply messages. There are eight SRAM control message rings paired for each microengine (ME) such that each ME has a control message input ring and a control message output ring.
Debug messages are limited to a maximum of 28 bytes (including the terminating NUL byte). This limitation is due to our use of an SRAM ring structure for debug messages that limits a message to 32 bytes where each message consists of a 4-byte message header and a 28-byte message body. The Xscale CP distinguishes between debug messages and other control messages through a type field in the 4-byte (1-word) message header. Local memory is used for the message to avoid the larger latency that comes with using SRAM.
Here are some important details that were glossed over in the description above:
This means that every call consumes part of the program store. Since the program store contains only 8K words, it is possible to exhaust it by over using the function.
The representation is not decimal.
Local memory only has 640 words which can only hold 320 28-byte string areas. Since local memory will be used for other things besides debug messages, you are likely to run out of local memory even if you plan to only make 20 unique messages.
The variable is independent of the Configuration => PluginDebugging menu item in the RLI that determines where debug messages should be logged; i.e., if you want mycount debug messages displayed, you will need to: 1) Use the RLI to define the debug log file; and 2) send a d message to the plugin to activate the code paths enclosed by if ( debug_on ) { ... }.
The message will still get delivered to the ONL daemon running on the Xscale. But the message will be thrown away instead of being written to a debug file. That's why the mycount plugin uses the debug_on variable to control the calling of the debug message functions.
There are helper functions that primarily use SRAM instead of local memory (they do use local memory sparingly) and output a decimal representation (instead of hexadecimal representation). Furthermore, they are higher-level functions in that they allow you to pass in multiple unsigned long values that make up a single debug message. Some of these functions are:
__forceinline void helper_dbg_message( __declspec(local_mem) char *dbgmsg, |
Copy a debug message from SRAM to local memory. |
void helper_sram_dbgmsg_1ul( unsigned long x0 ) |
Output a debug message which contains the value of x0 in decimal representation. |
void helper_sram_dbgmsg_3ul( unsigned long x0, |
Output a debug message which contains the values of x0, x1 and x2 in decimal representation. |
void helper_sram_dbgmsg_str_1ul( char *cstr, |
Output a debug message which is the concatenation a string and a value in decimal representation. |
__forceinline void helper_sram_dbgmsg_str_1ul( char *cstr, |
Output a debug message which is the concatenation a string and a value in decimal representation. |
void helper_sram_outmsg_3ul( unsigned long x0, |
Create a string in local memory containing the three unsigned long values in decimal representation with single-space separation. |
void helper_sram_outmsg_5ul( unsigned long x0, |
Create a string in local memory containing the five unsigned long values in decimal representation with single-space separation. |
These functions are used in the priq plugin that implements strict priority packet scheduling and all of the plugin chaining plugins (e.g., delay++, erd++, shaper++). They can be easily modified to exhibit slightly different behavior.
Revised: Fri, Apr 3, 2009
NPR Tutorial >> Writing A Plugin | TOC |