Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Add information about the hex file format #561

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions docs/devguide/hexformat.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.. _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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this contradicts what is done by makecombinedhex.py: it appends the user script (at 0x3e000) to the build/firmware.hex file, with the latter having the UICR info at the end of the .hex. So the final hex looks like this:

0x00000000 - uPy firmware
0x100010c0 - UICR info
0x0003e000 - appended script

And DAPLink seems fine with this, it seems to flash it without error.

Copy link
Contributor Author

@carlosperate carlosperate Sep 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on the move at the moment, so I cannot really look into this in much detail for a couple of hours, but if I download a hex file with RC5 + the default code from https://python.microbit.org/v/beta and manually move the UICR data between MicroPython and the appended code, the hex is not flashed correctly in my test:

...
:1082400005050505050505FF00000401E90000001E
:10825000852B000051340000257800006D6101007D
:108260004563010095630100C9880100C100000059
:020000041000EA
:1010C0007CB0EE17FFFFFFFF0A0000000000E10008
:0C10D000FFFFFFFF6D0E0300000000009A
:020000040003F7
:10E000004D509900232041646420796F757220502F
:10E010007974686F6E20636F646520686572652E21
:10E0200020452E672E0A66726F6D206D6963726FD0
:10E0300062697420696D706F7274202A0A0A0A7707
:10E0400068696C6520547275653A0A202020206446
:10E050006973706C61792E7363726F6C6C282748DA
:10E06000656C6C6F2C20576F726C642127290A2015
:10E07000202020646973706C61792E73686F772833
:10E08000496D6167652E4845415254290A20202078
:10E0900020736C6565702832303030290A0000002A
:0400000500019C0951
:00000001FF

Can you replicate this?

I'll have a look how makecombinedhex is combining the files, maybe I am missing something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot replicate. This test (of manually moving the UICR data for the default code) works fine for me (scrolling hello world, then a heart image, looping).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an important issue to work out, because makecombinedhex.py needs to be changed if it doesn't work with DAPLink.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I've been looking into this, and I think it works in older version of DAPLink, but not the new ones.

I was testing this today with version 0249 and didn't work, and also I'm pretty sure it didn't work either on the latest available version released during the time we were first looking into adding the UICR region, likely v0246.

The current DAPLink if the hex order is UICR + MicroPython + code, we get a fail.txt file. However if the hex file has MicroPython + UICR + code, then it fails silently (flashing MicroPython and the UICR, but not the appended code).

This limitation has been designed within DAPLink, however until today I didn't realised it wasn't present in older versions:
https://github.com/ARMmbed/DAPLink/blob/ab7abed209eb166a98a8ecc69b05a4dcbe86adc6/source/daplink/drag-n-drop/flash_manager.c#L127-L134

I found a micro:bit running 0234 and that one flashed both hex files correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so DAPLink 0241 which has been shipped from factory for quite a while already presents this limitation, and the new boards will be running 0249, so we should update makecombinedhex.py to append the code before the UICR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created #563


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)
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Projects related to MicroPython on the BBC micro:bit include:
devguide/installation
devguide/flashfirmware
devguide/repl
devguide/hexformat
devguide/devfaq
devguide/contributing

Expand Down