91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

嵌入式C開(kāi)發(fā)關(guān)鍵字的應(yīng)用技巧

硬件攻城獅 ? 來(lái)源:嵌入式系統(tǒng) ? 作者:嵌入式系統(tǒng) ? 2022-12-12 14:51 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

摘要:嵌入式C開(kāi)發(fā)關(guān)鍵字的應(yīng)用技巧

1、volatile

volatile修飾表示變量是易變的,編譯器中的優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地從內(nèi)存中重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份,有效的防止編譯器自動(dòng)優(yōu)化,從而與軟件設(shè)計(jì)相符合。

中斷服務(wù)與主程序共享變量:

//volatileuint8_tflag=1;
uint8_tflag=1;

voidtest(void)
{
while(flag)
{
//dosomething
}
}

//interruptserviceroutine
voidisr_test(void)
{
flag=0;
}

如果沒(méi)使用volatile定義flag,可能在優(yōu)化后test陷入死循環(huán),因?yàn)閠est里使用的flag并沒(méi)修改它,開(kāi)啟優(yōu)化后,編譯器可能會(huì)固定從某個(gè)內(nèi)存取值。例如:

for(inti=0;i<100000;i++);
//對(duì)比
for(volatileinti=0;i<100000;i++);

前者可能被優(yōu)化掉,雖然編碼本意是需要執(zhí)行操作延時(shí),但編譯器認(rèn)為代碼無(wú)意義。

總的來(lái)說(shuō),volatile是告知編譯器,不管代碼如何,必須保留,而且使用時(shí)需要重新從內(nèi)存讀取更新,不能使用先前讀取的緩存,一般在驅(qū)動(dòng)代碼中使用較多。

2、const

const是恒定不變的意思,其修飾的各種數(shù)據(jù)類似只讀效果。

1、 修飾變量

采用const修飾變量,即變量聲明為只讀,保護(hù)變量值以防被修改。例如

constinti=1;

上面這個(gè)例子表明,變量i具有只讀特性,不能夠被更改;若想對(duì)i重新賦值,如i = 10;屬于錯(cuò)誤操作。

特別說(shuō)明,定義變量的同時(shí)進(jìn)行初始化,寫(xiě)成int const i=1,是正確的。

2、 修飾數(shù)組

C語(yǔ)言中const還可以修飾數(shù)組,舉例如下:

constintarray[5]={1,2,3,4,5};
array[0]=array[0]+1;//錯(cuò)誤,array是只讀的,禁止修改

數(shù)組元素與變量類似,具有只讀屬性,不能被更改;一旦更改,編譯時(shí)就會(huì)報(bào)錯(cuò)。

使用大數(shù)組存儲(chǔ)固定的信息,例如查表(表驅(qū)動(dòng)法的鍵值表),可以使用const節(jié)省ram。編譯器并不給普通const只讀變量分配空間,而是將它們保存到符號(hào)表中,無(wú)需讀寫(xiě)內(nèi)存操作,程序執(zhí)行效率也會(huì)提高。

3、 修飾指針

C語(yǔ)言中const修飾指針要特別注意,共有兩種形式,一種是用來(lái)限定指向空間的值不能修改;另一種是限定指針不可更改。舉例如下:

inti=1;
intj=2;

constint*p1=&i;
int*constp2=&j;

上面定義了兩個(gè)指針p1和p2,區(qū)別是const后面是指針本身還是指向的內(nèi)容。

在定義1中const限定的是* p1,即其指向空間的值不可改變,若改變其指向空間的值如* p1=10,則程序會(huì)報(bào)錯(cuò);但p1的值是可以改變的,對(duì)p1重新賦值如p1=&k是沒(méi)有任何問(wèn)題的。

在定義2中const限定的是指針p2,若改變p2的值如p2=&k,程序?qū)?huì)報(bào)錯(cuò);但* p2,即其所指向空間的值可以改變,如* p2=20是沒(méi)有問(wèn)題的,程序正常執(zhí)行。

