色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

RT-Thread啟動流程?RT-Thread如何支持不同開發板?

冬至子 ? 來源:dejavudwh ? 作者:dejavudwh ? 2023-08-10 15:29 ? 次閱讀

啟動流程
一個開發板上的RT-Thread的啟動流程可能是首先從bsp?當中鏈接腳本指定的startup_xxx.S?中的入口函數(ENTRY)或者復位異常處理函數(ResetHandler)開始運行,這部分我們在講?bsp?支持時會詳細講解。

之后跳入entry?函數(GCC,使用不同編譯器會進入不同的函數)執行,這里也可以跳入用戶自己的main函數,但是需要用戶自己完成rtthread_startup?的工作。

這個函數十分簡單,首先先關中斷(關中斷操作由cpu支持部分提供),然后進入RT-Thread的全局初始化中。

#if defined (__CC_ARM)
extern int Super$main(void);
/* re-define main function /
int Sub$main(void)
{
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
}
#elif defined( ICCARM )
extern int main(void);
/
__low_level_init will auto called by IAR cstartup /
extern void __iar_data_init3(void);
int __low_level_init(void)
{
// call IAR table copy function.
__iar_data_init3();
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
}
#elif defined( GNUC )
extern int main(void);
/
Add -eentry to arm-none-eabi-gcc argument */
int entry(void)
{
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
}
#endif

?rtthread_startup?是啟動流程當中的關鍵,首先rtthread_startup?會先調用rt_hw_board_init?,這個函數也由bsp支持部分提供,一般來說主要完成例如初始化中斷向量表、系統時鐘的初始化,設置輸出控制臺,同時初始化系統堆內存。

緊接著會調用rt_show_version?打印RT-Thread內核的系統版本信息,其中主要是利用控制臺(rt_printf?)進行輸出,通常來說是用戶在bsp支持中提供串口的注冊來實現的。以RT-Thread Simulator 例程來說,會通過設備驅動一路調用到bsp支持部分提供的串口輸出。

void rt_kprintf(const char *fmt, ...) ->
rt_size_t rt_device_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) ->
static rt_size_t rt_serial_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size) ->
rt_inline int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length) ->

  • static int stm32_putc(struct rt_serial_device *serial, char c)
    

然后會調用rt_system_timer_init?初始化系統定時器鏈表,這個函數比較簡單,主要就是數據結構進行初始化。

緊接著會調用rt_system_scheduler_init?初始化RT-Thread系統調度器相關的數據結構:

線程優先級鏈表:每一個優先級對應一個鏈表,通過rt_thread?結構中的tlist?成員來進行相同優先級線程的連接
當前線程優先級
當前線程控制塊
?rt_thread_ready_priority_group?中的每一位代表1個優先級,該位為1表示該優先級下有就緒線程,該位為0表示該優先級下沒有就緒線程
僵尸線程鏈表
void rt_system_scheduler_init(void)
{
register rt_base_t offset;
rt_scheduler_lock_nest = 0;
RT_DEBUG_LOG(RT_DEBUG_SCHEDULER, ("start scheduler: max priority 0x%02xn",
RT_THREAD_PRIORITY_MAX));
for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++)
{
rt_list_init(&rt_thread_priority_table[offset]);
}
rt_current_priority = RT_THREAD_PRIORITY_MAX - 1;
rt_current_thread = RT_NULL;
/* initialize ready priority group /
rt_thread_ready_priority_group = 0;
#if RT_THREAD_PRIORITY_MAX > 32
/
initialize ready table /
rt_memset(rt_thread_ready_table, 0, sizeof(rt_thread_ready_table));
#endif
/
initialize thread defunct */
rt_list_init(&rt_thread_defunct);
}
接下來會調用rt_application_init?初始化一個main主線程(并不會馬上運行),主要完成組件的初始化以及多核的處理,最后跳入用戶的main?函數

完成組件初始化的實現與rt_components_board_init?類似,在BSP支持部分講解。

