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

Feature/electron/factory reset #975

Merged
merged 4 commits into from
Jun 10, 2016
Merged

Conversation

m-mcgowan
Copy link
Contributor

@m-mcgowan m-mcgowan commented Apr 21, 2016

Fixes the bootloader not recognising when a valid bootloader image is present.

During startup, FLASH_AddToFactoryResetModuleSlot is called by the system firmware to set the location of the factory reset image (since this changes between mono and modular firmware.) On the electron, this persists the factory firmware location to DCD.

The DCD implementation is a C++ object, and needs to be constructed b…
…efore it can be used (or the length field is 0, despite being a constant.) It's called from HAL_Core_Config to set up the location of the factory firmware, which is the key part factory reset to be available in the bootloader. However, since the DCD wasn't initialized any attempts to write to the DCD before it was constructed would fail - the write offset was checked against the length (which is 0.)

The fix is to create a static function instance so that it's constructed on first use, independent from global object construction.


Doneness:

  • Contributor has signed CLA
  • Problem and Solution clearly stated
  • Code peer reviewed
  • API tests compiled
  • Run unit/integration/application tests on device
  • Add documentation
  • Add to CHANGELOG.md after merging (add links to docs and issues)

@technobly
Copy link
Member

technobly commented Jun 8, 2016

