0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在STM32上实现驱动注册initcall机制

STM32嵌入式开发 来源:STM32嵌入式开发 2023-07-02 10:26 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、前言

每个硬件如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
    led
    +关注

    关注

    244

    文章

    24705

    浏览量

    692388
  • STM32
    +关注

    关注

    2312

    文章

    11189

    浏览量

    374547
  • 函数
    +关注

    关注

    3

    文章

    4421

    浏览量

    67822
  • 代码
    +关注

    关注

    30

    文章

    4976

    浏览量

    74358
  • GPIO
    +关注

    关注

    16

    文章

    1333

    浏览量

    56430

原文标题:在STM32上实现驱动注册initcall机制

文章出处:【微信号:c-stm32,微信公众号:STM32嵌入式开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    请问基于GCC编译器的initcallSTM32如何实现

    请问各位基于GCC编译器的initcallSTM32如何实现?有哪位实现了吗?
    发表于 03-13 06:24

    嵌入式linux 串口console注册

    是__con_initcall_start,该段中的所有函数driver\tty\tty_io.c\console_init函数中调用,console_initstart_kernel函数中被调用. console的
    发表于 03-05 13:53

    Linux的platform机制开发驱动流程是怎么样的?

    从Linux 2.6起引入了一套新的驱动管理和注册机制:platform_device和platform_driver。Linux中大部分的设备驱动,都可以使用这套机制,设备用plat
    发表于 09-23 07:31

    Delphi教程之软件注册机制的建立

    Delphi教程之软件注册机制的建立,很好的Delphi资料,快来下载吧。
    发表于 04-11 16:09 5次下载

    C#教程之注册注册机制

    C#教程之注册注册机制,很好的C#资料,快来学习吧。
    发表于 04-21 09:52 17次下载

    基于STM32单片机低功耗模式机制详细解析

    本文主要解读STM32低功耗模式的机制,并不侧重STM32低功耗的程序实现,而且借助STM32固件库实现
    发表于 10-24 16:16 2w次阅读
    基于<b class='flag-5'>STM32</b>单片机低功耗模式<b class='flag-5'>机制</b>详细解析

    Linux内核驱动的platform机制是怎样的

    从Linux 2.6起引入了一套新的驱动管理和注册机制:platform_device和platform_driver。
    发表于 11-06 14:12 2159次阅读
    Linux内核<b class='flag-5'>驱动</b>的platform<b class='flag-5'>机制</b>是怎样的

    STM32H743芯片实现CAN通信的步骤

    本篇笔记主要介绍,STM32H743芯片实现CAN通信,封装为BSP驱动,为之后实现CAN的
    的头像 发表于 09-14 14:33 1.9w次阅读
    <b class='flag-5'>在</b><b class='flag-5'>STM32</b>H743芯片<b class='flag-5'>上</b><b class='flag-5'>实现</b>CAN通信的步骤

    基于 RT-Thread STM32 实现 USB 虚拟串口

    之前由于工作需要,基于 RT-Thread STM32 实现了 USB 虚拟串口。为了方便大家,我在这里把正点原子 F429 阿波罗
    发表于 02-10 10:28 9次下载
    基于 RT-Thread <b class='flag-5'>在</b> <b class='flag-5'>STM32</b> <b class='flag-5'>上</b><b class='flag-5'>实现</b> USB 虚拟串口

    stm32_FSMC机制

    stm32_FSMC机制,介绍FSMC机制入门
    发表于 02-21 15:16 19次下载

    嵌入式函数回调注册机制实现

    嵌入式函数回调注册机制是一种常用的解耦技术,它通过应用程序中注册回调函数的方式来实现模块之间的通信,从而使系统更加灵活、可扩展和易于维护。函数回调
    的头像 发表于 04-13 15:52 2433次阅读

    什么是函数回调注册机制实现的大致步骤介绍

    嵌入式函数回调注册机制是一种常用的解耦技术,它通过应用程序中注册回调函数的方式来实现模块之间的通信
    的头像 发表于 05-20 16:43 5973次阅读

    initcall实现原理和调试方法介绍

    linux kernel启动过程中,通过initcall机制调用初始化函数。initcall作为kernel经典设计机制之一延续至今。
    的头像 发表于 06-05 11:38 2461次阅读
    <b class='flag-5'>initcall</b><b class='flag-5'>实现</b>原理和调试方法介绍

    如何解决引入注册机制问题

    耦合状态,失去了一个.c 一个 .h的意义。 如何解决这种问题     引入注册机制。为了方便说明注册机制,举一个例子:手机使用相机这个功能时,有一个操作:将拍摄的照片发送出去。以程序来实现
    的头像 发表于 08-16 09:17 1453次阅读

    基于表驱动的健康监控机制实现方法

    电子发烧友网站提供《基于表驱动的健康监控机制实现方法.pdf》资料免费下载
    发表于 11-06 10:09 0次下载
    基于表<b class='flag-5'>驱动</b>的健康监控<b class='flag-5'>机制</b><b class='flag-5'>实现</b>方法