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

tools/bootloader: add force-erase option and add bootloader version (Sponsored by CubePilot) #22777

Merged
merged 7 commits into from
May 22, 2024

Conversation

julianoes
Copy link
Contributor

@julianoes julianoes commented Feb 19, 2024

This PR does two things:

Add force-erase option

If the STM32H7 fails to program or erase a full chunk of 256 bytes, the ECC check will trigger a busfault when trying to read from it.

To speed up erasing and optimize wear, we read before erasing to check if it actually needs erasing. That's when a busfault happens and the erase time outs.

The workaround is to add an option to do a full erase without check.

Credit goes to:
ArduPilot/ardupilot#22090

And the protocol option added to the bootloader is the same as for ArduPilot, so compatible.

Add bootloader version

This PR also adds a new bootloader version essentially a string that we can set in the format of: PX4BLv1.15.0g12345678 constrained to max 32 chars. This allows to check if a bootloader needs updating while not breaking any tooling by bumping the bootloader protocol revision which has been stabilized at 5 for a long time by now.

The output of the px_uploader.py now looks as follows:

uploading px4
Waiting for bootloader...

Found board id: 140,0 bootloader protocol revision 5 on /dev/serial/by-id/usb-CubePilot_PX4_BL_CubePilot_CubeOrange_0-if00
Loaded firmware for board id: 140,0 size: 1902144 bytes (96.75%) 

Bootloader version: PX4BLv1.15.0g3bbeb0d87d
Sn: 003100433230510b39343831
Chip: 20036450
Family: STM32H7[4|5]x
Revision: V
Flash: 1966080 bytes
Windowed mode: False

Erase  : [====================] 100.0%
Program: [======              ] 33.9%

Copy link
Member

@davids5 davids5 left a comment

Choose a reason for hiding this comment

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

@julianoes Nice! The wording on the option felt wrong to me. See if what I added works for you.

Tools/px_uploader.py Outdated Show resolved Hide resolved
@julianoes
Copy link
Contributor Author

Fixed, thanks @davids5!

Copy link
Member

@davids5 davids5 left a comment

Choose a reason for hiding this comment

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

Thinking about this a bit more....Since this is s protocol change should we bump the rev and add it to https://github.com/PX4/PX4-Bootloader?

@julianoes
Copy link
Contributor Author

@davids5 we should but we haven't in the past, and it looks like ArduPilot has many more features and is also still on the same revision.

@julianoes
Copy link
Contributor Author

@davids5 it doesn't need to go into the Bootloader repo, because it only applies for H7, I think.

@julianoes
Copy link
Contributor Author

julianoes commented Feb 27, 2024

@davids5 I had messed up. Here is a fixup commit: ac5b06f It would be great if you could double check that line again. Thanks!

Needs rebasing/squashing before merging.

Copy link
Member

@davids5 davids5 left a comment

Choose a reason for hiding this comment

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

See inlines

@julianoes
Copy link
Contributor Author

Pushed another fixup @davids5.

Copy link
Member

@davids5 davids5 left a comment

Choose a reason for hiding this comment

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

I think it would be good to use
up_progmem_ispageerased as the name, see comment

platforms/nuttx/src/bootloader/nxp/imxrt_common/main.c Outdated Show resolved Hide resolved
@julianoes
Copy link
Contributor Author

@davids5 ok, I've accepted your suggestions. I'll run CI, then rebase, squash and force push.

Copy link
Member

@davids5 davids5 left a comment

Choose a reason for hiding this comment

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

On the issue of the revision - The uploader side can blindly send the command and it can fail silently.

As far as putting this in the the bootloader repo: It would be a nice to have but will not fit on all the SoC.

Copy link
Member

@davids5 davids5 left a comment

Choose a reason for hiding this comment

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

The rest all looks good. This is just a nit. I will leave it up to you, if you want to push again :)

platforms/nuttx/src/bootloader/common/bl.c Show resolved Hide resolved
@julianoes
Copy link
Contributor Author

@davids5 on second thought, I think you're right that it would be worthwhile to bump the version number.

