嵌入式系統(tǒng)第四章ARM的C語(yǔ)言編程技術(shù)_第1頁(yè)
嵌入式系統(tǒng)第四章ARM的C語(yǔ)言編程技術(shù)_第2頁(yè)
嵌入式系統(tǒng)第四章ARM的C語(yǔ)言編程技術(shù)_第3頁(yè)
嵌入式系統(tǒng)第四章ARM的C語(yǔ)言編程技術(shù)_第4頁(yè)
嵌入式系統(tǒng)第四章ARM的C語(yǔ)言編程技術(shù)_第5頁(yè)
已閱讀5頁(yè),還剩50頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

4.1概述4.1.1嵌入式系統(tǒng)應(yīng)用的編程語(yǔ)言匯編C目前使用的最多C++JAVA第4章ARM的C語(yǔ)言編程技術(shù)滿足系統(tǒng)的實(shí)時(shí)性要求盡量減少執(zhí)行代碼和數(shù)據(jù)所占的空間在算法上的特殊考慮

充分使用宏定義與條件編譯

運(yùn)用好位操作

I/O端口變量的定義要使用修飾符volatile

編制中斷服務(wù)程序是要注意有時(shí)要使用可重入函數(shù)

4.1.2嵌入式系統(tǒng)C語(yǔ)言程序設(shè)計(jì)考慮的問(wèn)題

字符型最基本數(shù)據(jù)類型整型

浮點(diǎn)型盡量少用盡可能使用4.2數(shù)據(jù)類型整型常量的表達(dá)(1)十六進(jìn)制數(shù)需在數(shù)字前加前綴0x(2)二進(jìn)制數(shù)需轉(zhuǎn)換成十六進(jìn)制數(shù)表示2.I/O端口的變量一般要使用易變性修飾符volatile(含義為易變的)修飾使用volatile的修飾符定義的變量,表示對(duì)它的訪問(wèn)不能采用緩存,不能將對(duì)幾次順序的訪問(wèn)優(yōu)化為一次訪問(wèn)。使用Volatil修飾的變量能反映I/O端口的實(shí)時(shí)變化。4.3常量與變量代碼1:voidmain(void){int*a=0x58000000//定義I/O端口

*a=0//輸出低電平*a=1//輸出高電平*a=0//輸出低電平

}程序的執(zhí)行結(jié)果I/O端口保持為0

例:比較有無(wú)volatile修飾的變量的差異

