Building from source for GNU Guix (was: Stuck in DFU mode)


#1

I've built the cross-compiler toolchain and the Axoloti software on GNU Guix, but so far have not been able to successfully upload a patch (as reported here https://github.com/axoloti/axoloti/issues/267).

Everything looks fine and the logs state that chunks are uploaded, but every time it reports a firmware CRC mismatch. So I thought that maybe I should try uploading the firmware via DFU mode and I disconnected the device, pressed S1, reconnected, and the device appeared in DFU mode:

Bus 006 Device 027: ID 0483:df11 SGS Thomson Microelectronics STM Device in DFU Mode

So I selected Board -> Firmware -> Flash (Rescue) and observed dfu-util do its thing. Here's the output:

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2014 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to dfu-util@lists.gnumonks.org

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 0483:df11
Run-time device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Setting #0 ...
Determining device status: state = dfuERROR, status = 10
dfuERROR, clearing status
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 011a
Device returned transfer size 2048
DfuSe interface name: "Internal Flash  "
Downloading to address = 0x08000000, size = 570468

Download	[                         ]   0%            0 bytes
...
Download	[============             ]  50%       288768 bytes
...
Download	[=========================] 100%       570468 bytes
Download done.
File downloaded successfully
Transitioning to dfuMANIFEST state
Done flashing firmware with DFU.

Now upon disconnecting the board and connecting it again it seems to be dead. lsusb does not show it, it does not power on, and the only way I can get it to reappear is by pressing S1 while connecting it. It appears again in DFU mode and I can again flash the rescue firmware as before, but I cannot seem to get it back into normal mode again.

I'm not sure what's going on here. In the regular mode uploading firmware had no effect (firmware CRC mismatch, no matter how often I flashed it) and in DFU mode flashing the firmware seems to not do anything either.

I have another board which is still in regular mode and it has the same issue with firmware CRC mismatch warnings, so I don't think it's a hardware problem.


Linux mintppc with axoloti?
#2

if you built the environment yourself, I guess there is a potential you are using different versions of things like dfu-util and libusb (or other dependent libraries), which may cause issues.
this is unfortunately a general issue, developers cant test on every possibly combination of libraries... this is a problem with linux, given its plethora of distributions which different libs... and of course every user (me included) having their own 'favourite'

I think the 'obvious' one to check is libusb, and to ensure you apply the libusb patch ... you will see the relevant line in build.sh


#3

Are you using the same arm-none-eabi-gcc version as in the build script to build the firmware (gcc-arm-none-eabi-4_9-2015q2-20150609)?


#4

ok, dont worry about these 'errors' I get these too.


#5

missing the libusb patch 'd only cause dfu-util to fail (issue with the rom bootloader in stm32f42x series), but that looks fine in @rekado's log


#6

I have applied the patch to the upstream sources of libusb 1.0.19. I used the patched version of libusb as an input to "dfu-util" version 0.8.

I followed the build.sh as closely as possible. I did not pass USB_LIBS and USB_CFLAGS during the configuration phase of dfu-util because there is only the patched version of libusb around at build time (Guix packages are built in a chroot where only declared inputs are visible).

(One additional configure flag that I pass to libusb is "--disable-udev" because uedev depends on libusb indirectly.)


#7

I'm not using the prebuilt gcc-arm-none-eabi distribution (primarily because it wouldn't work on my system). I built the cross compiler (version 4.9.3 for target "arm-none-eabi") and the "newlib" C library (version 2.2.0) from scratch. It compiles the firmware fine.

If it really is a problem with the firmware binary, would it be possible for you to share the binary firmware and let me try to upload that with dfu-util, rather than the firmware I built?


#8

Could you extract it from the .deb package?


#9

Oh, yes, I could try that.


#10

It worked with the firmware contained in the .deb package.

That's both good and bad. "Good" because the board is back to normal mode, "bad" because it means that my cross-compiler doesn't quite produce the correct binaries (although it seems to be very close).

At least I'm sure now that dfu-util works as it should, and that the boards are not broken :smile:

I would love to figure out what the difference between the two compilers or C libraries is (and the produced binaries). I'll investigate.

Thanks for the assistance so far!


#11

One obvious difference is that I used the regular GCC 4.9.3 sources, but the binary compiler toolchain (gcc-arm-none-eabi-4_9-2015q2-20150609) is based on a different branch of the GCC sources: https://gcc.gnu.org/svn/gcc/branches/ARM/embedded-4_9-branch/ at revision 224288.

I'll rebuild the cross-compiler with these sources; maybe that's enough to fix it.


#12

I rebuilt the cross-compiler using the exact same SVN branch and revision, but unfortunately the behaviour is unchanged. Maybe it's not the compiler that is to be blamed but differences in newlib?


#13

Don't know, haven't ever built arm-none-eabi-gcc myself. What prevents running the gcc-arm-none-eabi distribution?


#14

