Skip to content

Jump sys bl #1

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

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

Jump sys bl #1

wants to merge 15 commits into from

Conversation

Riffer
Copy link
Owner

@Riffer Riffer commented May 25, 2021

Pull Request template

Please, Make sure that your PR is not a duplicate.
Search among the Pull request before creating one.

IMPORTANT: Please review the CONTRIBUTING.md file for detailed contributing guidelines.

Thanks for submitting a pull request.
Please provide enough information so that others can review your pull request:

Summary

This PR fixes/implements the following bugs/features

  • Bug 1
  • Bug 2
  • Feature 1
  • Feature 2
  • Breaking changes

Explain the motivation for making this change. What existing problem does the pull request solve?

Validation

  • Ensure CI build is passed.
  • Demonstrate the code is solid. [e.g. Provide a sketch]

Code formatting

  • Ensure AStyle check is passed thanks CI

Closing issues

Fixes #xxx

fpistm and others added 15 commits September 18, 2020 17:54
Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Fixes stm32duino#706

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
The upload.use_1200bps_touch key tells the IDE to open the user-selected
serial port at 1200 baud, and then close it, before attempting an upload.
This allow to jump in BL mode.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
Instead, use a .noinit variable, which survives across reboots.

Note: This file uses the bool type, so needs to include stdbool.h.
It seems that for the F4, this was indirectly included elsewhere,
but for e.g. F0, this did not seem to be the case, causing the build
to fail.
This now runs in early startup, so the normal delay will not work
(systick is not running yet).

Note: Seems that on F0, inline assembler is compiled using the classic
rather than unified syntax (which *is* used on F4 it seems). This
explicitly selects the unified syntax in the inline assembly block, to
fix building for F0.

TODO: There is a variant which also overrides the enumeration.
Since the bootloader does not touch these flags, but can start the
sketch if instructed by the programmer (without a reset), clearing is
needed to prevent a start from the bootloader looking like a
software-reset. Otherwise, the startup code would be looking at the
BootIntoBootloaderAfterReset variable to decide whether to jump to the
bootloader. This variable should have been cleared before jumping to the
bootloader the last time, but the bootloader might have overwritten it
(or a sketch was uploaded with a different address for that variable).

Additionally, clearing the reset flags allows a sketch to see that the
they are started through the bootloader, when all reset flags are
cleared.
On most CPUs, detecting the system flash address is not needed, since
they can remap the system flash onto adress 0x0 and the bootloader reset
vector can be read from there. This approach also more closely mimics a
bootloader start using the BOOTx pins.

For CPUs that cannot remap flash, this hardcodes the address of system
flash and jumps there instead. For H7 and F7, this is also how it works
when using the BOOT pins. For F1, remapping can be done using the BOOT
pins, but not from software, resulting in a difference with a
BOOT-activated bootloader.

This puts the code that figures out where the bootloader lives back in a
separate function. This makes the code easier to read, and makes it
easier to jump to custom bootloaders (e.g. in normal flash instead of in
system flash).

TODO: Check value for H7, AN2606 and reference manual disagree
This waits for 250ms, just like the Arduino SAM and SAMD cores do (AVR
waits only 120ms), to allow the USB host and application a bit more time
to close the port and clean up.
This function calls HAL_Delay, which relies on the systick timer to be
running, so this results in an infinite loop. This should probably be
fixed in HAL_Delay, but for now just remove the calls to
USB_DevDisconnect and USB_DevConnect and replace it with the bit
twiddles needed for some chip families (e.g. the F4), breaking
compilation and/or functionality for others.
This adds support for the DFU runtime protocol, which allows resetting
into the bootloader using a DFU command. This allows e.g. dfu-util to
handle the complete firmware upload, including the needed reset.

This consists of a number of changes:
 - An extra interface is added to the USB configuration descriptor. This
   descriptor has two parts (interface descriptor and functional
   descriptor) which together indicate to a host that this device
   supports DFU.
 - Control packets to this new interface are detected by the CDC code an
   forwarded to a new USBD_DFU_Runtime_Control() function.
 - This new function handles the DFU GET_STATE, GET_STATUS and
   DFU_DETACH commands. The former are optional, but simple enough, the
   latter is mandatory and handles resetting into the bootloader.
 - The CDC device descriptor is changed to become a composite device
   (CDC and DFU). This allows operating systems (in particular Windows,
   Linux did not really need this) to identify two different subdevices,
   and install different drivers for each (on Windows, this is serusb
   for the CDC part and WinUSB/libusb for the DFU part). Without this,
   dfu-util on Windows could not access the DFU commands when the serial
   driver was loaded.

   Because the CDC functionality already exposes two interfaces (which
   together form a single serial port), an IAD (Interface Association
   Descriptor) is inserted before these interfaces to group them
   together in a single subdevice. No IAD is needed for the DFU
   interface, since it is just a single interface.

   To become a composite device, the device class must be changed from
   CDC to a composite device class. This was originally class 0/0/0, but
   together with the IAD, a new EF/2/1 deviceclass was also introduced,
   which is used now.

Note that this only adds descriptors and a command handler on the
default control endpoint, so no extra (scarce) endpoints are used by
this, just a bit of memory.

This commit is still a bit rough, because:
 - The DFU descriptors and code are now pulled in directly by the CDC
   code (and HID is not supported yet). Ideally, there should be some
   kind of pluggable USB library where different interfaces can be
   registered independent of each other (see also
   stm32duino#687).
 - The interface number is hardcoded in the DFU descriptor.
 - The reset to bootloader happens immediately, while it might be better
   to wait a short while to allow the current USB transaction to
   complete.
 - DFU support is unconditionally advertised, while not all boards might
   support DFU.
Bootloader management is not applicable for this serie.

Signed-off-by: Frederic Pillon <frederic.pillon@st.com>
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.

3 participants