void rt_application_init(void)
{
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(tid != RT_NULL);
#else
rt_err_t result;
tid = &main_thread;
result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(result == RT_EOK);
/* if not define RT_USING_HEAP, using to eliminate the warning */
(void)result;
#endif
rt_thread_startup(tid);
}
void main_thread_entry(void parameter)
{
extern int main(void);
extern int Super$main(void);
/
RT-Thread components initialization /
rt_components_init();
/
invoke system main function /
#if defined (__CC_ARM)
Super$main(); /
for ARMCC. */
#elif defined( ICCARM ) || defined( GNUC )
main();
#endif
}
void rt_components_init(void)
{
#if RT_DEBUG_INIT
int result;
const struct rt_init_desc *desc;
rt_kprintf("do components intialization.n");
for (desc = &__rt_init_desc_rti_board_end; desc < &__rt_init_desc_rti_end; desc ++)
{
rt_kprintf("initialize %s", desc->fn_name);
result = desc->fn();
rt_kprintf(":%d donen", result);
}
#else
const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
{
(*fn_ptr)();
}
#endif
}

然后,rt_system_timer_thread_init?主要是初始化軟件定時器的列表,并且創建軟件定時器線程。而rt_thread_idle_init?創建空閑線程,在系統沒有任何用戶線程調度的時候,就會被調度起來,這個空閑線程主要是檢查系統有沒有已經消亡的線程,如果有,則把消亡線程的資源進行回收,如果系統使能了電源管理,則會讓系統進行低功耗模式。

最后通過rt_system_scheduler_start?開啟調度器。

BSP支持
首先需要提供startup_xxx.S?類似的啟動文件,一般來說可能包含中斷向量表以及默認的中斷服務函數,以及選擇入口函數,一般可能為_start?或者ResetHandler?。

AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper
DCD RTC_IRQHandler ; RTC
DCD FLASH_IRQHandler ; Flash
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line 0
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
DCD ADC1_2_IRQHandler ; ADC1_2
DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
DCD TIM1_BRK_IRQHandler ; TIM1 Break
DCD TIM1_UP_IRQHandler ; TIM1 Update
DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler ; TIM3
DCD 0 ; Reserved
DCD I2C1_EV_IRQHandler ; I2C1 Event
DCD I2C1_ER_IRQHandler ; I2C1 Error
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SPI1_IRQHandler ; SPI1
DCD 0 ; Reserved
DCD USART1_IRQHandler ; USART1
DCD USART2_IRQHandler ; USART2
DCD 0 ; Reserved
DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
AREA |.text|, CODE, READONLY
; Reset handler routine
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
bsp支持主要提供對開發板的硬件初始化(通過rt_hw_board_init?向上提供接口)以及各類外設的驅動。

以RT-Thread Simulator 例程為例:rt_hw_board_init?中主要完成HAL庫的初始化、時鐘配置和RT-Thread系統堆的初始化,以及rt_components_board_init?會完成硬件的初始化。

#define RT_DEBUG_INIT 0
/**

  • RT-Thread Components Initialization for board
    */
    void rt_components_board_init(void)
    {
    #if RT_DEBUG_INIT
    int result;
    const struct rt_init_desc *desc;
    for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++)
    {
    rt_kprintf("initialize %s", desc->fn_name);
    result = desc->fn();
    rt_kprintf(":%d donen", result);
    }
    #else
    const init_fn_t *fn_ptr;
    for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < & **rt_init_rti_board_end; fn_ptr++)
    {
    (fn_ptr)();
    }
    #endif
    }
    ?RT_USED?: attribute ((used))?,標識不允許編譯器進行優化
    ?init_fn_t?:typedef int (init_fn_t)(void)?,函數指針
    ?##?:連接符
    ?SECTION?: attribute ((section(x)))?,執行輸入節名稱
    所以INIT_EXPORT(rti_board_start, "0.end")?等價于__attribute
    ((used)) const init_fn_t __rt_init_rti_board_start attribute ((section(".rti_fn.""0.end"))) = rti_board_start?

static int rti_board_start(void)
{
return 0;
}
INIT_EXPORT(rti_board_start, "0.end");
#define INIT_EXPORT(fn, level) RT_USED const init_fn_t _ rt_init ##fn SECTION(".rti_fn."level) = fn
?rt_board_end?同理,所以rt_components_board_init?的含義則為執行__rt_init_rti_board_start?到__rt_init_rti_board_end?之間函數