GuixSD doesn't follow the FHS to provide functional package management as well as stateless and declarative system configuration. Prebuilt binaries won't work as they expect certain libraries to be located in well-known locations. To make matters worse, I don't think I can easily get a 32 bit glibc on my 64 bit system (the glibc that comes with GuixSD doesn't currently support multilib).

That's why it's easier for me to build the compiler toolchain from source (Guix makes this pretty simple, actually). The compiler does seem to work (i.e. it builds ARM binaries and links them successfully), but Axoloti claims that the CRC after uploading via dfu-util differs. I find this rather odd.

I'll try to use the very same commit of "newlib" that is mentioned in the release.txt of the prebuilt gcc-arm-none-eabi tarball next, but I feel I'm soon running out of options. Maybe diffing the produced binaries themselves will shed some light on what's going on.

How is the hardware CRC computed? It seems to be the result of something transmitted via USB, but I don't understand the code well enough to know where it really comes from.

What is "firmware/flasher/flasher_build/flasher.bin" used for? Exactly what binaries are uploaded to the board? Is there some documentation about this or would it be better if I read the code?


#15

I have no clue about Guix, if you say prebuilt gcc won't work I totally believe you :smile:

Firmware computes crc32 from internal flash when booting on the microcontroller (in firmware/pconnection.c, in InitPConnection), the GUI computes the crc32 from the file firmware/build/axoloti.bin

They're verified, and also a patch launched will verify, since a mismatch can cause crashes (of just the board, and non-destructive), since firmware symbols could have moved.

firmware/flasher is a binary that loads via the same mechanism as a patch, but rather than being linked to the firmware, it is fully self-contained so it can erase/write a new firmware. This is used in the GUI in the firmware update process.

If you have managed to compile and upload a firmware with your self-compiled gcc, you're pretty close! The crc mismatch, that could come from different padding by the dfu-upload or something. Perhaps do a binary firmware download with dfu-util, and check a binary diff. I also get crc mismatches when launching firmware via gdb/openocd/stlink but haven't studied the origin. In this situation I bypass the patch-firmware crc validation (axoloti/src/main/java/axoloti/Patch.java , remove line 1199 with the return statement).


#16

I downloaded the firmware from the board with dfu-util and indeed there are a couple of difference between the file and axoloti.bin.

A common change is that the downloaded file has hex "0000 0000" where axoloti.bin has "aff3 0080". According to this page the latter is Thumb-2 hex for NOP.W; don't know why it would be replaced with all zeros upon uploading the firmware.

Yet another often repeated change is from 682f (axoloti.bin) to 482f (on board).

There are a few other minor changes, but they don't appear to have a simple pattern. It's often just a change of a single 32 bit word. I wonder what would cause this change when uploading the binary.

I tried uploading the firmware bundled with the .deb archive and see if there's any differences when downloading it from the board. (Just as a sanity check.) There are no such differences in the first 2^14 bytes, so I assume the file stays the same.


EDIT: I compared both the original firmware bundled with the .deb and the firmware I downloaded from the board --- and they are the same! This strongly suggests that my self-compiled firmware was never successfully uploaded. I will try uploading my custom firmware from the command line via dfu-util.

EDIT: this does work, but the board is stuck in DFU mode again. The differences I noted above are, in fact, between my self-built firmware and the bundled pre-compiled firmware. I'm surprised to see how similar the two are. I'll try to figure out what causes the differences --- and which of them are important.


#17

The first question I'd like to answer is: why does it look like my firmware is uploaded to the board (when in normal mode), but the board never actually retains it?

Whenever I download firmware from the board it is the one version that I successfully uploaded: the one bundled with the .deb archive.

Uploading my firmware in DFU mode causes the board to "die"; lsusb doesn't show that it's connected. Why doesn't this happen when I upload it via the GUI in normal mode?


#18

Quick update: replacing the firmware directory with the one that's bundled in the .deb file I can compile patches and upload them to the board --- and I actually get sound!

So, the compiler seems to work, but the firmware I built is broken.

(The board is lovely and the sound is great!)


#19

Maybe diff the output from arm-none-eabi-objdump disassembling axoloti.elf rather than the binary code?
I also suggest to ask on gcc-arm-embedded related discussion lists.

Uploading the standard firmware or your firmware? Double check the paths involved. How the firmware image is flashed does not matter. If the firmware does not run properly (due to the differences), and does not reach the firmware usb device setup, there will be nothing visible in lsusb.

Anyway thumbs up for getting it running!


#20

Uploading my own firmware. If I do this in the GUI via normal mode (i.e. the LED is lit) dfu-util starts working, but at the end when it says that the firmware was uploaded successfully the board reboots and the firmware hasn't actually been changed. (It reports a CRC mismatch again and again, and when downloading the firmware from the board I see that it's still the same binary as before.)

Only when flashing in DFU mode the firmware is in fact changed (as shown by downloading the uploaded firmware and comparing it) --- and since my firmware seems to be broken the board never initialises USB, so lsusb doesn't show it.

I find it odd that in normal mode this error does not occur and everything suggests that the firmware was updated, when in fact it was not.