<commit_before>
XMBurner application manual
==============================================================================

:Author:    <NAME> (Jubatian)
:License:   MPLv2.0 (version 2.0 of the Mozilla Public License)




Overview
------------------------------------------------------------------------------


This document serves as a guide on how to use the XMBurner library properly,
most notably so it can serve its intended purpose to the greatest extent.


The purpose of the library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

XMBurner may be used for two distinct purposes which require a different
approach when integrating it.

- Diagnostic (DIAG): The goal is to detect and report problems in the
  processor while trying to keep running. Examples could be various stress
  tests or environments where the processor can not be replaced, but it would
  be beneficial to know whether it operates correctly (such as space).

- Safety shut down (SAFE): The goal is to enforce a safe system shut down when
  processor malfunction is discovered. This case the most important is to
  prevent the processor operating further (and possibly generating dangerous
  output) when it is no longer capable to run the application correctly.

The "DIAG" and "SAFE" identifications will be used below to indicate whether a
particular requirement applies to either or both.




Hardware environment
------------------------------------------------------------------------------


- DIAG: No particular requirements apply.

- SAFE: An external watchdog is recommended which can either be armed by a
  specific command or has a significantly longer timeout on power-up than
  in normal operation. This is recommneded for properly guarding XMBurner's
  init routine. It is desirable if the watchdog could keep the processor in
  reset instead of restarting it by a pulse (if XMBurner detects an anomaly,
  the processor should no longer be permitted to perform any control).




Compiling and linking environment
------------------------------------------------------------------------------


To use XMBurner, you may copy it at an arbitrary location (within or external
to the application repository) and set up appropriate scripts to build and
link its modules. For normal Makefiles, the xmb_defs.mk and xmb_ruls.mk files
may be included with an appropriate configuration to assist building and
linking.

When including the xmb_defs.mk file, definition overrides should be added to
the XMB_CFLAGS variable as appropriate after this inclusion, such as for
example "-DXMB_INIT_GUARD my_guard_routine" to specify an init guard routine.

The XMBurner sources are all assembler, can be compiled with the avr-gcc
compiler package or a compatible assembler to that within this. They use C
preprocessor directives, so preprocessing is required (using the supplied
Makefiles ensure proper compilation). No C language modules are used.

For assembler interfacing, the xmburner/xmb_defs.h file may be included.

For C interfacing, the xmburner/xmburner.h file is provided which exposes the
library's functions to C modules.


Sections
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It is possible to use XMBurner without defining sections, but it is
recommended to set up sections for both DIAG and SAFE applications.

- XMB_RO64_SECTION: This definition may be pointed to a section which covers
  the low 64 KBytes of the ROM. It is used for certain data tables which can
  only be accessed in this region. By default this is the .progmem section
  which serves especially this purpose.

- XMB_COMP_SECTION: If desired, this section may be pointed to a specific
  section where non-public XMBurner components should reside. You can share
  it with XMB_JUMP_SECTION if the linker preserves the order of objects passed
  on the command line for linking.

- XMB_JUMP_SECTION: This definition should be pointed to 64 words before the
  largest valid power of 2 address of the ROM. This ensures that the jump
  tests exercise the longest carry chain in relative jumps.




Fault detection
------------------------------------------------------------------------------


The xmb_fault routine is responsible for handling detected failures (this
routine name may be modified by the XMB_FAULT definition). No default
implementation is provided, so in order to link, one has to be supplied. The
routine should be written in assembler to be able to track used instructions
ensuring robustness against the already detected failure.

- DIAG: The routine may return by jumping to xmb_glob_tail (which case the
  xmb_run() routine will return normally). Within the routine, diagnostic
  should be performed (to be able to store or report the failure). XMBurner
  will not continue execution, it must be re-initialized.

- SAFE: The routine should attempt to take measures to halt execution. Note
  that XMBurner itself will break its execution chain, so it is quite robust
  on its own (see also the "Using watchdogs (SAFE)" chapter), but taking
  proper measures here to halt execution improves robustness.




Using watchdogs (SAFE)
------------------------------------------------------------------------------


