www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式硬件
[導(dǎo)讀]引 言計(jì)算機(jī)編程語(yǔ)言的關(guān)鍵字就好比是它的靈魂,只有深入理解了它們的含義才能編寫(xiě)出優(yōu)秀的代碼。C語(yǔ)言以其簡(jiǎn)潔、高效和強(qiáng)大等特性成為嵌入式軟件編程的首選語(yǔ)言,但是某些

引 言

計(jì)算機(jī)編程語(yǔ)言的關(guān)鍵字就好比是它的靈魂,只有深入理解了它們的含義才能編寫(xiě)出優(yōu)秀的代碼。C語(yǔ)言以其簡(jiǎn)潔、高效和強(qiáng)大等特性成為嵌入式軟件編程的首選語(yǔ)言,但是某些關(guān)鍵字,例如const、static、extern和volatile等,在不同的場(chǎng)合具有不同的含義,而且某些用法晦澀難懂,為此本文詳細(xì)介紹這些關(guān)鍵字的用法及其背后的原理。

1 const

const限定的對(duì)象表示編譯器可以將它放在只讀存儲(chǔ)器中,也就意味著在對(duì)其進(jìn)行初始化之后就不能改變它的值。根據(jù)const使用的不同場(chǎng)合,大致可以分為三種情況,其一限定普通變量,其二限定函數(shù)參數(shù),其三限定指針變量。

第一和第二種情況最為簡(jiǎn)單,語(yǔ)句①和語(yǔ)句②分別展示了它的用法。語(yǔ)句①定義了一個(gè)值為10的整型常量。語(yǔ)句②中的const表示在函數(shù)體中不能修改src 指向的區(qū)域中的數(shù)據(jù),這與函數(shù)的拷貝功能相對(duì)應(yīng),只做它應(yīng)該做的事情而不應(yīng)該有其他副作用,編譯器可以利用這些信息進(jìn)行適當(dāng)?shù)膬?yōu)化。

①const int i=10;

②void*memcpy(void * dst,const void * src,size_t size);

③const int *ptr;

④int const *ptr;

⑤int*const ptr;

⑥int const*cons ptr;

第3種情況最為復(fù)雜,雖然只是const位置不同,但是卻可能具有完全不同的意義。一般,一個(gè)聲明語(yǔ)句由聲明說(shuō)明符(decl-specifier)和一系列聲明子(declarator)兩部分組成,而且聲明說(shuō)明符中的符號(hào)可以以任何次序出現(xiàn)。理解聲明的第一步是定位說(shuō)明符和聲明子的邊界。這很容易:所有的說(shuō)明符都是關(guān)鍵字或者類(lèi)型名,因此說(shuō)明符終止于第一個(gè)不是以上類(lèi)型之一的符號(hào)。例如,在語(yǔ)句③和④中第一個(gè)既不是關(guān)鍵字也不是類(lèi)型名的符號(hào)是“*”,即聲明說(shuō)明符分別為const.int和int const,由于聲明說(shuō)明符中的符號(hào)可以以任意次序出現(xiàn),因此語(yǔ)句③和④的含義是相同的。

為了迅速弄清語(yǔ)句表達(dá)的含義,參考文獻(xiàn)[1]介紹了一種簡(jiǎn)便的方法,其要點(diǎn)就是“逆序讀出定義”,如圖1所示。

 

 

2 static與extem

static的含義隨著出現(xiàn)位置(全局變量還是局部變量)和修飾對(duì)象(變量還是函數(shù))的不同而有很大的差別。下面各條目中的模塊指的是一個(gè)源文件或者一個(gè)翻譯單元:

①位于函數(shù)體中的靜態(tài)變量在多次函數(shù)調(diào)用間會(huì)維持其值。

②位于模塊內(nèi)(但在函數(shù)體外)的靜態(tài)變量可以被模塊內(nèi)的所有函數(shù)訪問(wèn),但不能被模塊外其他函數(shù)訪問(wèn)。也就是說(shuō),它是一個(gè)本地的全局變量。

