微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > AVR 单片机与GCC 编程----之二

AVR 单片机与GCC 编程----之二

时间:12-02 来源:互联网 点击:

#include EEPROM.h>

#include EEPROM.h>

#include EEPROM.h>

t8:

未用,用户可定义

.init9:

跳到main()

avr-libc 包含一个启动模块(startup module),用于应用程序执行前的环境设置,链接时它被分配到init2 和init4 中,负责提供缺省中断程序和向量、初始化堆栈、初始化.data 段和清零.bss 段等任务,最后startup 跳转到main 函数执行用户程序。

.finiN 段

此类段包含main()函数退出后执行的代码。

此类段可有0 到9 个, 执行次序是从fini9 到 fini1。

.fini9

此段绑定到函数exit()。用户可重载exit(),main 函数一旦退出exit 就会被执行。

.fini8:

未用,用户可定义

.fini7:

未用,用户可定义

.fini6:

C 代码未用, C++程序的析构代码

.fini5:

未用,用户可定义

.fini4:

未用,用户可定义

.fini3:

未用,用户可定义

.fini2:

未用,用户可定义

.fini1:

未用,用户可定义

.fini0:

进入一个无限循环。

用户代码插入到.initN 或.finiN

示例如下:

void my_init_portb (void) __attribute__ ((naked))

__attribute__ ((section (".init1")));

void my_init_portb (void)

{

outb (PORTB, 0xff);

outb (DDRB, 0xff);

}

由于属性section(“.init1”)的指定,编译后函数my_init_portb 生成的代码自动插入到.init1段中,在main 函数前就得到执行。naked 属性确保编译后该函数不生成返回指令,使下一个初始化段得以顺序的执行。

二..data 段

.data 段包含程序中被初始化的RAM 区全局或静态变量。而对于FLASH 存储器此段包含在程序中定义变量的初始化数据。类似如下的代码将生成.data 段数据。

char err_str[]=”Your program has died a horrible death!”;

struct point pt={1,1};

可以将.data 在SRAM 内的开始地址指定给连接器,这是通过给avr-gcc 命令行添加

-Wl,-Tdata,addr 选项来实现的,其中addr 必须是0X800000 加SRAM 实际地址。例如 要将.data 段从0x1100 开始,则addr 要给出0X801100。

三..bss 段

没有被初始化的RAM 区全局或静态变量被分配到此段,在应用程序被执行前的startup过程中这些变量被清零。

另外,.bss 段有一个子段 .noinit , 若变量被指定到.noinit 段中则在startup 过程中不会被清零。将变量指定到.noinit 段的方法如下:

int foo __attribute__ ((section (“.noinit”)));

由于指定到了.noinit 段中,所以不能赋初值,如同以下代码在编译时产生错误:

int fol __attribute__((section(“.noinit”)))=0x00ff;

四..EEPROM 段

此段存储EEPROM 变量。

Static unsigned char eep_buffer[3] __attribute__((section(“.EEPROM”)))={1,2,3};

在链接选项中可指定段的开始地址,如下的选项将.noinit 段指定位到RAM 存储器

0X2000 地址处。

avr-gcc ... -Wl,--section-start=.noinit=0x802000

要注意的是,在编译时Avr-gcc 将FLASH、RAM 和EEPROM 内的段在一个统一的地址空间内处理,flash 存储器被定位到0 地址开始处,RAM 存储器被定位到0x800000 开始处,EEPROM 存储器被定位到0X810000 处。所以在指定段开始地址时若是RAM 内的段或EEPROM 内的段时要在实际存储器地址前分别加上0x800000 和0X810000。

除上述四个段外,自定义段因需要而可被定义。由于编译器不知道这类段的开始地址,又称它们为未定义段。必需在链接选项中指定自定义段的开始地址。如下例:

void MySection(void) __attribute__((section(".mysection")));

void MySection(void)

{

printf("hello avr!");

}

链接选项:

avr-gcc ... -Wl,--section-start=.mysection=0x001c00

这样函数MySection 被定位到了FLASH 存储器0X1C00 处。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top