20
lorentz
4y

Sony updates the firmware on their wireless headphones over Bluetooth. For TWO FUCKING HOURS. If, for some reason, the connection was to break during that period, - perhaps because Bluetooth isn't a reliable connection and was never meant to be - then the device will turn itself off (as it does when it loses connection), and it will try to boot into the half-installed firmware the next time you turn it on.

Comments
  • 6
    Samsung does it this way too for its buds. Though the update is like 1.2MB usually and finishes in seconds.

    Not saying it's better, but at least less chance of things going bad
  • 1
    @MrCSharp Yup, same for the Huawei ones
  • 12
    The RIGHT way to implement that:

    - put a CRC32 in the firmware image
    - download it to a secondary storage
    - when transfer is complete, check CRC
    - if CRC is OK, set "new firmware available" flag in EEPROM
    - reboot
    - copy image to actual firmware location using a fucking bootloader that will not be overwritten itself
    - check CRC of copied firmware
    - if CRC is OK, reset "new firmware available" flag, otherwise copy again
    - start application
  • 2
    @Fast-Nop I don't think they wasted money on excess storage. My guess is, they have two microcontrollers, one for everything and another that's only capable of maintaining a Bluetooth connection and loading the received bytes into the first one.
  • 3
    @Lor-inc Yeah that's the usual consumer grade garbage. The way that I outlined was how I did it in industrial devices 20 years ago for update over GSM.
  • 3
    @Lor-inc It would be sufficient if the bootloader keeps the device updateable even if flashing the new firmware is interrupted.

    That's how I designed my first (and up to now last) bootloader for a microcontroller. If the firmware is broken, the device stays in the bootloader and waits for an update.

    A lot of embedded CPUs even carry a small on-chip-bootloader that can be used to update the device if anything else goes wrong. Although this bootloader will usually not be accessible over the air and is usually only activated by dedicated inputs.
  • 2
    @ddephor Since I can only interact with the device through Bluetooth (USB is exclusively for charging), no update mechanism beside Bluetooth would help. The next significant question is whether they can recover the device in place at a store.

    Based on what the guy said over the phone, they don't do that and I have to travel 2 hours to a repair center outside the city, or wait 3-4 days for the post to either deliver or lose it.
  • 2
    @Fast-Nop Android supports a slightly improved version of your algo. Device boots from partition A, firmware update is installed to partition B. Then a boot flag is toggled to boot from B and install updates to A. No waiting for firmware to install, no waste of write cycles for the copy.
  • 0
    @gronostaj That is the safest and often fastest way of updating, but it needs twice the storage space. So for many small devices it is not feasible.
  • 1
    @ddephor Yeah, that's the price of reliability and low downtime. If you're going to temporarily store downloaded firmware and CRC it before applying, you need twice the space anyway and you risk a failure when applying it. If you want to update in-place, I think a bulletproof bootloader with FW update capabilities is the only option.
  • 0
    > remotely sensitive

    Hahaha!

    Also: you don't need secondary storage to implement a CRC in your firmware download. Heck, a ZIP archive has CRCs.
  • 0
    @gronostaj That works because Android is not being executed from the ROM, but loaded into the RAM and then executed anyway. With actual micocontrollers, stuff is being run from the ROM directly.

    Though there are some that can do address remapping so that this could actually work, but not all.

    @SomeNone And where will you store the ZIP? Oh, in a secondary storage anyway.
  • 1
    @Fast-Nop Android doesn't load entirely to RAM, many middle range devices wouldn't even fit entire OS in RAM. The A/B system uses two sets of partitions: one for currently running OS and one for updates. So you do need twice the space for updates like in your scheme, but instead of copying downloaded update from temporary storage to main FW storage, they're simply logically swapped.
  • 1
    @gronostaj Sure, things that are not needed aren't loaded, but the stuff that is executed is loaded. You can't execute directly from a NOR flash that is attached over SPI or so. So the only thing that you need to change is where to load from.

    With microcontrollers, you need all the jump label addresses right where the code is located in the ROM. It's directly in the linear address space and the same as RAM, only that you can't write to it without erasing a whole page and reprogramming it.

    If the controller does not have a remapping feature, then you can't do the A/B stuff because someone might skip an update.
  • 1
    @Fast-Nop I guess you'd need some kind of partitioning with partitions aligned to pages, so you could store a tiny bootloader which handles updates and A/B switching but doesn't get updated itself? But at this scale this A/B system would probably be a huge overkill anyway.
  • 1
    @gronostaj Yeah sure, the bootloader itself is never overwritten, see my initial posting. Otherwise, cutting power during an update could brick the device. You have a bootloader page, an application section, and a download/data section.

    Or you could modify the build chain so that two actual images are generated, one for each possible location, and then the update software can negotiate which one of them to actually download to the device.

    On the other hand, flashing like half a meg or so takes maybe 30 seconds, that's not much of an issue. Even the really large MCUs only have 1-2MB of flash-ROM.
  • 3
    @Fast-Nop In fact you only need to remap the interrupt vector table, not all adresses. The approach is having the main interrupt table point to a secondary table in RAM which can be replaced at runtime, then you only need some lines of startup code which copies the right interrupt table to RAM, which will be the one for the bootloader. The bootloader can then do whatever is needed and replace that table with the right one for the main software. And it can also be changed at runtime any time if needed. Although this approach only works for simple microcontrollers running from ROM. A full featured modern CPU is way more complicated to start up.
  • 2
    @ddephor That's one part, but absolute label addresses within the code need also to match because you can't do every jump PC relative. That's why you either need two different images, or be able to remap the whole flash.
  • 0
    @frogstair OTA firmware updates are reliable
  • 1
    I liked the way dialog semiconductor’s da14580 does it It’s almost same as what android does they have 32KB ROM but a 82 KB ram
    Usually for Bluetooth based OTA update it’s recommended to have two images and not mess with the original one
    Also for low power systems execution from external flash is not feasible, because systems go to sleep too often
  • 0
    @frogstair

    > remotely sensitive

    Huehuehue
Add Comment