RM新时代网站-首页

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

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

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

RT-Thread記錄(二、RT-Thread內(nèi)核啟動(dòng)流程)

矜辰所致 ? 來(lái)源:矜辰所致 ? 作者:矜辰所致 ? 2022-06-20 00:30 ? 次閱讀
在上一篇文章中,我們了解了RT-Thread的版本以及開(kāi)發(fā)環(huán)境,使用RT-Thread Studio成功創(chuàng)建了一個(gè)工程。
但是要了解一個(gè)操作系統(tǒng),內(nèi)核的了解是必不可少的,
我們今天就在前面我們RT-Thread Studio工程基礎(chǔ)之上講一講RT-Thread內(nèi)核啟動(dòng)流程

RT-Thread啟動(dòng)流程

1、基礎(chǔ)介紹
2、源碼分析

2.1 匯編部分 — startup_xxxx.s說(shuō)明
2.2 C部分 — rtthread_startup 說(shuō)明
2.2.1 板級(jí)硬件初始化 — rt_hw_board_init
板級(jí)硬件初始化更新說(shuō)明
2.2.2 RT-Thread 堆和棧空間說(shuō)明(與FreeRTOS不同)
2.2.3 main線(xiàn)程創(chuàng)建 — rt_application_init
2.2.4 調(diào)度器說(shuō)明

1、基礎(chǔ)介紹

在裸機(jī)程序中,一般在 .s 文件中就跳轉(zhuǎn)到 _main從而跳轉(zhuǎn)到 main()函數(shù)啟動(dòng),而 RT-Thread 啟動(dòng)會(huì)先跳轉(zhuǎn)到其啟動(dòng)函數(shù) rtthread_startup()進(jìn)行一系列的必要的初始化,最后才跳轉(zhuǎn)至 main()函數(shù)。

簡(jiǎn)單來(lái)說(shuō)就是: 程序啟動(dòng),通過(guò) startup_xxxx.s 文件(匯編語(yǔ)言)跳轉(zhuǎn)到 RT-Thread啟動(dòng)函數(shù)rtthread_startup() (C語(yǔ)言),再通過(guò) rtthread_startup() 跳轉(zhuǎn)到 main()(C語(yǔ)言)函數(shù)。

官方的圖片很詳細(xì)的表明了這個(gè)流程:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_5,color_FFFFFF,t_70,g_se,x_16#pic_center

在 RT-Thread 中,會(huì)把 main()函數(shù) 當(dāng)成是一個(gè)線(xiàn)程。這個(gè)在 rtthread_startup() 就會(huì)將 main() 創(chuàng)建成一個(gè)線(xiàn)程,除此之外,rtthread_startup() 還會(huì)創(chuàng)建timer 線(xiàn)程 和 空閑線(xiàn)程 這兩個(gè)線(xiàn)程。

結(jié)合上圖,下面我們通過(guò)上篇文章創(chuàng)建的示例代碼來(lái)說(shuō)明一下這個(gè)流程。

2、源碼分析

2.1 匯編部分 — startup_xxxx.s說(shuō)明

打開(kāi)RT-Thread Studio工程,在哪里找到 startup_xxxx.s 文件呢,看下面一張圖:

在這里插入圖片描述

我們找到了啟動(dòng)文件,可以打開(kāi)查看,啟動(dòng)文件的說(shuō)明我在我在另一篇博文有詳細(xì)的介紹:

STM32的啟動(dòng)過(guò)程 — startup_xxxx.s文件解析(更新GCC環(huán)境下的啟動(dòng)文件分析)

已經(jīng)講解的比較詳細(xì)了,這里我只把主要的簡(jiǎn)單說(shuō)明一下。在上面推薦的博文中講到過(guò),GCC環(huán)境下面的啟動(dòng),需要兩個(gè)文件,一個(gè)是 startup_xxxx.s文件,還一個(gè)是 .ld鏈接文件,我們先看一下鏈接文件:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16



在以前講過(guò),GCC下的鏈接文件主要制定了入口函數(shù),堆棧大小和數(shù)據(jù)段的整體布局。在上圖中我們看到值定義了系統(tǒng)棧的大小,并沒(méi)有定義堆大小。

這里為什么只定義系統(tǒng)棧?
雖然我們?cè)谄渌┪恼f(shuō)過(guò),如果不用 malloc函數(shù),不需要用到堆,這里沒(méi)有定義是因?yàn)樵诤竺娉跏蓟臅r(shí)候會(huì)根據(jù)是否使用堆,來(lái)定義堆的大小。
在本文下面板級(jí)硬件初始化部分有介紹說(shuō)明。

