女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一文詳解RT-Thread自動初始化

RTThread物聯網操作系統 ? 來源:陳翠 ? 2019-07-21 10:17 ? 次閱讀

一、前言

在學RT-Thread時,經常能聽到這個詞:自動初始化。用起來也非常容易,一個宏就解決了,但是原理是什么呢?官網文檔提及到了,

(他們的文檔在這里:https://www.rt-thread.org/document/site/programming-manual/basic/basic/#rt-thread_3),但是寫的只是概念層面上的,看完后會使用但原理還是不太清楚。之前研究過,今天把它總結下,寫出來分享。

1.1、一般情況的初始化調用

一般情況下,系統中的初始化會這樣做,應該再熟悉不過了:

1//偽代碼 2 3voidmain(void) 4{ 5uart_init(); 6led_init(); 7... 8 910while(1)11{12//func113//func214}15}

這樣的顯式調用初始化函數,有時可能多達 十幾到幾十 個,看起來非常非常繁雜。但是好像沒啥問題,因為已經看習慣了。

1.2 使用自動初始化后

舉例一個自動初始化的用法如下:

1//這是led.c文件23voidled_init(void)4{5//省略6}7INIT_APP_EXPORT(led_init)1//這是main.c文件2intmain(void)3{45}

這樣,使用一個宏,初始化函數就會被自動初始化,不用在其他地方顯式調用 led_init() 。代碼瞬間清爽很多。

二、引入

當然也不用擔心一個初始化必須在另一個初始化之前的問題,因為這里有6個自動初始化等級可供選擇。

我摳了一張RT-Thread官網文檔的圖,該圖是RT-Thread代碼的啟動流程圖,該圖中的藍色方框部分就是自動初始化的6個等級以及初始化的先后順序。從圖中可以看出這6部分的初始化是由函數 rt_components_board_init() 與 rt_components_init() 完成的。

在一開始的例子中, INIT_APP_EXPORT(led_init) 就位于最后一個方框的位置,屬于applications init functions。

那么其他等級分別對應什么宏進行初始化的?看下面的表格:

三、自動初始化原理

3.1 6個自動初始化宏的定義

查看源碼,這 6 個宏定義如下:( 不同的段:1 2 3 4 5 6 )

1/*boardinitroutineswillbecalledinboard_init()function*/ 2#defineINIT_BOARD_EXPORT(fn)INIT_EXPORT(fn,"1") 3 4/*pre/device/component/env/appinitroutineswillbecalledininit_thread*/ 5/*componentspre-initialization(puresoftwareinitilization)*/ 6#defineINIT_PREV_EXPORT(fn)INIT_EXPORT(fn,"2") 7/*deviceinitialization*/ 8#defineINIT_DEVICE_EXPORT(fn)INIT_EXPORT(fn,"3") 9/*componentsinitialization(dfs,lwip,...)*/10#defineINIT_COMPONENT_EXPORT(fn)INIT_EXPORT(fn,"4")11/*environmentinitialization(mountdisk,...)*/12#defineINIT_ENV_EXPORT(fn)INIT_EXPORT(fn,"5")13/*appliationinitialization(rtguiapplicationetc...)*/14#defineINIT_APP_EXPORT(fn)INIT_EXPORT(fn,"6")

INIT_EXPORT(fn, level) 表示這個函數 fn 現在屬于哪個初始化 level 段, 由 SECTION(".rti_fn."level) 進行定義。

1#defineINIT_EXPORT(fn,level)2RT_USEDconstinit_fn_t__rt_init_##fnSECTION(".rti_fn."level)=fn

而 SECTION(x) 是:

1#defineSECTION(x)__attribute__((section(x)))

__attribute__((section("name"))) :將作用的函數或數據放入指定名為"name"的輸入段中。(在不同的編譯器中實現的方式也有所不同。)

以上就是整個的宏定義作用就是將函數 fn 的地址賦給一個 __rt_init_fn 的指針,然后放入相應 level 的數據段中。所以函數使用自動初始化宏導出后,這些數據段中就會存儲指向各個初始化函數的指針。

舉例:INIT_APP_EXPORT(pin_beep_sample);

1//函數pin_beep_sample(),使用INIT_APP_EXPORT()進行自動初始化。 2 3INIT_APP_EXPORT(pin_beep_sample); 4=INIT_EXPORT(pin_beep_sample,"6") 5=constinit_fn_t__rt_init_pin_beep_sampleSECTION(".rti_fn.""6")=pin_beep_sample 6 7/* 8表示把函數pin_beep_sample的地址賦值給常量函數指針__rt_init_pin_beep_sample, 9然后放入名稱為".rti_fn.6"的數據段中。10(其中init_fn_t是一個函數指針類型,原型為typedef int (*init_fn_t)(void)。)11*/

表示把函數 pin_beep_sample 的地址賦值給常量函數指針 __rt_init_pin_beep_sample,然后放入名稱為 ".rti_fn.6" 的數據段中。( 其中 init_fn_t 是一個函數指針類型,原型為 typedef int (*init_fn_t)(void)。)

注意被自動初始化的函數類型為:int (*init_fn_t)(void) ,無參,int 返回。

3.2 自動初始化過程

那么上面提到,在啟動流程中,調用了兩個函數 rt_components_board_init() 與 rt_components_init() 就完成了6部分的初始化。從啟動流程圖中可以看出:rt_components_board_init() 完成了第 1 段, rt_components_init() 完成了第2 到第6 段。

說明:rt_components_board_init()主要board板級的初始化,調度器還未啟動,是在系統起來之前做的初始化。所以在使用board級別的初始化時不要使用系統API,如rt_thread_delay()等。rt_components_init()主要是一些組件的初始化及應用初始化,是在main線程中完成的,當調度器啟動之后,系統啟動開始運行main線程時才會進行的初始化。是線程的運行環境。

3.2.1、兩個函數的實現

1、第一個函數 rt_components_board_init() 的實現:

1voidrt_components_board_init(void) 2{ 3constinit_fn_t*fn_ptr; 4 5for(fn_ptr=&__rt_init_rti_board_start;fn_ptr

非調試模式下rt_components_board_init():for循環會遍歷位于__rt_init_rti_board_start 到 __rt_init_rti_board_end 之間保存的函數指針,然后依次執行這些函數。

2、第二個函數 rt_components_init() 的實現:

1voidrt_components_init(void) 2{ 3constinit_fn_t*fn_ptr; 4 5for(fn_ptr=&__rt_init_rti_board_end;fn_ptr

非調試模式下rt_components_init():for循環會遍歷位于__rt_init_rti_board_end 到 __rt_init_rti_end 之間保存的函數指針,然后依次執行這些函數 。

那么 __rt_init_rti_board_start、__rt_init_rti_board_end、__rt_init_rti_end 是啥?

3.2.2 劃分

在系統中,定義了這幾個空函數:rti_start、rti_board_start、rti_board_end、rti_end。不同的段:0、 0.end 、 1.end 、6.end

1staticintrti_start(void) 2{ 3return0; 4} 5INIT_EXPORT(rti_start,"0"); 6 7staticintrti_board_start(void) 8{ 9return0;10}11INIT_EXPORT(rti_board_start,"0.end");1213staticintrti_board_end(void)14{15return0;16}17INIT_EXPORT(rti_board_end,"1.end");1819staticintrti_end(void)20{21return0;22}23INIT_EXPORT(rti_end,"6.end");

這幾個函數的導出,加上上面 6 個初始化宏的導出,就有了這樣一個表格:

可以看出,這4個空函數所導出的段中間,包含著這6個初始化宏定義的段,而這6個段中分別包含著各自宏導出函數時的函數指針。

rt_components_board_init() 完成了第 1 段, rt_components_init() 完成了第2 到第6 段。

1、rt_components_board_init() 完成了第 1 段,也就是初始化了由INIT_BOARD_EXPORT(fn) 的初始化的所有函數,也就是__rt_init_rti_board_start 到 __rt_init_rti_board_end 之間的函數指針。

2、rt_components_init() 完成了第2 到第6 段,也就是按順序初始化了由 INIT_PREV_EXPORT(fn) 到 INIT_DEVICE_EXPORT(fn) 到 INIT_COMPONENT_EXPORT(fn)、 INIT_ENV_EXPORT(fn)、 INIT_APP_EXPORT(fn)初始化的所有函數,也就是從 __rt_init_rti_board_end 到 __rt_init_rti_end 之間的函數指針。

所以,當你使用自動初始化導出宏 去初始化一個函數時,是由系統中的這兩個函數進行遍歷函數指針執行的。

3.2.3、示例

還是上面 INIT_APP_EXPORT(pin_beep_sample); 的例子。

舉例:INIT_APP_EXPORT(pin_beep_sample);

1//函數pin_beep_sample(),使用INIT_APP_EXPORT()進行自動初始化。 2 3INIT_APP_EXPORT(pin_beep_sample); 4=INIT_EXPORT(pin_beep_sample,"6") 5=constinit_fn_t__rt_init_pin_beep_sampleSECTION(".rti_fn.""6")=pin_beep_sample 6 7/* 8表示把函數pin_beep_sample的地址賦值給常量函數指針__rt_init_pin_beep_sample, 9然后放入名稱為".rti_fn.6"的數據段中。10(其中init_fn_t是一個函數指針類型,原型為typedef int (*init_fn_t)(void)。)11*/

表示把函數 pin_beep_sample 的地址賦值給常量函數指針 __rt_init_pin_beep_sample,然后放入名稱為 ".rti_fn.6" 的數據段中。( 其中 init_fn_t 是一個函數指針類型,原型為 typedef int (*init_fn_t)(void)。)

在編譯后的.map文件中可以查看到:

常量函數指針 __rt_init_pin_beep_sample 位于 .rti_fn.6 段中。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 初始化
    +關注

    關注

    0

    文章

    50

    瀏覽量

    12048
  • RT-Thread
    +關注

    關注

    32

    文章

    1369

    瀏覽量

    41506

原文標題:RT-Thread 自動初始化詳解

文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    RT-Thread自動初始化詳解

    我們知道,在寫裸機程序時,當我們完成硬件初始化后,就需要在主函數中進行調用。當我們使用RT-Thread后,完全不需要這樣做了,我們可以將硬件等自動初始化
    的頭像 發表于 06-25 21:38 ?1.2w次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>自動</b><b class='flag-5'>初始化</b><b class='flag-5'>詳解</b>

    RT-Thread qemu mps2-an385 bsp移植制作 :系統運行篇

    前面已經讓 RT-Thread 進入了 entry 入口函數,并且 調整 鏈接腳本,自動初始化與 MSH shell 的符號已經預留, 進入了 RT-Thread
    的頭像 發表于 11-14 12:27 ?1053次閱讀
    <b class='flag-5'>RT-Thread</b> qemu mps2-an385 bsp移植制作 :系統運行篇

    RT-thread初始化過程是怎樣進行的

    RT-thread初始化過程是怎樣進行的?擴展補丁Sub和super的作用是什么?如何去使用它們呢?
    發表于 11-29 07:42

    如何對RT-Thread系統進行初始化

    RT-Thread是如何啟動的?如何對RT-Thread系統進行初始化呢?
    發表于 11-30 07:54

    為什么RT-Thread要采用這種復雜的方式來進行自動初始化操作呢

    在分析之前首先查閱 RT-Thread 的官方文檔RT-Thread 自動初始化機制,根據官方文檔的講述在 RTT 源碼中共使用了 6 中
    發表于 04-06 17:49

    RT-Thread自動初始化機制簡介

    RT-Thread 的時鐘管理以時鐘節拍為基礎,時鐘節拍是 RT-Thread 操作系統中最小的RT-Thread 自動初始化機制時鐘單位。
    發表于 04-06 18:08

    RT-Thread系統自動初始化機制簡介

    RT-Thread 自動初始化機制1、自動初始化機制簡介在系統啟動流程圖中,有兩個函數:rt_c
    發表于 04-12 17:43

    RT-Thread系統初始化與啟動流程詳細描述

    時, 該函數將初始化系統的定時器線程。void rt_application_init( )創建用戶線程由此創建個用戶main()線程,而 main()函數是RT-Thread的用戶
    發表于 08-25 15:15

    RT-Thread自動初始化原理分析

    ;}這里我們直接就可以使用 printf 進行打印,而沒有進行些其它的初始化,參考這個思路引出了 RT-Thread自動初始化
    發表于 12-05 14:17

    RT-Thread學習筆記 --(3)RT-Thread自動初始化機制分析

    相信不少工程師在閱讀RT-Thread相關源代碼的時候,都會經??吹饺缦聢D所示的宏定義,按照宏定義的命名來理解,這些宏定義似乎都是對些...
    發表于 01-25 18:55 ?1次下載
    <b class='flag-5'>RT-Thread</b>學習筆記 --(3)<b class='flag-5'>RT-Thread</b><b class='flag-5'>自動</b><b class='flag-5'>初始化</b>機制分析

    RT-Thread全球技術大會:如何使用組件以及自動初始化流程

    RT-Thread全球技術大會:如何使用組件和自動初始化流程 ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 15:16 ?1171次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:如何使用組件以及<b class='flag-5'>自動</b><b class='flag-5'>初始化</b>流程

    RT-Thread自動初始化機制

    ??在分析之前首先查閱 RT-Thread 的官方文檔 [RT-Thread 自動初始化機制](https://www.rt-thread.
    的頭像 發表于 06-17 08:52 ?3115次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>自動</b><b class='flag-5'>初始化</b>機制

    rt-thread 優化系列(六)啟動流程重構

    去年此時,筆者剛接觸 rt-thread 的時候,被它的初始化過程深深折服了。第次打開rt-thread 的項目,竟然沒找到多線程在
    的頭像 發表于 07-04 15:30 ?2038次閱讀
    <b class='flag-5'>rt-thread</b> 優化系列(六)啟動流程重構

    rt-thread線程棧初始化參數分析

    RT-Thread 在線程初始化的代碼內有初始化線程堆棧的代碼
    的頭像 發表于 08-14 16:50 ?2129次閱讀
    <b class='flag-5'>rt-thread</b>線程棧<b class='flag-5'>初始化</b>參數分析

    RT-Thread使用經驗分享:鏈表未初始化造成死機

    最近在開發調試基于RT-Thread 的驅動時,遇到個比較奇怪的死機問題,后來經過步步排查,終于發現是驅動的鏈表節點沒有初始化造成的死機
    的頭像 發表于 10-08 14:49 ?1357次閱讀
    <b class='flag-5'>RT-Thread</b>使用經驗分享:鏈表未<b class='flag-5'>初始化</b>造成死機