代碼2:voidmain(void){volatileint*a=0x0x5800000050000000//定義I/O端口

*a=0//輸出低電平*a=1//輸出高電平*a=0//輸出低電平}程序的執(zhí)行結(jié)果為I/O端口先輸出為0,然后輸出為1,最后再輸出為0,即輸出一個(gè)脈沖預(yù)處理指令:文件包含預(yù)處理指令宏定義預(yù)處理指令條件編譯預(yù)處理指令#pragma4.4預(yù)處理指令1宏定義宏定義:用一個(gè)指定的標(biāo)識(shí)符來(lái)代表一個(gè)數(shù)據(jù)或字符串。#define標(biāo)識(shí)符數(shù)據(jù)(或字符串)例1:#definePI3.1415926其作用是PI定義后在程序中的PI代替數(shù)據(jù)1。例2:#defineU8unsignedchar,其作用是定義后在程序中的U8都用unsignedchar代替宏定義的基本思想是:一次定義,多次使用其優(yōu)點(diǎn)是:可以用標(biāo)識(shí)符來(lái)代替長(zhǎng)的數(shù)據(jù),減少需要輸入的數(shù)據(jù)或字符串;用易于理解的標(biāo)識(shí)符來(lái)代替那些不太好記的具體的數(shù)據(jù),便于程序的理解和維護(hù);有利于程序的修改和升級(jí),當(dāng)這個(gè)數(shù)據(jù)需要修改時(shí),只需改動(dòng)宏定義之處即可。其作用類似于匯編中的偽指令EQU還可以用指定的標(biāo)識(shí)符來(lái)代表一個(gè)內(nèi)存單元的數(shù)#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)地址定義后,程序中rUTRSTAT0代表(0x50000010)中的數(shù)RAM中的I/O寄存器標(biāo)識(shí)符while(!(rUTRSTAT0&0x1));例:#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)……(0x50000010)中的數(shù)與1與后取反作為循環(huán)判斷的條件也可以進(jìn)行帶參數(shù)的宏定義。#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)形式參數(shù)程序中宏調(diào)用WrUTXH0(0xa)的功能為:(0x50000020)=0xa數(shù)據(jù)類型地址#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)……WrUTXH0(0xa)帶參數(shù)的宏RAM中的I/O寄存器#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)也可以進(jìn)行帶返回?cái)?shù)據(jù)的宏定義。帶返回?cái)?shù)據(jù)的宏地址#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)……*Revdata=RdURXH0();程序中宏調(diào)用*Revdata=RdURXH0()的功能為:將(0x50000024)中的數(shù)據(jù)送到*

Revdata中RAM中的I/O寄存器#defineTRUE 1#definerUTRSTAT1(*(volatileunsignedchar*)0x50004010)#defineWrUTXH1(ch) (*(volatileunsignedchar*)0x50004020)=(unsignedchar)(ch)#defineRdURXH1() (*(volatileunsignedchar*)0x50004024)練習(xí):嵌入式C語(yǔ)言編程經(jīng)常用到位操作運(yùn)算:& 與操作;例:x=rUTRSTAT0&0x4

| 或操作;例:x=x|0xf

y=PRSCVL|ADCCON^ 異或操作;例:a=a^a~

取反操作;例:c=~ c>> 右移操作;例:d=8>>3<< 左移操作;例:r=0x1<<15

PRSCVL=49<<6

4.5位運(yùn)算#defineADCCON_FLAG(0x1<<15)#defineADCCON_ENABLE_START_BYREAD (0x1<<1)#definePRSCVL(49<<6)#defineADCCON_ENABLE_START(0x1)#defineSTDBM(0x0<<2)#definePRSCEN(0x1<<14)練習(xí):子函數(shù)聲明main()

{

……

函數(shù)調(diào)用

……

}子函數(shù)定義{

……}聲明該函數(shù)使用該函數(shù)定義函數(shù)方式一先聲明主函數(shù)后定義4.6函數(shù)的程序結(jié)構(gòu)

函數(shù)定義{……

}main()

{

……

函數(shù)調(diào)用

……

}定義函數(shù)使用該函數(shù)方式二先定義主函數(shù)直接調(diào)用/*********************************************\ Copyright(c)2004-2007Zhangming@,Allrightsreserved. byZhangming2004.5.12----------------------程序功能---------------------------------串口通信Cmain函數(shù)----------------------創(chuàng)建與修正時(shí)間----------------------- 2004-5-12 創(chuàng)建2005-1-10修正*********************************************/4.7嵌入式系統(tǒng)C語(yǔ)言應(yīng)用程序的結(jié)構(gòu)#include<string.h>#include<stdio.h>#defineU8unsignedchar#defineTRUE 1#defineFALSE 0#pragmaimport(_use_no_semihosting_swi)//不使用軟中斷

/**********串口自發(fā)自收通信主函數(shù)***********/#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)//#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)//#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)//voidUart_SendByten(int,U8);charUart_Getchn(char*Revdata,intUartnum,inttimeout);voidARMTargetInit(void);voidhudelay(inttime);/*******主函數(shù)********/intmain(void){charc1[1];charerr;ARMTargetInit();//目標(biāo)板初始化

while(1){Uart_SendByten(0,0xa);//向串口0發(fā)送“換行”符Uart_SendByten(0,0xd);//向串口0發(fā)送“回車”符err=Uart_Getchn(c1,0,0);//串口從超級(jí)終端接收數(shù)據(jù)Uart_SendByten(0,c1[0]);//串口向超級(jí)終端發(fā)送數(shù)據(jù)}}

/*****串口0向發(fā)送數(shù)據(jù)子函數(shù)*******/voidUart_SendByten(intUartnum,U8data){ while(!(rUTRSTAT0&0x4));// hudelay(10);//延時(shí) WrUTXH0(data);//}

/******串口0接收數(shù)據(jù)子函數(shù)*****/charUart_Getchn(char*Revdata,intUartnum,inttimeout){ while(!(rUTRSTAT0&0x1));// *Revdata=RdURXH0();// returnTRUE;//串口0接收數(shù)據(jù)成功返回}

4.8嵌入式C語(yǔ)言程序設(shè)計(jì)技巧4.8.1變量定義4.8.2參數(shù)傳遞4.8.3循環(huán)條件4.8.1變量定義

在變量聲明的時(shí)候,最好把所有相同類型的變量放在一起定義,這樣可以優(yōu)化存儲(chǔ)器布局。由下例可以看出:對(duì)于局部變量類型的定義,使用short或char來(lái)定義變量并不是總能節(jié)省存儲(chǔ)空間。有時(shí)使用32位int或unsinged

int局部變量更有效率一些,如下圖所示:變量定義中,為了精簡(jiǎn)程序,程序員總是竭力避免使用冗余變量。但有時(shí)使用冗余變量可以減少存儲(chǔ)器訪問(wèn)的次數(shù)這可以提高系統(tǒng)性能。

4.8.2參數(shù)傳遞

為了使單獨(dú)編譯的C語(yǔ)言程序和匯編程序能夠互相調(diào)用,定義了統(tǒng)一的函數(shù)過(guò)程調(diào)用標(biāo)準(zhǔn)ATPCS。ATPCS定義了寄存器組中的{R0~R3}作為參數(shù)傳遞和結(jié)果返回寄存器,如果參數(shù)數(shù)目超過(guò)四個(gè),則使用堆棧進(jìn)行傳遞。內(nèi)部寄存器的訪問(wèn)速度是遠(yuǎn)遠(yuǎn)大于存儲(chǔ)器的,所以要盡量使參數(shù)傳遞在寄存器里面進(jìn)行,即應(yīng)盡量把函數(shù)的參數(shù)控制在四個(gè)以下。4.8.3循環(huán)條件

計(jì)數(shù)循環(huán)是程序中十分常用的流程控制結(jié)構(gòu),一般有以下兩種形式:for(loop=1;loop<=limit;loop++)

for(loop=limit;loop!=0;loop--)這兩種循環(huán)形式在邏輯上并沒(méi)有效率差異,但是映射到具體的體系結(jié)構(gòu)中時(shí),就產(chǎn)生了很大的不同,如下圖所示。

4.9C與匯編語(yǔ)言混合編程4.9.1ATPCS介紹4.9.2內(nèi)嵌匯編4.9.3C和ARM匯編程序間相互調(diào)用4.9.1ATPCS介紹

ATPCS(ARM-ThumbProduceCallStandard)是ARM程序和Thumb程序中子程序調(diào)用的基本規(guī)則,目的是為了使單獨(dú)編譯的C語(yǔ)言程序和匯編程序之間能夠相互調(diào)用。這些基本規(guī)則包括子程序調(diào)用過(guò)程中寄存器的使用規(guī)則、數(shù)據(jù)棧的使用規(guī)則和參數(shù)的傳遞規(guī)則。

寄存器的使用規(guī)則寄存器別名特殊名使用規(guī)則R0a1

參數(shù)/結(jié)果/scratch寄存器1R1a2

參數(shù)/結(jié)果/scratch寄存器2R2a3

參數(shù)/結(jié)果/scratch寄存器3R3a4

參數(shù)/結(jié)果/scratch寄存器4R4v1

ARM狀態(tài)局部變量寄存器1R5v2

ARM狀態(tài)局部變量寄存器2R6v3

ARM狀態(tài)局部變量寄存器3R7v4wrARM狀態(tài)局部變量寄存器4Thumb狀態(tài)工作寄存器R8v5

ARM狀態(tài)局部變量寄存器5R9v6sbARM狀態(tài)局部變量寄存器6,在支持RWPI的ATPCS中為靜態(tài)基址寄存器R10v7slARM狀態(tài)局部變量寄存器7,在支持?jǐn)?shù)據(jù)棧檢查的ATPCS中為數(shù)據(jù)棧限制指針R11v8fpARM狀態(tài)局部變量寄存器8/幀指針R12

ip子程序內(nèi)部調(diào)用的scratch寄存器R13

sp數(shù)據(jù)棧指針R14

lr連接寄存器R15

pc程序計(jì)數(shù)器數(shù)據(jù)棧的使用規(guī)則根據(jù)堆棧指針指向位置的不同和增長(zhǎng)方向的不同可以分為以下4種數(shù)據(jù)棧:

FD(FullDescending)

滿遞減

ED(EmptyDescending)空遞減

FA(FullAscending)

滿遞增

EA(EmptyAscending)

空遞增ATPCS規(guī)定數(shù)據(jù)棧為FD(滿遞減)類型,并且對(duì)數(shù)據(jù)棧的操作是8字節(jié)對(duì)齊的。

參數(shù)的傳遞規(guī)則參數(shù)個(gè)數(shù)固定的子程序參數(shù)傳遞規(guī)則:第一個(gè)整數(shù)參數(shù),通過(guò)寄存器R0~R3來(lái)傳遞。其他參數(shù)通過(guò)數(shù)據(jù)棧傳遞。

參數(shù)個(gè)數(shù)可變的子程序參數(shù)傳遞規(guī)則:當(dāng)參數(shù)不超過(guò)4個(gè)時(shí),可以使用寄存器R0~R3來(lái)傳遞參數(shù);當(dāng)參數(shù)超過(guò)4個(gè)時(shí),還可以使用數(shù)據(jù)棧來(lái)傳遞參數(shù)子程序結(jié)果返回規(guī)則

結(jié)果為一個(gè)32位的整數(shù)時(shí),可以通過(guò)寄存器R0返回;結(jié)果為一個(gè)64位整數(shù)時(shí),可以通過(guò)寄存器R0和R1返回,依次類推。

NEXT4.9.2內(nèi)嵌匯編

在C程序中嵌入?yún)R編程序可以實(shí)現(xiàn)一些高級(jí)語(yǔ)言沒(méi)有的功能,并可以提高執(zhí)行效率。內(nèi)嵌的匯編指令包括大部分的ARM指令和Thumb指令,但是不能直接引用C的變量定義,數(shù)據(jù)交換必須通過(guò)ATPCS進(jìn)行。嵌入式匯編在形式上表現(xiàn)為獨(dú)立定義的函數(shù)體。內(nèi)嵌匯編指令的語(yǔ)法格式

__asm(“指令[;指令]”);ARMC匯編器使用關(guān)鍵字“__asm"。如果有多條匯編指令需要嵌入,可以用“{}”將它們歸為一條語(yǔ)句。如:__asm{ 指令[;指令] … [指令]}需要特別注意的是__asm是兩個(gè)下劃線。

內(nèi)嵌匯編指令的應(yīng)用舉例4.9.3C和ARM匯編程序間相互調(diào)用

在C和ARM匯編程序之間相互調(diào)用必須遵守ATPCS(ARM-ThumbProcedureCallStandard)規(guī)則。C和匯編之間的相互調(diào)用可以從以下這三方面來(lái)介紹:匯編程序?qū)全局變量的訪問(wèn)在C語(yǔ)言程序中調(diào)用匯編程序在匯編程序中調(diào)用C語(yǔ)言程序匯編程序訪問(wèn)全局C變量

匯編程序可以通過(guò)地址間接訪問(wèn)在C語(yǔ)言程序中聲明的全局變量。通過(guò)使用IMPORT關(guān)鍵詞引人全局變量,并利用LDR和STR指令根據(jù)全局變量的地址可以訪問(wèn)它們。對(duì)于不同類型的變量,需要采用不同選項(xiàng)的LDR和STR指令,如下所示:

unsignedchar LDRB/STRBunsignedshort LDRH/STRHunsignedint LDR/STRchar

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論