指定節.rti_fn.1?,根據鏈接器節放置規則,將放置在.rti_fn.0.end?節和.rti_fn.1.end?節之間。

#define INIT_BOARD_EXPORT(fn) INIT_EXPORT(fn, "1")
所以RT-Thread提供了另一個宏,它的主要作用就是用來在初始化硬件時調用相應的函數。所以一些外設驅動初始化都展開了這個宏。以RT-Thread Simulator 例程為例:

INIT_BOARD_EXPORT(rt_hw_usart_init);
INIT_BOARD_EXPORT(rt_hw_pin_init);
總的來說,一個基本的BSP主要任務是建立讓操作系統運行的基本環境,所以大致需要完成的主要工作是:

初始化CPU內部寄存器,設定RAM工作時序。
實現時鐘驅動及中斷控制器驅動,完善中斷管理。
實現串口和 GPIO 驅動。
初始化動態內存堆,實現動態堆內存管理。
CPU支持
這部分官方文檔很詳細,可參考內核移植 (rt-thread.org)

嵌入式領域有多種不同 CPU 架構,例如 Cortex-M、ARM920T、MIPS32、RISC-V 等等。為了使 RT-Thread 能夠在不同 CPU 架構的芯片上運行,RT-Thread 提供了一個 libcpu 抽象層來適配不同的 CPU 架構。libcpu 層向上對內核提供統一的接口,包括全局中斷的開關,線程棧的初始化,上下文切換等。

RT-Thread 的 libcpu 抽象層向下提供了一套統一的 CPU 架構移植接口,這部分接口包含了全局中斷開關函數、線程上下文切換函數、時鐘節拍的配置和中斷函數、Cache 等等內容。下表是 CPU 架構移植需要實現的接口和變量。

libcpu 移植相關 API
1.jpg

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

    關注

    115

    文章

    6230

    瀏覽量

    145252
  • 定時器
    +關注

    關注

    23

    文章

    3259

    瀏覽量

    115919
  • RT-Thread
    +關注

    關注

    31

    文章

    1321

    瀏覽量

    40845
  • gcc編譯器
    +關注

    關注

    0

    文章

    78

    瀏覽量

    3482
  • 調度器
    +關注

    關注

    0

    文章

    98

    瀏覽量

    5353
