Program in C?  (Without using IDE, etc)

I’ve just started playing around with an Arduino board, and have one really pressing question: is there any information on how to write normal C programs, cross-compile them, and upload to the board? That is, to eliminate the IDE entirely?

I’ve found some info on the Wiki about using the command line, but that just seems to replace the IDE with a rather complicated Makefile. I can probably decipher this if I need to, but would rather spare myself the effort if someone has already done it.


If you want to eliminate the Arduino IDE, have a look at AVRfreaks.



the ide does that... arduino programs are C/C++ programs. after you press the upload button you can see all the c files in the sketch folder.


Unfortunately, I do not play well with IDEs. I have my preferred editor, which I've used for many years and extensively customized. Using it I can write code without having to think at all about the mechanics of editing.

The IDE, by contrast, takes about a minute to load, displays code as black text on a glaring white background in a font that's too small to read easily, does syntax colorization... And that's just what I've noticed while trying to compile the blink program from the examples - I haven't even tried to actually write anything yet.

I'm sure that with some effort I could fix most of those problems by figuring out what changes to make in the preferences file, but why should I do all that work to set up & learn a tool for something that's an occasional hobby? Much more effective, I think, to figure out how to do it with the tools I'm familiar with.

PS: Oh, yeah. Forgot to mention that a lot of the IDE prompts &c are in French, but that's a Java problem - happens with most Java programs.

sure you can. you’ll use avr-gcc to compile your code, and avrdude to program it into the chip.

if you are on a linux box, there is likely a package for avr-gcc and avrdude. on debian, type ‘apt-get install gcc-avr avrdude’.

if you are using a mac, install crosspack from <link removed, see below>. that will give you avr-gcc and avrdude.

if windows, see the above link to winavr.

in addition to all of the stuff over at avrfreaks, be sure to also check out the procyon avrlib. .

I went this route for about 2 years, but i’ve finally decided to use the arduino API, as its so much more productive, and the community has really matured a lot.

of course, you can also go with some sort of half-way solution. the “sketch” files (*.pde) appear to be just plaintext cpp files, so you can edit them directly with your favorite editor.

also, when you click the ‘verify’ button, the hex gets compiled in a /tmp directory. so you could use the arduino API to compile your hex code and then load it onto your atmel chip with an ISP programmer (doesn’t have to be an arduino).

here are the links (the BB apparently doesn't allow you to post a link in your first forum post. guess that's a spam thing).


procyon lib:

sure you can. you'll use avr-gcc to compile your code, and avrdude to program it into the chip.

Sure, but that leaves me doing things like figuring out how to use avrdude, finding all the support code (e.g. the pinMode, DigitalWrite, and delay functions from the Blink example) and compiling that into a library. Nothing that I couldn't do, given time, but if someone's already done it (and written a good set of instructions), I'd be just that much ahead.

Thanks for the links. I run Linux, so the crosspack one probably won't be useful, but the procyon one surely will.

The recipe for C programming for me is this : WinAvr also Procyon AVR Library come in handy as it is very feature rich and a good starting point to see some code examples. As for an IDE... I tend to use one as it makes it easy for me to find/replace, syntax highlighting etc... You can use Microsoft visual C++ express edition in the visual studio (there you create a Makefile project ). You can also use Eclipse. In Eclipse under linux you can easily incorporate flashing of the device with avrdude. I usually use an AVRISP and the AVRStudio just for flashing the device. You can also configure the AVR Studio IDE and do your programming there with WinAVR. So... There are many ways - and all of them rather good. I have actually used all above ways in the past so if you decide on something let me know - I will be happy to provide details.


...figuring out how to use avrdude : Much more effective, I think, to figure out how to do it with the tools I'm familiar with.

