Codeblocks+AVR+ARDUINO

This Tutorial explains how to use Codeblocks with the avr-gcc compiler and avrdude, also it explains how to implementing the Arduino libraries in your project.

HOW TO USE CODE BLOCKS WITH AVR + ARDUINO

Introduction

Why would you want to use the Arduino library with another IDE? It helps organize your code (especially for large projects), is easier to implement other code not written specifically for Arduino and can be a gateway to more powerful programming tools and techniques.

To program and use Arduino libraries on the ATMEGA chip you need to set up a tool chain to:

  • 1. Write the code
  • 2. Compile the code
  • 3. Transfer the code to the chip

To do this I used:

  • 1. CodeBlocks IDE to write the code using their ATMEL project Wizard.
  • 2. I used the avr-gcc binutils tool chain to compile the code and debugging.
  • 3. I use the AVRDUDE programmer to take the compiled program and transfer it onto the chip with the AVRISPMKII.

There are many tutorials out there so this overview provides a overview with links already existing documentation. It then goes into detail documenting the steps to get the arduino library running with codeBlocks .

Overview of AVR programing

A overview of how code runs on the microcontroller:

The ATMEL microcontroller is a solid state device that performs tasks based on a set of INSTRUCTIONS. The basis of these instructions are a series of physical logic circuits built into the chip. Each of these circuits produces a known output when triggered, changing state by either storing a charge or dissipating one. For instance there are circuits that store numbers as a series of 1's (stored charge) and 0's (dissipated charge) these stored values can be combined to get a new number (addition or subtraction) according to how the physical gates in the microcontroller react to changes in voltage.

These physical operations when grouped together to perform a specific logical task are called an INSTRUCTION.

These instructions are documented for each microcontroller, Atmel's instruction set can be found here:

www.atmel.com/atmel/acrobat/doc0856.pdf

Each one of these circuits behaviors (instructions) can be set with a series of stored binary “numbers” in the microcontroller, in essence creating what is the program. A program is then just a series of instructions which execute one after another from memory. This is where human readable code and the programing tools come in, they provide a method for the user to describe a instruction pattern for the physical hardware, in human readable form. It is the link between the physical of voltage patterns in the microcontroller and our ideas based on language constructs.

So to program the chip, we must have a way of writing a text file so that a program (the compiler) can understand our logical requests and translate them into physical changes on the chip.

What this means is that we can use any text editor to write code as long as you can save the file with a .C extension for the compiler to understand. The compiler then takes that file and turns it into machine code, which you can burn onto your chip.

Below are good overviews/tutorials on getting the tools needed to work with Atmel chips on your platform.

First place to go:

http://www.nongnu.org/avr-libc/

Avr freaks for general questions: 

http://www.avrfreaks.net/

If you use linux:

http://electrons.psychogenic.com/modules/arms/art/3/AVRGCCProgrammingGuide.php

For mac:

http://www.obdev.at/products/crosspack/index.html

For general starter overviews:

http://imakeprojects.com/Projects/avr-tutorial/

http://www.avr-asm-tutorial.net/avr_en/

http://www.ladyada.net/learn/avr/

What is the Arduino core library

In order not to rewrite code over and over, previously written code is turned into LIBRARIES which can be reused in different programs. These libraries allow you to say things like “printf(a num is %d, 200)” to print a string with a number or “Serial.prinln(“hello world”) for Arduino.

The compiler is the one who uses these libraries to add extra functionality which has already been written for the device. What the compiler does is first check the newly written code “myTextFile.C” for all function names used in that specific file, in order to see what operations to perform. If it doesn't find the function definition in the current file, it bookmarks the name for when the file is LINKED with an outside library. It then looks up the name of the function in the linked libraries and translates that operation into a instruction set.

To get extra functionality from the ATMEL chips, a reduced c standard library was
made to be compatible with AVRs it is found at:

http://www.nongnu.org/avr-libc/

Full documentation of the available functions you can use and also a lot of information on general topics like creating libraries ect. can be found at the above link. The second library is the ARDUINO core library which has taken a lot of the functionality from avr-libc and wrapped it in even easier function calls. Under the below topic Arduino libraries It goes into how to use that library with an atmel chip.