4、 修飾函數(shù)參數(shù)

const關(guān)鍵字修飾函數(shù)參數(shù),對(duì)參數(shù)起限定作用,防止其在函數(shù)內(nèi)部被修改。所限定的函數(shù)參數(shù)可以是普通變量,也可以是指針變量。例如:

voidfun(constinti)
{
……
i++;//對(duì)i的值進(jìn)行了修改,程序報(bào)錯(cuò)
}

常用的函數(shù)如strlen

size_tstrlen(constchar*string);

const在庫(kù)函數(shù)中使用非常普遍,是一種自我保護(hù)的安全編碼思維。

3、struct與union

對(duì)于struct 結(jié)構(gòu)體和union共聯(lián)體在嵌入式領(lǐng)域是使用得非常頻繁的,一些可編程芯片提供的寄存器庫(kù)都是采用結(jié)構(gòu)體和共聯(lián)體結(jié)合的方式來(lái)提供給軟件人員進(jìn)行開(kāi)發(fā),同時(shí)在平時(shí)的編碼過(guò)程中這兩個(gè)數(shù)據(jù)類型的靈活應(yīng)用也能夠?qū)崿F(xiàn)代碼更好的封裝與簡(jiǎn)化。

如下面的簡(jiǎn)單示例,就可以非常靈活的訪問(wèn)Val中的bit位。

typedefunion
{
BYTEVal;
struct__packed
{
BYTEb0:1;
BYTEb1:1;
BYTEb2:1;
BYTEb3:1;
BYTEb4:1;
BYTEb5:1;
BYTEb6:1;
BYTEb7:1;
}bits;
}BYTE_VAL,BYTE_BITS;

其中:1表示按位操作。不只是位-字節(jié)可以,單字節(jié)與多字節(jié)也可以簡(jiǎn)化拼接。

#include"stdio.h"

typedefstruct
{
union
{
struct
{
unsignedcharlow;
unsignedcharhigh;
};
unsignedshortresult;
};
}test_t;


intmain(intargc,char*argv[])
{
test_thello;

hello.high=0x12;
hello.low=0x34;

printf("result=%04X
",hello.result);//輸出result=1234

return0;
}

運(yùn)行輸出 result=1234 (win7系統(tǒng)下QT開(kāi)發(fā)環(huán)境),原本需要 (high<<8)|low 運(yùn)算,可以簡(jiǎn)化為共用體類型自動(dòng)完成,但必須注意平臺(tái)的字節(jié)順序,屬于大端還是小端模式。

在應(yīng)用層面,如果明確某個(gè)數(shù)據(jù)可能存在兩種可能,而且兩種結(jié)果不會(huì)同時(shí)存在,也可以使用結(jié)構(gòu)體與共用體組合的方式,確保模塊對(duì)外接口統(tǒng)一。

例如移動(dòng)通信模塊,使用數(shù)據(jù)結(jié)構(gòu)保存其基站信息,因?yàn)橹剖讲煌?,模塊可能工作在2G-GSM,也可能在4G-Cat1,為保證上層讀取基站信息接口唯一,使用共用體就非常合適,否則需定義兩套接口。如果覺(jué)得文章可以,可關(guān)注微信公眾號(hào)【嵌入式系統(tǒng)】獲取更多信息。

4、預(yù)定義標(biāo)識(shí)符

一般編譯器都支持預(yù)定義標(biāo)識(shí)符,這些標(biāo)識(shí)符結(jié)合printf等打印信息幫助程序員調(diào)試程序是非常有用的,一般編譯器會(huì)自動(dòng)根據(jù)用戶指定完成替換和處理。

部分標(biāo)識(shí):

__FILE__//表示編譯的源文件名
__LINE__//表示當(dāng)前文件的行號(hào)
__FUNCTION__//表示函數(shù)名
__DATE__//表示編譯日期
__TIME__//表示編譯時(shí)間

使用范例:

printf("file:%s,line:%d,date:%s,time:%s",__FILE__,__LINE__,__DATE__,__TIME__);

這些比較常見(jiàn),主要用于日志分析、版本記錄,便于調(diào)試。

5、#與##

#:是一種運(yùn)算符,用于帶參宏的文本替換,將跟在后面的參數(shù)轉(zhuǎn)成一個(gè)字符串常量。

##:是一種運(yùn)算符,是將兩個(gè)運(yùn)算對(duì)象連接在一起,也只能出現(xiàn)在帶參宏定義的文本替換中。

#include"stdio.h"

#defineTO_STR(s)#s
#defineCOMB(str1,str2)str1##str2

intmain(intargc,char*argv[])
{
intUART0=115200;

printf("UART0=%d
",COMB(UART,0));//字符串合并為變量UART0
printf("%s
",TO_STR(3.14));//將數(shù)字變成字符串

return0;
}

6、void 與 void*

void表示的是無(wú)類型,不能聲明變量或常量,但是可以把指針定義為void類型,如void* ptr。void* 指針可以指向任意類型的數(shù)據(jù),在C語(yǔ)言指針操作中,任意類型的數(shù)據(jù)地址都可轉(zhuǎn)為void* 指針。因?yàn)橹羔槺举|(zhì)上都是unsigned int。

常用的內(nèi)存塊操作庫(kù)函數(shù):

void*memcpy(void*dest,constvoid*src,size_tlen);
void*memset(void*buffer,intc,size_tnum);

數(shù)據(jù)指針為void* 類型,對(duì)傳入任意類型數(shù)據(jù)的指針都可以操作。另外其中memcpy第二個(gè)參數(shù),const現(xiàn)在也如前文所述,拷貝時(shí)對(duì)傳入的原數(shù)據(jù)內(nèi)容禁止修改。

特殊說(shuō)明,指針是不能使用sizeof求內(nèi)容大小的,在ARM系統(tǒng)固定為int 4字節(jié)。對(duì)于函數(shù)無(wú)輸入?yún)?shù)的,也盡量加上void,如

voidfun(void);

7、weak

一般簡(jiǎn)化定義

#define_WEAK__attribute__((weak))

函數(shù)名稱前面加上__WEAK屬性修飾符稱為“弱函數(shù)”,類似C++的虛函數(shù)。鏈接時(shí)優(yōu)先鏈接為非weak定義的函數(shù),如果找不到則再鏈接帶weak函數(shù)。

_WEAKvoidfun(void)
{
//dothis
}

//不在同一個(gè).c,兩同名函數(shù)不能在同一個(gè)文件
voidfun(void)
{
//dothat
}

這種自動(dòng)選擇的機(jī)制,在代碼移植和多模塊配合工作的場(chǎng)景下應(yīng)用較多。例如前期移植代碼,需要調(diào)用某個(gè)接口fun,但當(dāng)前該接口不存在或者未移植完整使用,可以使用weak關(guān)鍵字定義為空函數(shù)先保證編譯正常。后續(xù)移植完成實(shí)現(xiàn)了fun,即軟件中有2個(gè)fun函數(shù)沒(méi)有任何錯(cuò)誤,編譯器自動(dòng)會(huì)識(shí)別使用后者。當(dāng)然也粗暴的#if 0屏蔽對(duì)fun的調(diào)用,但要確保后續(xù)記得放開(kāi)。

8、總結(jié)

存在即合理,C語(yǔ)言里面的關(guān)鍵字,每個(gè)都有其特殊的意義,只是一般使用較少,譬如作文,使用常用的漢字可以;但引經(jīng)據(jù)典,使用特殊的修飾辭藻更能顯出水平。后續(xù)對(duì)section 進(jìn)行詳細(xì)說(shuō)明,它和動(dòng)態(tài)加載(OTA)、接口自啟動(dòng)相關(guān)。

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5200

    文章

    20458

    瀏覽量

    334328
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    183

    文章

    7644

    瀏覽量

    145651
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1672

    瀏覽量

    51672