Except that the only familiar tool here seems to be the editor. As you're noticing, there's a bit more that the IDE does beyond just providing an editor, even though the editor is the most clearly visible part of the IDE. I use a different editor for editing my sketches quite frequently, and I still use the IDE for the compile/upload/small fix part of the cycle. This works reasonably well, given a little care. If your IDE takes a minute to load and speaks in the wrong language, that's sort of a separate issue...

Have you looked at: and the parent pages?

(Alas, building code for microcontrollers seems to involve either quirky IDEs or complicated Makefiles...)

The IDE does approximately:

1) retain settings (Board, Serial Port, Library locations) 2) Edit 3) Pre-process 4) Compile libraries and core code. 5) Compile sketch (using avr-gcc or avr-g++ as appropriate, and based on settings.) 6) Link with libraries and core. (avr-gld) 8) upload (using avrdude, according to settings.) 7) convert to uploadable format (avr-objcopy)

All but step 3 have normal CLI equivalents, but the file locations are obscure and the options significant, so it's not like they'll be easy without doing a lot of additional setup (depending on your operating system, somewhat.) You can turn on the "verbose" flags in preferences to see most of what is happening. Here's a summary (from a Mac):

[Build/link libraries]
/Applications/arduino/arduino-0017/ -c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega168 -DF_CPU=16000000L -I/Applications/arduino/arduino-0017/ /Applications/arduino/arduino-0017/ -o/Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/pins_arduino.c.o 

[ Lots more library builds ]

[preprocess and build sketch]
/Applications/arduino/arduino-0017/ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega168 -DF_CPU=16000000L -I/Applications/arduino/arduino-0017/ /Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp -o/Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp.o 

/Applications/arduino/arduino-0017/ -Os -Wl,--gc-sections -mmcu=atmega168 -o /Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp.elf /Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp.o /Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/core.a -L/Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet -lm 

[reformat for upload]
/Applications/arduino/arduino-0017/ -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp.elf /Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp.eep 

/Applications/arduino/arduino-0017/ -O ihex -R .eeprom /Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp.elf /Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp.hex 

/Applications/arduino/arduino-0017/ -C/Applications/arduino/arduino-0017/ -v -v -v -v -pm168 -cstk500v1 -P/dev/tty.usbserial-A9005bXZ -b19200 -D -Uflash:w:/Users/billw/Documents/Arduino/-Blink-Variants-/Blink_c/applet/Blink_c.cpp.hex:i

Except that the only familiar tool here seems to be the editor.[\QUOTE]

Not really. That is, the particular tools may be new, but the general process is something I’m quite familiar with, even if I more often cross-compile stuff for a BlueGene than a microprocessor :slight_smile:

So if I look at your list, I get the following:

  1. retain settings (Board, Serial Port, Library locations) - becomes a few shell script line, so I type say “set-ard” when I want to work on it.

  2. Edit - Just like any other C code.

  3. Pre-process - This is the unfamiliar one, but I’m guessing it’s the process of turning a “sketch” into a real C program. If so, I’d much rather start with C.

  4. Compile libraries and core code. - done once, creates say “arduino.a”, which gets linked.

  5. Compile sketch (using avr-gcc or avr-g++ as appropriate, and based on settings.)

  6. Link with libraries and core. (avr-gld)

  7. convert to uploadable format (avr-objcopy) - which condenses to a few lines in a Makefile, so I “just type make”, or in my case hit the editor shortcut key, which conveniently lets me go to file:line of any errors, saving lots of time.

  8. upload (using avrdude, according to settings.)

All of which is to say, rather long-windedly, that I’ve been programming for long enough to know what works well for me. Other people may work better with IDEs: that’s why we have choices.


You say you're familiar with makefiles/compilers/etc, but your first message complained that the playground-documented techniques for compiler from the CLI were "rather complicated"??

Your choices are essentially:

Install a standard avr-gcc environment (winavr, etc, as people have been saying), and extract the arduino library sources to appropriate "standard" places for compiler/makefiles to access.

