当前位置:首页 > 单片机 > 单片机
[导读]如何使用AVR-GCC编译软件

安装GNU C for AVR

一.执行安装程序

二.生成链接用的库文件

$(AVR)表示安装的根目录。(在本人系统里为f:\avrgCC)

生成库文件关键是要运行位于$(AVR)下的RUN.BAT。原程序如下:

@echo off

if NOT %AVR%!==! goto install

rem set environment variables

set AVR=f:\AVRGCC

set CC=avr-gcc

set PATH=.;f:\AVRGCC\bin;%path%

doskey

:install

if %1!==! GOTO end

rem install libc

cd f:\AVRGCC\lib\avr-libc-20010701\SRC

rem first win32_make_dirs will make some errors(I don’t know why?)

make -f makefile-win32 win32_make_dirs

make -f makefile-win32

make -f makefile-win32 install

make -f makefile-win32 clean

:end

f:

cd f:\AVRGCC

mode con: lines=43

要修改为:

@echo off

if NOT %AVR%!==! goto install

rem set environment variables

set AVR=f:\AVRGCC

set CC=avr-gcc

rem set PATH=.;f:\AVRGCC\bin;%path%

doskey

:install

rem if %1!==! GOTO end

rem install libc

cd f:\AVRGCC\lib\avr-libc-20010701\src

rem first win32_make_dirs will make some errors(I don’t know why?)

f:\AVRGCC\bin\make -f makefile-win32 win32_make_dirs

f:\AVRGCC\bin\make -f makefile-win32

f:\AVRGCC\bin\make -f makefile-win32 install

f:\AVRGCC\bin\make -f makefile-win32 clean

:end

f:

cd f:\AVRGCC

mode con: lines=43

在以后的应用中,运行的是修改之前的RUN.BAT,但要去掉rem if %1!==! GOTO end

的“rem”。去掉“rem”之后,后续的语句将被跳过。因此MAKE部分的“f:\AVRGCC\bin\”可加可不加。

编译和链接应用程序

首先在 www.pICavr.com 上下载测试程序集gcctest.zip,然后安装。

1. 将GCCTEST\INCLUDE下的MAKE1、MAKE2拷贝到$(AVR)\ INCLUDE

2. 将工作目录的MAKEFILE

(每个工程都要有一个此文件,且可由自己进行修改以适合自己的应用。如果要利用原有文件,则注意只能有一个C文件)中的MCU、TRG、SRC、ASRC、INC、LIB等项填入合适的内容

3.

在工作目录运行位于$(AVR)\BIN下的MAKE.EXE(注意:由于系统可能存在其他应用程序的MAKE,因此可能还需要加路径。也可以将其改名。)

4. 从MAKE1、MAKE2和MAKEFILE可以看出,用户可以修改诸如输出文件名等多种选项。

在C代码中嵌入汇编指令

一.GCC的ASM声明

首先看一个从PORTD读入数据的例子:

asm(“in %0, %1” : “=r”(value) : “I”(PORTD) : );

由上可以看出嵌入汇编的4个部分:

1. 汇编指令本身,以字符串“in %0, %1”表示;

2. 由逗号分隔的输出操作数,本例为“=r”(value)

3. 由逗号分隔的输入操作数,本例为“I”(PORTD)

4. Clobber寄存器

嵌入汇编的通用格式为:

asm(code : output operand list : input operand list : clobber list);

例子中%0表示第一个操作数,%1表示第二个操作数。即:

%0  “=r”(value)

%1  “I”(PORTD)

如果在后续的C代码中没有使用到汇编代码中使用的变量,则优化编译时会将这些语句删除。为了防止这种情况的发生,需要加入volatile属性:

asm volatile (“in %0, %1” : “=r”(value) : “I”(PORTD) : );

嵌入汇编的的Clobber寄存器部分可以忽略,而其他部分不能忽略,但可以为空。如下例:

asm volatile(“cli” : :);

二.汇编代码

用户可以在C代码里嵌入任意的汇编指令,就如同在汇编器里写程序一样。AVR-GCC提供了一些特殊的寄存器名称:

符号寄存器

__SREG__状态寄存器SREG(0x3F)

