一、前言

上一节我们实现了代码应用层和硬件层的分离管理,但是代码中还存在一个问题,每个硬件如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机制。具体讲解网络上很多,再次不在详细说明

二、参考资料

keil 之Image      :https://www.cnblogs.com/idle_man/archive/2010/12/18/1910158.html

linux的initcall机制(针对编译进内核的驱动) :https://www.cnblogs.com/downey-blog/p/10486653.html

三、代码

头文件

#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);

这样头文件中就没有有对外的接口函数了

四、代码下载

gitlab:https://gitee.com/schuck/cola_os

girhub:https://github.com/sckuck-bit/cola_os

嵌入式开发--STM32上实现驱动注册initcall机制(类linux)相关推荐

  1. 嵌入式开发-STM32硬件SPI驱动TFT屏

    嵌入式开发-STM32硬件SPI驱动TFT屏 这次用到的TFT屏 CubeMX设置 代码编写 增加的内容 需要注意问题 代码下载 这次用到的TFT屏 现在的TFT屏幕已经很便宜了,65536色屏幕,2 ...

  2. rust做嵌入式开发_Rust 嵌入式开发 STM32 amp; RISC-V

    Rust 嵌入式开发 STM32 & RISC-V 发布于 2020-04-03 11:07:06 本帖最后由 wuhanstudio 于 2020-4-3 11:58 编辑 更新地址: [m ...

  3. 【嵌入式开发-STM32】初识STM32

    [嵌入式开发-STM32]初识STM32 文章目录 [嵌入式开发-STM32]初识STM32 一.什么是STM32 二.STM32的拓展 三.如何确定STM32选型 3.1.STM32的命名方法 3. ...

  4. linux 嵌入上电自动运行,如何在linux嵌入式开发板上开机自动运行用户应用程序...

    开机后自动运行用户的应用程序或启动系统服务的命令保存在开发板根文件系统的/usr/etc/rc.local文件中.有的开发板开机后自动运行图形界面程序,需要按住ctrl+c让开发板进入到linux的S ...

  5. 在pcduino开发板上写驱动控制板载LED的闪烁

    由于关于pcduino的资料比较少,所以这篇文章是参考了pcduino爱好者论坛的一篇教程<手把手教你用A10点灯>,并且系统的结合了linux驱动的开发步骤.读完这篇文章,你不但可以对p ...

  6. 手把手教你在ARM嵌入式开发板上只做自己的人脸识别装置

    一下是自己一步步构建的嵌入式人脸识别装置,虽然样子比较丑陋,但是都是自己一步步移植构建出来的,一下是我的全部论文步骤,大家可以参考. http://wenku.baidu.com/view/ee746 ...

  7. LINUX嵌入式开发板上配置FTP 服务

    1)交叉编译出vsftpd以及相关的配置文件 2)交叉编译shadow-4.1.5.1,获取里面的useradd程序以及相关的配置文件 -----./configure --build=i386-li ...

  8. 嵌入式开发板上开启telnetd服务

    linux开发板开启telnet服务需要一下几个条件: 1.文件系统支持telnet busybox默认是把telnet和telnetd功能编进去了的,所以这一步一般都省了. 2.设定开发板root和 ...

  9. 嵌入式开发板上常用术语

最新文章

  1. Science Bulletin:崔杰组发表了深浅海软甲纲动物比较病毒组学分析成果
  2. SAP QM QAC1事务代码不能修改含有HU的检验批里的数量
  3. Alibaba Dubbo框架同步调用原理分析-2
  4. 哈尔滨学院 计算机等级考试证书,2018年9月黑龙江哈尔滨学院计算机等级考试证书领取通知...
  5. linux脚本漏洞,Silver Peak VX跨站脚本漏洞(CVE-2014-2975)
  6. 一个简单的游戏服务器框架
  7. mysql数据库备份工具expdb_expdp 备份数据库
  8. cpu计算速度排行榜_CPU速度的计算方法和单位
  9. pycharm的terminal无法识别到命令 pytest 不是内部或外部命令,也不是可运行的程序 或批处理文件。
  10. linux技术属于什么系,什么云计算技术?想学好这个必须了解的!
  11. 年会 炫酷 抽奖小程序
  12. scRNA-seq Course 学习
  13. masquerade词根词缀_词根词缀总结
  14. 部署Unbound实现DNS服务
  15. Solr的facet
  16. 从云计算到容器到容器云
  17. 爱快路由器使用L2TP线路做出口
  18. java中求某个时间跳过节假日和周末
  19. python合并word表格_python合并word
  20. React —— Descriptions(根据自己需求判断要显示哪些)

热门文章

  1. 规则引擎的介绍与Drools的流程分析
  2. FreeTpye库学习笔记:将矢量字体解析为位图
  3. MySQL基础教程——创建数据库并插入数据
  4. uniapp 小于1000 按原数字显示 超过1000 数字换算成10w+ 1.3k+ 显示
  5. 算法5:线性DP与区间DP
  6. linux下为命令设置别名
  7. 训练集、验证集、测试集的作用和区别
  8. OpenCV求(图像)矩阵中最大值,最小值函数minMaxLoc() vs minMaxIdx()
  9. CUDA矩阵乘法优化
  10. 用内网服务器对接微信公众号服务