一、前言
每個硬件如LED控制,GPIO口需要初始化,初始化函數bsp_led_init();這個函數需要在主函數中調用初始化,類似這樣:
void bsp_init(void)
{
bsp_rcc_init();
bsp_tick_init();
bsp_led_init();
bsp_usart_init();
}
這樣存在的問題是:
當有很對驅動,加入100個硬件驅動,我們只用到了了50個,剩下的源文件不參與編譯,此時如果忘記將主函數中的相應初始化刪除,就會報錯。這樣操作很麻煩,不能很好的實現單個驅動文件的隔離。 那么現在就提供解決此問題的方式。這個方式源自于Linux內核--initcall機制。具體講解網絡上很多,在此不在詳細說明。 可閱讀:
二、代碼
頭文件:
#ifndef _COLA_INIT_H_ #define _COLA_INIT_H_ #define __used __attribute__((__used__)) typedef void (*initcall_t)(void); #define __define_initcall(fn, id) static const initcall_t __initcall_##fn##id __used __attribute__((__section__("initcall" #id "init"))) = fn; #define pure_initcall(fn) __define_initcall(fn, 0) //可用作系統時鐘初始化 #define fs_initcall(fn) __define_initcall(fn, 1) //tick和調試接口初始化 #define device_initcall(fn) __define_initcall(fn, 2) //驅動初始化 #define late_initcall(fn) __define_initcall(fn, 3) //其他初始化 void do_init_call(void); #endif
源文件:
#include "cola_init.h"
void do_init_call(void)
{
extern initcall_t initcall0init$$Base[];
extern initcall_t initcall0init$$Limit[];
extern initcall_t initcall1init$$Base[];
extern initcall_t initcall1init$$Limit[];
extern initcall_t initcall2init$$Base[];
extern initcall_t initcall2init$$Limit[];
extern initcall_t initcall3init$$Base[];
extern initcall_t initcall3init$$Limit[];
initcall_t *fn;
for (fn = initcall0init$$Base;
fn < initcall0init$$Limit;
fn++)
{
if(fn)
(*fn)();
}
for (fn = initcall1init$$Base;
fn < initcall1init$$Limit;
fn++)
{
if(fn)
(*fn)();
}
for (fn = initcall2init$$Base;
fn < initcall2init$$Limit;
fn++)
{
if(fn)
(*fn)();
}
for (fn = initcall3init$$Base;
fn < initcall3init$$Limit;
fn++)
{
if(fn)
(*fn)();
}
}
在主進程中調用void do_init_call(void)進行驅動初始化,驅動注冊初始化時調用:
pure_initcall(fn) //可用作系統時鐘初始化 fs_initcall(fn) //tick和調試接口初始化 device_initcall(fn) //驅動初始化 late_initcall(fn)
舉個例子:
static void led_register(void)
{
led_gpio_init();
led_dev.dops = &ops;
led_dev.name = "led";
cola_device_register(&led_dev);
}
device_initcall(led_register);
這樣頭文件中就沒有有對外的接口函數了。
三、代碼
gitee:
https://gitee.com/schuck/cola_os
girhub:
https://github.com/sckuck-bit/cola_os
審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
led
+關注
關注
243文章
24596瀏覽量
690897 -
STM32
+關注
關注
2309文章
11162瀏覽量
373472 -
函數
+關注
關注
3文章
4417瀏覽量
67521 -
代碼
+關注
關注
30文章
4968瀏覽量
73988 -
GPIO
+關注
關注
16文章
1328瀏覽量
56231
原文標題:在STM32上實現驅動注冊initcall機制
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
熱點推薦
嵌入式linux 串口console注冊
是__con_initcall_start,該段中的所有函數在driver\tty\tty_io.c\console_init函數中調用,console_init在start_kernel函數中被調用. console的
發表于 03-05 13:53
Linux的platform機制開發驅動流程是怎么樣的?
從Linux 2.6起引入了一套新的驅動管理和注冊機制:platform_device和platform_driver。Linux中大部分的設備驅動,都可以使用這套機制,設備用plat
發表于 09-23 07:31
Linux內核驅動的platform機制是怎樣的
從Linux 2.6起引入了一套新的驅動管理和注冊機制:platform_device和platform_driver。
發表于 11-06 14:12
?2096次閱讀
基于 RT-Thread 在 STM32 上實現 USB 虛擬串口
之前由于工作需要,基于 RT-Thread 在 STM32 上實現了 USB 虛擬串口。為了方便大家,我在這里把在正點原子 F429 阿波羅
發表于 02-10 10:28
?9次下載
嵌入式函數回調注冊機制的實現
嵌入式函數回調注冊機制是一種常用的解耦技術,它通過在應用程序中注冊回調函數的方式來實現模塊之間的通信,從而使系統更加靈活、可擴展和易于維護。函數回調
如何解決引入注冊機制問題
耦合狀態,失去了一個.c 一個 .h的意義。 如何解決這種問題 ????引入注冊機制。為了方便說明注冊機制,舉一個例子:手機在使用相機這個功能時,有一個操作:將拍攝的照片發送出去。以程序來實現
在STM32上實現驅動注冊initcall機制
評論