回調函數是開發人員創建驅動程序或自定義庫所需的一個基本且通常很關鍵的概念。回調函數是對可執行代碼的引用,它作為參數傳遞給其他代碼,允許較低級别的軟件層調用在較高級别層中定義的函數 (10)。回調允許驅動程序或庫嵌入式開發人員在較低層指定行為,但将實現定義留給應用程序層。
最簡單的回調函數隻是一個函數指針,它作為參數傳遞給另一個函數。在大多數情況下,回調将包含三個部分:
• 回調函數
• 回調注冊
• 回調執行
下圖顯示了這三個部分如何在典型的回調實現中協同工作。
首先,開發人員創建将具有由應用程序開發人員确定的實現元素的庫或模塊。例如,開發人員創建了一個 GPIO 驅動程序,該驅動程序具有一個中斷服務例程,其代碼由應用程序開發人員指定。中斷可以處理按鈕按下或其他一些功能。驅動程序不關心功能,隻關心在運行時它知道在中斷觸發時應該調用什麼函數。在模塊中調用回調函數的代碼通常稱為信号處理程序。
接下來,需要有一些方法來告訴底層代碼應該執行什麼函數。有很多方法可以做到這一點,但對于驅動程序模塊,推薦的做法是在模塊内創建一個專門用于将函數注冊為回調的函數。擁有一個單獨的函數來注冊回調函數使嵌入式開發人員非常清楚回調函數正在注冊到特定的信号處理程序。當調用寄存器函數時,将被調用的所需函數作為參數傳遞給模塊并存儲函數地址。
最後,應用程序開發人員編寫他們的應用程序,其中包括創建回調和初始化代碼的實現,該代碼将該函數注冊到庫或模塊中。執行應用程序時,低級代碼存儲回調函數地址,當需要執行功能時,它會取消引用回調函數并執行它。
開發人員可以考慮使用回調的兩個主要示例。首先,在驅動程序中,開發人員将不知道最終應用程序可能需要如何使用任何中斷服務程序。如果開發人員正在為某些微控制器外設創建庫,則可以使用回調來指定所有中斷行為。使用回調将允許開發人員确保在應用程序開發人員沒有注冊自定義回調函數的情況下,每個中斷都有一個默認的服務程序。當回調與中斷一起使用時,開發人員需要記住,需要遵循中斷的最佳實踐。
其次,隻要應用程序中存在可能具有特定于實現行為的常見行為,就可以使用回調。例如,初始化數組是一項非常常見的任務,需要在應用程序中執行。如果對于某些應用程序,嵌入式開發人員希望将數組元素初始化為全零,而在另一個應用程序中他們希望将數組元素初始化為随機數怎麼辦?在這種情況下,他們可以使用回調來初始化數組。
ArrayInit 函數接受一個指向具有元素大小的數組的指針,然後它還接受一個指向返回整數的函數的指針。此時的功能尚未定義,但可以由應用程序代碼定義。當調用 ArrayInit 時,開發人員會傳遞他們選擇的任何函數來初始化數組元素。
帶回調的函數:
void ArrayInit(int * Array, size_t size, int (*Function)(void))
{
for(size_t i = 0; i < size; i )
{
Array[i] = Function();
}
}
将元素初始化為0:
int Zeros(void)
{
return 0;
}
将元素初始化為随機數:
int Random(void)
{
return rand();
}
函數Zeros或Random被傳遞給ArrayInit,這取決于應用程序嵌入式開發人員希望如何初始化數組。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!