__SP_H__堆栈指针高字节(0x3E)

__SP_L__堆栈指针低字节(0x3D)

__tmp_reg__r0

__zero_reg__r1。对于C代码而言其值永远为0

三.输入/输出操作数

约束符号适用于范围

a r16~r23

b指针Y,Z

d r16~r31

e指针X,Y,Z

G浮点常数0.0

I6比特正常数0~63

J6比特负常数-63~0

l r0~r15

M8比特正常数0~255

N整数常数-1

O整数常数8,16,24

P整数常数1

r r0~r31

t R0

W寄存器对r24,r26,r28,r30

X指针Xr27:r26

Y指针Yr29:r28

Z指针Zr31:r30

要注意的是,在使用这些约束符号时要防止选择错误。例如,用户选择了”r”约束符号,而汇编语句则使用了”ori”。编译器可以在r0~r31之间任意选择寄存器。若选择了r2~r15,则会由于不适用ori而出现编译错误。此时正确的约束符应该是”d”。

约束符号还可以有前置修饰符,如下表所示。

修饰符指定

=只写操作数

+读-写操作数(嵌入汇编不支持)

&寄存器只能用做输出

输出操作数必须为只写操作数,C表达式结果必须为l(r0~r15)。编译器不检查汇编指令中的变量类型是否合适。

输入操作数为只读。如果输入/输出使用同一个寄存器怎么办呢?此时可以在输入操作数的约束字符里使用一个一位数字来达到这个目的。这个数字告诉编译器使用与第n个(从0开始计数)操作数相同的寄存器。例如:

asm volatile(“SWAP %0” : “=r”(value) : “0”(value));

这条语句的目的是交换变量value的高低4位。约束符号“0”告诉编译器使用与第一个操作数相同的寄存器作为输入寄存器。要注意的是,即使用户没有指定,编译器也有可能使用相同的寄存器作为输入/输出。在某些情况下会引发严重的问题。如果用户需要区分输入/输出寄存器,则必须为输出操作数增加修饰符”&”。如下例所示。

asm volatile(“in %0, %1;

out %1, %2”

: “=&r”(input)

: “I”(port), “r”(output)

);

此例的目的是读入端口数据,然后给端口写入另一个数据。若编译器不幸使用了同一个寄存器作为参数input和output存储位置,则第一条指令执行后output的内容就被破坏了。而用了修饰符”&”之后,这个问题得以解决。

下面为一个高16位与低16位交换的32位数据操作的例子:

asm volatile(“ MOV __tmp_reg__, %A0;

MOV %A0, %D0;

MOV %D0, __tmp_reg__;

MOV __tmp_reg__, %B0;

MOV %B0, %C0;

MOV %C0, __tmp_reg__”

: “=r”(value)

: “0”(value)

)

31………………2423………………1615………………87…………………0

DCBA

四.Clobber

如前所示,asm语句的最后一部分为clobber。如果用户在汇编代码里使用了没有作为操作数声明的寄存器,就需要在clobber里声明以通知编译器。下面为一个中断无关的加一操作例子。

asm volatile(“cli;

ld r24, %a0;

inc r24;

st %a0, r24;

sei”

:

:”z”(ptr)

:”r24”

)

编译结果为:

CLI

LD R24, Z

INC R24

ST Z, R24

SEI

当然,用户也可以用__tmp_reg__来取代r24。此时就没有clobber寄存器了。

下面为考虑更详细的例子:

c_func

{

uint_t s;

asm volatile(“in %0, __SREG__;

cli;

ld, __tmp_reg__, %a1;

inc __tmp_reg__;

st %a1, __tmp_reg__;

out __SREG__, %0”

: “=r”(t)

:”z”(ptr)

);

}

现在看起来好象没问题了。其实不尽然。由于优化的原因,编译器不会更新C代码里其他使用这个数值的寄存器。出于同样的优化原因,上述代码的输入寄存器可能保持的不是当前最新的数值。用户可以加入特殊的”memory”

clobber来强迫编译器及时更新所有的变量。

更好的方法是将一个指针声明为volatile,如下所示:

volatile uint8_t *ptr;

这样,一旦指针指向的变量发生变化,编译器就会重新加载最新的数值。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