AVR Libc Home Page | AVR Libc Development Pages | ||||
Main Page | User Manual | Library Reference | FAQ | Alphabetical Index | Example Projects |
This chapter describes some methods and pointers on porting an AVR application built with the IAR compiler to the GNU toolchain (AVR GCC). Note that this may not be an exhaustive list.
#include <iom169.h>
-mmcu=processor
flag.) This is usually done in the Makefile. This allows you to specify only a single header file for any processor type:
#include <avr/io.h>
The AVR toolchain tries to adhere to the exact names of the registers and names of the bits found in the AVR datasheet. There may be some descrepencies between the register names found in the IAR IO header files and the AVR GCC IO header files.
IAR declares an ISR like so:
#pragma vector=TIMER0_OVF_vect __interrupt void MotorPWMBottom() { // code }
In AVR GCC, you declare an ISR like so:
ISR(PCINT1_vect) { //code }
AVR GCC uses the ISR
macro to define an ISR. This macro requries the header file:
#include <avr/interrupt.h>
The names of the various interrupt vectors are found in the individual processor IO header files that you must include with <avr/io.h>
.
__enable_interrupts()
__disable_interrupts()
__watchdog_reset()
These intrinsic functions compile to specific AVR opcodes (SEI, CLI, WDR).
There are equivalent macros that are used in AVR GCC, however they are not located in a single include file.
AVR GCC has sei()
for __enable_interrupts()
, and cli()
for __disable_interrupts()
. Both of these macros are located in <avr/interrupts.h>
.
AVR GCC has the macro wdt_reset()
in place of __watchdog_reset()
. However, there is a whole Watchdog Timer API available in AVR GCC that can be found in <avr/wdt.h>
.
IAR uses a non-standard keyword to declare a variable in Program Memory:
__flash int mydata[] = ....
AVR GCC uses Variable Attributes to achieve the same effect:
int mydata[] __attribute__((progmem))
#include <avr/pgmspace.h>
.
.
.
int mydata[] PROGMEM = ....
progmem
. This macro requires that you include <avr/pgmspace.h>
. This is the canonical method for defining a variable in Program Space.pgm_read_*
() macros defined in <avr/pgmspace.h>
. All Program Memory handling macros are defined there.There is also a way to create a method to define variables in Program Memory that is common between the two compilers (IAR and AVR GCC). Create a header file that has these definitions:
#if defined(__ICCAVR__) // IAR C Compiler #define FLASH_DECLARE(x) __flash x #endif #if defined(__GNUC__) // GNU Compiler #define FLASH_DECLARE(x) x __attribute__((__progmem__)) #endif
This code snippet checks for the IAR compiler or for the GCC compiler and defines a macro FLASH_DECLARE(x)
that will declare a variable in Program Memory using the appropriate method based on the compiler that is being used. Then you would used it like so:
FLASH_DECLARE(int mydata[] = ...);
__C_task void main(void) { // code }
To do the equivalent in AVR GCC, do this:
void main(void) __attribute__((noreturn)); void main(void) { //... }
void
.
__regvar __no_init volatile unsigned int filteredTimeSinceCommutation @14;
This line locks r14 for use only when explicitly referenced in your code thorugh the var name "filteredTimeSinceCommutation". This means that the compiler cannot dispose of it at its own will.
To do this in AVR GCC, do this:
register unsigned char counter asm("r3");
Typically, it should be possible to use r2 through r15 that way.
Locking registers is not recommended in AVR GCC as it removes this register from the control of the compiler, which may make code generation worse. Use at your own risk.