原文標(biāo)題:8、總結(jié)

文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Parasoft C/C++test:嵌入式安全關(guān)鍵行業(yè)的一體化軟件測(cè)試解決方案

    縫融入 DevOps 的自動(dòng)化測(cè)試工具。Parasoft C/C++test 正是為解決這一痛點(diǎn)而生,它是面向嵌入式安全關(guān)鍵行業(yè)的集成軟件測(cè)試解決方案,憑借全面的自動(dòng)化能力與深度流程適
    的頭像 發(fā)表于 03-06 09:42 ?261次閱讀

    什么是嵌入式應(yīng)用開(kāi)發(fā)?

    概述 所謂的嵌入式應(yīng)用開(kāi)發(fā)就是在嵌入式操作系統(tǒng)下進(jìn)行開(kāi)發(fā)、軟硬件綜合開(kāi)發(fā) ?嵌入式應(yīng)用
    發(fā)表于 01-12 16:13

    C語(yǔ)言嵌入式系統(tǒng)編程注意事項(xiàng)-內(nèi)存操作

    C語(yǔ)言嵌入式系統(tǒng)編程注意事項(xiàng)之內(nèi)存操作 在嵌入式系統(tǒng)的編程中,常常要求在特定的內(nèi)存單元讀寫(xiě)內(nèi)容,匯編有對(duì)應(yīng)的MOV指令,而除C/C++以外的
    發(fā)表于 01-04 07:31

    關(guān)鍵字volatile的含意

    關(guān)鍵字volatile有什么含意? 一個(gè)定義為volatile的變量是說(shuō)這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。精確地說(shuō)就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心
    發(fā)表于 12-23 06:33

    interrupt關(guān)鍵字使用

    中斷是嵌入式系統(tǒng)中重要的組成部分,這導(dǎo)致了很多編譯開(kāi)發(fā)商提供一種擴(kuò)展—讓標(biāo)準(zhǔn)C支持中斷。具代表事實(shí)是,產(chǎn)生了一個(gè)新的關(guān)鍵字__interrupt。下面的代碼就使用了__interrup
    發(fā)表于 12-22 09:36

    C語(yǔ)言單元測(cè)試在嵌入式軟件開(kāi)發(fā)中的作用及專業(yè)工具的應(yīng)用

    平臺(tái)和操作系統(tǒng)上運(yùn)行,無(wú)需進(jìn)行大量的修改 二、C語(yǔ)言單元測(cè)試在嵌入式開(kāi)發(fā)中的關(guān)鍵作用 嵌入式系統(tǒng)對(duì)實(shí)時(shí)性和可靠性要求極高,單元測(cè)試是確保代碼質(zhì)量的關(guān)
    發(fā)表于 12-18 11:46

    Temu跨境電商按關(guān)鍵字搜索Temu商品API的應(yīng)用及接口請(qǐng)求示例

    Temu跨境電商按關(guān)鍵字搜索Temu商品API的應(yīng)用及接口請(qǐng)求示例 Temu跨境電商按關(guān)鍵字搜索Temu商品API的應(yīng)用場(chǎng)景 Temu跨境電商平臺(tái)按關(guān)鍵字搜索Temu商品API的主要應(yīng)用場(chǎng)景包括但不
    的頭像 發(fā)表于 11-29 15:08 ?479次閱讀

    哪些場(chǎng)合會(huì)用到volatile關(guān)鍵字?

    當(dāng)你理解 volatile關(guān)鍵字的含義之后,你就能明白,其實(shí)很多場(chǎng)合都能用到 volatile關(guān)鍵字。 1.全局變量單片機(jī)開(kāi)發(fā),難免會(huì)用到全局變量。一些初級(jí)工程師,更是全局變量滿天飛。這種情況下
    發(fā)表于 11-25 08:19

    C語(yǔ)言在嵌入式開(kāi)發(fā)中的應(yīng)用

    C 語(yǔ)言在汽車(chē)電子控制系統(tǒng)開(kāi)發(fā)中的主導(dǎo)地位。 2、設(shè)備驅(qū)動(dòng)程序 設(shè)備驅(qū)動(dòng)程序是嵌入式系統(tǒng)中連接硬件和軟件的橋梁,它負(fù)責(zé)實(shí)現(xiàn)嵌入式系統(tǒng)與外部設(shè)備之間的通信和控制。
    發(fā)表于 11-21 08:09

    嵌入式開(kāi)發(fā)關(guān)鍵點(diǎn)介紹

    。 嵌入式開(kāi)發(fā)關(guān)鍵點(diǎn): 1. 硬件限制: 嵌入式系統(tǒng)通常具有嚴(yán)格的硬件限制,例如處理器速度、內(nèi)存和存儲(chǔ)容量等。因此,嵌入式開(kāi)發(fā)需要考慮這些限制,并編寫(xiě)高效的代碼以確保系統(tǒng)的可靠性和性
    發(fā)表于 11-13 08:12

    亞馬遜平臺(tái)根據(jù)關(guān)鍵字搜索商品API接口

    ? ?在電商開(kāi)發(fā)中,集成亞馬遜平臺(tái)的商品搜索功能是常見(jiàn)需求。通過(guò)亞馬遜的Product Advertising API(PAAPI),開(kāi)發(fā)者可以根據(jù)關(guān)鍵字高效檢索商品信息。本技術(shù)帖將逐步介紹如何調(diào)用
    的頭像 發(fā)表于 11-05 15:00 ?382次閱讀
    亞馬遜平臺(tái)根據(jù)<b class='flag-5'>關(guān)鍵字</b>搜索商品API接口

    micro 關(guān)鍵字搜索全覆蓋商品,并通過(guò) API 接口提供實(shí)時(shí)數(shù)據(jù)

    micro 關(guān)鍵字搜索全覆蓋商品”并通過(guò) API 接口提供實(shí)時(shí)數(shù)據(jù)
    的頭像 發(fā)表于 07-13 10:13 ?895次閱讀

    嵌入式開(kāi)發(fā)入門(mén)指南:從零開(kāi)始學(xué)習(xí)嵌入式

    特定功能的計(jì)算機(jī)系統(tǒng),廣泛應(yīng)用于智能家居、工業(yè)控制、醫(yī)療設(shè)備、車(chē)載系統(tǒng)等領(lǐng)域。 2. 學(xué)習(xí)嵌入式開(kāi)發(fā)的前置知識(shí)熟悉C語(yǔ)言編程掌握基本的數(shù)據(jù)結(jié)構(gòu)與算法了解數(shù)字電路與微控制器原理熟悉Linux操作系統(tǒng)
    發(fā)表于 05-15 09:29

    單片機(jī)編程關(guān)鍵字之volatile

    volatile 修飾的變量是說(shuō)這變量可能會(huì)被意想不到地改變。通常對(duì)于程序員而言,單片機(jī) 中用的就算常見(jiàn)了volatile 是易變的,不穩(wěn)定的意思。其實(shí)對(duì)于很多人來(lái)說(shuō),根本沒(méi)見(jiàn)過(guò)這個(gè)關(guān)鍵字,不 知道
    發(fā)表于 04-02 13:47 ?2次下載

    嵌入式主板開(kāi)發(fā)詳細(xì)指南

    嵌入式主板開(kāi)發(fā)涉及硬件設(shè)計(jì)、軟件集成、系統(tǒng)優(yōu)化等多個(gè)環(huán)節(jié),需要結(jié)合具體應(yīng)用場(chǎng)景進(jìn)行深度定制。以下是嵌入式主板開(kāi)發(fā)的詳細(xì)指南,涵蓋關(guān)鍵步驟、工
    的頭像 發(fā)表于 04-02 11:35 ?1390次閱讀
    <b class='flag-5'>嵌入式</b>主板<b class='flag-5'>開(kāi)發(fā)</b>詳細(xì)指南