Enable OTA DFU mode

Posted on
  • Hi,

    I just wanted to know if there is a possibility to that I can enable OTA DFU using just a Javascript?

    My scenario is that o do not have GPIO reach to enable DFU via hardware. So looking a softwares way to upgrade firmware using BLE.

    I am using nrf51822 based fitness tracker, which has very old SDK 9/10 maybe with softdevice S110. I am planning to upgrade softdevice, bootloader to S130, as Esprunio supports S130 onwards.

    Abhinav

  • Well, you have at least button there which is one GPIO for this. Anyway, yes it is possible, it depends on bootloader code, espruino bootloader by default requires holding some button but you can disable it in your own bootloader build. Typically this is done by setting some value in GPREGRET nrf register (which survives reset) and then performing soft reset. Then in bootloader you check this value and decide.

    Requiring some interaction is there for safety so nobody can reflash your device remotely without confirmation. So if you disable this just beware and protect espruino console so it is not accessible to everyone.

    The current way to switch to bootloader is a bit tricky with timing and there is no explicit method to switch to bootloader. I think better would be to allow switching to bootloader programatically but then there could be button confirmation before accepting the firmware (e.g. if you do not hold button while sending dfu zip it would fail). Safety would be same but you could invoke update procedure in deterministic way without user needing to hold button with precise timing while calling E.reboot()

  • I should also add that since you're using a nrf51822 there's really very little room available to fit in a bootloader and espruino - the micro:bit build overwrites the bootloader completely AFAIK to get a bit more space.

  • Any update about being able to invoke dfu from app/ide? This could be useful when we have no physical access to the button

  • Nothing added yet - I have avoided doing this precisely because you could do firmware updates with no physical access. It seems like a bit of a worry.

    The bootloader would be pretty easy to modify though. For instance we check the 'reset reason' at https://github.com/espruino/Espruino/blo­b/master/targets/nrf5x_dfu/main.c#L283

    It's easy enough to check if the reset reason is SW_RESET and then enter bootloader. But to avoid accidental entry you could also set the GPREGRET register in Espruino, and then check it in the bootloader before entering automatically?

  • I'm using precisely this as it is what most smart watches do to enter bootloder, so something like this could work

    +++ b/targets/nrf5x_dfu/main.c
    @@ -100,13 +100,39 @@ bool dfu_enter_check(void) {
     [#else](https://forum.espruino.com/searc­h/?q=%23else)
       dfu_start = dfuIsColdBoot; // if no button, enter bootloader if it's a cold boot, then exit after a few seconds
     [#endif](https://forum.espruino.com/sear­ch/?q=%23endif)
    +  if (NRF_POWER->GPREGRET == 1) { NRF_POWER->GPREGRET=0; return true; }
    [#ifdef](https://forum.espruino.com/sear­ch/?q=%23ifdef) BUTTONPRESS_TO_REBOOT_BOOTLOADER^M
         // if DFU looks invalid, go straight to bootloader
         if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_INVALID) {
           lcd_println("BANK0 INVALID");
    

    so just one line to put here https://github.com/espruino/Espruino/blo­b/master/targets/nrf5x_dfu/main.c#L103

    and then just poke32(0x4000051c,1) triggers DFU. However as Gordon mentions it is a bit dangerous, anyone can trigger DFU update remotely if you don't set up console password or other protection (like whitelisting/refusing unknown connections)

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Enable OTA DFU mode

Posted by Avatar for Abhigkar @Abhigkar

Actions