The untold truth about the OpenSDA messup

Introduction

Recently I came in need for a CMSIS-DAP compliant programmerdebugger to revive a locked-up ATSAMD20 MCU. While I do have plenty of programmers and debugging interfaces here, the ATSAMD20 requires a very special procedure called “cold-plugging” which (in an open source world) only CMSIS-DAP compliant interfaces seem to be capable of in addition to necessary manual patching, cf. this post.

So while I do have Cypress eval boards here which come with a KitProg programmer which is CMSIS-DAP compliant, the implementation is somewhat pedestrian and in addition Cypress decided to swim against the current by making their kit use 5V instead of the nowadays more common 3V3 which complicates things a bit. Using a level shifter I was able to confirm that the KitProg is able to do what I wanted it to do so I decided it was time to get some capable and better matching hardware in form of a FRDM board with it’s OpenSDA interface. The cheapest board I could get and which seemed to be properly equipped was the FRDM-KL26Z from NXP:

So what could go wrong?

The problem

Well, earlier (and probably still the current) OpenSDA versions ship with a proprietary bootloader from PEmicro. To “simplify” things even the bootloader comes with a MSD (Mass-storage device) emulation which allows you to plug it into any modern computer where it will pop up as disk drive and allows you to drag and drop a debugger application image onto it to get if flashed. The problem here is that this bootloader is so broken that it does not work with modern OSses anymore because most modern OSses (be it Windows, Linux or macOS) just love to dump random crap onto any device you connect to them; yeah, I guess no MSD is whole until it has its own virtual trash and search index…

These crap files/directories cause earlier bootloaders to automatically try to flash it, recognize that they can’t and immediately go into an unrecoverable error state.

Another problem with the specific implementation is that it does not seem like it would like being “ejected” from the system which most operating systems (seemingly expect Windows) require before they actually start writing cached data onto the medium. Linux and macOS appreciate that most USB MSDs are really slow and are even slower when nilly-willy randomly writing data to them so they try to be clever and collect all data to written in a cache which will only be flushed if a timer runs out, someone says “sync now” (which is also implied by an eject operation) or if the system needs the memory more urgently for something else.

The deep end

PEmicro claims that the only affected versions of the bootloader are version 1.10 and lower and that the only way to work around that problem is using a Windows XP or 7 machine to uprade to bootloader 1.11 which is a bunch of baloney.

Not only are there versions of macOS (respectively OS X) and Linux that will happily work even with this bug in play. Even worse, 1.11 is still so buggy that there’s a very good chance that the problem is still prevalent. Even after finding a way to upgrade (which I’ll describe in the next section) the device is still not able to application images in bootloader MSD mode in neither Windows 10 nor in macOS Sierra.

The workaround

As I mentioned two of the main problems are missing resilience against crap files and the need to do synchronuous writes. Windows seems to do synchronuos writes by default so it only fails the first requirement, Erich Styger claims to have a workaround for the crap file problem but ALAS it did not work for me at all.

Puzzled by the claim that Linux would have a problem I decided to dive into that because it’s really the only OS where I can fully control what happens (with respect to sychronuous writes and generation of crap files). So I borrowed my sons’ laptop running Linux Mint and did the obvious basic check by plugging it in trying to flash it. Of course it did not work because the data was only cached and not written back. So let’s fix that…

Instead of automatically mounting the MSD we’re going to eject it and re-mount it manually using the sync flag:

mount -o sync /dev/sdb /mnt/

Then I could easily copy the new bootloader (1.11) over, toggle power and it was successfuly installed. Hooray, only took a few hours!

After another detour of converting the DAPLink .hex format image to .s19 (SREC) format using arm-none-eabi-objcopy I could flash the image (this time using Windows 10). macOS is still a no-go with drag-and-drop, though; however debugging and programming using OpenOCD now works just fine.