TL,DR;

  • Branch feature/electron/factory_reset needs to be rebased against develop and force pushed.
  • OTA and FLASH memory addresses are inverted on the Electron, relative to when USER memory is used as a base address (vs Photon and P1). This is causing this PR to restore the OTA image instead of the FACTORY image. Needs to be resolved.

  • I started reviewing and testing this with 0.5.1 installed on my electron (this version shouldn't matter).
  • I flashed a 0.4.8-rc.6 fast blinky D7 app to the factory location particle flash --factory fast.bin
  • I flashed a 0.5.0 slow blinky D7 app to the user location via Build IDE (to ensure it was in OTA memory as well).
  • The particle serial inspect command would not yet show that I had a factory reset image as expected, and the factory reset sequence with MODE and RESET buttons will not show GREEN or WHITE flashing.
Platform: 10 - Electron
Modules
  Bootloader module #0 - version 7, main location, 16384 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #1 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #2 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #1 - version 15
  User module #1 - version 4, main location, 131072 bytes max size
    UUID: DE42EF4D960B553A4E2063AF1FD328C9B72CF78997330A3C07E7847219850ACF
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 13
  empty - factory location, 131072 bytes max size

Note: This PR is based on 0.5.0-rc.1 system firmware, and should be rebased. I rebased it locally to 0.5.1 for testing purposes. Keep that in mind for next results.

  • After flashing this PR's system firmware to my electron, entering Listening Mode via baud 14400, and running the particle system inspect command now shows the factory image, and notice it's version 10 (0.4.8-rc.6).
Platform: 10 - Electron
Modules
  Bootloader module #0 - version 7, main location, 16384 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #1 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #2 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #1 - version 15
  User module #1 - version 4, main location, 131072 bytes max size
    UUID: DE42EF4D960B553A4E2063AF1FD328C9B72CF78997330A3C07E7847219850ACF
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 13
  User module #1 - version 3, factory location, 131072 bytes max size
    UUID: 00910A460B462046FFF7B1FC0549054A204602B0BDE8104000F04DB800BF1406
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 10
  • I exited Listening Mode by holding MODE button for 5 seconds and letting go, and after verifying that the system runs again... I tried to factory reset using the MODE and RESET buttons. This time I saw GREEN then WHITE flashing.. after the system reset it booted up and was still running a slow blinky D7 app, not the desired fast blinky D7 app that I put in the factory reset location.
  • After entering Listening Mode again, and running particle serial inspect, it appears the application is not the version 10 one that is in the factory location, but the same one as before that was in user area. My guess is it's copying from the OTA section of memory instead of factory.
Platform: 10 - Electron
Modules
  Bootloader module #0 - version 7, main location, 16384 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #1 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #2 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #1 - version 15
  User module #1 - version 4, main location, 131072 bytes max size
    UUID: DE42EF4D960B553A4E2063AF1FD328C9B72CF78997330A3C07E7847219850ACF
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 13
  User module #1 - version 3, factory location, 131072 bytes max size
    UUID: 00910A460B462046FFF7B1FC0549054A204602B0BDE8104000F04DB800BF1406
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 10
  • To confirm this theory, I've flashed tinker to user memory via DFU particle flash --usb tinker
  • It seems to show correctly as version 10 (0.4.8-rc.6 tinker)
Platform: 10 - Electron
Modules
  Bootloader module #0 - version 7, main location, 16384 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #1 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #2 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #1 - version 15
  User module #1 - version 3, main location, 131072 bytes max size
    UUID: 6B38BF10BE92BA40717E91F2F0B68BA1310A96CA8E61F89F68753B4D06BA84F8
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 10
  User module #1 - version 3, factory location, 131072 bytes max size
    UUID: 35FA204610BD10B50446002060604FF47A70A060054821742060084611461A46
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 10
  • performing another factory reset, it resets and is slow blinky D7 again with the same UUID as before. It's definitely copying from OTA instead of FACTORY location.
Platform: 10 - Electron
Modules
  Bootloader module #0 - version 7, main location, 16384 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #1 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
  System module #2 - version 15, main location, 131072 bytes max size
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #1 - version 15
  User module #1 - version 4, main location, 131072 bytes max size
    UUID: DE42EF4D960B553A4E2063AF1FD328C9B72CF78997330A3C07E7847219850ACF
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 13
  User module #1 - version 3, factory location, 131072 bytes max size
    UUID: 00910A460B462046FFF7B1FC0549054A204602B0BDE8104000F04DB800BF1406
    Integrity: PASS
    Address Range: PASS
    Platform: PASS
    Dependencies: PASS
      System module #2 - version 10

After digging... it appears that in STM32F2xx/SPARK_Firmware_Diver/inc/flash_mal.h these are correct for the Photon/P1, but are inverted for Electron.

#define INTERNAL_FLASH_OTA_ADDRESS (USER_FIRMWARE_IMAGE_LOCATION+FIRMWARE_IMAGE_SIZE)
#define INTERNAL_FLASH_FAC_ADDRESS (USER_FIRMWARE_IMAGE_LOCATION+FIRMWARE_IMAGE_SIZE+FIRMWARE_IMAGE_SIZE)

Electron's Memory Map is defined as:

  • USER = 0x08080000
  • FACTORY / EXTENDED USER = 0x080A0000
  • OTA = 0x080C0000

Likely done this way for future expansion of USER to 256KB (while foregoing FACTORY functionality).

It doesn't appear that OTA updates are overwriting the FACTORY binary, and likely because the OTA address is defined separately again in: hal/src/electron/ota_flash_hal.cpp

m-mcgowan and others added 4 commits June 9, 2016 14:39
…he correct address.) This allows potentially a 256k user firmware image to be used instead of a factory reset image. (And a 256k OTA image starting at 0x80C0000).
…efore it can be used (or the length field is 0, despite being a constant.) It's called from HAL_Core_Config to set up the location of the factory firmware, which is the key trigger for a factory reset in the bootloader. However, since the DCD wasn't initialized any attempts to write to the DCD before it was constructed would fail - the write offset was checked against the length (which is 0.)

The fix is to create a static function instance so that it's constructed on first use, independent from global object construction.
@technobly technobly force-pushed the feature/electron/factory_reset branch from bf3d52d to 2d8f3d6 Compare June 9, 2016 19:45
@technobly
Copy link
Member

  • rebased to develop and force pushed
  • added an address flip for OTA vs FACTORY on Electron.
  • tested and working on Electron and Photon.

@technobly technobly merged commit 771a916 into develop Jun 10, 2016
@technobly technobly removed their assignment Jun 10, 2016
@m-mcgowan m-mcgowan deleted the feature/electron/factory_reset branch September 27, 2016 16:44
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