Install a standard arduino environment and extract the compiler/etc from it into standard binary locations so that it will run normally.

Either way, you'll have to learn enough about avrdude to use it to upload hex files to whichever variety of arduino you happen to have.

Either way isn't too hard, but will have a bit of a learning cliff before you can accomplish anything (unlike using the IDE.)

4) Compile libraries and core code. - done once, creates say "arduino.a", which gets linked.

This the the most serious "error" in your understanding. The libraries and core code needs to be recompiled each time you switch destination CPU type or clock speed. The IDE brute-forces this by recompiling libraries each time you change board types. and ALWAYS recompiles the core code each time you compile a sketch. I guess if you only have one arduino, only doing it once will last you quite a while...

You can suck over the arduino core and libraries without installing the full Arduino app.

Core: svn checkout

Libraries svn checkout

This the the most serious "error" in your understanding. The libraries and core code needs to be recompiled each time you switch destination CPU type or clock speed.

I wouldn't say that's an error. More like a reluctance to type a longwinded explanation. Of course you'd have to compile different libraries for different instruction sets, just as Linux has lib and lib64 versions of many libraries. But compiling/linking for different instruction sets really isn't a big deal. I'll grant that I don't know how much difference there is between the various Atmel processors, but as I only have one board at the moment that's not an issue. I'm also puzzled by your statement that I'd need to recompile simply on a change of clock speed...

It seems that most if not all the complexities could be rather easily handled with a few scripts, which would get me out of the two real problems: having to use the IDE editor, and writing "sketches" rather than real C programs. (It's a lot easier for me to write correct C than to remember rules for "almost C but not quite".)

In any case, we're wandering rather far from my original question, which wasn't "Is this a good idea?" (which I'd already answered to my own satisfaction before the post), but "Has anyone already done this, and wrote down simple instructions?". I guess the answer to the latter is no :-)

Thanks, James

I guess we're in violent agreement. You're basically looking for instructions on how to use the arduino libraries (and hardware) with a more traditional AVR development environment (WINAVR, etc.) As far as I know, no one has written anything along those lines. It'd end up being somewhat different for linux/macos/windows; there is a substantial possibility that the needed compiler versions (ie to support ATmegs328p) are not yet packaged in the binary distributions. Which OS are you using, anyway?

I've been a C programmer for 20+ years, and an emacs bigot for quite a bit longer, but I still find it useful to have the Arduino environment be COMMON across multiple OSes...

I'm using Linux - thought I'd mentioned that earlier. (Though I do tend to assume that anyone working with something like arduino is going to be using Linux, by default. Kind of the same principle, after all.) And I use only Linux, so the multi-OS isn't all that important, except in a backwards fashion. I want to use the Arduino to replace another board ("Handyboard") used in simple robotics projects, which isn't well-supported except on Windows, and only has an IDE instead of a good toolchain.

Try doing a forum search for "jbremnant tarball" and look at replies 116, 118, 122 and 124 of that thread and see if that's what you want.


I wrote several articles for Nuts&Volts about this topic, Smiley's Workshop 10, 11, 12 that can be gotten off my website

I kind of hesitate to recommend them though since one of the things I learned writing about this was that I found myself using the Arduino IDE exclusively for what Arduino is good at, and using AVRStudio for the things Arduino wasn't designed to do.

I've seen a lot of folks that seem to want it both ways, that is to make Arduino do everything the 'real' tools do and/or make the 'real' tools as easy to use as the Arduino. Frankly, the more I look at this concept, the less sense it makes.

Arduino is great for designers , newbies, hobbyists, etc. and even raggedy old engineers like me who just want to do a quick test of something simple. But for things it doesn't do easily, it just seems strange to try to bend it all out of shape and get folks all confused, when one could just switch over to AVRStudio/WinAVR/AVRDude.

Maybe I'm missing something.


Maybe I'm missing something.

Nope, you aren't missing a thing, you old fox ;)