1.AT89C51和AT89S51的区别?
2.交åç¼è¯å¨ arm-linux-gnueabi å arm-linux-gnueabihf çåºå«
AT89C51和AT89S51的区别?
ATC是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。ATC是一种带2K字节闪烁可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除次。该器件采用ATMEL高密度非易失存储器制造技术制造,手写数字时钟源码下载与工业标准的MCS-指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的ATC是一种高效微控制器,ATC是它的一种精简版本。ATC单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。外形及引脚排列如图所示[编辑本段]主要特性:
·与MCS- 兼容
·4K字节可编程闪烁存储器
·寿命:写/擦循环
·数据保留时间:年
·全静态工作:0Hz-MHz
·三级程序存储器锁定
·×8位内部RAM
·可编程I/O线
·两个位定时器/计数器
·5个中断源
·可编程串行通道
·低功耗的闲置和掉电模式
·片内振荡器和时钟电路
管脚说明:
VCC:供电电压。
GND:接地。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的活源码管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
P3口也可作为ATC的一些特殊功能口,如下表所示:
口管脚 备选功能
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 /INT0(外部中断0)
P3.3 /INT1(外部中断1)
P3.4 T0(记时器0外部输入)
P3.5 T1(记时器1外部输入)
P3.6 /WR(外部数据存储器写选通)
P3.7 /RD(外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:外部程序存储器的免费的源码选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加V编程电源(VPP)。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:来自反向振荡器的输出。
振荡器特性:
XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。
芯片擦除:
整个PEROM阵列和三个锁定位的电擦除可通过正确的控制信号组合,并保持ALE管脚处于低电平ms 来完成。在芯片擦操作中,代码阵列全被写“1”且在任何非空存储字节被重复编程以前,该操作必须被执行。
此外,ATC设有稳态逻辑,可以在低到零频率的条件下静态逻辑,支持两种软件可选的掉电模式。在闲置模式下,CPU停止工作。但RAM,定时器,计数器,串口和中断系统仍在工作。在掉电模式下,保存RAM的内容并且冻结振荡器,禁止所用其他芯片功能,直到下一个硬件复位为止。积分商城源码
串口通讯
单片机的结构和特殊寄存器,这是你编写软件的关键。至于串口通信需要用到那些特殊功能寄存器呢,它们是SCON,TCON,TMOD,SCON等,各代表什么含义呢?
SBUF 数据缓冲寄存器这是一个可以直接寻址的串行口专用寄存器。有朋友这样问起过“为何在串行口收发中,都只是使用到同一个寄存器SBUF?而不是收发各用一个寄存器。”实际上SBUF 包含了两个独立的寄存器,一个是发送寄存,另一个是接收寄存器,但它们都共同使用同一个寻址地址-H。CPU 在读SBUF 时会指到接收寄存器,在写时会指到发送寄存器,而且接收寄存器是双缓冲寄存器,这样可以避免接收中断没有及时的被响应,数据没有被取走,下一帧数据已到来,而造成的数据重叠问题。发送器则不需要用到双缓冲,一般情况下我们在写发送程序时也不必用到发送中断去外理发送数据。操作SBUF寄存器的方法则很简单,只要把这个H 地址用关键字sfr定义为一个变量就可以对其进行读写操作了,如sfr SBUF = 0x;当然你也可以用其它的名称。通常在标准的reg.h 或atx.h 等头文件中已对其做了定义,只要用#include 引用就可以了。
SCON 串行口控制寄存器通常在芯片或设备中为了监视或控制接口状态,都会引用到接口控制寄存器。SCON 就是 芯片的串行口控制寄存器。它的寻址地址是H,是一个可以位寻址的寄存器,作用就是监视和控制 芯片串行口的工作状态。 芯片的串口可以工作在几个不同的工作模式下,其工作模式的设置就是使用SCON 寄存器。它的各个位的具体定义如下:
SM0 SM1 SM2 REN TB8 RB8 TI RI
SM0、SM1 为串行口工作模式设置位,这样两位可以对应进行四种模式的设置。串行口工作模式设置。
SM0 SM1 模式 功能 波特率
0 0 0 同步移位寄存器 fosc/
0 1 1 8位UART 可变
1 0 2 9位UART fosc/ 或fosc/
1 1 3 9位UART 可变
在这里只说明最常用的网赚源码模式1,其它的模式也就一一略过,有兴趣的朋友可以找相关的硬件资料查看。表中的fosc 代表振荡器的频率,也就是晶振的频率。UART 为(Universal Asynchronous Receiver)的英文缩写。
SM2 在模式2、模式3 中为多处理机通信使能位。在模式0 中要求该位为0。
REM 为允许接收位,REM 置1 时串口允许接收,置0 时禁止接收。REM 是由软件置位或清零。如果在一个电路中接收和发送引脚P3.0,P3.1 都和上位机相连,在软件上有串口中断处理程序,当要求在处理某个子程序时不允许串口被上位机来的控制字符产生中断,那么可以在这个子程序的开始处加入REM=0 来禁止接收,在子程序结束处加入REM=1 再次打开串口接收。大家也可以用上面的实际源码加入REM=0 来进行实验。
TB8 发送数据位8,在模式2 和3 是要发送的第9 位。该位可以用软件根据需要置位或清除,通常这位在通信协议中做奇偶位,在多处理机通信中这一位则用于表示是地址帧还是数据帧。
RB8 接收数据位8,在模式2 和3 是已接收数据的第9 位。该位可能是奇偶位,地址/数据标识位。在模式0 中,RB8 为保留位没有被使用。在模式1 中,当SM2=0,RB8 是已接收数据的停止位。
TI 发送中断标识位。在模式0,发送完第8 位数据时,由硬件置位。其它模式中则是在发送停止位之初,由硬件置位。TI 置位后,申请中断,CPU 响应中断后,发送下一帧数据。在任何模式下,TI 都必须由软件来清除,也就是说在数据写入到SBUF 后,硬件发送数据,中断响应(如中断打开),这时TI=1,表明发送已完成,TI 不会由硬件清除,所以这时必须用软件对其清零。
RI 接收中断标识位。在模式0,接收第8 位结束时,由硬件置位。其它模式中则是在接收停止位的半中间,由硬件置位。RI=1,申请中断,要求CPU 取走数据。但在模式1 中,SM2=1时,当未收到有效的停止位,则不会对RI 置位。同样RI 也必须要靠软件清除。常用的串口模式1 是传输 个位的,1 位起始位为0,8 位数据位,低位在先,1 位停止位为1。它的波特率是可变的,其速率是取决于定时器1 或定时器2 的定时值(溢出速率)。ATC 和ATC 等 系列芯片只有两个定时器,定时器0 和定时器1,而定时器2是C 系列芯片才有的。
波特率在使用串口做通讯时,一个很重要的参数就是波特率,只有上下位机的波特率一样时才可以进行正常通讯。波特率是指串行端口每秒内可以传输的波特位数。有一些初学的朋友认为波特率是指每秒传输的字节数,如标准 会被误认为每秒种可以传送个字节,而实际上它是指每秒可以传送 个二进位,而一个字节要8 个二进位,如用串口模式1 来传输那么加上起始位和停止位,每个数据字节就要占用 个二进位, 波特率用模式1 传输时,每秒传输的字节数是÷= 字节。 芯片的串口工作模式0的波特率是固定的,为fosc/,以一个M 的晶振来计算,那么它的波特率可以达到1M。模式2 的波特率是固定在fosc/ 或fosc/,具体用那一种就取决于PCON 寄存器中的SMOD位,如SMOD 为0,波特率为focs/,SMOD 为1,波特率为focs/。模式1 和模式3 的波特率是可变的,取决于定时器1 或2( 芯片)的溢出速率。那么我们怎么去计算这两个模
式的波特率设置时相关的寄存器的值呢?可以用以下的公式去计算。
波特率=(2SMOD÷)×定时器1 溢出速率
上式中如设置了PCON 寄存器中的SMOD 位为1 时就可以把波特率提升2 倍。通常会使用定时器1 工作在定时器工作模式2 下,这时定时值中的TL1 做为计数,TH1 做为自动重装值 ,这个定时模式下,定时器溢出后,TH1 的值会自动装载到TL1,再次开始计数,这样可以不用软件去干预,使得定时更准确。在这个定时模式2 下定时器1 溢出速率的计算公式如下:
溢出速率=(计数速率)/(-TH1)
上式中的“计数速率”与所使用的晶体振荡器频率有关,在 芯片中定时器启动后会在每一个机器周期使定时寄存器TH 的值增加一,一个机器周期等于十二个振荡周期,所以可以得知 芯片的计数速率为晶体振荡器频率的1/,一个M 的晶振用在 芯片上,那么 的计数速率就为1M。通常用.M 晶体是为了得到标准的无误差的波特率,那么为何呢?计算一下就知道了。如我们要得到 的波特率,晶振为.M 和M,定时器1 为模式2,SMOD 设为1,分别看看那所要求的TH1 为何值。代入公式:
.M
=(2÷)×((.M/)/(-TH1))
TH1=
M
=(2÷)×((M/)/(-TH1))
TH1≈.
上面的计算可以看出使用M 晶体的时候计算出来的TH1 不为整数,而TH1 的值只能取整数,这样它就会有一定的误差存在不能产生精确的 波特率。当然一定的误差是可以在使用中被接受的,就算使用.M 的晶体振荡器也会因晶体本身所存在的误差使波特率产生误差,但晶体本身的误差对波特率的影响是十分之小的,可以忽略不计。
ATS是一个低功耗,高性能CMOS 8位单片机,片内含4k Bytes ISP(In-system programmable)的可反复擦写次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-指令系统及C引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的ATS可为许多嵌入式控制应用系统提供高性价比的解决方案。
ATS具有如下特点:个引脚,4k Bytes Flash片内程序存储器, bytes的随机存取数据存储器(RAM),个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
此外,ATS设计和配置了振荡频率可为0Hz并可通过软件设置省电模式。空闲模式下,CPU暂停工作,而RAM定时计数器,串行口,外中断系统可继续工作,掉电模式冻结振荡器而保存RAM的数据,停止芯片其它功能直至外中断激活或硬件复位。同时该芯片还具有PDIP、TQFP和PLCC等三种封装形式,以适应不同产品的需求。
1.主要特性:
• CPU与MCS- 兼容
• 4K字节可编程FLASH存储器(寿命:写/擦循环)
• 全静态工作:0Hz-KHz
• 三级程序存储器保密锁定
• *8位内部RAM
• 条可编程I/O线
• 两个位定时器/计数器
• 6个中断源
• 可编程串行通道
• 低功耗的闲置和掉电模式
• 片内振荡器和时钟电路
2.管脚说明:
VCC:供电电压。
GND:接地。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 /INT0(外部中断0)
P3.3 /INT1(外部中断1)
P3.4 T0(记时器0外部输入)
P3.5 T1(记时器1外部输入)
P3.6 /WR(外部数据存储器写选通)
P3.7 /RD(外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
I/O口作为输入口时有两种工作方式即所谓的读端口与读引脚读端口时实际上并不从外部读入数据而是把端口锁存器的内容读入到内部总线经过某种运算或变换后再写回到端口锁存器只有读端口时才真正地把外部的数据读入到内部总线上面图中的两个三角形表示的就是输入缓冲器CPU将根据不同的指令分别发出读端口或读引脚信号以完成不同的操作这是由硬件自动完成的不需要我们操心1然后再实行读引脚操作否则就可能读入出错为什么看上面的图如果不对端口置1端口锁存器原来的状态有可能为0Q端为0Q^为1加到场效应管栅极的信号为1该场效应管就导通对地呈现低阻抗,此时即使引脚上输入的信号为1也会因端口的低阻抗而使信号变低使得外加的1信号读入后不一定是1若先执行置1操作则可以使场效应管截止引脚信号直接加到三态缓冲器中实现正确的读入由于在输入操作时还必须附加一个准备动作所以这类I/O口被称为准双向口C的P0/P1/P2/P3口作为输入时都是准双向口接下来让我们再看另一个问题从图中可以看出这四个端口还有一个差别除了P1口外P0P2P3口都还有其他的功能
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加V编程电源(VPP)。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:来自反向振荡器的输出。
交åç¼è¯å¨ arm-linux-gnueabi å arm-linux-gnueabihf çåºå«
èªå·±ä¹åä¸ç´æ²¡ææ¸ æ¥è¿ä¸¤ä¸ªäº¤åç¼è¯å¨å°åºæä»ä¹é®é¢,ç¹ægoogleä¸çª,æ»ç»å¦ä¸,å¸æè½å¸®å°éä¸åææåæ ·å°æçå å¼â¦..
ä¸. ä»ä¹æ¯ABIåEABI
1) ABI: äºè¿å¶åºç¨ç¨åºæ¥å£(Application Binary Interface (ABI) for the ARM Architecture)
å¨è®¡ç®æºä¸ï¼åºç¨äºè¿å¶æ¥å£æè¿°äºåºç¨ç¨åºï¼æè å ¶ä»ç±»åï¼åæä½ç³»ç»ä¹é´æå ¶ä»åºç¨ç¨åºçä½çº§æ¥å£.
ABI涵çäºåç§ç»èï¼å¦ï¼
æ°æ®ç±»åç大å°ãå¸å±å对é½;
è°ç¨çº¦å®ï¼æ§å¶çå½æ°çåæ°å¦ä½ä¼ é以åå¦ä½æ¥åè¿åå¼ï¼ï¼ä¾å¦ï¼æ¯ææçåæ°é½éè¿æ ä¼ éï¼è¿æ¯é¨ååæ°éè¿å¯åå¨ä¼ éï¼åªä¸ªå¯åå¨ç¨äºåªä¸ªå½æ°åæ°ï¼éè¿æ ä¼ éç第ä¸ä¸ªå½æ°åæ°æ¯æå pushå°æ ä¸è¿æ¯æåï¼
ç³»ç»è°ç¨çç¼ç åä¸ä¸ªåºç¨å¦ä½åæä½ç³»ç»è¿è¡ç³»ç»è°ç¨ï¼
以åå¨ä¸ä¸ªå®æ´çæä½ç³»ç»ABIä¸ï¼ç®æ æ件çäºè¿å¶æ ¼å¼ãç¨åºåºççã
ä¸ä¸ªå®æ´çABIï¼åInteläºè¿å¶å ¼å®¹æ å (iBCS) ï¼å 许æ¯æå®çæä½ç³»ç»ä¸çç¨åºä¸ç»ä¿®æ¹å¨å ¶ä»æ¯ææ¤ABIçæä½ä½ç»ä¸è¿è¡ã
ABIä¸åäºåºç¨ç¨åºæ¥å£ï¼APIï¼ï¼APIå®ä¹äºæºä»£ç ååºä¹é´çæ¥å£ï¼å æ¤åæ ·ç代ç å¯ä»¥å¨æ¯æè¿ä¸ªAPIçä»»ä½ç³»ç»ä¸ç¼è¯ï¼ABIå 许ç¼è¯å¥½çç®æ 代ç å¨ä½¿ç¨å ¼å®¹ABIçç³»ç»ä¸æ éæ¹å¨å°±è½è¿è¡ã
2) EABI: åµå ¥å¼ABI
åµå ¥å¼åºç¨äºè¿å¶æ¥å£æå®äºæä»¶æ ¼å¼ãæ°æ®ç±»åãå¯åå¨ä½¿ç¨ãå 积ç»ç»ä¼ååå¨ä¸ä¸ªåµå ¥å¼è½¯ä»¶ä¸çåæ°çæ å约å®ã
å¼åè 使ç¨èªå·±çæ±ç¼è¯è¨ä¹å¯ä»¥ä½¿ç¨EABIä½ä¸ºä¸å ¼å®¹çç¼è¯å¨çæçæ±ç¼è¯è¨çæ¥å£ã
æ¯æEABIçç¼è¯å¨å建çç®æ æ件å¯ä»¥å使ç¨ç±»ä¼¼ç¼è¯å¨äº§çç代ç å ¼å®¹ï¼è¿æ ·å 许å¼åè é¾æ¥ä¸ä¸ªç±ä¸åç¼è¯å¨äº§ççåºã
EABIä¸å ³äºéç¨è®¡ç®æºçABIç主è¦åºå«æ¯åºç¨ç¨åºä»£ç ä¸å 许使ç¨ç¹ææ令ï¼ä¸éè¦å¨æé¾æ¥ï¼ææ¶æ¯ç¦æ¢çï¼ï¼åæ´ç´§åçå æ 帧ç»ç»ç¨æ¥èçå åã广æ³ä½¿ç¨EABIçæPower PCåARM.
äº. gnueabiç¸å ³ç两个交åç¼è¯å¨: gnueabiågnueabihf
å¨debianæºéè¿ä¸¤ä¸ªäº¤åç¼è¯å¨çå®ä¹å¦ä¸:
gcc-arm-linux-gnueabi â The GNU C compiler for armel architecture
gcc-arm-linux-gnueabihf â The GNU C compiler for armhf architecture
å¯è§è¿ä¸¤ä¸ªäº¤åç¼è¯å¨éç¨äºarmelåarmhf两个ä¸åçæ¶æ, armelåarmhfè¿ä¸¤ç§æ¶æå¨å¯¹å¾ æµ®ç¹è¿ç®éåäºä¸åççç¥(æfpuçarmæè½æ¯æè¿ä¸¤ç§æµ®ç¹è¿ç®çç¥)
å ¶å®è¿ä¸¤ä¸ªäº¤åç¼è¯å¨åªä¸è¿æ¯gccçé项-mfloat-abiçé»è®¤å¼ä¸å. gccçé项-mfloat-abiæä¸ç§å¼soft,softfp,hard(å ¶ä¸å两è é½è¦æ±arméæfpuæµ®ç¹è¿ç®åå ,softä¸å两è æ¯å ¼å®¹çï¼ä½softfpåhard两ç§æ¨¡å¼äºä¸å ¼å®¹)ï¼
soft : ä¸ç¨fpuè¿è¡æµ®ç¹è®¡ç®ï¼å³ä½¿æfpuæµ®ç¹è¿ç®åå ä¹ä¸ç¨,èæ¯ä½¿ç¨è½¯ä»¶æ¨¡å¼ã
softfp : armelæ¶æ(对åºçç¼è¯å¨ä¸ºgcc-arm-linux-gnueabi)éç¨çé»è®¤å¼ï¼ç¨fpu计ç®ï¼ä½æ¯ä¼ åæ°ç¨æ®éå¯åå¨ä¼ ï¼è¿æ ·ä¸æçæ¶åï¼åªéè¦ä¿åæ®éå¯åå¨ï¼ä¸æè´è·å°ï¼ä½æ¯åæ°éè¦è½¬æ¢ææµ®ç¹çå计ç®ã
hard : armhfæ¶æ(对åºçç¼è¯å¨gcc-arm-linux-gnueabihf)éç¨çé»è®¤å¼ï¼ç¨fpu计ç®ï¼ä¼ åæ°ä¹ç¨fpuä¸çæµ®ç¹å¯åå¨ä¼ ï¼çå»äºè½¬æ¢, æ§è½æ好ï¼ä½æ¯ä¸æè´è·é«ã
æ以ä¸æµè¯ä½¿ç¨çcæ件å 容ä¿åæmfloat.cï¼
#include <stdio.h>
int main(void)
{
double a,b,c;
a = .;
b = .;
c = b/a;
printf(âthe /2 = %f\nâ, c);
printf(âhello world !\nâ);
return 0;
}
1)使ç¨arm-linux-gnueabihf-gccç¼è¯ï¼ä½¿ç¨â-vâé项以è·åæ´è¯¦ç»çä¿¡æ¯:
# arm-linux-gnueabihf-gcc -v mfloat.c
COLLECT_GCC_OPTIONS=â-vâ â-march=armv7-aâ â-mfloat-abi=hardâ â-mfpu=vfpv3-dâ² â-mthumbâ
-mfloat-abi=hardï¼å¯çåºä½¿ç¨hard硬件浮ç¹æ¨¡å¼ã
2)使ç¨arm-linux-gnueabi-gccç¼è¯:
# arm-linux-gnueabi-gcc -v mfloat.c
COLLECT_GCC_OPTIONS=â-vâ â-march=armv7-aâ â-mfloat-abi=softfpâ â-mfpu=vfpv3-dâ² â-mthumbâ
-mfloat-abi=softfpï¼å¯çåºä½¿ç¨softfp模å¼ã
ä¸. æå±é 读
ä¸æéè¿°äºARM代ç ç¼è¯æ¶ç软浮ç¹(soft-float)å硬浮ç¹(hard-float)çç¼è¯ä»¥åé¾æ¥å®ç°æ¶çä¸åãä»VFPæµ®ç¹åå çå¼å ¥å°è½¯æµ®ç¹(soft-float)å硬浮ç¹(hard-float)çæ¦å¿µ
VFP (vector floating-point)
ä»ARMv5å¼å§ï¼å°±æå¯éç Vector Floating Point (VFP) 模åï¼å½ç¶ææ°çå¦ Cortex-A8, Cortex-A9 å Cortex-A5 å¯ä»¥é ç½®æä¸å¸¦VFPç模å¼ä¾è¯çååéæ©ã
VFPç»è¿è¥å¹²å¹´çåå±ï¼æVFPv2 (ä¸äº ARM9 / ARM)ã VFPv3-Dï¼åªä½¿ç¨ä¸ªæµ®ç¹å¯åå¨ï¼é»è®¤ä¸ºä¸ªï¼åVFPv3+NEON (å¦å¤§å¤æ°çCortex-A8è¯ç) ã对äºå å«NEONçARMè¯çï¼NEONä¸è¬åVFPå ¬ç¨å¯åå¨ã
硬浮ç¹Hard-float
ç¼è¯å¨å°ä»£ç ç´æ¥ç¼è¯æåå°ç»ç¡¬ä»¶æµ®ç¹åå¤çå¨ï¼æµ®ç¹è¿ç®åå FPUï¼å»æ§è¡ãFPUé常æä¸å¥é¢å¤çå¯åå¨æ¥å®ææµ®ç¹åæ°ä¼ éåè¿ç®ã
使ç¨å®é ç硬件浮ç¹è¿ç®åå FPUå½ç¶ä¼å¸¦æ¥æ§è½çæåãå 为å¾å¾ä¸ä¸ªæµ®ç¹çå½æ°è°ç¨éè¦å 个æè å å个æ¶éå¨æã
è½¯æµ®ç¹ Soft-float
ç¼è¯å¨ææµ®ç¹è¿ç®è½¬æ¢ææµ®ç¹è¿ç®çå½æ°è°ç¨ååºå½æ°è°ç¨ï¼æ²¡æFPUçæ令è°ç¨ï¼ä¹æ²¡ææµ®ç¹å¯åå¨çåæ°ä¼ éãæµ®ç¹åæ°çä¼ éä¹æ¯éè¿ARMå¯åå¨æè å æ å®æã
ç°å¨çLinuxç³»ç»é»è®¤ç¼è¯éæ©ä½¿ç¨hard-floatï¼å³ä½¿ç³»ç»æ²¡æä»»ä½æµ®ç¹å¤çå¨åå ï¼è¿å°±ä¼äº§çéæ³æ令åå¼å¸¸ãå èä¸è¬çç³»ç»éåé½éç¨è½¯æµ®ç¹ä»¥å ¼å®¹æ²¡æVFPçå¤çå¨ã
armel ABIåarmhf ABI
å¨armelä¸ï¼å ³äºæµ®ç¹æ°è®¡ç®ç约å®æä¸ç§ã以gcc为ä¾ï¼å¯¹åºç-mfloat-abiåæ°å¼æä¸ä¸ªï¼soft,softfp,hardã
softæ¯ææææµ®ç¹è¿ç®å ¨é¨å¨è½¯ä»¶å±å®ç°ï¼æçå½ç¶ä¸é«ï¼ä¼åå¨ä¸å¿ è¦çæµ®ç¹å°æ´æ°ãæ´æ°å°æµ®ç¹ç转æ¢ï¼åªéåäºæ©æ没ææµ®ç¹è®¡ç®åå çARMå¤çå¨ï¼
softfpæ¯ç®åarmelçé»è®¤è®¾ç½®ï¼å®å°æµ®ç¹è®¡ç®äº¤ç»FPUå¤çï¼ä½å½æ°åæ°çä¼ é使ç¨éç¨çæ´åå¯åå¨èä¸æ¯FPUå¯åå¨ï¼
hardå使ç¨FPUæµ®ç¹å¯åå¨å°å½æ°åæ°ä¼ éç»FPUå¤çã
éè¦æ³¨æçæ¯ï¼å¨å ¼å®¹æ§ä¸ï¼softä¸å两è æ¯å ¼å®¹çï¼ä½softfpåhard两ç§æ¨¡å¼ä¸å ¼å®¹ã
é»è®¤æ åµä¸ï¼armel使ç¨softfpï¼å æ¤å°hard模å¼çarmelåç¬ä½ä¸ºä¸ä¸ªabiï¼ç§°ä¹ä¸ºarmhfã
è使ç¨hard模å¼ï¼å¨æ¯æ¬¡æµ®ç¹ç¸å ³å½æ°è°ç¨æ¶ï¼å¹³åè½èç个CPUå¨æã对ARMè¿æ ·æ¯ä¸ªå¨æé½å¾éè¦çä½ç³»ç»ææ¥è¯´ï¼è¿æ ·çæåæ çæ¯å·¨å¤§çã
å¨å®å ¨ä¸æ¹åæºç åé ç½®çæ åµä¸ï¼å¨ä¸äºåºç¨ç¨åºä¸ï¼ä½¿ç¨armhfè½å¾å°%ââ%çæ§è½æåã对ä¸äºä¸¥éä¾èµäºæµ®ç¹è¿ç®çç¨åºï¼æ´æ¯å¯ä»¥è¾¾å°%çæ§è½æåã
Soft-floatåhard-floatçç¼è¯é项
å¨CodeSourcery gccçç¼è¯åæ°ä¸ï¼ä½¿ç¨-mfloat-abi=nameæ¥æå®æµ®ç¹è¿ç®å¤çæ¹å¼ã-mfpu=nameæ¥æå®æµ®ç¹åå¤ççç±»åã
å¯éç±»åå¦fpaï¼fpe2ï¼fpe3ï¼maverickï¼vfpï¼vfpv3ï¼vfpv3-fpï¼vfpv3-dï¼vfpv3-d-fpï¼vfpv3xdï¼vfpv3xd-fpï¼neonï¼neon-fpï¼vfpv4ï¼vfpv4-dï¼fpv4-sp-dï¼neon-vfpv4çã
使ç¨-mfloat-abi=hard (çä»·äº-mhard-float) -mfpu=vfpæ¥éæ©ç¼è¯æ硬浮ç¹ã使ç¨-mfloat-abi=softfpå°±è½å ¼å®¹å¸¦VFPç硬件以åsoft-floatç软件å®ç°ï¼è¿è¡æ¶çè¿æ¥å¨ld.soä¼å¨æ§è¡æµ®ç¹è¿ç®æ¶å¯¹äºè¿ç®åå çéæ©ï¼
æ¯ç´æ¥ç硬件è°ç¨è¿æ¯åºå½æ°è°ç¨ï¼æ¯æ§è¡/libè¿æ¯/lib/vfpä¸çlibmã-mfloat-abi=soft ï¼çä»·äº-msoft-floatï¼ç´æ¥è°ç¨è½¯æµ®ç¹å®ç°åºã
å¨ARM RVCTå·¥å ·é¾ä¸ï¼å®ä¹fpu模å¼ï¼
âfpu softvfp
âfpu softvfp+vfpv2
âfpu softvfp+vfpv3
âfpu softvfp+vfpv_fp
âfpu softvfp+vfpv_d
âfpu softvfp+vfpv_d_fp.
å®ä¹æµ®ç¹è¿ç®ç±»å
âfpmode ieee_full : ææå精度floatåå精度doubleç精度é½è¦åIEEEæ åä¸è´ï¼å ·ä½ç模å¼å¯ä»¥å¨è¿è¡æ¶å¨ææå®ï¼
âfpmode ieee_fixed ï¼ èå ¥å°ææ¥è¿çå®ç°çIEEEæ åï¼ä¸å¸¦ä¸ç²¾ç¡®çå¼å¸¸ï¼
âfpmode ieee_no_fenv ï¼èå ¥å°ææ¥è¿çå®ç°çIEEEæ åï¼ä¸å¸¦å¼å¸¸ï¼
âfpmode std ï¼éè§æ ¼æ°flushå°0ãèå ¥å°ææ¥è¿çå®ç°çIEEEæ åï¼ä¸å¸¦å¼å¸¸ï¼
âfpmode fast ï¼ æ´ç§¯æçä¼åï¼å¯è½ä¼æä¸ç¹ç²¾åº¦æ失ã