③位于模塊內(nèi)的靜態(tài)函數(shù)只能被此模塊內(nèi)的其他函數(shù)調(diào)用。也就是說(shuō),這個(gè)函數(shù)的作用域?yàn)槁暶魉诘哪K。

 

為了清楚地理解static的3種用法,必須首先了解C語(yǔ)言中每個(gè)標(biāo)識(shí)符都具有的作用域、鏈接和存儲(chǔ)持續(xù)期等特性的含義。在ISO C99標(biāo)準(zhǔn)中,其定義如下:

①對(duì)象的作用域指的是它僅在程序的某個(gè)區(qū)域中是可見(jiàn)的(即可以使用)。常見(jiàn)的作用域有文件作用域和塊作用域。

②對(duì)象的存儲(chǔ)持續(xù)期決定對(duì)象的生命周期,即在程序執(zhí)行某段區(qū)間中為對(duì)象保留存儲(chǔ)區(qū)。有兩種類(lèi)型的存儲(chǔ)持續(xù)期:靜態(tài)的和自動(dòng)的。靜態(tài)存儲(chǔ)持續(xù)期的對(duì)象的生命周期為程序執(zhí)行的全過(guò)程,它的值在程序啟動(dòng)前僅初始化一次。

③鏈接指的是在不同作用域中聲明的或者同一個(gè)作用域中多次聲明的標(biāo)識(shí)符可以引用相同的對(duì)象或函數(shù)。有3種類(lèi)型的鏈接:外部、內(nèi)部和無(wú)。在情況②和③ 中,static分別用來(lái)修飾全局變量glob-al和函數(shù)foo,改變它們的鏈接特性,使它們具有內(nèi)部鏈接。也就是說(shuō),只有在定義它們的翻譯單元或者文件內(nèi)才能使用它們,這對(duì)于創(chuàng)建模塊化的軟件非常重要。

與static相反,extern修飾的對(duì)象或函數(shù)具有外部鏈接。對(duì)于那些暴露給外部使用的接口函數(shù)應(yīng)該使用ex-tern限定,那些非接口函數(shù),例如工具函數(shù)或與實(shí)現(xiàn)細(xì)節(jié)相關(guān)的函數(shù),則應(yīng)該顯式地使用static限定。這是因?yàn)槿绻瘮?shù)聲明不帶任何存儲(chǔ)類(lèi)說(shuō)明符,那么它具有外部鏈接就好像使用了 extern一樣。

在情況①中,static用來(lái)修飾局部變量local,將local的存儲(chǔ)持續(xù)期由自動(dòng)的改變?yōu)殪o態(tài)的,這樣在foo函數(shù)的多次調(diào)用間會(huì)為其保留值。注意作用域、鏈接和存儲(chǔ)持續(xù)期特性之間是正交的。例如在情況①中,雖然變量local的存儲(chǔ)持續(xù)期變成靜態(tài)的,但是它的作用域仍然是塊作用域。

3 volatile

volatile關(guān)鍵字用來(lái)聲明這樣的對(duì)象,它們的值可能由于程序控制之外的事件而被潛在改變。volatile強(qiáng)制編譯器不會(huì)對(duì)其所限定的對(duì)象進(jìn)行任何優(yōu)化,每次讀寫(xiě)都必須訪問(wèn)實(shí)際的存儲(chǔ)器而不能使用寄存器中的副本。在實(shí)踐中,它大量的用來(lái)描述一個(gè)對(duì)應(yīng)于內(nèi)存映射的輸入/輸出端口,例如飛利浦公司 LPC21xx系列ARM處理器的向量地址寄存器定義為:

#define VICVectAddr (*((volatile unsigned long*)0xFFFFF030))

其次,中斷服務(wù)例程中使用的非自動(dòng)變量或者多線程應(yīng)用程序中多個(gè)任務(wù)共享的變量也必須使用volatile進(jìn)行限定。例如在下面的示例中,如果沒(méi)有使用 volatile限定g_Flag變量,編譯器看到在foo函數(shù)中并沒(méi)有修改g_Flag,可能只執(zhí)行一次g_Flag讀操作并將g_Flag的值緩存在寄存器中,以后每次g_Flag讀操作都使用寄存器中的緩存值而不進(jìn)行存儲(chǔ)器訪問(wèn),導(dǎo)致some_action函數(shù)永遠(yuǎn)無(wú)法執(zhí)行。

 