What tools do you need?

The below tools are programs like Arduino which compile and link your code. You open and run them by just typing their names on the command line in a UNIX shell. The shell looks in your systems ”/bin” directory to run them according to your $PATH enviornment variable. The avr-libc is the library that gives you all the functionality for the AVR chips and is located in the ”/lib” folder.

If your on windows you can use WinAvr or avrStudio from atmel, there are many
tutorials already on that subject if you google.
If your running Linux you will either need to compile form source 
(can be a real pain) or RPM/yum these packages (or their latest versions):

avr-binutils-2.14-1

avr-gcc-3.3.2-1

avr-g++-3.3.2-1

avr-gdb-6.8-1

avr-libc-1.0.2-1

avr-libc-docs

On a Mac OSX just go to:

http://www.obdev.at/products/crosspack/index.html

and download the package (I have tried it and it works well)

If you do compile from source I suggest compiling only the modules you need for the gcc compiler EG. gcc-core gcc-g++. It takes much less time and there is a greater chance of successes.

These are good links that explain the installation and set up of the tools for

Linux/UNIX: 

http://electrons.psychogenic.com/modules/arms/art/3/AVRGCCProgrammingGuide.php

http://www.nongnu.org/avr-libc/user-manual/install_tools.html

for mac:

http://www.ladyada.net/learn/avr/

You then need a text editor to write your code in. The editor can provide different editing functionality(code completion, file organization) and provide a way to use all the command line tools in a automated manner you could use:

Eclipse: 

http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin

which is a good open source tool written in JAVA.

VI / VIM:(I use this a lot it is very powerful) 

A powerful command line editor with syntax highlighting

or

CodeBlocks: 

www.codeblocks.org

CodeBlocks is cross platform, has a built in AVR wizard to help set up projects and is open sourced in C++. I also find the menus and build options better organized for C projects than eclipse.

Then you need a way to actually get the program on the chip (a programmer) and a application to talk to the programmer (a downloader).

I use AVRDUDE which is a open source downloader available here:

http://savannah.nongnu.org/projects/avrdude/

You need to download it and install it like the rest of the programs, which should be cover in the above links.

I then use the AVRISPMKII (the programmer) to upload the code onto the chip. The AVR wiki page has a good listing of the downloaders that are available. Atmel has ones you can buy, there are also many open sourced programmers out there AVRDUDE supports most that I have seen.

http://en.wikipedia.org/wiki/Atmel_AVR

How to set up Arduino library

