当前位置:网站首页>Implementing the driver registration initcall mechanism on stm32
Implementing the driver registration initcall mechanism on stm32
2022-06-13 04:54:00 【qq_ thirty-nine million two hundred and eighty thousand seven h】
Reprint :STM32 Implement driver registration on initcall Mechanism
One 、 Code
It realizes the separation management of code application layer and hardware layer , But there is a problem in the code , Each hardware such as LED control ,GPIO The port needs to be initialized , Initialization function bsp_led_init(); This function needs to be initialized in the main function , Like this :
void bsp_init(void)
{
bsp_rcc_init();
bsp_tick_init();
bsp_led_init();
bsp_usart_init();
}
The problem with that is : When there are very few drivers , Join in 100 Hardware drivers , We only used 50 individual , The remaining source files do not participate in compilation , At this point, if you forget to delete the corresponding initialization in the main function , You're going to report a mistake . It's a lot of trouble , The isolation of a single driver file cannot be well realized .
So now is the time to provide a solution to this problem . This method comes from Linux kernel --initcall Mechanism . There are many specific explanations on the Internet , I will not elaborate here .
Can be read :
keil And Image:
https://www.cnblogs.com/idle_man/archive/2010/12/18/1910158.html
linux Of initcall Mechanism ( For drivers compiled into the kernel ) :
https://www.cnblogs.com/downey-blog/p/10486653.html
Two 、 Code
The header file :
#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) // Can be used as system clock initialization
#define fs_initcall(fn) __define_initcall(fn, 1) //tick And debug interface initialization
#define device_initcall(fn) __define_initcall(fn, 2) // Drive initialization
#define late_initcall(fn) __define_initcall(fn, 3) // Other initialization
void do_init_call(void);
#endif
Source file :
#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)();
}
}
Called in the main process void do_init_call(void) Perform driver initialization , When the driver registration is initialized, call :
pure_initcall(fn) // Can be used as system clock initialization
fs_initcall(fn) //tick And debug interface initialization
device_initcall(fn) // Drive initialization
late_initcall(fn)
for instance :
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);
In this way, there is no external interface function in the header file .
3、 ... and 、 Code
gitee:
https://gitee.com/schuck/cola_os
girhub:
https://github.com/sckuck-bit/cola_os
Four 、 Header file interpretation
#ifndef _COLA_INIT_H_
#define _COLA_INIT_H_
#define __used __attribute__((__used__)) // Use __used__ attribute
typedef void (*initcall_t)(void); // Define function pointer type
#define __define_initcall(fn, id) \ // Define register function macros
// Define function pointers , The function pointer is named :__initcall_##fn##id , for example fn = test,id = 0;
// Then the function pointer is named __initcalltest0;
static const initcall_t __initcall_##fn##id __used \
// Description of function pointer storage location , In the custom segment .
__attribute__((__section__("initcall" #id "init"))) = fn;
#define pure_initcall(fn) __define_initcall(fn, 0) // Can be used as system clock initialization
#define fs_initcall(fn) __define_initcall(fn, 1) //tick And debug interface initialization
#define device_initcall(fn) __define_initcall(fn, 2) // Drive initialization
#define late_initcall(fn) __define_initcall(fn, 3) // Other initialization
void do_init_call(void);
#endif
reference :
C In language "#" and "##" Usage of
__attribute_unused__ and __attribute_used__ The role of
gcc Of __attribute__ Compile properties
边栏推荐
- Mysql database installation
- NodeJS 解析 GET 请求 url 字符串
- Crawler scrapy framework learning 1
- Spread your wings and soar
- Configuration used by automatic teaching evaluation script
- Robot pose description and coordinate transformation
- 工业互联网通用通信协议
- Section 2 - branch and loop statements
- C disk lossless move file
- Embedded hardware - read schematic
猜你喜欢
随机推荐
2022道路运输企业安全生产管理人员操作证考试题库及答案
UNO
工业互联网通用通信协议
第三方评论插件
Advanced C - Section 3 - character functions and string functions
Several methods of identifying equivalent circuit of circuit drawing
[untitled]
Ctfshow common postures (821-830)
Force buckle 25 A group of K flipped linked lists
Draw a hammer
[leetcode]- sliding window
E - Lucky Numbers
Infinite cycle scrolling code Alibaba international station store decoration code base map scrolling black translucent display effect custom content decoration code full screen display
PHP development 14 compilation of friendship link module
Vercel 使用 HTTP 缓存
Go scheduled task cron package usage
Red Treasure Book Reading Notes (continuously updated)
Analysis of scoped attribute principle and depth action selector
Crawler scrapy framework learning 2
Autumn wind, dust, youth