在嵌入式開(kāi)發(fā)軟件中回調(diào)函數(shù)是經(jīng)常接觸的一種軟件設(shè)計(jì)方法,像我們的事件處理機(jī)制基本上都會(huì)使用到回調(diào)函數(shù)。
那么就抽了點(diǎn)時(shí)間來(lái)聊聊他們:
什么是回調(diào)函數(shù)?
在C語(yǔ)言中,回調(diào)函數(shù)其實(shí)與函數(shù)指針的調(diào)用在語(yǔ)法上并沒(méi)有太大的差異,而為什么叫回調(diào)函數(shù)主要還是從功能上給它起的名字,即這個(gè)函數(shù)會(huì)被"返回來(lái)調(diào)用"。
而這里所謂的“返回”就涉及到一個(gè)方向性問(wèn)題,從哪里來(lái)到哪里去。而在軟件中通常就是與“分層設(shè)計(jì)思想”掛鉤的。
在軟件設(shè)計(jì)領(lǐng)域分層設(shè)計(jì)方式是非常廣泛的,在嵌入式中最簡(jiǎn)單的分層就是兩層"驅(qū)動(dòng)層"和“應(yīng)用層”。

當(dāng)函數(shù)功能上進(jìn)行分層以后不應(yīng)該直接在底層驅(qū)動(dòng)中直接調(diào)用應(yīng)用層函數(shù)等,比如應(yīng)用程序通過(guò)調(diào)用驅(qū)動(dòng)層接口獲得物理量數(shù)據(jù),我們常規(guī)的做法大部分都是不斷的輪詢相應(yīng)的API接口返回?cái)?shù)據(jù),這樣可能會(huì)導(dǎo)致不斷的IO操作,效率相對(duì)比較低下。
那么應(yīng)用程序是否可以化主動(dòng)為被動(dòng)呢,一直舔狗實(shí)在是太累了?既然你現(xiàn)在不想搭理我,那等你準(zhǔn)備好了,再來(lái)告訴我吧,到時(shí)候調(diào)用我給你的函數(shù)就可以了,這個(gè)函數(shù)已經(jīng)放在了傳給你的函數(shù)指針里了,那么這里應(yīng)用程序所給的函數(shù)就是回調(diào)函數(shù)。
比如我們經(jīng)常會(huì)在應(yīng)用程序中查詢按鍵是否被按下,然后得編寫一大堆的時(shí)序等等,還與應(yīng)用邏輯耦合在一起。
其實(shí)按鍵是是如何檢測(cè)被按下的過(guò)程對(duì)于應(yīng)用程序它并關(guān)心,底層程序查詢確定好狀態(tài)給應(yīng)用程序一個(gè)是否按下的通知或者狀態(tài)即可。
此時(shí)底層按鍵檢測(cè)程序要通知應(yīng)用程序,就可以通過(guò)相應(yīng)的回調(diào)函數(shù)來(lái)通知應(yīng)用層并處理即可。
如果還有點(diǎn)難理解,可以看看stm32使用hal庫(kù),你會(huì)發(fā)現(xiàn)在中斷中有大量的回調(diào)函數(shù)指針被調(diào)用,其實(shí)回調(diào)函數(shù)的效果與中斷服務(wù)函數(shù)的執(zhí)行效果是類似的,hal庫(kù)中使用回調(diào)函數(shù)的方式把中斷的相關(guān)事件服務(wù)處理交給了用戶自身來(lái)注冊(cè)。
把中斷看成一種事件類型,那么回調(diào)函數(shù)的使用其實(shí)就類似于一種事件驅(qū)動(dòng)機(jī)制。
同步與異步調(diào)用
首先要理清楚這兩種方式需要理解什么是同步和異步。
同步調(diào)用表示當(dāng)調(diào)用一個(gè)底層接口,必須回調(diào)函數(shù)被執(zhí)行完畢,不然該接口會(huì)一直處于堵塞狀態(tài)沒(méi)辦法返回結(jié)果,且程序無(wú)法往下執(zhí)行。
異步調(diào)用表示當(dāng)調(diào)用一個(gè)底層接口以后,不需要等待回調(diào)函數(shù)執(zhí)行完畢,便可以直接返回繼續(xù)做下面的事情,最終底層準(zhǔn)備好以后便會(huì)執(zhí)行回調(diào)函數(shù)處理應(yīng)用層事務(wù),所以我們也稱這種回調(diào)函數(shù)為異步回調(diào)函數(shù)。
而異步調(diào)用的好處在于調(diào)用函數(shù)不需要阻塞可以繼續(xù)執(zhí)行,從而大大提高程序運(yùn)行效率,但由于異步回調(diào)函數(shù)在時(shí)間上是無(wú)序的,導(dǎo)致當(dāng)我們需要異步調(diào)用函數(shù)能夠順序執(zhí)行時(shí)便會(huì)存在難度,使得業(yè)務(wù)邏輯比較復(fù)雜,難以理解。
為了保證回調(diào)的有序性,就需要以上一次回調(diào)的結(jié)果作為本次異步調(diào)用的條件,導(dǎo)致代碼一層嵌套一層非常的冗長(zhǎng),類似于ifelse里面再嵌套ifelse之勢(shì),所以也很多人稱這種方式為 Callback hell(回調(diào)地獄)。
為了改善這種結(jié)構(gòu),通常會(huì)采用協(xié)程的概念去處理異步回調(diào)來(lái)規(guī)避該問(wèn)題。對(duì)于異步調(diào)用常與多線程進(jìn)行結(jié)合,在另外一個(gè)線程中執(zhí)行異步操作,然后調(diào)用回調(diào)函數(shù)返回結(jié)果并繼續(xù)處理。
原文標(biāo)題:嵌入式軟件中回調(diào)函數(shù)同步與異步調(diào)用
文章出處:【微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5186文章
20133瀏覽量
328407 -
C語(yǔ)言
+關(guān)注
關(guān)注
183文章
7642瀏覽量
144530 -
回調(diào)函數(shù)
+關(guān)注
關(guān)注
0文章
93瀏覽量
12109
原文標(biāo)題:嵌入式軟件中回調(diào)函數(shù)同步與異步調(diào)用
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
ARM嵌入式系統(tǒng)開(kāi)發(fā)軟件設(shè)計(jì)與優(yōu)化
嵌入式單片機(jī)開(kāi)發(fā)軟件CodeWarrior怎么下載?如何安裝?
什么是嵌入式傳統(tǒng)開(kāi)發(fā)軟件直接控制硬件
嵌入式web服務(wù)器boa-0.94.13開(kāi)發(fā)軟件
Ubuntu嵌入式開(kāi)發(fā)環(huán)境的建立
工業(yè)用SBCS嵌入式開(kāi)發(fā)軟件的選擇技巧
嵌入式軟件開(kāi)發(fā)是什么該如何理解
嵌入式系統(tǒng)仿真開(kāi)發(fā)軟件proteus8.9的安裝教程資料免費(fèi)下載
嵌入式Linux內(nèi)核驅(qū)動(dòng)開(kāi)發(fā)學(xué)習(xí)路線圖
淺談嵌入式開(kāi)發(fā)
嵌入式開(kāi)發(fā)概述
嵌入式開(kāi)發(fā)概述(20190325小結(jié))

嵌入式開(kāi)發(fā)軟件中回調(diào)函數(shù)的使用
評(píng)論