然后就簡(jiǎn)單來(lái)看一下 startup_xxxx.s文件,首先我們找到上電執(zhí)行的第一個(gè)指令 Reset_Handler(芯片剛上電,就是上電復(fù)位,直接就會(huì)觸發(fā)Reset_Handler):

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16


上圖中所進(jìn)行的操作不理解的可以查看博文:

STM32的內(nèi)存管理相關(guān)(內(nèi)存架構(gòu),內(nèi)存管理,map文件分析)

完成數(shù)據(jù)搬運(yùn)以后,就是系統(tǒng)基本的初始化,如下圖:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16


完成基本初始化,MCU得以運(yùn)行起來(lái),就跳轉(zhuǎn)到我們上面基礎(chǔ)介紹里面說(shuō)到的入口函數(shù),如下圖:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

通過(guò)上面的步驟,最終就從 .s 中的匯編跳轉(zhuǎn)到了 C語(yǔ)言部分,通過(guò)入口函數(shù)跳轉(zhuǎn)到 rtthread_startup函數(shù),我們通過(guò)下面的介紹說(shuō)明一下,進(jìn)入rtthread_startup函數(shù) 后,RT-Thread 確實(shí)做了哪些工作。

2.2 C部分 — rtthread_startup 說(shuō)明

在本文第一節(jié)基礎(chǔ)介紹中通過(guò)官方的一張圖表示了進(jìn)入rtthread_startup后,所會(huì)進(jìn)行的操作,我們上面也說(shuō)明了工程是怎么進(jìn)入 rtthread_startup 函數(shù)的,那么進(jìn)入 rtthread_startup函數(shù) 后執(zhí)行了哪些操作,如下圖:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16


補(bǔ)充說(shuō)明: 上圖中的SMP相關(guān),是與多核處理器有關(guān)的設(shè)置。

上面的過(guò)程很好理解,主要有做了以下工作:

1、基本的硬件初始化;

2、一定會(huì)創(chuàng)建main現(xiàn) 線(xiàn)程;

3、根據(jù)是否使用軟件定時(shí)器創(chuàng)建 time r線(xiàn)程;

4、一定會(huì)創(chuàng)建 idle 線(xiàn)程;

5、初始化開(kāi)啟調(diào)度器;

其中有一些初始化我們可以更加深入的看看具體的操作:

2.2.1 板級(jí)硬件初始化 — rt_hw_board_init

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

在上圖找那個(gè),板級(jí)硬件初始化最后調(diào)用了rt_components_board_init()函數(shù),這個(gè)函數(shù)如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

rt_components_board_init()函數(shù)會(huì)把所有 INIT_BOARD_EXPORT 的設(shè)備都初始化,這里暫時(shí)不介紹是如何實(shí)現(xiàn)的,但是有必要說(shuō)明一下。

比如我們什么外設(shè)都沒(méi)使能,但是使用到了串口1作為打印LOG的設(shè)備,所以串口1 必定會(huì)被使能,那么這個(gè)初始化就是在這里完成的,我們可以在工程 drivers 文件夾里的drv_usart.c 文件中查看到串口相關(guān)的初始化代碼,我們可以看到如下圖所示部分(此部分串口1 的說(shuō)明有待確認(rèn),因?yàn)楹笃诩恿似渌谝院蠡仡^來(lái)看這個(gè)地方,并沒(méi)有發(fā)現(xiàn)下圖代碼……):

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_17,color_FFFFFF,t_70,g_se,x_16


板級(jí)硬件初始化更新說(shuō)明

對(duì)于上圖提到的串口會(huì)使用 INIT_BOARD_EXPORT(rt_hw_usart_init),后續(xù)我反而并沒(méi)有找到圖示代碼,也不知道是因?yàn)榘姹締?wèn)題還是什么原因,這里需要補(bǔ)充說(shuō)明一下:

硬件設(shè)備的初始化是在hw_board_init函數(shù)中的:

pYYBAGKueT-AT5aBAADBiQQ3Pqo300.png

2.2.2 RT-Thread 堆和棧空間說(shuō)明(與FreeRTOS不同)

