何為RT-Thread Nano?大家知道,Keil5以后采用pack形式管理芯片及各種相關組件的。RT-Thread Nano就是通過Keil pack方式發布,在保持原有RT-Thread基本功能的情況下,實現了極小的Flash和Ram占用。默認配置下,Flash可小至2.5K, Ram可以小至1K。
目前pack包含有kernel、shell(msh)、device drivers三部分功能,這3個功能可按實際使用情況按需加載。本次使用的主芯片為GD32F150C8T6,資源為Flash:64K,RAM:8K。
一、RT-Thread Nano Pack下載安裝
1.在Keil5主界面上點擊“Pack Install”按鈕,即可進入Pack Install界面
圖1:Keil5主界面
2.在Pack Install界面下,RT-Thread Pack在右邊欄中。如未下載,可點擊“Install”下載;如已安裝,版本有更新,將提示“Update”可更新。
圖2:RT-ThreadPack下載
3.如在圖2界面“Packs”欄中未發現“RT-Thread”,可先在菜單“Packs”下點擊“Check for Updates”。Update完成后,將可看到RT-Thread Pack。
圖3:Pack Update
4.Pack下載完成后,Keil將自動彈出Pack安裝界面,按步驟依次完成安裝。
二、裸機最小系統工程建立
1.本次工程使用的是芯片是GD32F150C8T6,64KFlash、8KRam。Keil5下開發須先在官網下載Keil Pack (GigaDevice.GD32F1x0_DFP.pack),并正確安裝。
2.先按照裸機Keil工程流程搭建工程,為測試Flash及Ram大小,最小工程只包含必須的Libraries文件,main函數也未作任何多余處理。
圖4:GD32F150C8T6最小工程
3.編譯完成后,默認配置Flash:1112字節、Ram:2144字節
4.修改默認啟動文件startup_gd32f1x0.s定義堆和棧大小:默認堆為0x400,棧為0x400。后續我們將采用RT-Thread管理內存堆,所有堆設置為0;棧可按照main函數應用需求調整為0x100或以上。
圖5:啟動文件棧和堆修改
啟動文件修改后,Ram大小為352字節
圖6:修改堆和棧后Flash和棧占用大小
三、kernel加載與應用
1.加載RT-Thread Kernel:在主界面點擊“ManageRun-Time Environment”按鈕即可進入加載頁。
圖7:ManageRun-Time Environment
在“RTOS”一欄中選中“RT-Thread”,并在列表中選中“kernel”,當前版本為2.1.2。
圖8:RT-Thread kernel選擇
2.確定后,keil界面上會加載RT-Thread的kernel文件,更根據當前選擇芯片類型加入已移植完成的M3芯片內核代碼、配置文件等。
圖9:RT-Thread kernel文件
其中:
Kernel文件包括:
-
clock.c
-
components.c
-
device.c
-
idle.c
-
ipc.c
-
irq.c
-
kservice.c
-
mem.c
-
object.c
-
scheduler.c
-
thread.c
-
timer.c
Cortex-m3芯片內核移植代碼:
應用代碼及配置文件:
-
board.c
-
rtconfig.h
3.此時再次編譯工程,編譯器會提示有函數被重復定義了。需按照如下方式做一些修改:
a) 修改gd32f10x_it.c文件,刪除如下函數:
-
void HardFault_Handler(void)
-
void PendSV_Handler(void)
-
void SysTick_Handler(void)
b) 按照board.c上的說明,依次完成如下操作:
圖10:board.c修改流程說明
-
修改24行:#include “gd32f1x0.h”
-
修改48行:在rt_hw_board_init()函數內開啟SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
-
修改66行:voidSysTick_Handler(void)
4.修改main.c:
-
加入#include
-
在while循環中加入rt_thread_dealy(100);
5.再次編譯順利通過,下載至芯片運行可看到main函數中每1s可中斷一次。RT-Thread任務調度器已經正常運行。
圖11:RT-Thread正常運行
通過查看.map文件可獲取當前各文件資源占用情況。在未開啟任何優化的情況下,可以看到RT-Thread內核各文件資源占用情況。
圖12:資源占用表
6.可在main函數內添加RT-Thread支持的任務、定時器、信號量等功能。Nano默認rtconfig.h配置只支持靜態任務、信號量創建。在靜態模式下,不能使用rt_thread_create/rt_thread_delete/rt_sem_create/rt_sem_delete/rt_malloc/rt_free與動態創建、刪除有關的接口。如需動態創建,需開啟RT_USING_HEAP項,詳見本篇第五部分:《RT-Thread配置》
四、RT-Thrad啟動流程分析
這次創建的keil工程雖然應用了RT-Thread嵌入式操作系統,但開發流程無不帶os開發幾乎沒有差別。都是將main作為入口,完成硬件初始化、應用代碼添加,而且可以直接應用RT-Thread的各種功能完成產品開發。但是我們沒有添加RT-Thread相關初始化、啟動等代碼到我們的工程里面,但實際情況是調度器已經正常運行了,這是怎么實現的呢?
01
RT-Thread入口
我們可以在components.c文件的140行看到#ifdef RT_USING_USER_MAIN宏定義判斷,這個宏是定義在rtconfig.h文件內的,而且處于開啟狀態。同時我們可以在146行看到#if defined (__CC_ARM)的宏定義判斷,__CC_ARM就是指keil的交叉編譯器名稱。
我們可以在這里看到定義了2個函數:$$Sub$$main()和$$Super$$main()函數;這里通過$$Sub$$main()函數在程序就如主程序之前插入一個例程,實現在不改變源代碼的情況下擴展函數功能。鏈接器通過調用$$Sub$$Main()函數取代main(),然后通過$$Super$$main再次回到main()
#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;
}
在$$Sub$$main函數內調用了rt_hw_interrutp_disable()和rtthread_startup()兩個函數。熟悉RT-Thread開發流程的,一看就知道這是標準的RT-Thread的啟動入口。
其中:
-
rt_hw_interrupt_disable():關中斷操作,
-
rtthread_startup():完成systick配置、timer初始化/啟動、idle任務創建、應用線程初始化、調度器啟動等工作。
int rtthread_startup(void)
{
rt_hw_interrupt_disable();
/* board level initalization
* NOTE: please initialize heap insideboard initialization.
*/
rt_hw_board_init();
/* show RT-Thread version */
rt_show_version();
/* timer system initialization */
rt_system_timer_init();
/* scheduler system initialization */
rt_system_scheduler_init();
/* create init_thread */
rt_application_init();
/* timer thread initialization */
rt_system_timer_thread_init();
/* idle thread initialization */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return 0;
}
-
rt_hw_board_init():該函數定義在board.c文件內,需要修改systick配置
-
rt_system_timer_init()/rt_system_timer_thread_init():timer初始化/啟動
-
rt_thread_idle_init():idle任務創建
-
rt_application_init():應用線程初始化
-
rt_system_scheduler_start():調度器啟動
02
應用線程入口
rt_application_init()
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_THREAD_PRIORITY_MAX / 3, 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_THREAD_PRIORITY_MAX / 3, 20);
RT_ASSERT(result == RT_EOK);
#endif
rt_thread_startup(tid);
}
在這里,我們可以看到應用線程創建了一個名為main_thread_entry的任務,并且已經啟動了該任務。我們再次來看一下man_thread_entry任務。
/* the system main thread */
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
}
man_thread_entry任務完成了2個工作:調用rt_components_init()、進入應用代碼真正的main函數。
在這里我們看到了$$Super$$main()的調用,在前面我們講了調用該函數可用來回到main()的。
圖13:RT-Thread初始化及啟動流程
從以上分析可以,正是由于在rtconfig.h內開啟了RT_USING_USER_MAIN選項,編譯器在main之前插入了$$Sub$$main(),完成了RT-Thread初始化及調度器啟動工作。并且通過創建main_thread_entry任務,并通過$$Super$$main()回到main()函數。這樣看來main()函數其實只是RT-Thread的一個任務,該任務的優先級為 RT_THREAD_PRIORITY_MAX / 3,任務棧為RT_MAIN_THREAD_STACK_SIZE。
圖14:RT_USING_USER_MAIN選項
五、RT-Thread配置(rtconfig.h)
RT-Thread是一個高度可配置的嵌入式實時操作系統,配置通過rtconfig.h文件實現。Nano就是在rtconfig.h配置下實現了2.5KFlash,1KRam的內核應用,但是由于Nano未開啟RT_USING_HEAP選項,故只支持靜態方式創建任務及信號量。下面分步開啟rtconfig.h配置常用選項。
01
RT_USING_HEAP:開啟heap
根據芯片型號在board.c第37行,修改SARM_SIZE大小,默認為8,GD32F150C8T6正好也為8K。
圖15:SRAM_SIZE配置
開啟RT_USING_HEAP選項后,在board.c的rt_hw_board_init()內將調用rt_system_heap_init()
#if defined(RT_USING_USER_MAIN)&& defined(RT_USING_HEAP)
rt_system_heap_init((void*)HEAP_BEGIN,(void*)SRAM_END);
#endif
其中:
SRAM_END:根據宏定義為0x20000000 +SRAM_SIZE * 1024
HEAP_BEGIN:
圖16:HEAP_BEGIN定義
其中Image$$RW_IRAM1$$ZI$$Limit是鏈接器導出符號,表示ZI段的結束地址。
配置完成后,就可通過動態創建任務、信號量等方式開發軟件了。
02
RT_USING_TIMER_SOFT:開啟軟件定時器
Nano默認配置未開啟軟件定時器功能。開啟軟件定時器功能后,可創建多個軟件定時器,定時器精度為Systick觸發精度。
圖17:軟件定時器開啟
- End -
-
rt_thread
+關注
關注
2文章
13瀏覽量
14669
原文標題:手把手教你實戰RT-Thread Nano,不信都這樣了你還不會
文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
RT-Thread最新推出Nano極簡版
i.MX RT1170:VGLite移植RT-Thread Nano過程講解(下)
基于 Keil MDK 移植 RT-Thread Nano
怎么在 RT-Thread Studio 上使用 RT-Thread Nano
RT-Thread Nano 簡介
在 RT-Thread Studio 上使用 RT-Thread Nano
pack的安裝和rt-thread的使用
基于 Keil MDK 移植 RT-Thread Nano
![基于 Keil MDK 移植 <b class='flag-5'>RT-Thread</b> <b class='flag-5'>Nano</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論