Motive
Using different tools to program a board that I purchased quite some time ago and never spent the time to learn about it.
Intro
I purchased this STM32F407VET6 board quite some time ago but I never spent time to learn how to program it. These last days I "forced" myself to learn it, search and ask questions to people more knowledgeable than me, how could I do it.
After knowing it could be programmed via USB cable I started to search which tools would I need. Then, the learning curve was more with the tools and how to use them, than actually writting any code.
After a few failed attempts I managed to get the expected result, which was to compile, upload and run a code to toggle a pin.
Step 1 - Install required tool to communicate with the board
Skipping all the searches that I did and help that I got from a few resources (foruns, internet and a friend), first thing was to install dfu-util in my Debian BullsEye. I had one other tool that I thought it was the right one, but it wasn't (dfu-tools).
Step 2 - Install required boards in Arduino IDE
Here we have to install the appropriate cores for Arduino IDE to be able to compile for the correct target. For this, we go to Arduino IDE -> File -> Preferences and pasted this link in the Aditional Boards Manager URLs field. Restart Arduino IDE, go to Tools -> Boards -> Boards Manager and in the search field, type in stm32 and install the STM32 MCU based boards.
Step 3 - Verify we can communicate with the board
To verify we can communicate with the board we can use dfu-util --list command. If it can communicate with the board, it will list it in the output.
But first things first. To be able to communicate with the board, the board needs to be in DFU bootloader mode. To make this happen, when need to pull down BOOT1 pin and RST button prior to plug in the USB cable. After doing this, we can see that the kernel reacted to it with the following command priviously started:
$ sudo udevadm monitor
[sudo] password for psysc0rpi0n:
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent
KERNEL[353587.418746] add /devices/pci0000:00/0000:00:14.0/usb2/2-2 (usb)
KERNEL[353587.420050] add /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0 (usb)
KERNEL[353587.420146] bind /devices/pci0000:00/0000:00:14.0/usb2/2-2 (usb)
UDEV [353587.433539] add /devices/pci0000:00/0000:00:14.0/usb2/2-2 (usb)
UDEV [353587.437370] add /devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0 (usb)
UDEV [353587.438722] bind /devices/pci0000:00/0000:00:14.0/usb2/2-2 (usb)
So, we know that the board is reacheable.
Step 4 - Get to know how and what to do with dfu-util.
So, the help of dfu-util is kind of pretty straightforward:
$ sudo dfu-util -h
Usage: dfu-util [options] ...
-h --help Print this help message
-V --version Print the version number
-v --verbose Print verbose debug statements
-l --list List currently attached DFU capable devices
-e --detach Detach currently attached DFU capable devices
-E --detach-delay seconds Time to wait before reopening a device after detach
-d --device <vendor>:<product>[,<vendor_dfu>:<product_dfu>]
Specify Vendor/Product ID(s) of DFU device
-p --path <bus-port. ... .port> Specify path to DFU device
-c --cfg <config_nr> Specify the Configuration of DFU device
-i --intf <intf_nr> Specify the DFU Interface number
-S --serial <serial_string>[,<serial_string_dfu>]
Specify Serial String of DFU device
-a --alt <alt> Specify the Altsetting of the DFU Interface
by name or by number
-t --transfer-size <size> Specify the number of bytes per USB Transfer
-U --upload <file> Read firmware from device into <file>
-Z --upload-size <bytes> Specify the expected upload size in bytes
-D --download <file> Write firmware from <file> into device
-R --reset Issue USB Reset signalling once we're finished
-s --dfuse-address <address> ST DfuSe mode, specify target address for
raw file download or upload. Not applicable for
DfuSe file (.dfu) downloads
Next, just try:
$ dfu-util --list
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Found DFU: [0483:df11] ver=2200, devnum=72, cfg=1, intf=0, path="2-2", alt=3, name="@Device Feature/0xFFFF0000/01*004 e", serial="3962374B3238"
Found DFU: [0483:df11] ver=2200, devnum=72, cfg=1, intf=0, path="2-2", alt=2, name="@OTP Memory /0x1FFF7800/01*512 e,01*016 e", serial="3962374B3238"
Found DFU: [0483:df11] ver=2200, devnum=72, cfg=1, intf=0, path="2-2", alt=1, name="@Option Bytes /0x1FFFC000/01*016 e", serial="3962374B3238"
Found DFU: [0483:df11] ver=2200, devnum=72, cfg=1, intf=0, path="2-2", alt=0, name="@Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg", serial="3962374B3238"
3 devices found. But I only have one connected, so I assume these are memory regions. So which one is the one where we should flash our firmware? Good question. But that last one is not completely unfamiliar. Internal Flash seems a reasonable candidate.
Next, I see in the help menu a few more options that might be needed, namelly the --device <vendor>:<product>. But how do I know the vendor and the product?
First thing coming to my mind is to run lsusb in my terminal because I know there is info there in that format <xxxx>:<xxxx> (or whatever).
$ lsusb
...
Bus 002 Device 072: ID 0483:df11 STMicroelectronics STM Device in DFU Mode
...
Bingo. It seems to be just what we need. <0483>:<df11>.
Step 5 - Compile a small program in Arduino IDE
I open Arduino IDE, open the sketch I attached to this project, selected the appropriate board and hit the button to compile.
Step 6 - Trying to upload the code with dfu-util
Ok, the most exciting part is now. To actually use dfu-util to flash our firmware.
For a start I just tried the most basic command I could think of:
$ dfu-util --download /tmp/arduino/sketches/565B457541832EAED9889914CDFB6C29/test.ino.elf --device=0483:df11
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
dfu-util: More than one DFU capable USB device found! Try `--list' and specify the serial number or disconnect all but one device
Ok, one message at a time. The first 2 messages I don't know what they mean at this point, so I went for the last one. I actually only have one board connected, but the command we ran above, the dfu-util --list actually shows several devices that I assumed were different memory regions, just like happens with external memory chips. Each page is detected as a different device. Anyway, there must be a way of selecting the device (or memory region) from those listed in the dfu-util --list output command.
From the output, one thing calls my attention. Is that the only obvious thing that distinguish the 3 memory regions is that alt=[0,1,2].
Looking to dfu-util --help output, there is one option that allow us to select memory regions, so I tried the following:
$ dfu-util --download /tmp/arduino/sketches/565B457541832EAED9889914CDFB6C29/test.ino.elf --device=0483:df11 -a 0
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
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 "
dfu-util: Only DfuSe file version 1.1a is supported
dfu-util: (for raw binary download, use the --dfuse-address option)
The `-a 0` specifies the exact device as there are several within this board that the following command detects (alt=0):
So, this is still a no-go. But from the output I can see that a tip is given. To use --dfuse-address option.
So, let's try that:
$ dfu-util --download /tmp/arduino/sketches/565B457541832EAED9889914CDFB6C29/test.ino.elf --device=0483:df11 -a 0 --dfuse-address 0x08000000
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
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 = 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 = 619652
Download [=========================] 100% 619652 bytes
Download done.
File downloaded successfully
Ohh wow, it worked. So, let's test it.
Step 7 - Test if the code is running as expected
So, to test the code running, we have to change the boot mode to the flash program. To do this, we unplug the USB clabe, remove the pull down on BOOT1 and put it on BOOT0. Then we plug the USB cable back in an hit the RST button.
After this, is just a matter of checking with a DMM if PC8 pin is toggling at 1Hz.
So I did but the pin is not toggling. Is sat at a voltage around 1V or so. Definitly something is wrong.
At this point, I don't know what else to do, so I tried another approach. Downloaded STM32CubeProgrammer and tried to flash the same .elf file as I did with dfu-util. No need to mention (but I do it anyways) that we need to switch the boot mode back to what it was before - unplug USB cable, remove pull-down on BOOT0, put it on BOOT1, plug in USB cable and hit RST button)
After this, I tested again the PC8 pin with DMM and it was actually toggling as expected. Good and bad news at the same time. Something is wrong with dfu-util.
Step 8 - Friends to the help
I'm now completely out of knowledge so I went for some online friends that are way more experienced than me and I was told that dfu-util could eventually not be able to handle .elf files properly and that I should convert it to a raw image and try again.
Wow, I couldn't have dreamed anything like this. But, hope is not lost. Arduino IDE creates 3 files. .hex, .elf and .bin. Let's try the .bin file with dfu-util again.
$ dfu-util --download /tmp/arduino/sketches/565B457541832EAED9889914CDFB6C29/test.ino.bin --device=0483:df11 -a 0 --dfuse-address 0x08000000
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
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 = 13872
Download [=========================] 100% 13872 bytes
Download done.
File downloaded successfully
Time to change boot modes again, same procedure and test PC8 again with the DMM and finally I got it working.
Well, long story but good learning.
Thanks for reading and hope you enjoy the thrill!
Psy
Comments