在上圖中,有一點(diǎn)比較特殊,就是對(duì) 堆 空間的初始化,我們以前遇到的都是在啟動(dòng)文件中定義好堆??臻g,而我們上面分析 RT-Thread 啟動(dòng)文件的時(shí)候,只定義了??臻g,堆空間沒(méi)有定義,其實(shí)是放在了這個(gè)地方:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

剛開(kāi)始看到這里還有個(gè)疑問(wèn),HEAP 把余下 所有的 RAM 都使用了,按照以前的理解,系統(tǒng)棧應(yīng)該是在最后面的位置的,這里是怎么回事?

關(guān)于 系統(tǒng)棧位置的問(wèn)題,可以參考博文:RTOS的 任務(wù)棧 和 系統(tǒng)棧

上面我們通過(guò)源碼看到的結(jié)論和 這篇博文說(shuō)到的不一樣(當(dāng)時(shí)是用裸機(jī)和 FreeRTOS作為例子說(shuō)明的),然后在 RT-Thread 下,系統(tǒng)棧的位置在什么地方,于是乎回頭看了看定義數(shù)據(jù)段整體布局的鏈接文件:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_17,color_FFFFFF,t_70,g_se,x_16

通過(guò)鏈接文件我們可以推斷 .stack 的位置,那么為了確認(rèn)一下,我們可以查看程序編譯過(guò)后的 .map文件:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

在 RAM 數(shù)據(jù)段我們可以查看數(shù)據(jù)存放的位置,找到關(guān)于 系統(tǒng)棧的位置部分:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

確認(rèn)了在 RT-Thread 中,系統(tǒng)棧的位置是確實(shí)存放于 .data 段和 .bss 之間的,所以堆空間即便使用了余下全部的 ram 空間也是沒(méi)有問(wèn)題的。

2.2.3 main線(xiàn)程創(chuàng)建 — rt_application_init

在 RT-Thread 中,創(chuàng)建了一個(gè)名字為 "main" 的線(xiàn)程來(lái)調(diào)用 main() 函數(shù),就是在rtthread_startup函數(shù)中的rt_application_init(),如下圖:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

2.2.4 調(diào)度器說(shuō)明

調(diào)度器是操作系統(tǒng)的核心知識(shí),調(diào)度器是基于鏈表進(jìn)行操作的,具體的原理將來(lái)會(huì)單獨(dú)寫(xiě)一篇文章說(shuō)明,這里我們就簡(jiǎn)單的過(guò)一遍,知道函數(shù)的用意。

rtthread_startup函數(shù)中,使用rt_system_scheduler_init();初始化調(diào)度器,rt_system_scheduler_start();開(kāi)啟調(diào)度器,開(kāi)啟調(diào)度器之后,線(xiàn)程之間就會(huì)根據(jù)一定的規(guī)則進(jìn)行切換(時(shí)間片,優(yōu)先級(jí)):

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

開(kāi)啟調(diào)度器后,會(huì)在就緒列表中找到最高優(yōu)先級(jí)的線(xiàn)程,然后通過(guò)設(shè)置 線(xiàn)程指針(PSP),來(lái)跳轉(zhuǎn)到對(duì)應(yīng)的位置執(zhí)行:

線(xiàn)程指針什么意思,可以參考博文:FreeRTOS記錄(三、FreeRTOS任務(wù)調(diào)度原理解析_Systick、PendSV、SVC)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