To use the Arduino library you have to know what libraries and header files are ( files that allow you to access the library's functions).

This is a great tutorial of what a library is and how to make one:

http://www.nongnu.org/avr-libc/user-manual/library.html

If you don't know what a header file is here is a good overview:

http://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

Once you understand what a header file does you are ready to get and use the Arduino Library. First thing is to get the right Arduino library for your chip and put it into a folder with all the header files you will need. Below are good tutorials that walk you through the how and why of this:

Here are a couple tutorials on the Arduino site that documents 
the process of finding and using the Arduino library:

http://www.arduino.cc/playground/Code/Eclipse

The method I use follows:

0.You get the core.a library first from the applet folder Arduino makes when 
you compile a program for a specific chip. So you need to pick any program example 
from the example sketches like the BLINK example and open it.

1.In the Arduino environment-> Choose
TOOLS->BOARD->Arduino....w/ATmega168 (or whatever chip you want to use)

2.Then go and hit the upload button WITHOUT THE PROGRAMMER CONNECTED this 
will compile the Arduino library for the ATmega168 chip. (If you want 
to use a different chip just select it and recompile)

3.You then need to get the header files you will include in your Code Blocks 
(or whatever editor you use) program and the actual Arduino Library to link 
against. To do this you have to go to the applet folder of the project you 
just compiled. 

4.So if you were using the BLINK example: 
You would go into-> the Arduino BLINK folder->applet->core.a

5.Take the core.a file and make a copy of it (it is the library), 
then create a separate folder anywhere you want (but have it relevant to where 
you want to save your projects) 
something like: /home/ME/AVR/ArduinoLibrary/core.a

6.Next you need to get the header files for Arduino they are located: 
arduino-0017/Hardware/cores/ (then copy all files that end with a .h)

7.Put all the copied header files into the same folder you put the core.a files in: 
/home/ME/AVR/ArduinoLibrary/(core.a + all.h files)

What you just did is compiled the Arduino Library for the ATmega168 chip. If you want to use another chip you have to select that one and recompile the code.This is because each chip has different functionality and hardware (num of pins ect.).

You are now ready to set up the code blocks environment.

Setting up Code Blocks.

This assumes you were able to install the GNU tool chain / Avrdude and they are installed in the correct directories. You also need the Arduino core.a library and header files in a accessible directory.

First lets get the editing environment set up. To get code blocks you can either download the source and build it yourself or get the binaries (pre-compiled for your platform).

They are both available here:

http://www.codeblocks.org/downloads

They have comprehensive instructions on their site and in their manual here:

http://www.codeblocks.org/user-manual

Code blocks provides a atmel wizard you can use to set up projects,to start a new AVR project you can go to:

File->New->project

Then choose the “AVR project” option.

This then puts you into the “AVR project Wizard” where you fill out the fields (they are pretty self explanatory).

First Screen:

Project title→AVRmyTest

(you can then choose a folder to keep all your projects in like:/home/YOURACCOUNT/AVR/CBProjects/) just a way to organize.

Then hit→next

Compiler configurations screen:

This is where your compiled code will be kept you can just hit →next unless you want to change something. *under compiler you should see “GNU AVR GCC compiler” if not you have to install the compiler, if it is installed you might have to manually set the compiler. It is covered in the “copy compiler” section of the code blocks manual it is also covered below.*

Choose a processor:

Then you specify the processor you are using EG. atmega168. The F_CPU option defines what the clock speed you are running the chip at, for almost all Arduino chips it is 16000000 (I think the liliyPad is 8000000 can't remember for sure). The other options can be unchecked except for the create hex files option. That is the file format of the executable code you actually load on the chip.

→finish

Post compiler options:

Once you set up the project you need to set the two different project build methods “DEBUG” and “RELEASE”. The debug option allows you to compile the code without loading it on the board, the release allows you to compile and load to the board for testing.

To get these going you have to set the “post compiler options” this is where the GNU TOOL CHAIN you downloaded gets called using the command line. It is the same as if you typed them yourself from the command line but the process is automated for you. To set up the debugger setting in codeblocks you select your project then go to:

project (at the top)->project setting->project's build options(at the bottom)

This should take you to the “project build options” screen. You then go to:

(in the tab's) "pre/post build steps"

Here is where you change the settings to build your code into a hex file and load it to the microcontroller. On the left should be three names your “project name”, “debug” and “release”. When you click on your project name under the “pre/post build steps” tab you should see something like this in the post build box:

avr-objcopy -O ihex -R .eeprom -R .eesafe $(TARGET_OUTPUT_FILE) $(TARGET_OUTPUT_FILE).hex
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma .eeprom=0 -O ihex \
$(TARGET_OUTPUT_FILE)     $(TARGET_OUTPUT_FILE).eep.hex

Those are the lines that take your complied “o” object file and using the options -O ihex turn it into a hex file which can be loaded onto your chip.

What you need to do is cut them form the overall “project name” and re paste them under “debug” and “release” then under just the release tab you need to put the command line that uses avrdude to upload the newly made hex file onto the chip:

avrdude -p m168 -c avrispmkII -P usb -U flash:w:$(TARGET_OUTPUT_FILE).hex

so overall the settings for your “pre/post build steps” tab should look like this:

“project name” selected

LEAVE BLANK

“debug” selected

avr-objcopy -O ihex -R .eeprom -R .eesafe $(TARGET_OUTPUT_FILE) $(TARGET_OUTPUT_FILE).hex
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma .eeprom=0 -O ihex\
 $(TARGET_OUTPUT_FILE) $(TARGET_OUTPUT_FILE).eep.hex

“release” selected

avr-objcopy -O ihex -R .eeprom -R .eesafe $(TARGET_OUTPUT_FILE) $(TARGET_OUTPUT_FILE).hex
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma .eeprom=0 -O ihex\
 $(TARGET_OUTPUT_FILE) $(TARGET_OUTPUT_FILE).eep.hex
avrdude -p m168 -c avrispmkII -P usb -U flash:w:$(TARGET_OUTPUT_FILE).hex

Next we have to define for the linker where the arduino library is located so it can find all of the function calls. This is set also under:

project(at the top)->project setting->project's build options(at the bottom)-> "Linker settings" tab

Once you are on the tab you have to put the full path of where the Arduino core.a library id located, for example:

/home/ME/AVR/ArduinoLibrary/

It can live anywhere as long as you tell Codeblocks where it is. When you finish code blocks will compile your code and create a hex file in debug and release mode. You could also leave the “debug” post compile options BLANK and build the hex file only when uploading with the “release” option but I like going through the whole build process. When you build and run the release target your code will be compiled AND Avrdude will upload it to your chip.

These are the few settings you need to change to get code blocks set up to run with your GNU toolchain.

GOTCHAS***
Adding a compiler with the copy compiler option, if it does not appear:

If for some reason (especially on a mac) the avr-gcc compiler is not detected you can go and manually add a compiler to your list. You can do this in code blocks by going to:

Settings (at the top)-> compiler and Debugger settings -> selected compiler -> copy

Then once you selected “copy” rename the compiler and go to the “tool chain executable” tab. Here you need to set all the tools you installed. They must be in a “bin/” directory under the main “compilers installation directory”. So if you installed all the tools under ”/home/ME” the executables need to be in ”/home/ME/bin/”.

You can also make a custom compiler to test non-standard settings if you want to test different avr-gcc build options out.*

Programmer set up ISPMKII

To set up the physical programmer you need to have an external power source (* the programmer will not work without an external power source*) and a way to attach the programmer to the board.

The manual can be found here:

www.atmel.org/dyn/resources/prod_documents/AVRISPmkII_UG.pdf

You need to find the corresponding pins on the ATMEL chip, they are documented in the manual:

www.atmel.com/dyn/resources/prod_documents/doc2545.pdf

and the arduino pins are listed in this diagram:

http://www.vintagecomputercables.com/arduino/img/new_arduino_pin_mapping.jpg

Below is a schematic of the programmer circuit I used for the ATMEL 168MEGA:

To use the AVRISPMKII you need to have AVRDUDE set up on your computer, If you went through the above steps you should be ok.The programmer uses the ISP protocol utilizing th MOSI, MISO, SCK pins on the ATmega168 here is a

Overview of In System Programing:

http://en.wikipedia.org/wiki/In-System_Programming

To check if your computer can talk to the programmer you have to apply power to the chip and plug in the programmer to your usb port. Then to test if you can talk you can then type:

avrdude -c avrispmkII -P usb -pm168

on the command line. If your programmer is recognized you should get this response:

avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e9406
avrdude: safemode: Fuses OK
avrdude done. Thank you.

If you get anything else check the power and the pins and try again there is general debug information in the manual.

         Problem                       Reason                    Solution 
1 Can't connect to AVRISP       USB hub cannot provide      The AVRISP mkII requires an 
  mkII from PC.                 enough power.               active/self-
                                                            powered USB hub, i.e deliver 
                                                            500mA.
2 Can't connect to AVRISP       USB driver is not installed Install USB driver as described 
  USB status LED is not lit,                                in USB Setup mkII from PC,
  and point 1 is OK.                                        the green properly.
3 AVRISP mkII status LED        ISP cable is not mounted    Check that the red stripe on 
  is blinking orange.           correctly                   the cable is mating pin 1 on the 
                                                            ISP header.
                                 
                                                          

4 AVRISP mkII status LED       There is a problem on the    Check that the reset has 
  is blinking orange in spite  reset line.                  a proper pull-up.
  of correct ISP cable
  connection.                                               Read more about Reset line.
  
 
5  AVRISP mkII reports          The ISP cable is not        Check point 3, and check for 
   short-circuit on the target. mounted correctly, or       short circuits.
   some of the target pins      Also check that the pullup  on the
                                are shorted to GND or       target lines further details in
                                VCC, or they are too        are not to strong. See Target Interface.
                                heavily loaded.                         
                             
                                                          
                              
6  Can't detect target        The SPI interface on the    If the ISP interface is disabled by fuse
   fuses.                     target is disabled          settings, one have to use another
                              because the SPI fuse is     programming interface to reset these  
                              not programmed, and/or      Check the device datasheet for further
                              RSTDSBL or DWEN fuse        details on fuse settings and programming 
                              is programmed.              interface.
                                                          STK500 can be used for High Voltage
                                                          Parallel Programming, and JTAGICE mkII
                                                          can be used for JTAG programming.

7  Detects target, but can't    The ISP frequency is      Lower the ISP frequency. The ISP
   enter prog mode or           high.                     frequency is dependent on the 
   programming fails.                                                       target clock.
                                                          Read more
                                                          about this in the Board section.

Avrdude overview of commands:

There are many commands for avrdude they are documented here:

http://www.nongnu.org/avrdude/user-manual/avrdude_4.html

There are also a bunch of in depth tutorials out there:

http://electrons.psychogenic.com/modules/arms/art/14/AVRFusesHOWTOGuide.php

http://www.ladyada.net/make/usbtinyisp/avrdude.html

Also to find what command line arguments to give avrdude there is this very helpful applet:

http://www.engbedded.com/fusecalc

Writing the code and uploading

WRITE THE CODE AND UPLOAD: Now we can burn the final settings onto the chip to get it ready to program. We set the avrdude options above in code blocks:

avrdude -p m168 -c avrispmkII -P usb -U flash:w:$(TARGET_OUTPUT_FILE).hex
To upload the compiled hex file onto the board an overview of those commands are:
 -p -> sets what chip to use
 -c -> says what programmer you are using
 -P -> tells what port
 -U -> the option where you can write or read a memory space

But before we can use that to upload code for the first time onto the chip, we need to set all the general configuration properties of the chip were using (like clock speed, brown out detection ect.).

So before we upload we need to set the chip to:

  1. Use our external full swing crystal
  2. Set the clock speed accordingly (16000000)
  3. Not to internally divide the clock
  4. Set the brown out detection
  5. Set the boot size
  6. (we get all these settings for the chip by reading the ATmega manual)

To find out what option to give avrdude you can look them up in the manual: http://www.nongnu.org/avrdude/user-manual/avrdude_4.html

or use the online calculator:

http://www.engbedded.com/fusecalc

and we get:

-U lfuse:w:0xc7:m -U hfuse:w:0xdd:m -U efuse:w:0xf9:m

Each one of these -U option commands takes a fuse block “lfuse” and writes “w” a setting “0xc7”. We then have to program the chip ONCE with these settings before we can start uploading code so we connect and power up our board, then open a command line and type: avrdude -U lfuse:w:0xc7:m -U hfuse:w:0xdd:m -U efuse:w:0xf9:m

Your chip is now ready to be programmed using the codeblocks settings we already made.

So go back to your project in Code Blocks and create a new file:

file->new-file

Then select a C++ file and follow the wizard, setting it for “debug” and “release” and the location of the file on your computer.

Then right or (Ctrl) click on the main.c file and say remove from project.

Next you have to add all the Arduino header files to your project so the complier knows where to look for your functions.To do this you go to:

project-> addfiles

Then navigate to the folder that holds all the arduino .h files and select all of them and press ok.

You are now ready to write your code. There are a couple main differences between arduino and programing with straight C++ here is a sample hello arduino code you can use.

extern "C" void __cxa_pure_virtual(void); //for C++ defines
 
void __cxa_pure_virtual(void) {};
 
 
 
#include "../ArduinoLIB/WProgram.h" //import main Arduino header file
 
 
 
int main(){
 
    init(); //Don't forget this!
 
    pinMode( 6,OUTPUT);
 
 
 
    while(1){
 
    digitalWrite(6,HIGH);
 
    delay(1000);
 
    digitalWrite(6,LOW);
 
    delay(2000);
 
    }
 
}

The first lines you have to add into all your C++ projects to avoid linking errors. They define a function which is defined elsewhere in the library.

extern “C” void cxa_pure_virtual(void); void cxa_pure_virtual(void) {};

more info on this here:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=457778

Then this line is used to get the main header file which contains all the other header files for the Arduino library. The path has to be relative to where the source file is so ../ (one directory up) then in /ArduinoLIB/ is where to find the WProgram.h. And be sure to use the double quotes to indicate a local include.

#include ”../ArduinoLIB/WProgram.h”

main()is the beginning of the program, it is where you do things you normally would do in setup(). Everything here gets done once before it goes into into the while(1) loop. The while loop replaces the loop() in arduino and will execute over and over, you do not want to do a return statement from main because there is nowhere to go!

int main(){

This last bit is a very important Arduino function which needs to be called before anything else from the arduino library. It initializes all the functions which relate to timing in Arduino like Delay() or Serial.begin(), so it is very important you call this first.

init();

That is it, once you type the code in, save it, select “release” hook up the programmer turn the power on then hit the “compile and run” button. The code should compile and load up to your chip. The led or whatever you put on pin 6 should be turning on and off!

programing help + links

Programing help + links Here is a reference to all the useful links I have found:

AVR::
LIBRARY

http://www.nongnu.org/avr-libc/

GENERAL INFO

http://www.nongnu.org/avr-libc/

http://www.avrfreaks.net/

http://electrons.psychogenic.com/modules/arms/art/3/

http://www.ladyada.net/learn/avr/

TOOLS

http://www.obdev.at/products/crosspack/index.html

http://electrons.psychogenic.com/modules/arms/art/3/AVRGCCProgrammingGuide.php

http://www.nongnu.org/avr-libc/user-manual/install_tools.html

C++

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=457778

ASSEMBLY

http://www.avr-asm-tutorial.net/avr_en/

ATMEL LINKS::

www.atmel.com/dyn/resources/

http://en.wikipedia.org/wiki/Atmel_AVR

ATMEGA168 DATASHEET

www.atmel.com/dyn/resources/prod_documents/doc2545.pdf

INSTRUCTIONS SET

www.atmel.com/atmel/acrobat/doc0856.pdf

Programmers

www.atmel.org/dyn/resources/prod_documents/AVRISPmkII_UG.pdf

EDITORS::

www.codeblocks.org http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin

AVRDUDE::

http://savannah.nongnu.org/projects/avrdude/

http://www.nongnu.org/avrdude/user-manual/avrdude_4.html

http://electrons.psychogenic.com/modules/arms/art/14/AVRFusesHOWTOGuide.php

http://www.ladyada.net/make/usbtinyisp/avrdude.html

http://www.engbedded.com/fusecalc

Arduino::

http://www.arduino.cc/playground/Code/Eclipse

http://www.vintagecomputercables.com/arduino/img/new_arduino_pin_mapping.jpg

GNU TOOL CHAIN::
rpm/Yum packages
  • avr-binutils-2.14-1
  • avr-gcc-3.3.2-1
  • avr-g++-3.3.2-1
  • avr-gdb-6.8-1
  • avr-libc-1.0.2-1
  • avr-libc-docs
Source download:
Current binutils Source: 

www.gnu.org/directory/binutils.html

GNU Compiler Collection: 

gcc.gnu.org/mirrors.html

AVR Libc Package: 

www.nongnu.org/avr-libc

Psychogenic Makefile Template: 

electrons.psychogenic.com/avr/linux/makefile.php

simulavr: 

savannah.nongnu.org/projects/simulavr

GDB: 

sources.redhat.com/gdb

AVRDUDE: 

www.bsdhome.com/avrdude

Navigation
Print/export
Toolbox