Skip to content

boards/common: Make Adafruit nRF52 Bootloader shared #21281

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

Merged
merged 6 commits into from
Mar 25, 2025

Conversation

crasbe
Copy link
Contributor

@crasbe crasbe commented Mar 8, 2025

Contribution description

Currently the flash related Makefiles and the documentation about the flash process are in the documentation for the Feather nRF52840 and Feather nRF52840 Sense board.
With upcoming boards that utilize the same Adafruit nRF52840 Bootloader, like the Seeedstudio Xiao nRF52840 ( #20980 ) and Xiao nRF52840 Sense, it makes sense to put the makefiles and documentation into the boards/common folder.

Furthermore I used the opportunity to move the doc.txt files to Markdown format.

This can also be a good starting point to address #21205 and implement a flag to conditionally keep or discard SoftDevice.

Testing procedure

Make sure that the flashing of the feather-nrf52840 and feather-nrf52840-sense still works as it should with your favorite application, for example BOARD=feather-nrf52840 make -C examples/basic/hello-world flash term

Alternatively if you don't have a feather at hand or don't want to harm any birds to obtain one, you can use an nRF52840dk and flash the Adafruit Bootloader. The board is called pca10056 in the Adafruit Bootloader (https://github.com/adafruit/Adafruit_nRF52_Bootloader/). You can program the nRF52840DK as if it was a Feather or Feather Sense.

It is important to check that the offset is correctly set in the uf2conv command (0x26000 for the nRF52840DK). You can also check if the UF2_SOFTDEV=DROP option works to override the Soft Device (then the offset should be 0x1000).

$ BOARD=feather-nrf52840 make -C tests/sys/shell flash term
make: Verzeichnis „/home/chris/riot-ada-bl/RIOT/tests/sys/shell“ wird betreten
Building application "tests_shell" for "feather-nrf52840" with CPU "nrf52".

stty -F /dev/ttyACM0 raw ispeed 1200 ospeed 1200 cs8 -cstopb ignpar eol 255 eof 255
sleep 3
"make" -C /home/chris/riot-ada-bl/RIOT/pkg/cmsis/ 
...
"make" -C /home/chris/riot-ada-bl/RIOT/sys/ztimer
   text	   data	    bss	    dec	    hex	filename
  23688	    128	   4696	  28512	   6f60	/home/chris/riot-ada-bl/RIOT/tests/sys/shell/bin/feather-nrf52840/tests_shell.elf
/home/chris/riot-ada-bl/RIOT/dist/tools/uf2/uf2conv.py -f 0xADA52840 /home/chris/riot-ada-bl/RIOT/tests/sys/shell/bin/feather-nrf52840/tests_shell.hex --base 0x26000
Converted to uf2, output size: 48128, start address: 0x26000
Flashing /media/chris/NRF52BOOT (nRF52840-pca10056-v1)
Wrote 48128 bytes to /media/chris/NRF52BOOT/NEW.UF2
sleep 2
/home/chris/riot-ada-bl/RIOT/dist/tools/pyterm/pyterm -p "/dev/ttyACM0" -b "115200" -ln "/tmp/pyterm-chris" -rn "2025-03-11_11.17.53-tests_shell-feather-nrf52840"  
Twisted not available, please install it if you want to use pyterm's JSON capabilities
2025-03-11 11:17:53,935 # Connect to serial port /dev/ttyACM0
Welcome to pyterm!
Type '/exit' to exit.
help
2025-03-11 11:17:59,926 # min( Ts  help
2025-03-11 11:17:59,927 # shell: command not found: min(
> help
2025-03-11 11:18:00,769 # help
2025-03-11 11:18:00,770 # Command              Description
2025-03-11 11:18:00,771 # ---------------------------------------
2025-03-11 11:18:00,772 # bufsize              Get the shell's buffer size
2025-03-11 11:18:00,772 # start_test           starts a test
2025-03-11 11:18:00,773 # end_test             ends a test
2025-03-11 11:18:00,774 # echo                 prints the input command
2025-03-11 11:18:00,774 # empty                print nothing on command
2025-03-11 11:18:00,775 # periodic             periodically print command
2025-03-11 11:18:00,776 # xfa_test1            xfa test command 1
2025-03-11 11:18:00,776 # xfa_test2            xfa test command 2
2025-03-11 11:18:00,777 # app_metadata         Returns application metadata
2025-03-11 11:18:00,778 # pm                   interact with layered PM subsystem
2025-03-11 11:18:00,779 # ps                   Prints information about running threads.
2025-03-11 11:18:00,780 # version              Prints current RIOT_VERSION
2025-03-11 11:18:00,781 # bootloader           Reboot to bootloader
2025-03-11 11:18:00,781 # reboot               Reboot the node
>
$ UF2_SOFTDEV=DROP BOARD=feather-nrf52840 make -C tests/sys/shell flash
make: Verzeichnis „/home/chris/riot-ada-bl/RIOT/tests/sys/shell“ wird betreten
Building application "tests_shell" for "feather-nrf52840" with CPU "nrf52".

stty -F /dev/ttyACM0 raw ispeed 1200 ospeed 1200 cs8 -cstopb ignpar eol 255 eof 255
stty: /dev/ttyACM0: Eingabe-/Ausgabefehler
make: [/home/chris/riot-ada-bl/RIOT/tests/sys/shell/../../../Makefile.include:852: preflash] Fehler 1 (ignoriert)
sleep 3
"make" -C /home/chris/riot-ada-bl/RIOT/pkg/cmsis/ 
...
"make" -C /home/chris/riot-ada-bl/RIOT/sys/usb/usbus/cdc/acm
   text	   data	    bss	    dec	    hex	filename
  23688	    128	   4696	  28512	   6f60	/home/chris/riot-ada-bl/RIOT/tests/sys/shell/bin/feather-nrf52840/tests_shell.elf
/home/chris/riot-ada-bl/RIOT/dist/tools/uf2/uf2conv.py -f 0xADA52840 /home/chris/riot-ada-bl/RIOT/tests/sys/shell/bin/feather-nrf52840/tests_shell.hex --base 0x1000
Converted to uf2, output size: 48128, start address: 0x1000
Flashing /media/chris/NRF52BOOT (nRF52840-pca10056-v1)
Wrote 48128 bytes to /media/chris/NRF52BOOT/NEW.UF2

Also resetting to the Bootloader should still work when

  1. Programming the board with make flash
  2. Double Tapping the reset button
  3. Writing the bootloader command in the shell
$ BOARD=feather-nrf52840 make -C tests/sys/shell term
make: Verzeichnis „/home/chris/riot-ada-bl/RIOT/tests/sys/shell“ wird betreten
/home/chris/riot-ada-bl/RIOT/dist/tools/pyterm/pyterm -p "/dev/ttyACM0" -b "115200" -ln "/tmp/pyterm-chris" -rn "2025-03-11_11.22.50-tests_shell-feather-nrf52840"  
Twisted not available, please install it if you want to use pyterm's JSON capabilities
2025-03-11 11:22:50,305 # Connect to serial port /dev/ttyACM0
bWelcome to pyterm!
Type '/exit' to exit.
bootloader
2025-03-11 11:22:52,479 # bootloader
2025-03-11 11:22:52,479 # shell: command not found: ma()Th
> bootloader
2025-03-11 11:22:54,179 # bootloader
2025-03-11 11:22:54,179 # Serial port disconnected, waiting to get reconnected...

The first command is scrambled due to a known bug in stdio_cdc_acm.

Check that the documentation looks good.

Issues/PRs references

Has influence on #20980.
Can be a starting point for Closes #21205.
Applies the Markdown format to doc.txt as discussed in #21220.

@crasbe crasbe added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet labels Mar 8, 2025
@crasbe crasbe requested a review from jia200x as a code owner March 8, 2025 00:46
@github-actions github-actions bot added Area: doc Area: Documentation Area: boards Area: Board ports labels Mar 8, 2025
@crasbe crasbe added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 8, 2025
@riot-ci
Copy link

riot-ci commented Mar 8, 2025

Murdock results

✔️ PASSED

ebcb656 boards/common/ada-nrf52-bootl: refactor and enhance documentation

Success Failures Total Runtime
10269 0 10269 09m:36s

Artifacts

Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

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

Thanks, nice idea!

@crasbe
Copy link
Contributor Author

crasbe commented Mar 10, 2025

I changed the boards/common/adafruit-nrf52-bootloader/Makefile.include in a way to conditionally select the SoftDevice version. That way the board-dependant Makefile.include files don't have to define everything and can just define a different SoftDevice version if necessary (for example that will be necessary for the seeedstudio-xiao-nrf52840 because it uses SoftDevice 7 instead of SD6).

Also it is possible to drop the SoftDevice if you can't stand the idea of having a piece of closed source software in your Flash :)

Request for Comments: Should the board-dependant Makefile.include files still define the SoftDevice version, even if they use the standard?

@crasbe crasbe removed the State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet label Mar 11, 2025
@crasbe
Copy link
Contributor Author

crasbe commented Mar 11, 2025

I think this is ready for testing and reviewing now :)

To make it a bit less cluttered, I could squash it before review.
Squashed. I couldn't work with the amount of fixup!s anymore 😅

@crasbe crasbe changed the title boards/feather-nrf52840*: Move Flash Makefiles and Documentation to Common Folder boards/common: Make Adafruit nRF52 Bootloader shared Mar 11, 2025
@crasbe crasbe force-pushed the pr/ada_nrf52_bootloader branch 3 times, most recently from 42143eb to 452930d Compare March 12, 2025 14:51
Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

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

Also it is possible to drop the SoftDevice if you can't stand the idea of having a piece of closed source software in your Flash :)

Great, thanks for addressing this and making it configurable! I'm not fully decided on what the default should be though. Is it more friendly to leave the softdevice present and allow for the boards to be reused for other projects, or to not ship proprietary blobs (which are not used anyway though)? I guess both are fine with me.

Request for Comments: Should the board-dependant Makefile.include files still define the SoftDevice version, even if they use the standard?

If there is a standard as in something that is documented in the bootloader sources as such, I'd be fine to make it the default and not define it. If not, and if it rather depends on the board, I'd propose not having a default at all and erroring out if no SD version is defined by the board.

@crasbe
Copy link
Contributor Author

crasbe commented Mar 13, 2025

Also it is possible to drop the SoftDevice if you can't stand the idea of having a piece of closed source software in your Flash :)

Great, thanks for addressing this and making it configurable! I'm not fully decided on what the default should be though. Is it more friendly to leave the softdevice present and allow for the boards to be reused for other projects, or to not ship proprietary blobs (which are not used anyway though)? I guess both are fine with me.

Technically, we aren't shipping the blob, we're just not touching it.
The friendlier solution is certainly to keep it because it won't cause the board to be soft-locked to RIOT.

Request for Comments: Should the board-dependant Makefile.include files still define the SoftDevice version, even if they use the standard?

If there is a standard as in something that is documented in the bootloader sources as such, I'd be fine to make it the default and not define it. If not, and if it rather depends on the board, I'd propose not having a default at all and erroring out if no SD version is defined by the board.

I thought about it yesterday on my way home and even though Adafruit does not specifically set the SoftDevice version, I think they are rather fixed for a certain board. It is unlikely that there will be an update for the feather-nrf52840 for example that changes the SoftDevice version.
While having defaults won't break anything, IMO explicit is better than implicit and will make the life of someone porting a new board (similar to the feather-nrf52840), which might have a newer SD version, a lot easier.

Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

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

Thanks for restructuring the documentation, reads good now!

@crasbe crasbe force-pushed the pr/ada_nrf52_bootloader branch from afea23e to 4e8df40 Compare March 14, 2025 21:05
@crasbe
Copy link
Contributor Author

crasbe commented Mar 14, 2025

I took the liberty to squash everything together since the last review only addressed some details in the documentation.

Other than that IMO this is ready to be merged :)