In SAFE applications, a watchdog or watchdogs should be used. The most
important role of the watchdog is preventing the processor to produce
dangerous output (note that this doesn't necessarily mean that the processor
itself should be reset by the watchdog, a device breaking the output path also
serves as a watchdog in this regard).

The XMB_WDRESET definition should be used to point at the routine managing the
watchdogs (this can be a C routine if desired). The routine takes a single 32
bit parameter, XMBurner passes the value 0xDEADF158 on this which the routine
should use to check whether the call came from the intended source.

A default implementation is provided for this routine which resets the
internal watchdog (by the WDR instruction).

The routine is called once for every xmb_run() call if XMBurner didn't detect
any fault (including faults of its execution chain which is broken by any
detected fault).


Guarding initialization with a Watchdog
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The watchdog(s) also serve for guarding the initialization routine of
XMBurner. For this to be effective, a watchdog which can be armed, or one with
significantly longer power-up timeout than normal operation timeout is
required.

The XMB_INIT_DELAY definition should be set to a value which is larger than
the normal timeout of the watchdog. This ensures that if the initialization
routine is executed for any reason during normal operation, it can not
complete without the watchdog timing out (assuming that at least the
instructions and registers performing this delay are still operational).


Guarding initialization with a routine
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The XMB_INIT_GUARD definition could be used to set up a routine which guards
the initialization routine. It could carry out the following tasks:

- Set the outputs to a safe initial state, ensuring that the controlled
  process returns to an acceptable safe state if the initialization routine is
  re-entered.

- Attempt to detect a false initialization if there is any condition which
  could be used for this purpose. On detecting such a condition, it may halt
  the processor.

Using this guard function properly can make the system more robust against
processor faults, but it may not be as efficient in this task like the
recommended watchdog.




ROM CRC calculation
------------------------------------------------------------------------------


The ROM is guarded by a standard CRC32 (the same which is used for example for
PNG or BZIP). This CRC is used to verify whether the ROM contents are still
sound, or that the instructions fetching from the ROM can still operate
correctly.

To calculate and apply this CRC on the binary, the xmbtools/crchex.c program
is provided along with Makefile assistance to use it.

