microbit-foundation / standalone-error-program

A small, standalone (No CODAL) bit of code to display errors on the micro:bit, for use in DAPLink and as a template for BLE bootloader
MIT License
0 stars 1 forks source link

Error Message Transfer #3

Closed jaustin closed 4 years ago

jaustin commented 4 years ago

Now Martin has proved that a tiny binary to display an error is feasible, we need to move onto the step of making the error number changeable.

@microbit-carlos and I have discussed this and would like @gerargz and @martinwork to comment on the following proposal

  1. In the Stand Alone Panic programme we will add a section to the linker script at the end of the binary that contains the error code. This should be last 4 bytes of the binary. By default this should be 0d71 (error 71). We would read the errors from this location and print them to the screen. (@martinwork I think this means you'd need to include 0-9 in your font code if you haven't already).
  2. In DAPLink, when we want to change the error, we just overwrite the last byte of the binary file.

Is this both straightforward and effective for both projects? If not, what's an easier way to have a flash location that both projects know about for writing the number. I'd like to avoid using the UICR because it has slightly odd write/erase semantics

martinwork commented 4 years ago

Will this do it?

Change the error code... In the bin and hex, near the end, the 4 bytes after magic 53 41 45 50 (SAEP), contain the error code (2 bytes) and iterations (2 bytes), little endian.

The default is 70 at the moment. This is what you originally asked for. I changed it just so I could see 3 different digits.

Note that I have added an nrfx build now with slightly smaller bin and hex.

jaustin commented 4 years ago

This looks fine as an approach if @gerargz is happy searching for the location of the magic. If we want a defined location, or just "at the end of the binary" this looks to be viable https://github.com/cirosantilli/cpp-cheat/tree/8b67c0713c332d0f6971a0d09f3cd6d713014566/linker/variable-address

(I think if we wanted 'end of file' we'd just let the linker choose the location, but keep the section definition?)

martinwork commented 4 years ago

Added a build (microbit-linker) with the error code variable in a section added to the linker script.

Seems to work but should be checked by a non-novice linker hacker!

https://github.com/martinwork/standalone-error-program/blob/standalone-panic/microbit-linker/armgcc/gcc_nrf52.ld

jaustin commented 4 years ago

@gerargz does this work better for you as you won't have to search through the whole binary for the magic word, but can still check for it?

@martinwork I took a quick look with a binary editor at the .bin

image

A couple of thoughts on this

  1. It looks like there's some other stuff after the magic word. I was going to guess padding but there's some real stuff there. Is that intentional?
  2. Is there a reason you're putting this section in RAM not FLASH (IE insert after .text) - my guess is that perhaps if not in RAM it ends up earlier in the file?
  3. Could we please use 0xFACECODE as the magic instead of "SAEP" - or just 0xCODE if you want 4 bytes? I like FACECODE as it's quite descriptive! - Makes searching a binary without remembering ASCII easier
gerargz commented 4 years ago

@gerargz does this work better for you as you won't have to search through the whole binary for the magic word, but can still check for it?

From the DAPLink interface perspective, I don't see an advantage of searching through the binary for the magic word at runtime as we can just enter the offset manually. If we update the binary with a different offset we can just update the new offset as we still need to rebuild the interface. The magic word is still handy for manually finding the error code location, so either way works for me.

martinwork commented 4 years ago

@jaustin @gerargz

This is the latest file: https://github.com/martinwork/standalone-error-program/blob/standalone-panic/built/linker_nrf52833_xxaa.bin

The bin is now 2008 bytes and the code is the last 4 bytes in the file.

Maybe we should merge the PR to make it easier to find?

martinwork commented 4 years ago

@jaustin @gerargz Sorry, I'm sure I said this yesterday somewhere, but can't find where...

I added a build which puts the variable at the end of the file using a linker section (microbit-linker folder). This seems to work but should be checked by a non-novice linker hacker!

The linker method has a smaller binary. I then enabled link time optimisation which reduced it further. LTO removed the magic from the earlier attempts!

martinwork commented 4 years ago

It looks like there's some other stuff after the magic word. I was going to guess padding but there's some real stuff there. Is that intentional?

In the builds that use the magic, it's whatever the linker puts there.

Is there a reason you're putting this section in RAM not FLASH (IE insert after .text) - my guess is that perhaps if not in RAM it ends up earlier in the file?

In the custom linker script build (ie. not the file in the dump above), I initially put it after .text, which did put it further up. So I tried after .data which seemed to imply using ">RAM".

My understanding is that the lump after .text is flash-stored, variable initialisation data, that gets copied to RAM.

As I meant to say yesterday "danger: novice linker hacker at work!"

Could we please use 0xFACECODE as the magic instead of "SAEP" - or just 0xCODE if you want 4 bytes? I like FACECODE as it's quite descriptive! - Makes searching a binary without remembering ASCII easier.

The magic is a 4 byte integer which gets reversed by the endianness in the binary and hex. I've changed it to 0xFACEC0DE which will be DE C0 CE FA in a binary dump. Maybe you meant the other way round? It depends on how you're searching the binary. I think it will be on a 4 byte boundary.

martinwork commented 4 years ago

It looks like DAPLink is using the nrfx build with the magic (now FACEC0DE). The python build.py creates a C header with a variable for the offset of the code.