一、前言
每个硬件如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
+关注
关注
244文章
24705浏览量
692388 -
STM32
+关注
关注
2312文章
11189浏览量
374547 -
函数
+关注
关注
3文章
4421浏览量
67822 -
代码
+关注
关注
30文章
4976浏览量
74358 -
GPIO
+关注
关注
16文章
1333浏览量
56430
原文标题:在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
•2159次阅读
基于 RT-Thread 在 STM32 上实现 USB 虚拟串口
之前由于工作需要,基于 RT-Thread 在 STM32 上实现了 USB 虚拟串口。为了方便大家,我在这里把在正点原子 F429 阿波罗
发表于 02-10 10:28
•9次下载
嵌入式函数回调注册机制的实现
嵌入式函数回调注册机制是一种常用的解耦技术,它通过在应用程序中注册回调函数的方式来实现模块之间的通信,从而使系统更加灵活、可扩展和易于维护。函数回调
如何解决引入注册机制问题
耦合状态,失去了一个.c 一个 .h的意义。 如何解决这种问题 引入注册机制。为了方便说明注册机制,举一个例子:手机在使用相机这个功能时,有一个操作:将拍摄的照片发送出去。以程序来实现
在STM32上实现驱动注册initcall机制
评论