[!--empirenews.page--]

4 Dacked

嵌入式軟件編程中,經(jīng)常需要精確控制結(jié)構(gòu)體在內(nèi)存中的布局和訪問(wèn)非自然對(duì)齊的數(shù)據(jù),但是C語(yǔ)言標(biāo)準(zhǔn)中并沒(méi)有統(tǒng)一的規(guī)定而是留給編譯器廠商自行處理。在 ARM C編譯器中,使用__packed關(guān)鍵字將任何類(lèi)型的對(duì)齊設(shè)置為1字節(jié)。在實(shí)踐中,__packed主要有兩個(gè)功能:其一,當(dāng)它修飾指針時(shí),表示此指針指向的地址是非自然對(duì)齊的,編譯器會(huì)生成特殊的代碼以確保獲得正確的結(jié)果;其二,當(dāng)它修飾結(jié)構(gòu)體、聯(lián)合或它們中的域時(shí),可以用來(lái)創(chuàng)建沒(méi)有填充的結(jié)構(gòu)。

與其他RISC架構(gòu)一樣,ARM處理器能夠高效地訪問(wèn)對(duì)齊的數(shù)據(jù),即字地址的末尾兩位為零,半字地址的最后一位為零,也稱這樣的數(shù)據(jù)位于它的自然大小邊界或者是自然對(duì)齊的。ARM編譯器希望普通的“C”指針指向一個(gè)4字節(jié)對(duì)齊內(nèi)存地址,這樣它可以在代碼中使用LDR/STR指令一次操作4個(gè)字節(jié),否則只能使用LDRB/LDRH等字節(jié)/半字操作指令。相反如果指針指向一個(gè)非自然對(duì)齊的地址,例如如果一個(gè)整型指針指向地址0x8006,當(dāng)然希望裝載地址 0xS006-0xS007-0x8008-0xS009處的數(shù)據(jù),但是實(shí)際上ARM會(huì)對(duì)非自然對(duì)齊的地址進(jìn)行轉(zhuǎn)換而從裝載地址 0xS004-0xS005-0x8006-0xS007處的數(shù)據(jù)。在下面的示例中(測(cè)試環(huán)境為uVision3),首先定義了一個(gè)大小為16字節(jié)的整型數(shù)組,依次初始化為0,1,2,…,15。由于array是一個(gè)整型數(shù)組,編譯器會(huì)確保它是4字節(jié)對(duì)齊的,即指針pc指向一個(gè)4字節(jié)對(duì)齊的地址。運(yùn)行程序后,可以看到如果對(duì)pc指針不加__packed標(biāo)記進(jìn)行修飾,將得到一個(gè)奇怪的0x01000302;而在添加了__packed關(guān)鍵字之后,就得到了正確的結(jié)果。也就是說(shuō),如果要訪問(wèn)非自然對(duì)齊的數(shù)據(jù),必須使用__packed關(guān)鍵字顯式地標(biāo)記出來(lái)。

 

ARM編譯器總是保證程序中的變量、結(jié)構(gòu)體或聯(lián)合中的域分配到自然對(duì)齊的地址。這意味著編譯器經(jīng)常需要在各個(gè)域之間插入填充,以確保每個(gè)域的自然對(duì)齊。通常來(lái)說(shuō),程序員可以對(duì)這些填充視而不見(jiàn),但是也有例外,例如為了節(jié)省結(jié)構(gòu)體占用的空間,可以利用__packed去除填充。在了解了編譯器的填充行為之后,可以通過(guò)調(diào)整域的順序來(lái)減小結(jié)構(gòu)體占用的空間。例如雖然結(jié)構(gòu)體s1和s2的域相同,但是sizeof(s1)等于16,而sizeof(s2)等于 12。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(chē)(EV)作為新能源汽車(chē)的重要代表,正逐漸成為全球汽車(chē)產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車(chē)的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車(chē)的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車(chē) 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車(chē)場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周?chē)娮釉O(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