@julianoes julianoes changed the title tools/bootloader: add force-erase option [DON'T MERGE yet] tools/bootloader: add force-erase option Feb 29, 2024
davids5
davids5 previously approved these changes Mar 4, 2024
Copy link
Member

@davids5 davids5 left a comment

Choose a reason for hiding this comment

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

Ok Looks good!

@julianoes
Copy link
Contributor Author

Thanks @davids5. I'll properly squash the commits and then merge it.

@julianoes julianoes changed the title [DON'T MERGE yet] tools/bootloader: add force-erase option tools/bootloader: add force-erase option Mar 4, 2024
@julianoes
Copy link
Contributor Author

@dagar what's an easy way to update all bootloader images? Do I have to do it one by one?

@davids5
Copy link
Member

davids5 commented Mar 14, 2024

@julianoes There is a target iirc. something like update_bootloaders

@julianoes
Copy link
Contributor Author

@davids5 thanks, I'll try that. However, I wonder whether we should really bump the protocol version. The problem is that QGC refused to flash bootloader rev 6, and so does the uploader script, and that's even though they would just work fine. Instead of a "major" change it's more like a hidden extra feature. On the other hand, it's hard to know whether a flashed bootloader supports the force-erase option. You basically don't know until you try.

@davids5
Copy link
Member

davids5 commented Mar 18, 2024

@davids5 thanks, I'll try that. However, I wonder whether we should really bump the protocol version. The problem is that QGC refused to flash bootloader rev 6, and so does the uploader script, and that's even though they would just work fine. Instead of a "major" change it's more like a hidden extra feature. On the other hand, it's hard to know whether a flashed bootloader supports the force-erase option. You basically don't know until you try.

So it would force an update for QGC and the uploader on the users. How bad is that?

@julianoes
Copy link
Contributor Author

How bad is that?

Not the end of the world but still unexpected.

@julianoes julianoes changed the title tools/bootloader: add force-erase option [Sponsored by CubePilot] tools/bootloader: add force-erase option and add bootloader version May 10, 2024
@julianoes
Copy link
Contributor Author

julianoes commented May 10, 2024

@davids5 this has evolved a bit. @bugobliterator and I came up with a bootloader version additional to the bootloader protocol revision. For more info, see the PR description and the individual commits. I also took the liberty to clean up the Python script a bit.

I'd appreciate your review @davids5.

FYI @dagar

TODO: re-generate all bootloaders from here.

@davids5
Copy link
Member

davids5 commented May 10, 2024

@davids5 this has evolved a bit. @bugobliterator and I came up with a bootloader version additional to the bootloader protocol revision. For more info, see the PR description and the individual commits. I also took the liberty to clean up the Python script a bit.

I'd appreciate your review @davids5.

FYI @dagar

TODO: re-generate all bootloaders from here.

@julianoes - can we have a call on this? I am in US EST so maybe 4 AM my time next week or 03:00 PM EST. Let me know

@julianoes
Copy link
Contributor Author

@davids5 I have the feeling the GET_SUPPORTED_COMMANDS API that you suggested is - unfortunately - not really worth the trouble.

It seems worthwhile because it would solve the problem where we don't know if force-erase is supported or not, basically if GET_SUPPORTED_COMMANDS is not supported, force-erase won't be either. However, this doesn't hold for the ArduPilot bootloader, so we're sort of back at square one.

I agree that it would only be worthwhile for the next bootloader addition down the road, but it doesn't seem quite worth it, because you can easily just "try" every command, except erase which take a long time to time out.

@davids5 davids5 self-requested a review May 17, 2024 05:21
Copy link
Member

@davids5 davids5 left a comment

Choose a reason for hiding this comment

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

See inline.

return

raise RuntimeError("timed out waiting for erase")
if self.force_erase:
raise RuntimeError("timed out waiting for erase, force erase is likely not supported by bootloader!")
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't the the force erase bet met with an immediate command error? In that case should you attempt to use an erase or suggest a bootloader upgrade?

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, that would be nice. But a unknown byte seems to just be ignored. And the erase command is not acked until it is erased, so you have to wait a long time. Not optimal I know...

Copy link
Member

Choose a reason for hiding this comment

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

geez That seems wrong, bit it is what the code does.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep.

@davids5 davids5 self-requested a review May 21, 2024 13:59
davids5
davids5 previously approved these changes May 21, 2024
@julianoes julianoes changed the title [Sponsored by CubePilot] tools/bootloader: add force-erase option and add bootloader version tools/bootloader: add force-erase option and add bootloader version (Sponsored by CubePilot) May 22, 2024
If the STM32H7 fails to program or erase a full chunk of 256 bytes, the
ECC check will trigger a busfault when trying to read from it.

To speed up erasing and optimize wear, we read before erasing to check
if it actually needs erasing. That's when a busfault happens and the
erase time outs.

The workaround is to add an option to do a full erase without check.

Credit goes to:
ArduPilot/ardupilot#22090

And the protocol option added to the bootloader is the same as for
ArduPilot, so compatible.

Signed-off-by: Julian Oes <julian@oes.ch>
This adds a new protocol extension which allows to get the bootloader
version.

The bootloader version is different from the bootloader protocol
revision which has stabilized at 5 and is not easy to update unless a
bootloader is actually breaking the protocol. The reason being that both
the Python script as well as the uploader used in QGC will not attempt
to load firmware if they don't know the bootloader version, so it could
basically be considered a "breaking" protocol revision.

Signed-off-by: Julian Oes <julian@oes.ch>
Includes:
- Remove some of the outdated Python2 checks and compatibility.
- Try not catch all exceptions but only the expected ones. Otherwise,
  this makes it really hard to debug if anything unexpected actually
  goes wrong.
- Make use of fstrings.
- Make output slightly prettier.

Signed-off-by: Julian Oes <julian@oes.ch>
Just so we don't conflict on these commands in the future.
Signed-off-by: Julian Oes <julian@oes.ch>
@julianoes
Copy link
Contributor Author

Final rebase, bootloader rebuild and push. As soon as CI is happy I'll merge.

@julianoes
Copy link
Contributor Author

CI results are the same as main. Merging.

@julianoes julianoes merged commit a9962dc into main May 22, 2024
87 of 93 checks passed
@julianoes julianoes deleted the pr-bootloader-full-erase branch May 22, 2024 06:18
@PetervdPerk-NXP
Copy link
Member

PetervdPerk-NXP commented May 23, 2024

px4_fmu-v6xrt: Build regression on main since this PR.

/home/peter/src/Firmware/platforms/nuttx/src/bootloader/nxp/imxrt_common/main.c:399:1: error: return type defaults to 'int' [-Werror=implicit-int]
  399 | up_progmem_ispageerased(unsigned sector)
      | ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.
cc1: all warnings being treated as errors

Commit 4a13e49 was succesful on px4_fmu-v6xrt before this PR.

@davids5
Copy link
Member

davids5 commented May 23, 2024

px4_fmu-v6xrt: Build regression on main since this PR.

/home/peter/src/Firmware/platforms/nuttx/src/bootloader/nxp/imxrt_common/main.c:399:1: error: return type defaults to 'int' [-Werror=implicit-int]
  399 | up_progmem_ispageerased(unsigned sector)
      | ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.
cc1: all warnings being treated as errors

Commit 4a13e49 was succesful on px4_fmu-v6xrt before this PR.

Fixed in #23174

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants