##################################
AN00239: Using the logging library
##################################

********
Overview
********

This application note shows how to use the logging library. It covers the
difference between the logging library (``debug_printf()``) and the system library
printing function (``printf()``).

It also covers the difference between JTAG and xSCOPE to perform the I/O to the
host, including approximate values for resource usage and performance of each approach.

*****************************
Example logging library usage
*****************************

The CMakeLists.txt file
=======================

To start using the XMOS logging library, you need to add ``lib_logging`` to the
dependent module list in the ``CMakeLists.txt`` file::

  set(APP_DEPENDENT_MODULES "lib_logging")

The dependencies for this example are specified by ``deps.cmake`` in the ``examples``
directory and are included in the application ``CMakeLists.txt`` file.

Also, ``debug_printf()`` calls are only active if you enable
them in your ``CMakeLists.txt`` file. This is done by by setting ``DEBUG_PRINT_ENABLE``
to 1 in the ``APP_COMPILER_FLAGS``::

  set(APP_COMPILER_FLAGS ... -DDEBUG_PRINT_ENABLE=1 ...)

Include
=======

The function prototypes are declared in a single header file which must
be included from your source file::

  #include "debug_print.h"

Example application output
==========================

The example application outputs "Hello world".

.. literalinclude:: ../../src/main.xc
   :start-after: main(
   :end-at: debug_printf(

Building and Running the application using the command line
===========================================================

First open an command prompt/terminal window with the tools environment setup. 
A setup batch/script file is provided in the xTIMEcomposer package to do this for you.

To configure the build run the following from an XTC command prompt::

    cd examples
    cd AN00239
    cmake -B build -G "Unix Makefiles"

Finally, the application binaries can be built using ``xmake``::

    xmake -C build

Running the application is then done using the command::

    xrun --xscope bin/AN00239.xe

Debug units
===========

Applications can be created with different *units* whose debug output is independently
controlled. The example application also calls a function in another unit:

.. literalinclude:: ../../src/main.xc
   :start-after: debug_printf(
   :end-at: unit_function(

That file has put its debug messages as a separate debug unit by doing:

.. literalinclude:: ../../src/unit.xc
   :start-at: define
   :end-at: include

And by default these debug messages are not enabled, so running the program
will only produce the following output::

  $ xrun --xscope bin/AN00239.xe
  Hello world

In order to enable the debug_print messages in ``unit.xc`` it is necessary to
add to the list of compiler flags in the ``CMakeLists.txt`` file::

  set(APP_COMPILER_FLAGS ... -DDEBUG_PRINT_ENABLE_unit=1 ...)

After rebuilding the application it will now produce::

  $ xrun --xscope bin/AN00239.xe
  Hello world
  Unit print

xSCOPE printing
===============

On the xCORE platform it is possible to have I/O messages sent to the
console using either JTAG or xSCOPE. The default is for JTAG to be used. However,
when doing I/O over JTAG all cores on the xCORE are stopped and hence
real-time functionality is no longer maintained. As a result xSCOPE I/O should
be preferred.

xSCOPE I/O is enabled by creating a ``config.xscope`` file. This file can be
created in the same folder as the Makefile or with the source files. When
``config.xscope`` exists, it controls whether I/O messages are enabled, and
whether they use xSCOPE or JTAG. A basic file which enables I/O over xSCOPE
contains::

  <xSCOPEconfig ioMode="basic" enabled="true">
  </xSCOPEconfig>

*****
Notes
*****

Resource usage
==============

The following table shows the memory and cycle requirements for doing
a simple print of "Hello world %d\\n", using either ``printf()`` or ``debug_printf()``,
and using either JTAG or xSCOPE as the transport to the host.

.. list-table:: Resource usage
 :header-rows: 1

 * - Function
   - Transport
   - Program Memory (kB)
   - Time (us)
   - Channel Ends
 * - None
   - N/A
   - 0.9
   - 0.0
   - 0
 * - debug_printf()
   - JTAG
   - 1.86
   - 72000
   - 0
 * - debug_printf()
   - xSCOPE
   - 2.88
   - 8.5
   - 1 per tile
 * - printf()
   - JTAG
   - 9.02
   - 72000
   - 0
 * - printf()
   - xSCOPE
   - 9.99
   - 18.6
   - 1 per tile

.. note:: The JTAG timings are approximate and will depend on a number of factors
          including the host machine being used.

Lossless vs lossy
=================

The advantage of using xSCOPE instead of JTAG should be clear from the performance
figures above. However, it is important to understand that xSCOPE is a lossy
transport and as such if too much I/O is created then messages can be lost.

Ordering
========

It is also essential to understand that messages produced by different
logical cores are interleaved on the host console. There is no guarantee of the
order in which they will be printed.

print.h
=======

The tools provide extremely lightweight printing functions in ``print.h``. For
example it is possible to do::

  #include <print.h>
  ...
  printstr("The number ");
  printint(10);
  printstrln(" should be 10");

But each of these print fragments can arrive mixed with messages from
other logical cores. Whereas::

  debug_printf("The number %d should be 10\n", 10);

will be printed as a single line.

***************
Further Reading
***************

 * `XTC tools`_

 * `XMOS xCORE Programming Guide`_

 * `XMOS Libraries <https://www.xmos.com/libraries>`_
