點 擊深 藍 字 體 關 注 我 們~~~
——/// 概述 \\\——
☟☟☟
本章描述如何將RTT的源碼移植到Cortex-Mx系列平臺,移植時間大約為1個小時。RT-Thread的源碼可以從官網下載,具體方法為進入rt-thread的官網
http://www.rt-thread.org/,找到「入門」選項,單擊「下載」按鈕,進入下載頁。
1.1 Keil構建編譯系統MDK編譯環境需要安裝RealView MDK3.5+,因為會用到它的編譯連結器和調試器,可以從Keil官網下載,目前使用的keil版本是4.72,如圖1-1所示圖1-1 keil 編譯系統版本
1.2環境設置
建立好工程後需要target進行設置
1.2.1打開Project,從中選擇Options for Target,如圖1-2所示
圖1-2 Options for Target 『Target 1』
1.2.2點擊Device選擇Cortex-M3
1.2.3 點擊Target選項,當使用內置20KROM,128KRAM時,設置如圖1-3所示;當使用內置128KROM,設置如圖1-4所示。當使用Finsh Shell時候,編譯的代碼會超過20K,晶片的固有ROM1不夠,因此要改到ROM2.
圖1-3 Target Option
圖1-4 Target for external flash
1.2.4 output選項如圖1-5所示
圖1-5 Output option
1.2.5 listing選項保持默認即可
1.2.6 User選項需要生成bin文件,然後燒到外部Flash裡面,設置如圖1-6所示
圖1-6 User Option
1.2.7 C/C++ 選項需要設置需要包含的頭文件,如圖1-7所示,並且把Optimization設置到Level 0,如果設置默認,則使用Level2優化,標上One ELF Section per Function,這個可以使編譯的代碼足夠小,並且不影響程序執行。
圖1-7 Folder Setup Option
1.2.8 Linker選項中Misc controls 需要添加「--keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab)」,不然編譯的時候會把有些文件優化掉
1.2.9 Debug選項選擇Ulink即可,如圖1-8所示,ULink的Setting選項如圖1-9所示
至此所有的設置選項已經設置好,後面開始代碼的設計和編譯
圖1-8 Debug Option
圖1-9 Debug for Setting Option
1.3 開始編譯之旅
首先創建1個Group,分別是Applications,Drivers,kernel,library,cortex-M3,DeviceDriver,
1.3.1 添加application.c和startup.c到Applications文件夾,這兩個文件的來源可以選擇其他BSP M3文件夾的文件,其中main函數在startup.c中,在startup.c中需要注意堆的處理,因為使用的是__CC__ARM,
Image$$RW_IRAM1$$ZI$$Limit表示SRAM中除去從ROM搬來的數據和生成的變量後剩下的 空間,CM_SRAM_END=(SRAM_BASE + 128 * 1024),如果使用外部的Flash則,CM_SRAM_END=( ITCM_BASE+ 128 * 1024),因為程序是在整個ROM2中執行的,這個要指向ROM2的末尾地址。
圖1-10 rtthread_startup function
1.3.2 從startup.c中的rt_application_init跳轉到application.c中執行,rt_application_init中執行的是創建一個叫做init_thread的線程,並啟動它,啟動後根據線程的優先級進入rt_init_thread_entry中執行,因為只有這一個線程創建了,所以直接會跳進來執行。如圖1-11所示,如果定義相關的宏定義,就會到相應的函數中執行。
圖1-11 rt_init_thread_entry function
1.4 串口移植
其實晶片的移植不如說是串口的移植,串口初始化在main->rtthread_startup->rt_hw_board_init->rt_hw_usart_init裡面,rt_hw_board_init函數如圖1-12所示,主要實現的功能是重新配置向量表,systick初始化,串口初始化,把串口設備註冊到系統中。值得注意的是NVIC_Configuration函數中的NVIC_VectTab_RAM的指向要正確,如果使用內部ROM1,NVIC_VectTab_RAM=0x0;如果使用ROM2,NVIC_VectTab_RAM= (uint32_t)0x00010000,意思就是你的程序放到哪裡,這個中斷向量表就指向哪裡。
圖1-12 rt_hw_board_init function
SysTick_Config是配置RTT系統的滴答時間的,以這個時間為基準進行進程調度,用法是當系統創建進程或者初始化進程的時候給予,這個滴答時間是線程運行的時間,具體函數實現參見圖1-13
圖 1-13 systick_handler function
rt_hw_usart_init函數主要實現的功能是開啟10號中斷,向設備中註冊uart1,並且註冊方式是以讀寫的方式,中斷接收方式,數據流的方式註冊。另外RTT的設備管理,可以簡單的概括為:每一個設備都會用於一個rt_device數據結構,這些數據結構通過某種方式組織起來,每個數據結構都會有一個唯一的device_id,以及一組硬體操作函數等等。這樣硬體就被抽象成統一的邏輯設備了,即rt_device。還有一個小問題,device_id是純粹的數字,所以難以記憶,因此RTT中為其分配一個ascii碼字符串來以方便是使用,比如將字符串」uart1」和usart的rt_device數據結構關聯起來,這和網絡裡,ip地址不好記憶,因此使用域名系統是一個道理。rt_hw_usart_init函數如圖1-14所示:
圖 1-14 rt_hw_usart_init function
CM_configure是串口的配置函數,初始化串口的基本參數,如圖1-15所示
圖1-15 CM_configure function
CM_control實現的是對串口中斷的控制,通過不同的命令實現對中斷的打開和關閉。如圖1-16所示
圖1-16 CM_control function
n10_URT0_IRQHandler串口中斷入口函數作用是把M3的串口中斷函數和RTT的設備驅動聯繫起來(相關變量可以參考技術手冊),函數原型參見圖1-17
圖1-17 n10_urt0_irqhandler function
CM_getc主要是處理串口接收到的數據,當串口數據寄存器裡面有數據的時候,bsUART_RECEIVE_EMPTY不會置位,當把數據讀完的時候bsUART_RECEIVE_EMPTY會置位。函數原型參見圖1-18
圖1-18 CM_getc function
1.5 打開finish調試
1.5.1首先要確定使用哪個串口進行調試,在串口初始化後有個console的設置,該設置就是在確定使用哪個串口顯示命令行,列印信息。在rtconfig.h裡面設置使用串口1,具體設置為#define RT_CONSOLE_DEVICE_NAME "uart1",如圖所示:
至此,平臺移植結束。
如果想加入RT-Thread Nano交流群,與RT-Thread官方團隊直接交流,請添加微信13924608367,註明rt-thread,直接拉進群。
歡迎大家積極投稿,會有驚喜等著你哦
▼ 徵稿 | 你寫不寫,福利就在這裡~~