至此,整個(gè)系統(tǒng)就正常跑起來(lái)了,然后用戶(hù)運(yùn)行自己想要做的事情,可以在 main 中設(shè)計(jì)自己的應(yīng)用代碼,或者創(chuàng)建線(xiàn)程。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(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)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1372

    瀏覽量

    40276
  • STM
    STM
    +關(guān)注

    關(guān)注

    1

    文章

    556

    瀏覽量

    42437
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1285

    瀏覽量

    40081
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    RT-Thread記錄(一、版本開(kāi)發(fā)環(huán)境及配合CubeMX)

    RT-Thread 學(xué)習(xí)記錄的第一篇文章,RT-Thread記錄(一、RT-Thread 版本、RT-T
    的頭像 發(fā)表于 06-20 00:28 ?5225次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>記錄</b>(一、版本開(kāi)發(fā)環(huán)境及配合CubeMX)

    RT-Thread記錄(三、RT-Thread線(xiàn)程操作函數(shù))

    講完了RT-Thread開(kāi)發(fā)環(huán)境,啟動(dòng)流程,啟動(dòng)以后當(dāng)然是開(kāi)始跑線(xiàn)程了,那么自然我們得學(xué)會(huì)如何創(chuàng)建線(xiàn)程以及線(xiàn)程的有關(guān)操作。
    的頭像 發(fā)表于 06-20 00:31 ?6806次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>記錄</b>(三、<b class='flag-5'>RT-Thread</b>線(xiàn)程操作函數(shù))

    RT-Thread內(nèi)核簡(jiǎn)介

    、RT-Thread 啟動(dòng)流程5、RT-Thread 程序內(nèi)存分布keil工程編譯內(nèi)存分布RT-thread studio 工程編譯內(nèi)存分布
    發(fā)表于 08-06 07:44

    【原創(chuàng)精選】RT-Thread征文精選技術(shù)文章合集

    及配合CubeMX)RT-Thread記錄、RT-Thread內(nèi)核啟動(dòng)
    發(fā)表于 07-26 14:56

    RT-Thread快速入門(mén)之了解內(nèi)核啟動(dòng)流程

    1、了解RT-Thread內(nèi)核啟動(dòng)流程  內(nèi)核是操作系統(tǒng)最基礎(chǔ)也是最重要的部分。從本文開(kāi)始進(jìn)入 RT-
    發(fā)表于 09-05 17:01

    RT-Thread編程指南

    RT-Thread編程指南——RT-Thread開(kāi)發(fā)組(2015-03-31)。RT-Thread做為國(guó)內(nèi)有較大影響力的開(kāi)源實(shí)時(shí)操作系統(tǒng),本文是RT-Thread實(shí)時(shí)操作系統(tǒng)的編程指南
    發(fā)表于 11-26 16:06 ?0次下載

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 理解defunct僵尸線(xiàn)程

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)
    發(fā)表于 01-25 18:19 ?8次下載
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>內(nèi)核</b>學(xué)習(xí)筆記 - 理解defunct僵尸線(xiàn)程

    大佬帶你理解RT-Thread內(nèi)核并上手實(shí)踐

    RT-Thread內(nèi)核的相關(guān)概念和基礎(chǔ)知識(shí),然后了解RT-Thread系統(tǒng)的啟動(dòng)流程、內(nèi)存分布情況以及內(nèi)
    發(fā)表于 06-30 17:10 ?1251次閱讀

    RT-Thread學(xué)習(xí)筆記 RT-Thread的架構(gòu)概述

    RT-Thread 簡(jiǎn)介 作為一名 RTOS 的初學(xué)者,也許你對(duì) RT-Thread 還比較陌生。然而,隨著你的深入接觸,你會(huì)逐漸發(fā)現(xiàn) RT-Thread 的魅力和它相較于其他同類(lèi)型 RTOS
    的頭像 發(fā)表于 07-09 11:27 ?4545次閱讀
    <b class='flag-5'>RT-Thread</b>學(xué)習(xí)筆記 <b class='flag-5'>RT-Thread</b>的架構(gòu)概述

    RT-Thread文檔_RT-Thread 簡(jiǎn)介

    RT-Thread文檔_RT-Thread 簡(jiǎn)介
    發(fā)表于 02-22 18:22 ?5次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 簡(jiǎn)介

    RT-Thread文檔_內(nèi)核基礎(chǔ)

    RT-Thread文檔_內(nèi)核基礎(chǔ)
    發(fā)表于 02-22 18:28 ?0次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>內(nèi)核</b>基礎(chǔ)

    RT-Thread文檔_內(nèi)核移植

    RT-Thread文檔_內(nèi)核移植
    發(fā)表于 02-22 18:31 ?3次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>內(nèi)核</b>移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植
    發(fā)表于 02-22 18:31 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

    基于RT-Thread Studio學(xué)習(xí)

    前期準(zhǔn)備:從官網(wǎng)下載 RT-Thread Studio,弄個(gè)賬號(hào)登陸,開(kāi)啟rt-thread學(xué)習(xí)之旅。
    的頭像 發(fā)表于 05-15 11:00 ?3930次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio學(xué)習(xí)

    RT-Thread v5.0.2 發(fā)布

    ://github.com/RT-Thread/rt-thread/releases/tag/v5.0.2 RT-Thread 迎來(lái)了全新的版本 v5.0.2,自 v5.0.0?版本發(fā)布以來(lái),
    的頭像 發(fā)表于 10-10 18:45 ?1464次閱讀
    <b class='flag-5'>RT-Thread</b> v5.0.2 發(fā)布
    RM新时代网站-首页