mguetschow
mguetschow previously approved these changes Mar 17, 2025
Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

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

Successfully tested to work both with and without UF2_SOFTDEVICE=DROP on all three supported boards. Thanks for doing this!

@mguetschow mguetschow enabled auto-merge March 17, 2025 10:07
@mguetschow mguetschow added this pull request to the merge queue Mar 17, 2025
@mguetschow mguetschow removed this pull request from the merge queue due to a manual request Mar 17, 2025
@mguetschow
Copy link
Contributor

Oh, I actually just (by chance) found the following issue: When flashing a new application with the new default (expecting the SoftDevice) to a board that has previously been flashed with RIOT, it will seem to the user as if the flashing process failed as the old application is still present and started (instead of the SoftDevice).

This is pretty bad user experience, I'd say. Not sure how to prevent this... Maybe checking INFO_UF2.txt for an existing softdevice when selected, and at least warn or error in case it is not available? Maybe that could be done directly from the uf2conv.py by applying a patch?

I can also try to look into it one of these days if you don't want to invest more time here.

@mguetschow mguetschow dismissed their stale review March 17, 2025 10:15

We should try to improve the user experience for existing RIOT users first.

@crasbe
Copy link
Contributor Author

crasbe commented Mar 18, 2025

uf2conv has a command line option that is called --list. That returns all the mounted devices with UF2 bootloader.