Within the application, the xmb_bsize location (2 or 3 bytes Little Endian
depending on the MCU's ROM size) is used to determine the location of the CRC
(this location name can be changed by the XMB_BSIZE definition). It has to be
filled accordingly to make the CRC check functional.




Boot time tests
------------------------------------------------------------------------------


XMBurner provides routines to perform a full ROM and RAM test during bootup
(xmb_crc_isromok() and xmb_ram_isramok()). These should be used as part of the
application's initialization as they together may take several hundreds of
milliseconds on larger MCUs.

Note that ROM and RAM tests are also performed during runtime, these routines
only ensure that the application doesn't start at all if either the ROM or the
RAM has a fault.


Using a watchdog with short timeout
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If your design involves a watchdog which has a relatively short timeout even
during init, and it resets the processor (not the critical outputs or the
controlled process only), you might need to split up ROM CRC calculation on
larger devices.

You can enable this by setting the XMB_CRC_SPLIT nonzero. This case the CRC
calculation will include xmb_run() calls after every 64 Kbytes (if your binary
size is a multiple of 64 Kbytes, then after the last byte, too), which may
reset the watchdog (see "Using watchdogs (SAFE)"). Note that you will need to
call xmb_init() before xmb_crc_isromok() this case.

Note that this design is not recommended as guarding the initialization
routine is recommended by a watchdog which usually implies a longer timeout.
If absolutely necessary, using xmb_run() to reset the watchdog during init is
recommended.<commit_msg>Added notes on DMA usage for MCUs having DMA controller.<commit_after>
XMBurner application manual
==============================================================================

:Author:    <NAME> (Jubatian)
:License:   MPLv2.0 (version 2.0 of the Mozilla Public License)




Overview
------------------------------------------------------------------------------


This document serves as a guide on how to use the XMBurner library properly,
most notably so it can serve its intended purpose to the greatest extent.


The purpose of the library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

XMBurner may be used for two distinct purposes which require a different
approach when integrating it.

- Diagnostic (DIAG): The goal is to detect and report problems in the
  processor while trying to keep running. Examples could be various stress
  tests or environments where the processor can not be replaced, but it would
  be beneficial to know whether it operates correctly (such as space).

- Safety shut down (SAFE): The goal is to enforce a safe system shut down when
  processor malfunction is discovered. This case the most important is to
  prevent the processor operating further (and possibly generating dangerous
  output) when it is no longer capable to run the application correctly.

The "DIAG" and "SAFE" identifications will be used below to indicate whether a
particular requirement applies to either or both.




Hardware environment
------------------------------------------------------------------------------


- DIAG: No particular requirements apply.

- SAFE: An external watchdog is recommended which can either be armed by a
  specific command or has a significantly longer timeout on power-up than
  in normal operation. This is recommneded for properly guarding XMBurner's
  init routine. It is desirable if the watchdog could keep the processor in
  reset instead of restarting it by a pulse (if XMBurner detects an anomaly,
  the processor should no longer be permitted to perform any control).




Compiling and linking environment
------------------------------------------------------------------------------


To use XMBurner, you may copy it at an arbitrary location (within or external
to the application repository) and set up appropriate scripts to build and
link its modules. For normal Makefiles, the xmb_defs.mk and xmb_ruls.mk files
may be included with an appropriate configuration to assist building and
linking.

When including the xmb_defs.mk file, definition overrides should be added to
the XMB_CFLAGS variable as appropriate after this inclusion, such as for
example "-DXMB_INIT_GUARD my_guard_routine" to specify an init guard routine.

The XMBurner sources are all assembler, can be compiled with the avr-gcc
compiler package or a compatible assembler to that within this. They use C
preprocessor directives, so preprocessing is required (using the supplied
Makefiles ensure proper compilation). No C language modules are used.

For assembler interfacing, the xmburner/xmb_defs.h file may be included.

For C interfacing, the xmburner/xmburner.h file is provided which exposes the
library's functions to C modules.


Sections
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It is possible to use XMBurner without defining sections, but it is
recommended to set up sections for both DIAG and SAFE applications.

- XMB_RO64_SECTION: This definition may be pointed to a section which covers
  the low 64 KBytes of the ROM. It is used for certain data tables which can
  only be accessed in this region. By default this is the .progmem section
  which serves especially this purpose.

- XMB_COMP_SECTION: If desired, this section may be pointed to a specific
  section where non-public XMBurner components should reside. You can share
  it with XMB_JUMP_SECTION if the linker preserves the order of objects passed
  on the command line for linking.

- XMB_JUMP_SECTION: This definition should be pointed to 64 words before the
  largest valid power of 2 address of the ROM. This ensures that the jump
  tests exercise the longest carry chain in relative jumps.




Fault detection
------------------------------------------------------------------------------


The xmb_fault routine is responsible for handling detected failures (this
routine name may be modified by the XMB_FAULT definition). No default
implementation is provided, so in order to link, one has to be supplied. The
routine should be written in assembler to be able to track used instructions
ensuring robustness against the already detected failure.

- DIAG: The routine may return by jumping to xmb_glob_tail (which case the
  xmb_run() routine will return normally). Within the routine, diagnostic
  should be performed (to be able to store or report the failure). XMBurner
  will not continue execution, it must be re-initialized.

- SAFE: The routine should attempt to take measures to halt execution. Note
  that XMBurner itself will break its execution chain, so it is quite robust
  on its own (see also the "Using watchdogs (SAFE)" chapter), but taking
  proper measures here to halt execution improves robustness.




Using watchdogs (SAFE)
------------------------------------------------------------------------------


In SAFE applications, a watchdog or watchdogs should be used. The most
important role of the watchdog is preventing the processor to produce
dangerous output (note that this doesn't necessarily mean that the processor
itself should be reset by the watchdog, a device breaking the output path also
serves as a watchdog in this regard).

The XMB_WDRESET definition should be used to point at the routine managing the
watchdogs (this can be a C routine if desired). The routine takes a single 32
bit parameter, XMBurner passes the value 0xDEADF158 on this which the routine
should use to check whether the call came from the intended source.

A default implementation is provided for this routine which resets the
internal watchdog (by the WDR instruction).

The routine is called once for every xmb_run() call if XMBurner didn't detect
any fault (including faults of its execution chain which is broken by any
detected fault).


Guarding initialization with a Watchdog
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The watchdog(s) also serve for guarding the initialization routine of
XMBurner. For this to be effective, a watchdog which can be armed, or one with
significantly longer power-up timeout than normal operation timeout is
required.

The XMB_INIT_DELAY definition should be set to a value which is larger than
the normal timeout of the watchdog. This ensures that if the initialization
routine is executed for any reason during normal operation, it can not
complete without the watchdog timing out (assuming that at least the
instructions and registers performing this delay are still operational).


Guarding initialization with a routine
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The XMB_INIT_GUARD definition could be used to set up a routine which guards
the initialization routine. It could carry out the following tasks:

- Set the outputs to a safe initial state, ensuring that the controlled
  process returns to an acceptable safe state if the initialization routine is
  re-entered.

- Attempt to detect a false initialization if there is any condition which
  could be used for this purpose. On detecting such a condition, it may halt
  the processor.

Using this guard function properly can make the system more robust against
processor faults, but it may not be as efficient in this task like the
recommended watchdog.




ROM CRC calculation
------------------------------------------------------------------------------


The ROM is guarded by a standard CRC32 (the same which is used for example for
PNG or BZIP). This CRC is used to verify whether the ROM contents are still
sound, or that the instructions fetching from the ROM can still operate
correctly.

To calculate and apply this CRC on the binary, the xmbtools/crchex.c program
is provided along with Makefile assistance to use it.

Within the application, the xmb_bsize location (2 or 3 bytes Little Endian
depending on the MCU's ROM size) is used to determine the location of the CRC
(this location name can be changed by the XMB_BSIZE definition). It has to be
filled accordingly to make the CRC check functional.




Boot time tests
------------------------------------------------------------------------------


XMBurner provides routines to perform a full ROM and RAM test during bootup
(xmb_crc_isromok() and xmb_ram_isramok()). These should be used as part of the
application's initialization as they together may take several hundreds of
milliseconds on larger MCUs.

Note that ROM and RAM tests are also performed during runtime, these routines
only ensure that the application doesn't start at all if either the ROM or the
RAM has a fault.


Using a watchdog with short timeout
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If your design involves a watchdog which has a relatively short timeout even
during init, and it resets the processor (not the critical outputs or the
controlled process only), you might need to split up ROM CRC calculation on
larger devices.

You can enable this by setting the XMB_CRC_SPLIT nonzero. This case the CRC
calculation will include xmb_run() calls after every 64 Kbytes (if your binary
size is a multiple of 64 Kbytes, then after the last byte, too), which may
reset the watchdog (see "Using watchdogs (SAFE)"). Note that you will need to
call xmb_init() before xmb_crc_isromok() this case.

Note that this design is not recommended as guarding the initialization
routine is recommended by a watchdog which usually implies a longer timeout.
If absolutely necessary, using xmb_run() to reset the watchdog during init is
recommended.




Notes on DMA usage
------------------------------------------------------------------------------


Some XMega chips contain DMA hardware which is capable to move data between
memory and peripherals without active CPU intervention.

Using DMA together with XMBurner implies complications as the DMA accesses can
not be predicted in a system where DMA transactions are enabled. Such accesses
conflict with the RAM test, and may cause either corrupted peripheral writes
or false alarms on the RAM test.

The following workarounds may apply:

- Don't use DMA. This is the simplest solution if the system's architecture
  permits it (there are no tasks requiring high bandwidth).

- Time DMA transactions so they don't conflict with xmb_run(). This solution
  is workable for transmit type transactions which are started by user code
  and their runtime is deterministic.

It is not possible to use XMBurner with receive type transactions which are
completely asynchronous to the running user code and calls to xmb_run(). It
would be possible to disable DMA for xmb_run() calls, but such high bandwidth
usage which would require using the DMA (instead of a normal interrupt)
wouldn't permit the approximately 10K cycle disable periods which xmb_run()
calls may impose.
{'fraction_non_alphanumeric': 0.11196671130667687, 'fraction_numerical': 0.002487086282762579, 'mean_word_length': 3.447777068708785, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2188035', 'n_tokens_mistral': 5044, 'n_tokens_neox': 4773, 'n_words': 2971}