This page is for those who want to develop software for the Arduino ATmega328-based microcontrollers using OpenBSD, but don't want to use (or cannot use) the Arduino IDE. In contrast to the instructions for FreeBSD, this page will set up your environment to be able to use and take advantage of the Arduino progamming language. (These instructions may also work to some degree for other BSDs, but I have not tested on anything other than OpenBSD.)
As of this writing (4.6-CURRENT, 12/20/2009), only a few packages need to be installed outside of what comes with the base system:
| avr-binutils-2.19.1 | Atmel AVR 8-bit RISC microcontrollers' GNU binutils | |
| avr-gcc-4.2.2p2 | Atmel AVR 8-bit RISC microcontrollers' XGCC | |
| avr-gdb-6.3p3 | Atmel AVR 8-bit RISC microcontrollers' GNU gdb | |
| avr-libc-1.6.7 | libc for Atmel AVR 8-bit RISC microcontrollers | |
| avrdude-5.8p0 | AVR microcontroller hardware in-system programmer |
Note: The version numbers you see may be different than those listed here. If the versions you see are earlier than those listed, you should update to the latest version of each of these packages.
Note 2: For those who notice that the avr-gcc package is still at 4.2.2, it seems that the version of this package in ports does in fact recognize the ATmega328. At least, this post makes it sound like avr-gcc should not have compiled any of the code below, but I can attest that it did compile, and ran successfully, on a Duemilanove board with an ATmega328 microcontroller. I'm also new to this, so please correct me if I'm wrong.
Install the packages like this:
~ $ sudo pkg_add -i avr-binutils avr-gcc avr-gdb avr-libc avrdude subversion
(Properly configuring the PKG_PATH with a suitable package mirror is left as an exercise for the reader. I suspect if you not only have OpenBSD installed, but want to use it as a development platform, you'll already have this set up.)
I snuck another package into that last command: subversion. You'll need this to get the Arduino core files in a bit.
Let's take some time out to go over the command-line convention used in this document. First, note that the prompts are in the format
curDir $ someCommand
where curDir is the current directory, $ is the prompt, and someCommand is the command to run.
If the command is preceded by "sudo", this means that the command must be run with root privileges. Be sure to have sudo(8) set up correctly, or use su(1) to become root and then issue the command as root.
Finally, if a command continues on to the next line, it will be indicated by a trailing backslash (\) at the end of the line(s).
With that out of the way, let's set up the environment.
First, create a directory structure for your Arduino projects. I keep all of my code in subdirectories under a directory aptly-named code, but you could put it anywhere. We also need a place to put the Arduino programming language core library source files. We'll create a directory called "libs", and under that we create a directory structure that mimics the directory structure of the Arduino googlecode project (note that the Arduino svn repo directory structure was altered slightly, so "mimics" is a good word to use here...). We can create everything with one command:
~ $ mkdir -p ~/code/arduino/{projects/,libs/hardware/cores/}
Now we need to fetch the most current Arduino core source files. The following command will check these files out into a subdirectory called arduino in the directory structure we created above:
~ $ svn co http://arduino.googlecode.com/svn/trunk/hardware/arduino/cores/arduino \ ~/code/arduino/libs/hardware/cores/arduino A /home/user/code/arduino/libs/hardware/cores/arduino/wiring_private.h A /home/user/code/arduino/libs/hardware/cores/arduino/pins_arduino.h A /home/user/code/arduino/libs/hardware/cores/arduino/wiring.c A /home/user/code/arduino/libs/hardware/cores/arduino/Print.h A /home/user/code/arduino/libs/hardware/cores/arduino/HardwareSerial.h A /home/user/code/arduino/libs/hardware/cores/arduino/WProgram.h A /home/user/code/arduino/libs/hardware/cores/arduino/wiring.h A /home/user/code/arduino/libs/hardware/cores/arduino/WInterrupts.c A /home/user/code/arduino/libs/hardware/cores/arduino/wiring_pulse.c A /home/user/code/arduino/libs/hardware/cores/arduino/WConstants.h A /home/user/code/arduino/libs/hardware/cores/arduino/WMath.cpp A /home/user/code/arduino/libs/hardware/cores/arduino/wiring_analog.c A /home/user/code/arduino/libs/hardware/cores/arduino/main.cpp A /home/user/code/arduino/libs/hardware/cores/arduino/binary.h A /home/user/code/arduino/libs/hardware/cores/arduino/pins_arduino.c A /home/user/code/arduino/libs/hardware/cores/arduino/Makefile A /home/user/code/arduino/libs/hardware/cores/arduino/Print.cpp A /home/user/code/arduino/libs/hardware/cores/arduino/wiring_digital.c A /home/user/code/arduino/libs/hardware/cores/arduino/wiring_shift.c A /home/user/code/arduino/libs/hardware/cores/arduino/HardwareSerial.cpp Checked out revision 808.
Note that you can keep this directory in sync with the source by issuing the following command every so often in the ~/code/arduino/libs/hardware/cores/arduino/ directory:
~/code/arduino/libs/hardware/cores/arduino $ svn up
After compiling things a few times, you'll probably start to tire of seeing some of the compiler warnings about implicit casts, the new location of delay.h, etc. While this is not necessary, you can apply the patch below to the source you just checked out:
~/code/arduino/libs/hardware/cores/arduino $ patch -p0 < ~/arduino_core.patch
The patchfile: arduino_core.patch.txt
Note that this patch has been submitted upstream.
A template Makefile is included in the arduino directory we downloaded above, but it doesn't work out-of-the-box for OpenBSD's version of make(1)--it is for the GNU version of make, which is not included in the OpenBSD base system. Instead of downloading and installing yet another package, just download a version of the stock Makefile that has been tweaked to work with OpenBSD's make(1):
~ $ ftp -o ~/code/arduino/libs/hardware/cores/arduino/BSDmakefile \ https://www.crosse.org/svn/arduino/libs/hardware/cores/arduino/BSDmakefile Trying 2001:470:8:1ee:20c:29ff:fee1:a7a2... Requesting https://www.crosse.org/svn/arduino/libs/hardware/cores/arduino/BSDmakefile 100% |**************************************************| 7484 00:00 7484 bytes received in 0.00 seconds (2.50 MB/s)
For your convenience, the BSDmakefile is also attached to this wiki article.
Open that file up in your favorite editor and ensure that the first few variables listed suit your environment. The stock file will work for an Arduino Duemilanove (ATMega328) board. You may have to play with the PORT variable, depending on your computer. Everything else should be okay if you're following these instructions. If you are using different paths for your projects directory, or if you have placed the Arduino core source files somewhere different, be sure to edit the file to reflect their placement in your system. In addition, if you use arduino_core.patch.txt, you will need to edit BSDmakefile and change "main.cxx" to "main.cpp"
Of course, if you just want to use the stock Makefile, go ahead and install the gmake package.
For vim users, get a vim syntax highlighting file for PDE files. Read "Syntax file for Arduino .PDE files" for more information. I'm sure there are extensions for other editors as well. If you are not using vim, feel free to skip this section.
First, create the appropriate folder to hold the syntax file (if it doesn't already exist) and download it:
~ $ mkdir -p .vim/syntax ~ $ ftp -o .vim/syntax/arduino.vim \ "http://www.vim.org/scripts/download_script.php?src_id=10674" Trying 216.34.181.97... Requesting http://www.vim.org/scripts/download_script.php?src_id=10674 100% |**************************************************| 1595 00:00 1595 bytes received in 0.00 seconds (2.62 MB/s)
Next, create the filetype.vim file (or add to it if you already have one). Mine looks like this:
~ $ cat ~/.vim/filetype.vim
" local filetype file
" loads various extra filetypes
if exists("did_load_filetypes")
finish
endif
augroup filetypedetect
au! BufRead,BufNewFile *.pde setfiletype arduino
augroup END
Now that you have the environment set up, the Arduino core files downloaded, and a place to put all your projects, let's create one!
~ $ cd ~/code/arduino/projects/ ~/code/arduino/projects $ mkdir helloworld ~/code/arduino/projects $ cd helloworld/
Copy the BSDmakefile we downloaded earlier into your new project directory:
~/code/arduino/projects/helloworld $ cp ../../libs/hardware/cores/arduino/BSDmakefile ./
Create the "helloworld.pde" file (ensure that your pde file always bears the same name as the project directory--this is how the makefile knows what to compile!):
~/code/arduino/projects/helloworld $ cat helloworld.pde
// helloword.pde
//
// A simple test sketch that blinks the on-board LED,
// or any LED connected to digital pin 13.
// The pin to manipulate.
int digitalPin = 13;
void setup() {
// Set the pin as an output pin.
pinMode(digitalPin, OUTPUT);
}
void loop() {
// Set the pin HIGH
digitalWrite(digitalPin, HIGH);
// Wait for a second
delay(1000);
// Set the pin LOW
digitalWrite(digitalPin, LOW);
// Wait for another second
delay(1000);
}
Now, compile the project. The makefile will compile the core.a Arduino library file as well, just like the Arduino IDE would.
~/code/arduino/projects/helloworld $ make [lots of compiling, linking, etc., happens here]
If there were any errors, correct them and re-run the make command.
If you get the error
applet/core.a(Print.o):(.data+0x6): undefined reference to `__cxa_pure_virtual' *** Error code 1 Stop in /home/seth/code/arduino/projects/temperature (line 202 of BSDmakefile).
you will need to add the following code to your PDE file:
extern "C" void __cxa_pure_virtual(void) {
while(1);
}
Want more information about this error? Search the internet for the function name, or have a look at this post. The problem here is that, as someone put it, the avr-libc implementation is sort of "swiss-cheesed" in that it does not include all of the functions that the full libc/glibc does (in this case, the the __cxa_* functions defined in /usr/include/g++/cxxabi.h). This is not only an issue with OpenBSD, but happens on other platforms as well, whether using the stock Makefile or the modified BSDmakefile above.
Once you have a working sketch (or at least one that compiles!), connect your Arduino to your computer and upload the new project. (Note the use of sudo in the following command):
~/code/arduino/projects/helloworld $ sudo make upload
/usr/local/bin/avrdude -V -F -C /etc/avrdude.conf -p atmega328p -P /dev/cuaU0
-c stk500v1 -b 57600 -U flash:w:applet/helloworld.hex
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.05s
avrdude: Device signature = 0x1e950f
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "applet/helloworld.hex"
avrdude: input file applet/helloworld.hex auto detected as Intel Hex
avrdude: writing flash (1184 bytes):
Writing | ################################################## | 100% 0.62s
avrdude: 1184 bytes of flash written
avrdude: safemode: Fuses OK
avrdude done. Thank you.
Note: The reason that you have to run the make upload command using sudo(8) (or as root) is because the avrdude command requires access to the COM port, which normal users cannot access. If you do not want to have to remember to run the command as root (or via sudo(8)) every time, you can set the setuid(2) bit on the avrdude executable, like so:
~ $ sudo chown root /usr/local/bin/avrdude ~ $ sudo chmod 4755 /usr/local/bin/avrdude
Note that you should only run the above commands if you know what they do and are okay with another setuid(2) binary on your system. Standard disclaimers apply.
You can checkout the example sketches like this:
~ $ svn co http://arduino.googlecode.com/svn/trunk/build/shared/examples \ ~/code/arduino/libs/build/shared/examples
And keep them updated with:
~/code/arduino/libs/build/shared/examples $ svn up
With this setup, you should now be able to download and run any of the Example sketches from Arduino's site, plus create and edit your own projects that utilize the Arduino progamminng language extensions to C/C++, using OpenBSD.