I've been wanting to get into microcontroller programming for a while now, and last week I broke down and ordered components for a [breadboard Arduino][breadboard-Arduino] from [Mouser]. There's a fair amount of buzz about the [Arduino][] platform, but I find the whole [sketch infrastucture][sketch] confusing. I'm a big fan of command line tools in general, so the whole IDE thing was a bit of a turn off. Because the [ATMega328][] doesn't have a USB controller, I also bought a [Teensy 2.0][Teensy] from [PJRC][]. The Teensy is just an [ATMega32u4][] on a board with supporting hardware (clock, reset switch, LED, etc). I've packed the Teensy programmer and HID listener in my [[Gentoo overlay]], to make it easier to install them and stay up to date. Arduinos (and a number of similar projects) are based on [AVR][] microcontrollers like the ATMegas. Writing code for an AVR processor is the similar to writing code for any other processor. [GCC][] will cross-compile your code once you've setup a cross-compiling toolchain. There's a good intro to the whole embedded approach in the [Gentoo Embedded Handbook][handbook]. For all the AVR-specific features you can use [AVR-libc][], an open source C library for AVR processors. It's hard to imagine doing anything interesting without using this library, so you should at least skim through the manual. They also have a few interesting [demos][] to get you going. AVR-libc sorts chip-support code into AVR architecture subdirectories. For example, object code specific to my [ATMega32u4][] is installed at `/usr/avr/lib/avr5/crtm32u4.o`. `avr5` is the [AVR architecture version][arch] of this chip. Crossdev -------- Since you will probably not want to build a version of GCC that runs on your AVR chip, you'll be building a cross comiling toolchain. The toolchain will allow you to use your development box to compile programs for your AVR chip. On Gentoo, the recommended approach is to use [crossdev][] to build the toolchain (although [crossdev's AVR support can be flaky][bug147155]). They suggest you install it in a [stage3 chroot to protect your native toolchain][chroot], but I think it's easier to just make [[btrfs]] snapshots of my hard drive before doing something crazy. I didn't have any trouble skipping the chroot on my sytem, but your mileage may vary. # emerge -av crossdev Because it has per-arch libraries (like `avr5`), AVR-libc needs to be built with [multilib][] support. If you (like me) have avoided multilib like the plague so far, you'll need to patch crossdev to turn on multilib for the AVR tools. Do this by applying Jess' [patch][multilib-patch] from [bug 377039][bug377039]. # wget -O crossdev-avr-multilib.patch 'https://bugs.gentoo.org/attachment.cgi?id=304037' # patch /usr/bin/crossdev < crossdev-avr-multilib.patch If you're using a profile where multilib is masked (e.g. `default/linux/x86/10.0/desktop`) you should use Niklas' [extended version of the patch][niklas-patch] from the duplicate [bug 378387][bug378387]. Despite claiming to use the last overlay in `PORTDIR_OVERLAY`, crossdev currently [uses the first][bug428420], so if you use [layman][] to manage your overlays (like [[mine|Gentoo_overlay]]), you'll want to tweak your `make.conf` to look like: source /var/lib/layman/make.conf PORTDIR_OVERLAY="/usr/local/portage ${PORTDIR_OVERLAY}" Now you can install your toolchain following the [Crossdev wiki][crossdev-avr]. First install a minimal GCC (stage 1) using # USE="-cxx -openmp" crossdev --binutils 9999 -s1 --without-headers --target avr Then install a full featured GCC (stage 4) using # USE="cxx -nocxx" crossdev --binutils 9999 -s4 --target avr I use `binutils-9999` to install live from the [git mirror][git], which avoids [a segfault bug in binutils 2.22][bug12161]. After the install, I was getting bit by [bug 147155][bug147155]: cannot open linker script file ldscripts/avr5.x Which I work around with: # ln -s /usr/x86_64-pc-linux-gnu/avr/lib/ldscripts /usr/avr/lib/ldscripts Now you're ready. Go forth and build! Cross compiler construction --------------------------- Why do several stages of GCC need to be built anyway? From `crossdev --help`, here are the stages: 0. Build just binutils 1. Also build a bare C compiler (no C library/C++/shared GCC libs/C++ exceptions/etc…) 2. Also build kernel headers 3. Also build the C library 4. Also build a full compiler [breadboard-Arduino]: http://arduino.cc/en/Main/Standalone [Mouser]: http://www.mouser.com/ [Arduino]: http://arduino.cc/ [sketch]: http://arduino.cc/en/Guide/Environment [ATMega328]: http://www.atmel.com/devices/atmega328.aspx [Teensy]: http://pjrc.com/teensy/ [PJRC]: http://pjrc.com/ [ATMega32u4]: http://www.atmel.com/devices/atmega32u4.aspx [AVR]: http://en.wikipedia.org/wiki/Atmel_AVR [GCC]: http://gcc.gnu.org/ [handbook]: http://www.gentoo.org/proj/en/base/embedded/handbook/ [AVR-libc]: http://www.nongnu.org/avr-libc/ [demos]: http://www.nongnu.org/avr-libc/user-manual/group__demos.html [arch]: http://www.nongnu.org/avr-libc/user-manual/using_tools.html#using_avr_gcc_mach_opt [crossdev]: http://en.gentoo-wiki.com/wiki/Crossdev [bug147155]: https://bugs.gentoo.org/show_bug.cgi?id=147155 [chroot]: http://www.gentoo.org/proj/en/base/embedded/handbook/?part=1&chap=2#doc_chap1 [multilib]: http://www.gentoo.org/doc/en/gentoo-amd64-faq.xml#multilib [multilib-patch]: https://bugs.gentoo.org/attachment.cgi?id=304037 [bug377039]: https://bugs.gentoo.org/show_bug.cgi?id=377039 [bug428420]: https://bugs.gentoo.org/show_bug.cgi?id=428420 [layman]: http://layman.sourceforge.net/ [crossdev-avr]: http://en.gentoo-wiki.com/wiki/Crossdev#AVR_Architecture [git]: http://sourceware.org/git/?p=binutils.git [niklas-patch]: https://bugs.gentoo.org/attachment.cgi?id=285901 [bug378387]: https://bugs.gentoo.org/show_bug.cgi?id=378387 [bug12161]: http://sourceware.org/bugzilla/show_bug.cgi?id=12161 [link]: http://en.gentoo-wiki.com/wiki/Paludis/AVR_Crossdev#Post-install [bug147155]: https://bugs.gentoo.org/show_bug.cgi?id=147155 [[!tag tags/C]] [[!tag tags/hardware]] [[!tag tags/linux]] [[!tag tags/programming]]