libmaple Unix Toolchain Quickstart
You'll need a Maple board, a mini-b USB cable, a functional computer, and possibly root access to that computer. This guide assumes you've had success with the IDE on your machine and that you are fairly comfortable with the Unix command line; some previous experience with editing your shell startup script (.bashrc, .tcshrc, etc.) and using make is recommended. For generic installation/setup issues the install and troubleshooting pages may be helpful. If all else fails try google, our forum, or contact us directly!
We currently have instructions for Linux and OS X Snow Leopard. If you're on another Unix platform, Windows, or an earlier version of OS X, we're guessing that you can translate/port these directions on your own. As a jumping off point, you can find stripped down distributions of the CodeSourcery GCC compiler tools (including win32 versions) in the same download directory as the Linux ones mentioned below. If you do have success on other platforms, please post in the forums so we can fold your tips into this document!
- Linux setup
- OS X setup
- Test compilation
- Upload a program
- Communicate over USB-serial interface
- Starting your own projects
- Debug with OpenOCD
- Do it all with Code::Blocks
- Go forth exuberantly!
Linux Setup
These instructions are oriented towards Linux users using a contemporary Debian-based distribution.1. Collect and Install Tools
First I'll give the commands to run, then explain:
$ sudo aptitude install build-essential git-core wget screen dfu-util \
openocd python python-serial
You'll want to install a bunch of developer "basics" like make,
tar, etc. A good catch-all for these tools is the
"build-essential" meta-package on most debian platforms: installing this fake
package will pull in dozens of useful tools without bogging your system down
too much. git-core is the name of the git package; git is a
distributed code versioning system we use to track changes in our source code.
wget is a simple tool to download files over http from the command
line and is optional (you could pull in the required downloads using a
browser). screen is a really cool virtual terminal program; in the
context of Maple we use it to connect to serial port devices.
dfu-util is a tool from the OpenMoko project that we use to upload programs
to the Maple over USB.
openocd is a JTAG control program used in conjunction with an
ARM JTAG device to do in circuit debugging (pause/resume program execution,
upload and download code, read out register status, etc). (optional)
Lastly, our reset script (which sends control signals over the USB-serial
connection to restart and enter the bootloader) is written in Python and
requires the PySerial library (the python-serial package; this
could also be installed with easy_install).
2. Fetch libmaple and Compiler Toolchain
$ cd ~ $ git clone git://github.com/leaflabs/libmaple.git libmaple $ cd libmaple $ wget http://static.leaflabs.com/pub/codesourcery/\ $ arm-2009q3-68-arm-none-eabi-toolchain-linux32.tar.gz tar xvf arm-*.tar.gz $ export PATH=$PATH:~/libmaple/arm/bin # or wherever these tools ended up
Fairly straight forward... do a git clone of the libmaple repository to some directory, then download and extract the ARM compiler toolchain.
The arm/bin/ directory will needs to be added to PATH; you can
check that this worked by entering arm-none- and hitting tab to
auto-complete (bash should show a bunch of results). If you want to move that
toolchain somewhere else and add it in a .bashrc script or whatever make sure
to preserve the directory layout as the binaries will make relative path calls
and references.
3. Install udev Rules
$ groups # make sure it includes plugdev; if not add yourself to it $ sudo cp support/scripts/45-maple.rules /etc/udev/rules.d/45-maple.rules $ sudo /etc/init.d/udev restart
As a security precaution on linux, unknown USB devices can only be accessed by
the superuser. This udev script identifies the Maple based on it's vendor and
product IDs, mounts it to /dev/maple, and grants read/write permissions to the
plugdev group. After restarting udev you'll need to fully unplug
or power cycle any Maples connected to the computer.
All done?
Great! Go ahead and test everything out.OS X Setup
These instructions have been tested successfully on OS X 10.6.4. As stated previously, this document assumes a general level of Unix aptitude on the part of the reader; if you're uncomfortable using Terminal (or if you don't know what that means), then you should probably stick with using the Maple IDE to develop programs. Some of these software packages might be available on MacPorts. The author had some bad experiences with MacPorts a few years ago, though, and hasn't touched it since. Of course, your mileage may vary.1. Collect and Install Tools
You will need the following tools to get started:- XCode: If you're reading this, you've probably already got this. Provides compilers and other basic tools of the trade. It's a free download, but requires registration (gross, we know).
- Git: All of our code is tracked by a distributed versioning system called git. A Mac installer is available.
- dfu-util: A tool
from OpenMoko that we use to
upload programs to the Maple over USB. If you're feeling
masochistic, there are instructions
for building
dfu-util from source.
However, if you've got better things to do, you can steal a
dfu-utilbinary from a program called Openmoko Flasher. To do this, first download Openmoko Flasher, then copy the .app into your Applications folder (or wherever you like). Let's pretend you saved the .app to the directory/Applications/OpenMoko Flasher.app
Then the dfu-util binary resides in/Applications/OpenMoko Flasher.app/Contents/Mac OS/dfu-util
To get access to it from the command line, just make a symbolic link to the binary from some place on your PATH:$ ln -s /Applications/OpenMoko\ Flasher.app/Contents/Mac\ OS/dfu-util \ /somewhere/on/your/PATH/dfu-utilNote that just copying the binary doesn't work, as it relies on dynamically linked libraries found elsewhere in the .app bundle. (You can alternatively pull all of the relevant pieces out of the .app and save them somewhere, but you're on your own). To make sure this worked, try plugging in your Maple, making sure it's in bootloader mode (you can do this by pressing RESET, then quickly pressing BUT and holding it for several seconds), then running$ dfu-util -l
If you see some lines that look likeFound DFU: [0x1eaf:0x0003] devnum=0, cfg=0, intf=0, alt=0, name="DFU Program RAM 0x20000C00" Found DFU: [0x1eaf:0x0003] devnum=0, cfg=0, intf=0, alt=1, name="DFU Program FLASH 0x08005000"
then you're all set. - PySerial: our reset script (which sends control signals over the
USB-serial connection to restart and enter the bootloader) is
written in Python and requires
the PySerial library.
Download the latest
version. After you download and untar, install it with
$ cd /path/to/pyserial-x.y $ python setup.py build $ sudo python setup.py install
The package is also available viaeasy_install, so if you're comfortable using that, you could also install it with$ easy_install pyserial
2. Fetch libmaple and Compiler Toolchain
You first need to clone libmaple:$ cd ~ $ git clone git://github.com/leaflabs/libmaple.git libmapleThen you need to get the cross-compilers we use to build a project. These are just modified versions of GCC; you can download them for OS X here. Assuming you saved this file to
~/Downloads/arm-2010q1-188-arm-none-eabi-toolchain-macosx32.tar.gz,
you can then unpack the archive and let OS X know where the
compilers live with
$ cd ~/Downloads $ tar -xvzf arm-2010q1-188-arm-none-eabi-toolchain-macosx32.tar.gz $ mv arm ~/libmaple/armAfter that's done, you'll probably want to update your shell startup script to stick
~/libmaple/arm/bin into
your PATH.
All done?
Great! Go ahead and test everything out.Test compilation
Get back into the libmaple directory (this tutorial assumes you put it in ~/libmaple) and test that you've installed all the compilation tools correctly:$ cd ~/libmaple $ cp main.cpp.example main.cpp $ make clean $ makeIf it all worked out, you should end up seeing something like this at the end:
find build -iname *.o | xargs arm-none-eabi-size -t
text data bss dec hex filename
482 4 24 510 1fe build/wirish/comm/HardwareSerial.o
260 0 0 260 104 build/wirish/comm/HardwareSPI.o
60 0 0 60 3c build/wirish/wirish.o
[...]
2196 0 1 2197 895 build/libmaple/usb/usb_lib/usb_core.o
1904 0 0 1904 770 build/libmaple/usb/usb_lib/usb_regs.o
56 0 0 56 38 build/libmaple/usb/usb_lib/usb_init.o
344 0 0 344 158 build/libmaple/usb/usb_hardware.o
6637 0 58 6695 1a27 build/main.o
21499 201 391 22091 564b (TOTALS)
Final Size:
arm-none-eabi-size build/maple.out
text data bss dec hex filename
21824 200 552 22576 5830 build/maple.out
Flash build
That's it! You're all set. The "dec" field at the end gives the
total program size in bytes. The long listing of object files above
the Final Size helps to identify bloated code; as you write larger
projects, you may find that they use too much space. If that
happens, the file-by-file listing will help you track down the
fatties porking up your program.
Upload a program
$ cd ~/libmaple $ cp examples/test-session.cpp main.cpp $ make clean $ make $ make install
Ok, let's blow away the little example program and upload the
interactive test session. If you're on Linux, then before
executing make install you'll want to have the udev rules
setup as described above and have the Maple
plugged in.
A number of things can go wrong at this stage; simple debugging steps include using the perpetual bootloader mode, restarting Maple a couple times, make-ing clean, etc. If nothing works, the forum is your friend.
Communicate over USB-serial interface
Okay, now that we've flashed the interactive test session to the Maple, let's test it out. The device for the maple should look something like "/dev/ttyACMXXX" on Linux or "/dev/tty.usbmodemXXX" on OS X, but it might have a slightly different name on your system. To open up a session, run$ screen /dev/tty-whatever-it-isIf the interactive test program built and uploaded correctly, you should be able to connect with
screen. Type 'h' or hit
the space bar to get a response; there are a number of commands which
demonstrate Maple peripheral features.
As of August 2010, the HardwareSerial library is blocking, so using
any commands which would write to the USART Serial ports will cause
the program to hang.
To exit the screen session, type C-a C-\ (control-a, followed by
control-backslash), and type "y" when prompted if you're sure.
Starting your own projects
So everything worked, and you want to start your own project? Great! It's easy. Just set the environment variableLIB_MAPLE_HOME in your shell startup script to
point to the libmaple repository you cloned (this tutorial assumes you
put it in ~/libmaple). For example, if you
use bash as your shell, just put this line in your
~/.bashrc or ~/.bash_profile:
export LIB_MAPLE_HOME=~/libmapleNow, in order to start your own projects, just grab a copy of the
Makefile and skeleton main.cpp we provided
in the libmaple repository, and you're good to go:
$ cd $ mkdir my-awesome-project $ cp ~/libmaple/Makefile my-awesome-project $ cp ~/libmaple/main.cpp.example my-awesome-project/main.cppThen hack away! You can
make, make clean,
and make install from your new
directory my-awesome-project just like you did in the
libmaple repository.
Debug with OpenOCD
TODO. For now see this great guide from fun-tech.se.Do it all with Code::Blocks
Optional. Code::Blocks is a generic cross platform IDE. We don't personally use it for development so we haven't worked out all the kinks (eg, debugging isn't integrated), but it might be helpful for people who are allergic to vim and/or Emacs. The simple configuration described here just calls down to the Makefile, so follow the above directions to get the command line tools configured (you'll definitely need the arm-none-eabi-* tools on your path by default), then install Code::Blocks. You can do this on Linux with:$ sudo aptitude install codeblocksThe first time it runs you'll maybe want to disable all the glitzy "Getting Started" crap (when will they learn?). We've added a .cbp "projects" file to the libmaple repository: you can try using that one by copying it from
support/codeblocks/libmaple.cbp to the top level directory, but no
promises (it might be missing new source files etc). It's probably worth
reading through these instructions as well to get a feel for how it all works.
To create your own "libmaple" project, start with an "Empty Project" with the
"Folder to create project in" set to your libmaple directory. Make sure that
the "Resulting filename" is in the top level directory as well.
Select the "GNU GCC Compiler" (it won't be used anyways) and disable the
"Debug" configuration in the next window. Now you should have a project with no
files; add files by right clicking on the project in the left panel file
hierarchy and "Add files recursively". Import both the wirish and libmaple
directories recursively, then add main.cpp separately.
Next we have to configure the Makefile targets. Go to the "Properties..." menu
under "Project" and check the "This is a custom Makefile" box. Then go to the
"Build targets" tab and create "ram" and "flash" targets, both of type "Console
application" and without the Auto-generated filename prefixes or extensions.
Set the Output filename to support/codeblocks/program_flash.sh and
support/codeblocks/program_ram.sh respectively; these scripts just
call the program_ram/program_flash make targets and are a hack to get the "run"
button to upload code to the Maple. The IDE will warn that these files will be
overwritten, but they won't be. For both the "flash" and "ram" targets, click
the "Build options..." button (below "Virtual targets..." etc) and go to the
far right tab ("'Make' commands"). Edit the Clean project/target line so it's
just "clean" (not "clean$target"), and set the "Build project/target" and
"Compile single file" commands to $make -f $makefile
MAPLE_TARGET=$target and $make -f $makefile MAPLE_TARGET=$target
$file respectively.
Save all these changes, go back to the main IDE window, and try to build/run.
"Build" will compile everything, "Run" will run the upload script in a terminal
window (if there are problems they will flash by very quickly; you can start
Code::Blocks in a terminal window and check the output in that base window if
necessary), and "Rebuild" will clean before rebuilding.
Success!
Go forth exuberantly!
Let us know what you come up with! Use #leaflabs on Twitter, post in the forums, track us down in the real world, whatever. We love projects!
Appendix
Further information about our repository structure. This section is optional. Read it only if you're curious about how things work under the hood.Our repository setup is a little unconventional. Usually libraries get compiled down to a binary archive which other programs link (or pull from) using hints from source code header files. With that structure the "library" code and build process is separated from the individual "program". At this point we frequently end up customizing the "library" part of the code to suit the "program", so we left it all mixed together.
The main.cpp file in the top directory is often the only "program"
part of the code (of course it could reference arbitrary other source and
header files if it helped break up a larger project). At a minimum it must
declare an int main(void) function; our
main.cpp.example files takes on a structure identical to Arduino
"sketches" with setup() and loop() functions.
A second layer of confusion is the separation between the
libmaple/ directory and the wirish/ directory. The
libmaple/ directory contains our low-level, C-only library for
accessing STM32 hardware peripherals. The wirish/ directory
contains C++ code implementing the "Arduino programming language" (called
Wiring); our implementation is not 100% compatible, it's just "Wiring-ish".
When we casually refer to "libmaple" we usually mean both parts together. As
you may imagine, mixing C and C++ code together so close to the metal can get
pretty sticky; if you look through our code there are lots of
#ifdefs and other nonsense to ensure the compiler doesn't throw up
on it.
A last, important chunk of libmaple which isn't immediately obvious are the
linker scripts in support/ld/ which are essential for actually
building binary files. Hopefully you won't have to modify those unless you're
porting the entire library, through it can be educational to read through the
interrupt jump table.
The Makefile can build and upload to RAM or FLASH; the RAM target
is useful for rapid development because it uploads a little faster and doesn't
burn up FLASH write cycles, but programs in RAM won't persist after a power
cycle and there is significantly less memory available for more elaborate
programs. The target is determined by an environment variable,
MAPLE_TARGET) which defaults to FLASH. It can be modified by
editing the Makefile, specifying in the command (eg, make
MAPLE_TARGET=ram), or with the ram and flash
targets, which modify the environment variable locally. The make
sketch (or just make) target just builds .bin files;
make install will build and upload the program. If you forget you
can just make help, which dumps a table of targets. You might
also find the make cscope or make ctags targets
helpful as well if you use those tools.
About this Document
A more recent version of this document may be available from the LeafLabs website. Our documentation is versioned on github; you can track changes to the master branch at this link.
This documentation is released under a
Creative Commons Attribution-Share Alike 3.0 license.
Translations are welcomed; give us a ping to make sure we aren't in the process of revising or editing first.
About
Contact
Community
Distributors
Licensing
Feeds
Search
Contact webmaster@leaflabs.com with website issues
Powered by WordPress, nginx, Linux, vim, and coffee.
This site intended to be valid HTML 4.01 Strict. Best viewed with any standards-compliant browser.
Copyright LeafLabs LLC, 2009-2010, a member of the
Green Street Space.
Unless otherwise noted all content on this website is released under the
Creative Commons Attribution Licence 3.0
Hello Anonymous! Login?