RIOT/$ python3 ./dist/tools/uf2/uf2conv.py --list
/media/chris/NRF52BOOT nRF52840-pca10056-v1

With that it's pretty easy to check if the INFO_UF2.txt file has a SoftDevice. The best approach is probably to create a dedicated shell script which is executed before the programming script. I'll have to see where the best spot is for it in the make system.
If you have a good idea, I'm open for suggestions.

This is a script that ChatGPT suggested, it obviously has to be adapted still but it's a starting point.

#!/bin/bash

# Find device with UF2 bootloader
MOUNTPOINT=$(uf2conv.py --list | awk '{print $1}')

# Check if a device was found
if [ -z "$MOUNTPOINT" ]; then
    echo "No UF2 device found!"
    exit 1
fi

# Read file and check for "SoftDevice: not found"
if grep -q "SoftDevice: not found" "$MOUNTPOINT/INFO_UF2.txt"; then
    echo "SoftDevice not found!"
    exit 2
else
    echo "SoftDevice detected!"
fi

@mguetschow
Copy link
Contributor

The best approach is probably to create a dedicated shell script which is executed before the programming script.

Sounds reasonable to me.

I'll have to see where the best spot is for it in the make system.
If you have a good idea, I'm open for suggestions.

I'd probably try to call the script instead of python in makefiles/tools/uf2conv.inc.mk.

