打印
[AVR单片机]

转贴: Documentation:AVR GCC/IarToAvrgcc

[复制链接]
2059|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
testcode|  楼主 | 2007-8-21 01:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
 A few tips on porting code from IAR to AVR-GCC (WinAVR)...
[edit] 1) REGISTER/MEMORY LOCATIONS

have aliases in the IAR .h file, sometimes have unidentical entries in the avr-gcc files (Often, avr-gcc are the correct ones wrt the datasheet). Such entries must be edited in the source code to match avr-gcc names.

Also, .h files are not called explicitly when using WinAVR, you just use a general call, and the makefile generator takes care of calling the proper .h file.

Example:

IAR: #include <iom169.h>
GCC: #include <avr/io.h>


[edit] 2) INTERRUPT SERVICES

are handled using #pragma directives in IAR.

Example(IAR):

#pragma vector=TIMER0_OVF_vect
__interrupt void MotorPWMBottom(){
// blabla    
}

Interrupt Service Routines have been greatly simplified in recent WinAVR releases, using the ISR() wrapper.

Example(GCC):

ISR(PCINT1_vect){ 
//code 
}

All vectors are defined in the parts' respective avr-gcc header file, so they will be included using the general #include <avr/io.h>

NB! You MUST also #include <avr/interrupt.h> in the compilation. It will compile without this, but the behaviour will not be correct.


[edit] 3) INTRINSIC FUNCTIONS

Examples: __enable_interrupts(), __disable_interrupts(), and __watchdog_reset(); are intrinsic functions that have counterparts with other names in avr-gcc.

All these are actual AVR instructions, so they can be called using C-syntax like: asm("SEI"); etc....

These are usually defined as macros for avr-gcc, but they're not co-located in one single file covering _all_ intrinsic functions, rather in the particular .h file pertaining to their function.

Example: sei() and cli() are defined in <avr/interrupts.h>

Example of how to define:

#define wdt_reset() __asm__ __volatile__ ("wdr")

You can can now call wdt_reset() from your C source, effectively executing a wdr instruction.


[edit] 4) LOCKING REGISTERS

The IAR compiler lock general registers, from r15 and down, by using compiler options and this keyword syntax:

__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.

There is a way to do this in avr-gcc also: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind

NB! Doing this is not recommended as it removes this register from the purview of the compiler, which may make code generation worse. Use at your own risk.


[edit] 5) FLASH VARIABLES

IAR has non-standard keywords to define data to be put in Flash. GCC uses "attributes" with their own, non-standard syntax. The reason why both syntaxes are non-standard, is because the C language was not designed for Harvard architecture devices, such as the AVR. So for example, one would have to create macros to define a common way to do this. Like so:

#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 

To-the-point:

IAR syntax: __flash int myData[] = ....
GCC syntax: int myData[] PROGMEM = ...  OR  int myData[] __attribute__((progmem)) = ...

NB! To read back flash data, use pgm_read_*() functions, defined in <avr/pgmspace.h>. All progmem/flash handling macros are defined there.

The STK504 LCD driver has been ported to avr-gcc and can be used as an example (Look for "FLASH_DECL").


[edit] 6) NON-RETURNING main() FUNCTIONS: C_TASK

In IAR, simply declare the main() like this:

__C_task void main(void) {
//...
}


With gcc, use a prototype first, that declares it's a non-return function:

void main(void) __attribute__((noreturn));
    
Void main(void) {
//...
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

245

帖子

0

粉丝