收藏 人收藏

    評論

    相關推薦

    RT-Thread記錄(一、版本開發環境及配合CubeMX)

    RT-Thread 學習記錄的第一篇文章,RT-Thread記錄(一、RT-Thread 版本、RT-Thread Studio開發環境 及
    的頭像 發表于 06-20 00:28 ?5486次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(一、版本<b class='flag-5'>開發</b>環境及配合CubeMX)

    RT-Thread記錄(二、RT-Thread內核啟動流程

    在前面我們RT-Thread Studio工程基礎之上講一講RT-Thread內核啟動流程.
    的頭像 發表于 06-20 00:30 ?5193次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(二、<b class='flag-5'>RT-Thread</b>內核<b class='flag-5'>啟動</b><b class='flag-5'>流程</b>)

    如何使用RT-Thread Studio創建支持HPM6750開發板RT-Thread項目

    StudioRT-Thread Studio安裝程序下載頁面RT-Thread Studio安裝程序下載完成后,運行安裝程序,一路下一步即可完成RT-Thread Studio的安裝。添加HPM6750
    發表于 06-08 11:22

    RT-Thread編程指南

    RT-Thread編程指南——RT-Thread開發組(2015-03-31)。RT-Thread做為國內有較大影響力的開源實時操作系統,本文是RT
    發表于 11-26 16:06 ?0次下載

    RT-Thread開發,如何有效學習RT-Thread的五個步驟

    RT-Thread推出RT-Thread Inside戰略開放RT-Thread開發平臺授權合作,與硬件十萬個為什么合作首次推出第一款RT-
    的頭像 發表于 09-25 09:55 ?3.5w次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>開發</b>,如何有效學習<b class='flag-5'>RT-Thread</b>的五個步驟

    RT-Thread Studio驅動SD卡

    總結前言硬件平臺:RT-Thread ART-Pi STM32H750XBH6開發板 H750開發板開發軟件:RT-Thread Studi
    發表于 12-27 19:13 ?20次下載
    <b class='flag-5'>RT-Thread</b> Studio驅動SD卡

    RT-Thread學習筆記 RT-Thread的架構概述

    的種種優越之處。RT-Thread 是一款完全由國內團隊開發維護的嵌入式實時操作系統(RTOS),具有完全的自主知識產權。經過 16 個年頭的沉淀,伴隨著物聯網的興起,它正演變成一個功能強大、組件豐富的物
    的頭像 發表于 07-09 11:27 ?4704次閱讀
    <b class='flag-5'>RT-Thread</b>學習筆記 <b class='flag-5'>RT-Thread</b>的架構概述

    RT-Thread文檔_RT-Thread 簡介

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

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南
    發表于 02-22 18:23 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 潘多拉 STM32L475 上手指南

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

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

    基于RT-Thread Studio學習

    前期準備:從官網下載 RT-Thread Studio,弄個賬號登陸,開啟rt-thread學習之旅。
    的頭像 發表于 05-15 11:00 ?4404次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio學習

    機智云設備移植RT-Thread

    開發環境:Keil版本:V5.30RT-Thread版本:3.1.5STM32cubeMX:V6.0.1開發板MCU:STM32F103機智云平臺生成的應用代碼是裸機版本的,而在實際應用過
    的頭像 發表于 04-19 18:39 ?1066次閱讀
    機智云設備移植<b class='flag-5'>RT-Thread</b>

    RT-Thread框架下的SMP支持

    最近報名參加了恩智浦社區的 LPC55S69 開發板測評活動,由于其搭載的是一顆 Cortex-M33 Dual Core 的 CPU,而且有大佬已經支持RT-Thread 的 BSP,就考慮
    的頭像 發表于 10-11 10:34 ?1322次閱讀
    <b class='flag-5'>RT-Thread</b>框架下的SMP<b class='flag-5'>支持</b>

    基于rt-thread的socket通信設計

    最近再研究 rt-thread 的通信 ,想設計出 eps8266(多個) rt-thread(作為中控) 服務器的通信框架,使用的開發板是 潘多拉
    的頭像 發表于 10-13 15:02 ?1478次閱讀
    基于<b class='flag-5'>rt-thread</b>的socket通信設計

    rt-studio潘多拉開發板最新rt-thread不能運行解決辦法

    rt-studio 上 選擇基于開發板的項目,選擇潘多拉,rt-thread選擇lasted ,如下圖
    的頭像 發表于 10-16 14:50 ?1509次閱讀
    <b class='flag-5'>rt</b>-studio潘多拉<b class='flag-5'>開發板</b>最新<b class='flag-5'>rt-thread</b>不能運行解決辦法
    主站蜘蛛池模板: 榴莲推广APP网站入口官网 | 精品无人区麻豆乱码1区2 | 一级无毛片 | 青青久久网 | 国产专区亚洲欧美另类在线 | 国产午夜视频 | 成人免费毛片观看 | 99国产在线精品视频 | 青青伊人影院 | 99re6久久热在线播放 | 久久青草影院 | 日韩大胆视频 | 女人爽到高潮嗷嗷叫视频 | 美女穿丝袜被狂躁动态图 | 免费人成在线观看视频不卡 | 精品国产5g影院天天爽 | 中文字幕在线免费观看视频 | 国产小视频免费看 | 亚洲欧美日本久久综合网站 | 美妇教师双飞后菊 | 亚洲成人精品久久 | 国产哺乳期奶水avav | 男人有噶坏 | 天天看学生视频 | 一本道高清码v京东热 | 国产精品伦理一二三区伦理 | 久青草国产在线视频亚瑟影视 | 大肥女ass樱桃 | 6080YYY午夜理论片在线观看 | 老司机深夜福利ae 入口网站 | 香蕉99久久久久成人麻豆 | 老师别揉我胸啊嗯小说 | 国产精品.XX视频.XXTV | 嫩草电影网嫩草影院 | 亚洲国产区中文在线观看 | 青娱国产区在线 | 十九岁在线观看免费完整版电影 | 最近免费中文MV在线字幕 | 亚洲精品国产字幕久久vr | 牛牛超碰 国产 | 老司机午夜影院试看区 |