基於STM32標準庫移植RT-Thread Nano
1 前言
RT-Thread Nano是RT-Thread(RTT)的裁剪版,相比完整版本的RT-Thread,RT-Thread Nano保留了RT-Thread的硬實時核心,保證了極少的資源消耗。“麻雀雖小五臟俱全”,RT-Thread Nano核心包含完整的作業系統功能, 執行緒管理、執行緒間同步與通訊、時鐘管理、中斷管理、記憶體管理等。執行緒通訊與標準版RT-Thread的相容,無縫支援RT-Thread應用程式。
更多RT-Thread Nano描述,參考RT-Thread官方文件。
2 什麼時候使用RT-Thread Nano
標準版RT-Thread包含了核心、裝置驅動、第三方元件、packages等等,而且這些幾乎都是開源的,通過“堆積木”的方式即可快速搭建一個基本專案小系統工程,但是帶來的代價之一是增加資源(RAM、ROM)的消耗,一些資源比較緊張的CPU則需外擴RAM和ROM。RT-Thread Nano最大特點之一是“資源佔用小”,基於資源不足的考慮,RT-Thread Nano是一個優異的選擇。
使用RT-Thread Nano的場景參考建議:
-
資源有限
RAM、ROM資源有限,而專案任務量比較多,必須使用RTOS,此時考慮使用RT-Thread Nano -
只需一個排程核心
只需一個排程核心,不需裝置管理、第三方元件等外部資源,直接使用RT-Thread Nano,省去裁剪標準RTT時間 -
複用已有的裝置驅動、元件
公司已存在一套出貨量巨大的、穩定的裝置驅動、元件,不需要使用RTT裝置驅動和元件,此時建議使用RT-Thread Nano一個排程核心即可,複用已有的驅動、元件
3 STM32標準庫移植
RT-Thread Nano移植非常簡單,RT-Thread Nano已經支援常用CPU,相關啟動檔案已經提供,移植步驟也給出詳細的描述文件,可以參考官方移植教程。對於Keil MDK的下移植,RT-Thread Nano 已整合在其IDE中,可以直接在 IDE 中進行下載新增,十分便捷,而且與使用何種庫沒有太多關係。本文主要描述IAR下的STM32標準庫移植(其實差異也很小很小!)。
第一步:準備IAR工程和RT-Thread Nano原始碼
- 準備一個可以正常使用的裸機程式碼IAR工程
- 下載RT-Thread Nano程式碼,RT-Thread Nano
第二步:拷貝原始碼
-
將RT-Thread Nano原始碼拷貝到 工程原始碼目錄下,目錄內容包括:
[1] 原始碼檔案,
include、libcpu、src
資料夾,如需需finsh元件,還需新增components
檔案[2] 配置檔案,原始碼程式碼
rtthread/bsp
資料夾下board.c
與rtconfig.h
第三步:加入工程
- 新增工程下
RT-Thread/src/
資料夾中所有檔案到工程 - 新增工程下
RT-Thread/libcpu/
資料夾中相應核心的 CPU 移植檔案及上下文切換檔案cpuport.c
和context_iar.S
- 新增
RT-Thread/
資料夾下的板級配置檔案board.c
第四步:新增標頭檔案路徑
第五步:板級配置
這一步主要是板級CPU相關資訊配置,原始碼檔案位於board.c
。我直接拷貝現有的STM32的工程board.c
檔案,幾乎不用修改。
-
RT-Thread Nano 已實現異常處理函式
HardFault_Handler
和懸掛處理函式PendSV_Handler
,如原工程已實現這兩者中斷函式,應遮蔽掉,避免編譯報錯 -
中斷向量,如果存在BootLoader,需先設定中斷偏移地址;如沒有則不需配置
void rt_hw_board_init()
{
/* 配置中斷向量表偏偏移地址 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x400);
/* System Clock Update */
SystemCoreClockUpdate();
/* System Tick Configuration */
_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}
-
時鐘配置,呼叫
SystemCoreClockUpdate
配置CPU主時鐘 -
新增系統時鐘節拍
/* 滴答定時器配置 */ static uint32_t _SysTick_Config(rt_uint32_t ticks) { if ((ticks - 1) > 0xFFFFFF) { return 1; } _SYSTICK_LOAD = ticks - 1; _SYSTICK_PRI = 0xFF; _SYSTICK_VAL = 0; _SYSTICK_CTRL = 0x07; return 0; } /* 時鐘節拍中斷函式 */ void SysTick_Handler(void) { /* enter interrupt */ rt_interrupt_enter(); rt_tick_increase(); /* leave interrupt */ rt_interrupt_leave(); }
至此,一個基本的RT-Thread Nano小系統工程移植完成。
4 應用例項
main函式為RT-Thread Nano的主執行緒,我們再建立於一個led執行緒。
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
static void led_thread_entry(void* parameter)
{
GPIO_Configuration();
for (;;)
{
GPIO_SetBits(GPIOB, GPIO_Pin_0);
rt_thread_mdelay(500);
GPIO_ResetBits(GPIOB, GPIO_Pin_0);
rt_thread_mdelay(500);
}
}
void led_thread_init(void)
{
static rt_uint8_t s_led_stack[256];
static struct rt_thread led_thread;
rt_err_t result;
result = rt_thread_init(&led_thread,
"led",
led_thread_entry,
RT_NULL,
(rt_uint8_t*)&s_led_stack[0],
sizeof(s_led_stack),
7,
5);
if (result == RT_EOK)
{
rt_thread_startup(&led_thread);
}
}
注意:
- main執行緒預設堆疊大小為512位元組,如main執行緒任務量比較大,需調堆疊大小,否則導致執行緒堆疊溢位
- RT-Thread Nano預設配置不支援動態執行緒,因此採用靜態方式建立執行緒
- RT-Thread Nano執行緒優先順序預設最低為8,建立執行緒指定優先順序不能超過該值
完整示例工程下載:點選下載
相關文章
- (RT-Thread學習筆記1)基於 CubeMX 移植 RT-Thread Nanothread筆記NaN
- STM32 移植 RT-Thread 標準版的 FinSH 元件thread元件
- RT-Thread移植到stm32thread
- stm32標準庫和HAL庫的關係
- STM32標準庫通用定時器PWM生成定時器
- CUJ:標準庫:基於檔案的容器 (轉)
- 將STM32的標準庫編譯成lib編譯
- STM32標準庫通用定時器輸入捕獲定時器
- STM32 + RT-Thread + LVGLthread
- RT-Thread移植入門學習thread
- STM32 GPIO詳細篇(基於HAL庫)
- STM32 ADC詳細篇(基於HAL庫)
- STM32系統時鐘RCC(基於HAL庫)
- RT-Thread 的STM32 通用 Bootloaderthreadboot
- Arduino庫和STM32的暫存器、標準庫、HAL庫、LL庫開發比較之GPIOUI
- STM32 定時器詳細篇(基於HAL庫)定時器
- 2.12.uboot的移植2-從uboot官方標準uboot開始移植boot
- C 標準庫 -
- C++標準庫、C++標準模版庫介紹C++
- micropython STM32移植筆記(一)Python筆記
- [C++][基礎]5_標準庫型別C++型別
- 基於HAL庫的STM32的DSP庫詳解(附FFT應用)FFT
- C++標準庫C++
- 標準庫之template
- CUJ:標準庫:標準庫中的搜尋演算法 (轉)演算法
- 基礎知識6——標準資料庫稽核——未完資料庫
- LKCOS:基於程式移植的COS系統
- python常用標準庫Python
- PHP 標準庫 SplStack 棧PHP
- C標準庫學習
- Go標準庫ContextGoContext
- Swift標準庫解析:IntSwift
- - C語言標準庫C語言
- 標準模板庫STL (轉)
- golang標準庫之 fmtGolang
- 標準庫之 random 模組random
- C++標準庫:chronoC++
- C++標準庫:randomC++random