0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在STM32上實(shí)現(xiàn)驅(qū)動(dòng)注冊(cè)initcall機(jī)制

STM32嵌入式開(kāi)發(fā) ? 來(lái)源:STM32嵌入式開(kāi)發(fā) ? 2023-07-02 10:26 ? 次閱讀

一、前言

每個(gè)硬件如LED控制,GPIO口需要初始化,初始化函數(shù)bsp_led_init();這個(gè)函數(shù)需要在主函數(shù)中調(diào)用初始化,類似這樣:

void bsp_init(void)
{
    bsp_rcc_init();
    bsp_tick_init();
    bsp_led_init();
    bsp_usart_init();
}

這樣存在的問(wèn)題是:

當(dāng)有很對(duì)驅(qū)動(dòng),加入100個(gè)硬件驅(qū)動(dòng),我們只用到了了50個(gè),剩下的源文件不參與編譯,此時(shí)如果忘記將主函數(shù)中的相應(yīng)初始化刪除,就會(huì)報(bào)錯(cuò)。這樣操作很麻煩,不能很好的實(shí)現(xiàn)單個(gè)驅(qū)動(dòng)文件的隔離。 那么現(xiàn)在就提供解決此問(wèn)題的方式。這個(gè)方式源自于Linux內(nèi)核--initcall機(jī)制。具體講解網(wǎng)絡(luò)上很多,在此不在詳細(xì)說(shuō)明。 可閱讀:

二、代碼

頭文件:

#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)時(shí)鐘初始化  
#define fs_initcall(fn)         __define_initcall(fn, 1) //tick和調(diào)試接口初始化
#define device_initcall(fn)     __define_initcall(fn, 2) //驅(qū)動(dòng)初始化
#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)();
    }
       
}

在主進(jìn)程中調(diào)用void do_init_call(void)進(jìn)行驅(qū)動(dòng)初始化,驅(qū)動(dòng)注冊(cè)初始化時(shí)調(diào)用:

 pure_initcall(fn)        //可用作系統(tǒng)時(shí)鐘初始化  
 fs_initcall(fn)          //tick和調(diào)試接口初始化
 device_initcall(fn)      //驅(qū)動(dòng)初始化
 late_initcall(fn)

舉個(gè)例子:

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

這樣頭文件中就沒(méi)有有對(duì)外的接口函數(shù)了。

三、代碼

gitee:

https://gitee.com/schuck/cola_os

girhub:

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

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • led
    led
    +關(guān)注

    關(guān)注

    242

    文章

    23329

    瀏覽量

    662117
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10918

    瀏覽量

    356896
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4344

    瀏覽量

    62839
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4814

    瀏覽量

    68849
  • GPIO
    +關(guān)注

    關(guān)注

    16

    文章

    1216

    瀏覽量

    52248

原文標(biāo)題:在STM32上實(shí)現(xiàn)驅(qū)動(dòng)注冊(cè)initcall機(jī)制

