Diagnostics

All Lighfoot applications supports diagnostics for various modules. This allows you to develop and debug new modules very easily, and also keep the diagnostics in the code for troubleshooting when the module is being used.

Using diagnostics in code

There are a number of ways to produce messages on the diagnostics device.
The recommended approach is to used the DCT_DIAG_XXXX macros in C and the Log class in Java as these provide you with the most control at runtime. If you need to use diagnostics from within assembler, use the DCT_LLDIAG_XXXX macros, but make sure they are called from within code using the C Constant Pool (CCP).

DCT_DIAG_XXXX diagnostics

The DCT_DIAG_XXXX diagnostics use a module identifier that can be used to control whether or not the diagnostics appear at runtime. You can use them in the code as shown below.
    DCT_DIAG_ERROR((DCT_CONST_DIAG_MODULE_UNASSIGNED_09, "Debug message %d\n", i));
The recommended way of defining the module is to define a macro in a local header file to the correct module name as shown below
#define MODULE_ID DCT_CONST_DIAG_MODULE_UNASSISNGED_15

fprintf diagnostics

Instead of using the DCT_DIAG_XXXX  macros, you can directly create diagnostic messages using the fprintf function on the stddiag stream. This is not recommended for permanent diagnostics, but for temporary ones when developing new modules.
    fprintf(stddiag, "Direct diagnostic message %d\n", i);

Java diagnostics

Java diagnostics use the Log class from the com.dctl.j2me.system package. The best way to use this is to have a static final boolean variable that controls whether or not diagnostics are enabled, as this allows the Log calls to be compiled out if not enabled.
The recommended way of using Java diagnostics is shown below.

import com.dctl.j2me.system.Log;
import com.dctl.j2me.system.LogFactory;
public class Test {
    private static final Log log = LogFactory.getLog(Test.class);
    private static final boolean DEBUG = true;

    public void testMethod() {
      if (DEBUG) log.debug("In test method");
    }
}

Controlling the production of diagnostics

There are two points at which the production of diagnostics can be controlled, compile time and runtime.

Compile time diagnostic control

The following pre-processor defines can be used to enable or disable the DCT_DIAG_XXX diagnostics at compile time.
Macro
Description
DCT_BUILD_DIAGNOSTICS
Define to enable the production of diagnostics. If this is not defined then diagnostics will not be produced. This is the default for non debug builds. This is used to enable the DCT_DIAG_XXXX macros as well as the DCT_LLDIAG_XXXX macros.
DCT_SUPPRESS_DIAGNOSTICS
Define to suppress building of diagnostics in a debug build.
DCT_BUILD_DIAG_ENABLE_ERROR
Define to enable diagnostics for errors. This is enabled by default in debug builds.
DCT_BUILD_DIAG_ENABLE_INFO
Define to enable diagnostics for information. This is enabled by default in debug builds.
DCT_BUILD_DIAG_ENABLE_VERBOSE
Define to enable verbose messages. By default, debug builds do not enable this.

Run time diagnostic control

Runtime diagnostic control is controlled by the XML configuration file. This allows you to control the level of debugging for modules, whether diagnostics are enabled and the destination for diagnostics. Even if diagnostics are disabled at runtime, your application will still be calling the diagnostic routines, causing a minor slow down in performance.

Controlling the level of diagnostics for individual modules

You can control the diagnostic level for modules by adding lines of the following format to config.xml.
    <diagnostics module="XXXXX" level="YYYYY">
where XXXXX is the name of the module as defined in the diagnostics.h header file, and YYYYY is one of error, info, verbose or none.

Globally enabling or disabling diagnostics

To globally enable or disable diagnostics, add the following line to the target's constants section in  config.xml, with XXXX set to 1 to enable, or 0 to disable.
    <constant type="var" name="DIAG_ENABLED" value="XXXX" format="integer"/>

Controlling the destination for diagnostics

The destination for diagnostics can be set in the config.xml configuration file. The default is to send it across a UART, but the higher level diagnostics can also be sent across another stream. The low level (DCT_LLDIAG_XXXX) diagnostics are only supported across the diagnostic UART.

The change the UART used, at the following line to the target's constants section in config.xml.
    <constant type="var" name="DIAG_INST" value="XXXX" format="integer"/>
where XXXX is set to the instance of the UART to use.

If the target supports changing the speed of the UART, add this line with the appropriate speed.
    <constant type="var" name="DIAG_BAUD_RATE" value="115200" format="integer"/>

You can send high level diagnostics across the network to a remote machine using the udp diagnostics protocol. This requires that you have enabled networking in your config.xml file. Add the following line to the target section in your config.xml file.
    <stream name="stddiag" class="output_udp" technology="virtual"/>
The sends diagnostics to the machine used to download the application to the development board. You must have invoked lfdownload with the '-u <instance>' option to enable receipt of these messages. The instance number is used when more than one stream is redirected to UDP. If only one stream is redirected, use instance 0.
If your application is running from flash, or you want to send the messages to another system, you need to add the following entry to the target's constants section in config.xml.
    <constant type="var" name="UDP_DEBUG_SERVER" value="XXXX" format="string"/>
where XXXX is the name of the server to use.