Introduction
OpenOCD is an extremely useful (and free!) piece of software for microcontroller programming. In particular, I use it to program to and debug with various development boards I have laying around. I have a Luminary Micro/TI Stellaris LM3S2965 evaluation kit that has a built-in USB port which can be used for JTAG. The board also has a JTAG connector on it, so you can use it as a passthrough for JTAG on another board. The JTAG is powered by an FTDI FT2232D USB to serial chip. Just calling it a USB to serial chip is not giving it quite enough credit, though — it can be used for all kinds of crazy things, including JTAG. I would venture a guess that most USB to JTAG adapters you can buy are really just a simple board with this chip on it connected to a JTAG connector on one end, and USB on the other.
Anyway, OpenOCD is a bit interesting. It can interface to FT2232-based JTAG devices with two options for communication. The first option is libftdi, an open-source library that uses libusb to talk to the FTDI chip. The second option is ftd2xx, which is a proprietary library provided by FTDI itself (which also appears to be based on libusb?).
So naturally the question is: which one should you use?
Well, I think it depends on your specific needs. I first got OpenOCD working a couple of years ago in Ubuntu Linux. At the time, it didn’t really matter to me which library to use, so I tried them both. My experience was that FTDI’s own driver was much faster than libftdi. The situation may have changed since then, but I haven’t had a reason to change my setup.
When I got OpenOCD working on Windows 7 64-bit, it got even more interesting. At the time, libusb was not a signed driver, so it was a huge pain in the butt to get it to work with Windows 7. Apparently you could get it to work by starting up Windows with a special option in the same startup menu you’d use to boot into safe mode. But you’d have to do that EVERY time you booted, or the driver wouldn’t work. That’s my understanding of the situation, anyway. The other option was just to use FTDI’s driver and forget about it all. So I did.
Things have changed since then, though. libusb is now available as a signed driver that won’t make you jump through hoops on Windows. I haven’t tested libftdi lately to see how it compares performance-wise to ftd2xx. Anyway, I’ve stuck with ftd2xx just because it’s what I started with, so this post will be about the ftd2xx library. It’s very possible that my instructions will still work with libftdi though!
Anyway, here’s the other thing about the ftd2xx library. It’s a proprietary library incompatible with the license used by OpenOCD (GPL). So you won’t be able to find a (legally good) distribution of OpenOCD that has the ftd2xx library capability built-in. It’s perfectly OK to distribute OpenOCD that’s linked against libftdi since it’s compatible with the “viral” GPL. But since back in the day I needed OpenOCD with ftd2xx, I had to compile it myself.
I recently had to compile OpenOCD for 64-bit Windows again. That’s where this blog post comes in.
Compiling OpenOCD for Windows
There are a few options you can use to compile stuff designed for GNU tools in Windows. One example would be MSYS, and another would be Cygwin. These are both EXCELLENT environments, but I don’t like having to install a bunch of their stuff on my computer just for the sole purpose of having all the crazy tools necessary to be able to compile OpenOCD. I’d rather keep my Windows partition nice and clean to the point where I just have the OpenOCD executable and any supporting libraries, and that’s it. But how do you get past needing all the stuff necessary to run configure scripts, process Makefiles, and yadda yadda yadda?
You cross-compile it for Windows using Linux and MinGW! That’s how!
Here are the basic instructions I found on Dangerous Prototypes for cross-compiling OpenOCD for Windows from Linux. I tried to follow them step-by-step, but I ran into a few snags, so I decided to make my own post that will go step-by-step through compiling OpenOCD for 64-bit Windows (Vista and 7, and probably 64-bit XP too?). I see no reason why this shouldn’t work on a 32-bit platform as well–just substitute any 64-bit compilers/tools I specify with the corresponding 32-bit versions instead!
I had trouble getting 64-bit MinGW to work correctly in Ubuntu, so this post by Matpen on the Ubuntu forums also helped me immensely. I’m guessing if you’re doing a 32-bit compile, you don’t need to worry about the problems I had with the 64-bit MinGW included with Ubuntu. The version included with Ubuntu 10.04 had a really deep problem in that it doesn’t include libgcc_s.a, and the version included with Ubuntu 11.04 has problems such as not providing a getopt.h include file.
Finally, I had more trouble getting OpenOCD to link against the ftd2xx library after I solved the first problem, and this post by el_nihilo on the SparkFun forums also helped me out.
I’m hoping that by combining the instructions from these three sources, I can create a single source that anyone can go to in order to get OpenOCD to compile on the FIRST TRY. Here goes nothing!
Prerequisites (for Ubuntu 12.04)
Since I first wrote this article, Ubuntu 12.04 came out, and this process is MUCH simpler to get working with it. The supplied toolchains work fine now. All you need to do is:
sudo apt-get install mingw-w64
No need to install weird packages or regenerate FTDI’s .lib file. Great!
Prerequisites (for Ubuntu < 12.04)
You’re going to need an install of Ubuntu (32-bit or 64-bit — your choice). I have successfully tested this procedure on the 64-bit version of Ubuntu 10.04, the 32-bit version of Ubuntu 10.10, and the 64-bit version of Ubuntu 11.04. Use whatever you’d like. You can do it on a separate partition, in a VMware Player virtual machine, or whatever else it takes to get Ubuntu.
To start, we’re going to install some packages that Ubuntu will need:
sudo apt-get install libcloog-ppl0 libgmpxx4ldbl libmpfr1ldbl libppl-c2 libppl7
Now, rather than use Ubuntu’s provided 64-bit MinGW package, which does not work (as of this writing), we will instead use a version which does. So get the two packages that apply to you and install them:
If you’re on a 32-bit version of Ubuntu:
wget http://ppa.launchpad.net/mingw-packages/ppa/ubuntu/pool/main/w/w64-toolchain/i686-w64-mingw32-toolchain_1.0b+201011211643-0w2273g93970b22426p16~karmic1_i386.deb wget http://ppa.launchpad.net/mingw-packages/ppa/ubuntu/pool/main/w/w64-toolchain/x86-64-w64-mingw32-toolchain_1.0b+201011211643-0w2273g93970b22426p16~karmic1_i386.deb dpkg -i i686-w64-mingw32-toolchain_1.0b+201011211643-0w2273g93970b22426p16~karmic1_i386.deb dpkg -i x86-64-w64-mingw32-toolchain_1.0b+201011211643-0w2273g93970b22426p16~karmic1_i386.deb
If you’re on a 64-bit version of Ubuntu:
wget http://ppa.launchpad.net/mingw-packages/ppa/ubuntu/pool/main/w/w64-toolchain/i686-w64-mingw32-toolchain_1.0b+201011211643-0w2273g93970b22426p16~karmic1_amd64.deb wget http://ppa.launchpad.net/mingw-packages/ppa/ubuntu/pool/main/w/w64-toolchain/x86-64-w64-mingw32-toolchain_1.0b+201011211643-0w2273g93970b22426p16~karmic1_amd64.deb dpkg -i i686-w64-mingw32-toolchain_1.0b+201011211643-0w2273g93970b22426p16~karmic1_amd64.deb dpkg -i x86-64-w64-mingw32-toolchain_1.0b+201011211643-0w2273g93970b22426p16~karmic1_amd64.deb
These commands will install special versions of MinGW that aren’t broken for producing 64-bit code. I’m not 100% sure if you actually need to do the i686 toolchain as well, but I’ve included them because the original steps from the Ubuntu forums also included them. The packages may say Karmic in the filenames, but I was also able to install them successfully in 10.04, 10.10, and 11.04.
Downloading OpenOCD and FTDI’s library
So now let’s grab OpenOCD and the FTDI library:
wget http://download.berlios.de/openocd/openocd-0.5.0.tar.bz2 wget http://www.ftdichip.com/Drivers/CDM/CDM20814_WHQL_Certified.zip
First, if you’re using the MinGW toolchain from before Ubuntu 12.04, you need to regenerate the FTDI library’s .lib file, because it and that MinGW version just don’t get along. If you have Ubuntu 12.04 and its built-in MinGW toolchain, skip down to “The actual compilation of OpenOCD.” If you have an Ubuntu version before 12.04 and don’t do this step, the final link of openocd.exe will fail with several errors similar to: undefined reference to `__imp__FT_Write’. Extract CDM20814_WHQL_Certified.zip and do the following commands:
cd CDM20814_WHQL_Certified/amd64 echo "LIBRARY ftd2xx64.dll" > ftd2xx64.def echo "EXPORTS" >> ftd2xx64.def strings ftd2xx64.dll | grep FT_ >> ftd2xx64.def mv ftd2xx.lib ftd2xx.lib.old x86_64-w64-mingw32-dlltool -d ftd2xx64.def -l ftd2xx.lib
If you go to the post by el_nihilo on the SparkFun forums which I mentioned earlier, you’ll see what’s going on. It has to do with the difference between how DLL function names are expected to be prefixed in Visual C++ and MinGW. It’s pretty goofy that there have to be all these stupid incompatibilities, but this clever little trick fixes it by regenerating the .lib file so it’s compatible with MinGW. This step was borrowed directly from that post.
Once all this preparation is done, it’s now safe to try to install OpenOCD!
The actual compilation of OpenOCD
Now, compiling OpenOCD is relatively straightforward!
Go into the OpenOCD directory, and do this command:
./configure --host=x86_64-w64-mingw32 --disable-werror --with-ftd2xx-win32-zipdir=/path/to/CDM20814_WHQL_Certified --with-ftd2xx-lib=static --enable-ft2232_ftd2xx --prefix=$PWD/_install
Let’s step through the options we gave to the configure script so we make sure we understand what it’s doing.
-
--host=x86_64-w64-mingw32
specifies that we are compiling for a different host that we’re running on now. This is how we tell it to use the MinGW cross compiler.
-
--disable-werror
makes it so a compiler warning is not treated as an error. We will get some compiler warnings which would cause the build to fail if we didn’t provide this option. The warnings seem to be harmless; it works just fine!
-
--with-ftd2xx-win32-zipdir=/path/to/CDM20814_WHQL_Certified
is just the path to the folder containing the contents of the extracted zip file with the ftd2xx driver and libraries. It’s telling the configure script where to find the header file and library to compile/link against.
-
--with-ftd2xx-lib=static
supposedly tells it to link OpenOCD against the static library instead of the dynamic library. Despite that fact, I still have to include ftd2xx64.dll with the final generated binary. Not sure why, but it works!
-
--enable-ft2232_ftd2xx
tells the configure script that we’re going to want FT2232 support provided by the ftd2xx proprietary library.
-
--prefix=$PWD/_install
just tells it to install in a directory called _install in the current directory instead of the default location of /usr/local. Since we’re just going to be transporting it over to the Windows computer when done, it makes no sense to install it in /usr/local.
So, do it!
Then, when it’s done and succeeds (hopefully), compile it:
make
and install it:
make install
Now, your OpenOCD directory should have a directory called _install inside of it, containing several directories including (almost) everything you need to get OpenOCD running on Windows! The only thing it’s missing is ftd2xx64.dll. Grab it from the CDM20814_WHQL_Certified/amd64 directory and stick it in the bin directory alongside openocd.exe. At this point, you should be able to transfer this directory over to your Windows partition/machine/whatever and run OpenOCD just like any other random Windows console app.
Hope this helps someone else who, like me, was struggling to get it to work!