文章出處:【微信號(hào):c-stm32,微信公眾號(hào):STM32嵌入式開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    嵌入式linux 串口console注冊(cè)

    是__con_initcall_start,該段中的所有函數(shù)driver\tty\tty_io.c\console_init函數(shù)中調(diào)用,console_initstart_kernel函數(shù)中被調(diào)用. console的
    發(fā)表于 03-05 13:53

    Linux的platform機(jī)制開(kāi)發(fā)驅(qū)動(dòng)流程是怎么樣的?

    從Linux 2.6起引入了一套新的驅(qū)動(dòng)管理和注冊(cè)機(jī)制:platform_device和platform_driver。Linux中大部分的設(shè)備驅(qū)動(dòng),都可以使用這套機(jī)制,設(shè)備用plat
    發(fā)表于 09-23 07:31

    Delphi教程之軟件注冊(cè)機(jī)制的建立

    Delphi教程之軟件注冊(cè)機(jī)制的建立,很好的Delphi資料,快來(lái)下載吧。
    發(fā)表于 04-11 16:09 ?5次下載

    C#教程之注冊(cè)注冊(cè)機(jī)制

    C#教程之注冊(cè)注冊(cè)機(jī)制,很好的C#資料,快來(lái)學(xué)習(xí)吧。
    發(fā)表于 04-21 09:52 ?17次下載

    基于STM32單片機(jī)低功耗模式機(jī)制詳細(xì)解析

    本文主要解讀STM32低功耗模式的機(jī)制,并不側(cè)重STM32低功耗的程序實(shí)現(xiàn),而且借助STM32固件庫(kù)實(shí)現(xiàn)
    發(fā)表于 10-24 16:16 ?1.9w次閱讀
    基于<b class='flag-5'>STM32</b>單片機(jī)低功耗模式<b class='flag-5'>機(jī)制</b>詳細(xì)解析

    Linux內(nèi)核驅(qū)動(dòng)的platform機(jī)制是怎樣的

    從Linux 2.6起引入了一套新的驅(qū)動(dòng)管理和注冊(cè)機(jī)制:platform_device和platform_driver。
    發(fā)表于 11-06 14:12 ?1648次閱讀
    Linux內(nèi)核<b class='flag-5'>驅(qū)動(dòng)</b>的platform<b class='flag-5'>機(jī)制</b>是怎樣的

    STM32H743芯片實(shí)現(xiàn)CAN通信的步驟

    本篇筆記主要介紹,STM32H743芯片實(shí)現(xiàn)CAN通信,封裝為BSP驅(qū)動(dòng),為之后實(shí)現(xiàn)CAN的
    的頭像 發(fā)表于 09-14 14:33 ?1.6w次閱讀
    <b class='flag-5'>在</b><b class='flag-5'>STM32</b>H743芯片<b class='flag-5'>上</b><b class='flag-5'>實(shí)現(xiàn)</b>CAN通信的步驟

    基于 RT-Thread STM32 實(shí)現(xiàn) USB 虛擬串口

    之前由于工作需要,基于 RT-Thread STM32 實(shí)現(xiàn)了 USB 虛擬串口。為了方便大家,我在這里把正點(diǎn)原子 F429 阿波羅
    發(fā)表于 02-10 10:01 ?4次下載
    基于 RT-Thread <b class='flag-5'>在</b> <b class='flag-5'>STM32</b> <b class='flag-5'>上</b><b class='flag-5'>實(shí)現(xiàn)</b> USB 虛擬串口

    stm32_FSMC機(jī)制

    stm32_FSMC機(jī)制,介紹FSMC機(jī)制入門
    發(fā)表于 02-21 15:16 ?18次下載

    AN4099_STM32F0和STM32F3系列MCU實(shí)現(xiàn)紅外遙控收發(fā)控制協(xié)議

    AN4099_STM32F0和STM32F3系列MCU實(shí)現(xiàn)紅外遙控收發(fā)控制協(xié)議
    發(fā)表于 11-21 17:06 ?0次下載
    AN4099_<b class='flag-5'>在</b><b class='flag-5'>STM32</b>F0和<b class='flag-5'>STM32</b>F3系列MCU<b class='flag-5'>上</b><b class='flag-5'>實(shí)現(xiàn)</b>紅外遙控收發(fā)控制協(xié)議

    嵌入式函數(shù)回調(diào)注冊(cè)機(jī)制實(shí)現(xiàn)

    嵌入式函數(shù)回調(diào)注冊(cè)機(jī)制是一種常用的解耦技術(shù),它通過(guò)應(yīng)用程序中注冊(cè)回調(diào)函數(shù)的方式來(lái)實(shí)現(xiàn)模塊之間的通信,從而使系統(tǒng)更加靈活、可擴(kuò)展和易于維護(hù)。函數(shù)回調(diào)
    的頭像 發(fā)表于 04-13 15:52 ?1449次閱讀

    什么是函數(shù)回調(diào)注冊(cè)機(jī)制?實(shí)現(xiàn)的大致步驟介紹

    嵌入式函數(shù)回調(diào)注冊(cè)機(jī)制是一種常用的解耦技術(shù),它通過(guò)應(yīng)用程序中注冊(cè)回調(diào)函數(shù)的方式來(lái)實(shí)現(xiàn)模塊之間的通信
    的頭像 發(fā)表于 05-20 16:43 ?4460次閱讀

    initcall實(shí)現(xiàn)原理和調(diào)試方法介紹

    linux kernel啟動(dòng)過(guò)程中,通過(guò)initcall機(jī)制調(diào)用初始化函數(shù)。initcall作為kernel經(jīng)典設(shè)計(jì)機(jī)制之一延續(xù)至今。
    的頭像 發(fā)表于 06-05 11:38 ?1426次閱讀
    <b class='flag-5'>initcall</b><b class='flag-5'>實(shí)現(xiàn)</b>原理和調(diào)試方法介紹

    如何解決引入注冊(cè)機(jī)制問(wèn)題

    耦合狀態(tài),失去了一個(gè).c 一個(gè) .h的意義。 如何解決這種問(wèn)題 ????引入注冊(cè)機(jī)制。為了方便說(shuō)明注冊(cè)機(jī)制,舉一個(gè)例子:手機(jī)使用相機(jī)這個(gè)功能時(shí),有一個(gè)操作:將拍攝的照片發(fā)送出去。以程序來(lái)實(shí)現(xiàn)
    的頭像 發(fā)表于 08-16 09:17 ?704次閱讀

    基于表驅(qū)動(dòng)的健康監(jiān)控機(jī)制實(shí)現(xiàn)方法

    電子發(fā)燒友網(wǎng)站提供《基于表驅(qū)動(dòng)的健康監(jiān)控機(jī)制實(shí)現(xiàn)方法.pdf》資料免費(fèi)下載
    發(fā)表于 11-06 10:09 ?0次下載
    基于表<b class='flag-5'>驅(qū)動(dòng)</b>的健康監(jiān)控<b class='flag-5'>機(jī)制</b><b class='flag-5'>實(shí)現(xiàn)</b>方法