龍芯ls2k1000開發(fā)板移植rt-thread筆記
掃描二維碼
隨時隨地手機(jī)看文章
ls2k1000開發(fā)板移植rt-thread筆記
-
1.前言
-
2.龍芯派基本介紹
-
3.rt-thread在龍芯派上的運(yùn)行過程
-
4.rtt的啟動分析
-
4.1 啟動代碼引導(dǎo)
-
4.2 rt-thread的啟動流程
-
5.關(guān)鍵部分驅(qū)動的初始化
-
6.Stack Frame
-
7.總結(jié)
1.前言
龍芯2k1000開發(fā)板擁有非常豐富的外設(shè)資源,板子設(shè)計也非常的精致。
所以打算運(yùn)行一下rt-thread,然后進(jìn)行相關(guān)的開發(fā)操作。
本文主要針對龍芯2k1000的龍芯派的開發(fā)板進(jìn)行rt-thread移植,通過這篇文章,基本上掌握rt-thread對于一個新的體系架構(gòu)上的移植過程,同時也可以很好的掌握mips64體系架構(gòu)上的相關(guān)知識,同時熟悉使用龍芯派2k1000。
由于裸機(jī)開發(fā)與rtos開發(fā)有著一定的聯(lián)系,所以如果要想理解rt-thread更加底層的東西,一定需要理解芯片的設(shè)計以及各種體系架構(gòu)的設(shè)計。
2.龍芯派基本介紹
龍芯派就是面對普通開發(fā)群體的一個開發(fā)板,龍芯派搭載 2K1000 處理器(主頻 1GHz),板載 DDR3 顆粒,實現(xiàn) DDR3 的運(yùn)行存儲功能。實現(xiàn)了 GPIO 的輸入輸出,中斷功能。板上集成 1 個網(wǎng) 口,集成 3 個 USB 接口,HDMI 接口,LCD 接口,音頻輸入/輸出,集成 SD 卡接口,集成 2 個 CAN 接口,集成 RTC 計時功能??梢酝鈹U(kuò) WIFI 模塊。2K 龍芯派可以廣泛應(yīng)用于信息安 全、電力、軌道交通、工業(yè)控制、信號處理、數(shù)據(jù)通信、信息教育等領(lǐng)域。
由于其強(qiáng)大的性能以及多接口,也讓更多方案實現(xiàn)變的可能。
龍芯派擁有8Mb的SPI Flash,龍芯的BIOS就是存放在這個SPI Flash中,龍芯叫pmon。可以理解為uboot,由于龍芯的pmon的使用,我們?yōu)榱蓑炞C和體驗效果,并且方便開發(fā)測試,我們可以利用pmon的tftp的下載功能,將固件拷貝到內(nèi)存中,然后直接執(zhí)行即可。這種方式有利于程序的調(diào)試和開發(fā)。
當(dāng)實際應(yīng)用到生產(chǎn)環(huán)境中時,可以將rt-thread固化到spi flash中,這樣就可以很好的加快啟動速度了?,F(xiàn)在我們只講開發(fā)階段的啟動過程。
3.rt-thread在龍芯派上的運(yùn)行過程
龍芯派是通過網(wǎng)絡(luò)下載方式將固件進(jìn)行燒錄的,所以首先啟動了pmon,然后將rt-thread固件轉(zhuǎn)移到ddr中。
上電之后,龍芯的pmon開始啟動,當(dāng)串口打印過程中,我們可以通過輸入鍵盤上的c字符進(jìn)入pmon的控制臺中,這樣就可以利用pmon的tftp將固件加載到ddr中,然后跳轉(zhuǎn)到ddr中去執(zhí)行。
ifaddr syn0 192.168.12.100 load tftp://192.168.12.35/rtthread.elf; g
其中ifaddr為設(shè)置開發(fā)板的ip地址,syn0表示第一個網(wǎng)卡,load加載程序到內(nèi)存,g開始執(zhí)行。
接著,rt-thread啟動初始化流程,初始化串口,初始化中斷,然后開啟中斷,線程開始調(diào)度,rt-thread開始進(jìn)行任務(wù)調(diào)度。
這就是一個龍芯派執(zhí)行的完整流程。
4.rtt的啟動分析
對于龍芯派的移植,或者說對于一個新的體系架構(gòu)移植rt-thread,基本過程分為如下幾個部分:
1.裸機(jī)代碼引導(dǎo),初始化??臻g與bss段,為運(yùn)行c代碼提供環(huán)境
2.關(guān)閉中斷,直到所有的流程初始化完成,第一個最高優(yōu)先級的線程出棧時,打開中斷
3.初始化uart
4.初始化os tick中斷
5.控制臺輸出logo
6.初始化ipc,以及組件,初始化timer()以及idle線程
4.1 啟動代碼引導(dǎo)
這部分的主要功能就是為啟動C代碼做準(zhǔn)備。
這部分的代碼一般是由匯編寫的,準(zhǔn)備好sp的棧指針,然后清空bss段然后直接跳轉(zhuǎn)到了rtthread_startup函數(shù)中。
然后就進(jìn)入rt-thread入口函數(shù)。
4.2 rt-thread的啟動流程
簡述一下rt-thread的啟動流程如下:
1.關(guān)閉全局中斷
2.板級驅(qū)動初始化(關(guān)鍵初始化,timer、uart等,移植大部分工作)
3.初始化選中的rtt組件
4.打印logo
5.調(diào)度器初始化
6.初始化main、idle等線程
7.啟動調(diào)度(出棧時開啟全局中斷)
8.線程開始調(diào)度
5.關(guān)鍵部分驅(qū)動的初始化
對于龍芯2k1000來說,我們需要關(guān)注的是rt_hw_board_init里面關(guān)鍵外設(shè)的初始化。這里主要涉及到兩個,一個是uart驅(qū)動初始化,另外一個就是timer初始化。
對于tick,我們采用mips中的c0寄存器進(jìn)行比較。
HPET 控制器
通過配置,每個定時器都能獨(dú)立產(chǎn)生中斷。
這組定時器由一個向上累加的主計時器(up-counter)以及一組比較器構(gòu)成。這個計時器以固定的頻率(125MHz)向上累加,因此當(dāng)軟件兩次讀取計時器的值時,除非遇到計時器溢出,否則第二次讀取的值總是比第一次讀取的值大。而每個定時器都包含一個 match 寄存器以及一個比較器。當(dāng) match 寄存器的值與主計時器相等時,那么定時器產(chǎn)生中斷。部分定時器可產(chǎn)生周期性中斷。HPET 模塊包括一個主計數(shù)器(main count)以及三個比較器(comparator),且他們的寬度都是 32 位。在這三個比較器中,有且僅有一個比較器支持周期性中斷(periodic-capable),這三個比較器都支持非周期性中斷。
而在我們的rtt中正常情況下是使用非周期性中斷。相關(guān)的寄存器不展開描述,使用的過程中配置好即可。
uart控制器
作為rtt的控制臺,串口這部分也是必不可少的,在使用ls2k1000的時候,需要充分考慮到uart資源使用情況。
2K1000 集成了 12 個 UART 控制器,通過 APB 總線與總線橋通信。雖然說有這么多串口控制器,但是實際上很多都是復(fù)用的串口控制器,所以實際上只能最大同時使用的是4路uart接口。
其uart控制器有如下幾個部分:
1.發(fā)送和接收控制器負(fù)責(zé)將fifo中的數(shù)據(jù)進(jìn)行分發(fā)或者接收
2.moden寄存器控制著串口的輸出信號 DTR 和 RTS 的狀以及相關(guān)的校驗狀態(tài)。
3.中斷仲裁模塊:當(dāng)任何一種中斷條件被滿足,并且在中斷使能寄存器(IER)中相應(yīng)位置 1,那么 UART 的中斷請求信號 UAT_INT 被置為有效狀態(tài)。
4.訪問寄存器模塊:當(dāng) UART 模塊被選中時,CPU 可通過讀或?qū)懖僮髟L問被地址線選中的寄存器。
其中中斷這一塊必須十分的小心,因為串口的使用,涉及到fifo的時候,需要知道空閑狀態(tài)以及相關(guān)的半滿或者全滿或者32字節(jié)產(chǎn)生中斷等屬性。否則讀取數(shù)據(jù)出來將異常復(fù)雜。
6.Stack Frame
棧幀這部分與編譯器相關(guān),也與體系架構(gòu)相關(guān),所以在使用的時候,需要知道棧的活動軌跡。函數(shù)的壓棧與出棧,操作系統(tǒng)的調(diào)用,都和這部分相關(guān)。
rt-thread的壓棧操作在libcpu的特定的體系架構(gòu)的stack.c文件中。
每個線程在初始化的時候,都會進(jìn)行壓棧操作。出棧的操作在context_gcc.S文件中。
壓棧除了壓入通用寄存器外,還會涉及到狀態(tài)寄存器,比如spsr或者cpsr等等,如果有FPU,也需考慮進(jìn)去。
需要注意的是,壓棧的順序與出棧的順序必須是一一對應(yīng)的。這部分的調(diào)試功能比較繁瑣,需要一步一步的進(jìn)行跟蹤。
7.總結(jié)
移植rt-thread到ls2k1000的開發(fā)板的過程主要如上述所示。如果有新的體系架構(gòu)要移植到rt-thread上,需要充分的考慮移植的過程與移植的流程。