I've been trying to get the re-installation of the Adafruit Bootloader somehow integrated into our build system as a pkg in dist/tools, with automatic board name mapping. Not sure if that's worth it though or if erroring out is enough for the user.

@mguetschow
Copy link
Contributor

I've been trying to get the re-installation of the Adafruit Bootloader somehow integrated into our build system as a pkg in dist/tools, with automatic board name mapping. Not sure if that's worth it though or if erroring out is enough for the user.

Just for reference, here is the current WIP state: https://github.com/mguetschow/RIOT/tree/adafruit-bootloader-pkg

@github-actions github-actions bot added Area: build system Area: Build system Area: tools Area: Supplementary tools labels Mar 18, 2025
@crasbe
Copy link
Contributor Author

crasbe commented Mar 18, 2025

I've been trying to get the re-installation of the Adafruit Bootloader somehow integrated into our build system as a pkg in dist/tools, with automatic board name mapping. Not sure if that's worth it though or if erroring out is enough for the user.

For the time being, I just added an error message. Personally I'd prefer not to put the re-install of the Adafruit Bootloader into this PR as well, as it already has become quite extensive.

In the fixups, you can find a possible solution that involes a bash script that checks the INFO_UF2.txt. It could probably use some additional documentation, but this is something to work with.

@crasbe
Copy link
Contributor Author

crasbe commented Mar 18, 2025

Okay, I've extended the check script to check more variants that can happen and display according error messages:

This message will be shown when a version mismatch occurs (you can test that by trying to flash your Xiao as a Feather):
Version Mismatch

This message will be shown when no SoftDevice is found but there should be one. I added the URL to the documentation (the link won't work because this PR is not merged yet);
No SoftDev

This message will be shown when there is a SoftDevice about to be overridden with the UF2_SOFTDEV=DROP command. It will NOT be shown when there is no SoftDevice present anymore and the UF2_SOFTDEV=DROP command is issued.
DROP warning

Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

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

Just a nit, I really like this solution. Thanks!

Tested locally and confirmed to work, feel free to squash directly :)

@crasbe
Copy link
Contributor Author

crasbe commented Mar 21, 2025

@mguetschow Let me know when I should squash this.

Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

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

Please squash :)

@crasbe crasbe force-pushed the pr/ada_nrf52_bootloader branch from 10fcbe9 to ebcb656 Compare March 21, 2025 14:20
@mguetschow mguetschow added this pull request to the merge queue Mar 25, 2025
Merged via the queue into RIOT-OS:master with commit 75e22e5 Mar 25, 2025
25 checks passed
@crasbe
Copy link
Contributor Author

crasbe commented Mar 25, 2025

Thank you for working with me on this rather extensive PR :)

@crasbe crasbe deleted the pr/ada_nrf52_bootloader branch March 25, 2025 20:16
@mguetschow mguetschow added this to the Release 2025.04 milestone Apr 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: boards Area: Board ports Area: build system Area: Build system Area: doc Area: Documentation Area: tools Area: Supplementary tools CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dist/tools/uf2: Flashing a board with RIOT seems to prevent flashing other UF2 files afterwards
3 participants