.. _hexformat:

=================
Firmware Hex File
=================

When MicroPython is built, the compiler produces an
`Intel Hex <https://en.wikipedia.org/wiki/Intel_HEX>`_ file containing the
MicroPython firmware.
Additional data can then be added to this file to contain information about the
MicroPython version, or the Python code to execute on start-up.

The general memory layout used is:

- ``0x00000000``: Start of MicroPython firmware - up to 248 KBs
- ``0x0003e000``: Start of appended script (optional) - up to 8 Kbs
- ``0x100010c0``: UICR customer[16] register, start of MicroPython information - 28 bytes
    
.. note::
    If you append any data or modify the Intel Hex file, please ensure the
    addresses of the data stored progress in incremental order.
    If there is an address jump backwards DAPLink will fail to flash the file.

Appended script format
----------------------

MicroPython checks the first 2 bytes at address ``0x0003e000`` for a magic
string to indicate if there is an appended script. If the magic string is
found, it will automatically execute the Python code stored there, unless there
is a main.py file stored in the MicroPython filesystem.

- ``0x0003e000``: 2 bytes "MP"
- ``0x0003e002``: 2 bytes, little endian integer for the length (in bytes) of the appended script (not counting this 4 byte header)
- ``0x0003e004``: Script stored as bytes, for MicroPython to decode using utf-8.

UICR format
-----------

The User Information Configuration Registers (UICR) is a region of Non-Volatile
Memory available to store user-specific settings.
The first 128 Bytes are reserved, but we can use the other 128 Bytes to store
any arbitrary data.

MicroPython stores the following information, in little endian, starting from
the UICR customer[16] register:

- ``0x100010c0``: 4-byte integer with magic value ``0x17eeb07c``
- ``0x100010c4``: 4-byte integer with value ``0xffffffff``
- ``0x100010c8``: 4-byte integer with value ``0x0000000a`` (log base 2 of the flash page size, being 1024 bytes)
- ``0x100010ca``: 2-byte integer with value ``0x0000`` (start page of the firmware)
- ``0x100010cc``: 2-byte integer storing number of pages used by the firmware
- ``0x100010d0``: 4-byte integer with value ``0xffffffff``
- ``0x100010d4``: 4-byte integer with the address in the firmware of the version string
- ``0x100010d8``: 4-byte integer with value ``0x00000000``

Steps to create the firmware.hex file
-------------------------------------

The yotta tool is used to build MicroPython, but before that takes place
additional files have to be generated by the Makefile in preparation for the 
build, and additional data is added to the hex file after.

Running the ``make all`` command executes the following steps:

- The ``tools/makeversionhdr.py`` script creates the ``microbitversion.h`` file with macros containing build information
- Yotta builds the source and creates a bare hex file with just the firmware
- The ``tools/adduicr.py`` script adds the UICR to the bare hex
- The final hex file is placed in ``build/firmware.hex``
- The user can optionally append a script using ``tools/makecombinedhex.py`` (or other tools)
