Skip to content

riotboot: Mode selection for boards#16011

Merged
dylad merged 1 commit intoRIOT-OS:masterfrom
chrysn-pull-requests:riotboot-modeselect
Mar 20, 2021
Merged

riotboot: Mode selection for boards#16011
dylad merged 1 commit intoRIOT-OS:masterfrom
chrysn-pull-requests:riotboot-modeselect

Conversation

@chrysn
Copy link
Copy Markdown
Member

@chrysn chrysn commented Feb 15, 2021

Contribution description

For USB bootloaders, it is common to have a way of entering the bootloader even when the application is not cooperating. A typical way is to poll a button on startup. (For example, the bootloaders shipped with nrf52840dongle and the particle xenon boards to that; the latter in a more elaborate fashion that includes blink patterns).

It doesn't help with remote bricking, and it doesn't help against flash writes to the bootloader (both of which might be mitigated by additional means), but solves the common case of "I forgot to give my application the right USEMODULES to get back into DFU" or "crash at board_init".

Testing procedure

  • Flash the bootloader using make -C bootloaders/riotboot_dfu BOARD=particle-xenon PROGRAMMER=openocd DEBUG_ADAPTER=stlink all flash
  • Dismantle your programmer. (Well, at least assume that from now on you won't want to use it any more).
  • Notice how it comes up in the bootloader by running dfu-util -l and seeing "Found DFU" (unless, of course, there happens to be a valid image in there; an openocd flash erase_sector 0 0 last before the original programming ensures a cleans state)
  • Add FEATURES_REQUIRED += riotboot to examples/filesystem/Makefile
  • make -C examples/usbus_minimal BOARD=particle-xenon APP_VER=$(date +%s) PROGRAMMER=dfu-util all riotboot/flash-slot0`
  • Notice how we forgot to add USEMODULE += usbus_dfu, and the board doesn't even come up. (That's probably a different bug, at least an ACM TTY should come up). Add the USEMODULE to filesystem example.
  • To get the device usable without connecting a programmer, just keep the user button pressed while briefly pressing the reset button.
  • On dfu-util -l the device now shows "Found DFU", indicating it's in bootloader mode.
  • Run the riotboot/flash-slot0 target again.
  • There should now be a ttyACM0, and dfu-util would report having found a Runtime.

Open questions

  • The board's ability to pick an alternate mode is modeled as a FEATURE, which is optionally used by the bootloader. Is that the right choice?
  • I'm extracting whether or not the feature is used into a CFLAGS+=-D.... That looks uncommon, but creating a complete pseudomodule for it sounds extraneous. What's the best way?
  • The way the definition is then used in the code is crude; I hope to get some guidance out of board_init: Inconsistent declaration #16007 on whether there should be an extra header file or whether it's really just extern bool ... everywhere it's used.
  • Do we want to allow boards to do more fancy indicating? (Might be in one go -- a feature that, if set, provides this function and a "switch on whichever LED indicates bootloader mode here").
  • For the DFU bootloader, there's a pretty obvious thing to do with the information. Can other variants (riotboot without DFU) make any use of it? That bootloader isn't much use if it doesn't find an image, but it might be asked to load the other image if still good (yay downgrade attacks -- but is local downgrading allowed?).

@chrysn chrysn added the Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation label Feb 15, 2021
@benpicco benpicco requested a review from dylad February 15, 2021 12:44
@chrysn
Copy link
Copy Markdown
Member Author

chrysn commented Feb 15, 2021 via email

Comment on lines +49 to +51
ifneq (,$(filter bootloader_alternative_mode,$(FEATURES_USED)))
CFLAGS += -DALTERNATIVE_MODE
endif
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would add a PSEUDOMODULE instead (answering your question)

Comment on lines +93 to +99
bool board_bootloader_alternative_mode(void)
{
/* If the application button is pressed, this indicates that the bootloader
* should switch to its alternative mode (eg. DFU recovery). */
gpio_init(BTN0_PIN, BTN0_MODE);
return !gpio_read(BTN0_PIN);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The button should probably be configurable no? I imagine many will implement this, and it will pretty much be the same only maybe with different pin numbers.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If we're going with the Ben's suggestion, the board.h of providing boards would

#eefine BTN_BOOTLOADER_PIN BTN0_PIN

etc -- but per board it can IMO be fixed (especially on boards that have only one button)

@chrysn
Copy link
Copy Markdown
Member Author

chrysn commented Feb 15, 2021

Based on benpicco's original comment and dylad's note on IRC I think this can be vastly simplified, to the point where any board's BTN0 makes the bootloader divert when pressed, and the boards can override that.

So no features, no pseudomodules, no dependencies, just a small preprocessor default and an optional GPIO step.

@chrysn
Copy link
Copy Markdown
Member Author

chrysn commented Feb 15, 2021

Thanks for all your input, this is all much simpler now. (If and when boards need an actual function to be evaluated, that can still be added at that point, but maybe it never will.)

My remaining qualm is that the documentation, even though written, is not visible, for bootloaders are not part of what's built into the documentation. (Which also means that riotboot/README.md is not rendered). It's all prepared though, so whenever we do something there it should show up in the docs.

@chrysn
Copy link
Copy Markdown
Member Author

chrysn commented Feb 15, 2021

Sorry for the many fixups; I think by all I've fumbled around here it should be much more readable if I squash.

@chrysn chrysn force-pushed the riotboot-modeselect branch from fdeea7b to 5f18e29 Compare February 15, 2021 15:18
@chrysn chrysn added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 15, 2021
@fjmolinas fjmolinas removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 16, 2021
@chrysn
Copy link
Copy Markdown
Member Author

chrysn commented Feb 23, 2021

Does this mean it's good for squashing final review?

@dylad
Copy link
Copy Markdown
Member

dylad commented Feb 25, 2021

Does this mean it's good for squashing final review?

This is fine by me.

@chrysn chrysn force-pushed the riotboot-modeselect branch from 51d8ce5 to 2669f05 Compare February 26, 2021 09:55
@chrysn chrysn added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 26, 2021
@chrysn chrysn requested a review from dylad February 26, 2021 12:08
@dylad
Copy link
Copy Markdown
Member

dylad commented Feb 27, 2021

Looks good to me. I succesfully tested this PR on SAML21-XPRO, press & hold BTN0, then reset and the board stays in bootloader mode as expected.
@fjmolinas any last word ?

Copy link
Copy Markdown
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

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

last comments, you can squash directly.

Boards can override this; by default it's BTN0
@chrysn chrysn force-pushed the riotboot-modeselect branch from 2669f05 to d770917 Compare March 18, 2021 18:32
@chrysn
Copy link
Copy Markdown
Member Author

chrysn commented Mar 18, 2021

Last changes addressed, thanks for pointing them out. CI seems to be happy -- are you too?

Copy link
Copy Markdown
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

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

ACK.
Looks good to me.
I tested this PR on SAML21-XPRO and it works as expected.

@dylad
Copy link
Copy Markdown
Member

dylad commented Mar 20, 2021

Here we go

@dylad dylad merged commit 160251b into RIOT-OS:master Mar 20, 2021
@chrysn chrysn deleted the riotboot-modeselect branch March 20, 2021 22:12
@kaspar030 kaspar030 added this to the Release 2021.04 milestone Apr 23, 2021
@chrysn chrysn added the Release notes: added Set on PRs that have been processed into the release notes for the current release. label Apr 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Release notes: added Set on PRs that have been processed into the release notes for the current release. 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.

6 participants