一、前言
每個硬件如LED控制,GPIO口需要初始化,初始化函數(shù)bsp_led_init();這個函數(shù)需要在主函數(shù)中調(diào)用初始化,類似這樣:
void bsp_init(void) { bsp_rcc_init(); bsp_tick_init(); bsp_led_init(); bsp_usart_init(); }
這樣存在的問題是:
當有很對驅(qū)動,加入100個硬件驅(qū)動,我們只用到了了50個,剩下的源文件不參與編譯,此時如果忘記將主函數(shù)中的相應初始化刪除,就會報錯。這樣操作很麻煩,不能很好的實現(xiàn)單個驅(qū)動文件的隔離。 那么現(xiàn)在就提供解決此問題的方式。這個方式源自于Linux內(nèi)核--initcall機制。具體講解網(wǎng)絡上很多,在此不在詳細說明。 可閱讀:
二、代碼
頭文件:
#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) //可用作系統(tǒng)時鐘初始化 #define fs_initcall(fn) __define_initcall(fn, 1) //tick和調(diào)試接口初始化 #define device_initcall(fn) __define_initcall(fn, 2) //驅(qū)動初始化 #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)(); } }
在主進程中調(diào)用void do_init_call(void)進行驅(qū)動初始化,驅(qū)動注冊初始化時調(diào)用:
pure_initcall(fn) //可用作系統(tǒng)時鐘初始化 fs_initcall(fn) //tick和調(diào)試接口初始化 device_initcall(fn) //驅(qū)動初始化 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);
這樣頭文件中就沒有有對外的接口函數(shù)了。
三、代碼
gitee:
https://gitee.com/schuck/cola_os
girhub:
https://github.com/sckuck-bit/cola_os
審核編輯:湯梓紅
-
led
+關注
關注
242文章
23141瀏覽量
658539 -
STM32
+關注
關注
2266文章
10873瀏覽量
354843 -
函數(shù)
+關注
關注
3文章
4307瀏覽量
62433 -
代碼
+關注
關注
30文章
4751瀏覽量
68358 -
GPIO
+關注
關注
16文章
1196瀏覽量
51920
原文標題:在STM32上實現(xiàn)驅(qū)動注冊initcall機制
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發(fā)】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論