一個優秀的RTOS(Real-Time Operating system)不但要擁有一個高可靠、多任務的實時內核,還應具有可剪裁和可移植的能力。RTEMS(the Real - Time Executivefor Multiprocessor Systems)就是這樣的系統,它提供的環境可以滿足高性能的嵌入式多任務實時應用。目前,RTEMS支持的CPU系列有:A29k、ARM、H8300、1386、1960、M68k、MIPS、PPC和SPARC等。
板級支持包BSP(Board Support Package)是嵌入式實時系統的基礎部分,也是實現系統可移植性的關鍵。它負責上電時的硬件初始化、啟動嵌入式操作系統或應用程序模塊、提供底層硬件驅動,為上層軟件提供訪問底層硬件的手段。BSP針對目標板設計,其結構和功能隨目標板的不同而呈現較大的差異。在將嵌入式系統移植到一種新的CPU時,必須提供相應的板級支持包。
本文參考SPARC微處理器ERC32的BSP,主要討論RTEMS的BSP開發過程。
1 RTEMS體系結構
RTEMS采用微內核基礎上的層次化結構,如圖l所示。這種結構只把那些絕對必需的系統功能置于內核之中(如中斷管理、上下文切換、內存訪問管理、時間管理、線程及線程間的通信與同步管理等),而把那些并非必需的系統功能(如文件系統、網絡、遠程過程調用等)置于微內核之上在用戶模式下運行。
RTEMS的板級支持包是啟動代碼、連接器腳本和編譯規范文件(specs)和設備驅動程序的集合,它們針對不同目標機的硬件環境剪裁RTEMS。
2 RTEMS啟動過程
處理器加電或復位時,基于RTEMS的應用程序初始化或者重新初始化。BSP中的啟動代碼負責為RTEMS應用程序建立運行環境。
RTEMS啟動過程的順序如下:
① 執行BSP中的啟動代碼;
② 調用rtems_initialize_executive;
③ 局部和全局應用程序的初始化。
處理器復位時,首先執行BSP的啟動代碼。BSP必須將所有的硬件初始化為一個靜止狀態,然后操作系統才能初始化。rtems_initialize_executive指令不返回啟動代碼,它將導致最高優先級的初始化任務開始執行。初始化任務用于完成局部或全局依賴于RTEMS的應用程序初始化。
3 BSP開發過程
下面以SPARC微處理器ERC32為例,說明RTEMSBSP的開發步驟:
①建立開發環境。開發模式采用宿主機/目標機模式。宿主機運行環境采用Linux系統,目標機為ERC32。宿主機和目標機通過串口連接。交叉開發工具采用添加了RTEMS補丁的GNU工具鏈(GCC,GDB,Newlib,binary utilities)。
② 選擇BSP模板。通常是根據操作系統提供的BSP模板,選擇與應用硬件環境最為相似的參考設計,針對具體的目標機對參考BSP進行必要的修改和增刪,以形成自己的BSP。選擇一個適當的BSP模板可以達到事半功倍的效果。
③建立新bsp目錄。將模板BSP整個目錄拷貝到適當的目錄下(如libbsp/),重命名為mybsp。
④ 建立bsp配置文件。拷貝任意一個BSP.cfg,重命名為mybsp.cfg,修改相關的體系結構定義,如:RTEMS_CPU_MODEL,RTEMS_BSP,CPU_CFLAGS和制定make_exe規則。
⑤修改makefile文件。對mybsp-bsp中每一個Makefile.in文件,運行acpolish,并檢查運行的結果,例如:
cd /mybsp - bsp/some_subdir
/path_to_SACOS/t00ls/update/acpolishMakefile.new
再次運行acpolish:
/path_to_SACOS/tools/update/acpolishMakefile.in
將Makefile.new和Makefile.in進行比較。如果不相同,則重新編輯Makefile.new,多次運行acpolish,直到連續兩次產生的Makefile.in相同。
⑥ 修改啟動代碼。建立自陷表、基本的CPU初始化、設置中斷堆棧等。
⑦ 配置RTEMS。設置RTEMS相關全局變量和常量、RTEMS配置表、CPU依賴信息表、系統初始化任務表,以及用戶初始化任務表等,除完成相關的系統功能之外,提供板上外設的設備驅動程序。
⑧調試和測試。建立RTEMS執行映像,利用串口下載可執行映像到目標機,測試BSP的正確性。
3.1 啟動代碼實現
BSP的啟動代碼主要包含在五個文件中。它們是Start.s、boardinit.S、bootcard.c、bspstart.C和main.C。
Start.s包含了用于硬件初始化的匯編語言代碼,它是RTEMS的引導ROM入口。入口點SYM(start)是目標機上電后執行的第一段程序。SYM(start)的工作是完成將控制轉移到C程序boot_card()所需要的最少的設置,如初始化堆棧和禁止外部中斷等。它的具體操作包括:
①定義自陷表。這個自陷表是SPARC V7體系共有的,可從參考BSP中復制。
②初始化處理器。
a)初始化自陷基地址寄存器TBR,即將自陷表地址寫入TBR;
b)初始化處理器狀態寄存器PSR,設置系統為最高優先級運行模式,禁止所有可屏蔽中斷;
c)設置窗口無效寄存器WIM;
d)初始化堆棧,設置堆棧指針。
③調用SYM(_bsp_board_init)(在boardinit.S中定義,這些代碼是目標板專用的),初始化MEC系統寄存器,初始化定時器。
④將已初始化數據從ROM拷貝到RAM,未初始化內存清零。
⑤初始化環境變量和參數,調用C程序boot_card()。
boot_card()完成RTEMS的基本配置,如設置RTEMS配置表、CPU依賴信息表的相關入口等。它調用bsp_start()完成目標板特定的系統配置,調用內核初始化函數完成RTEMS系統的初始化。boot_card()的具體操作包括:
①定義和聲明RTEMS全局變量。
extern rtems_configuration_table Configuration;
extern rtems_.configuration_.table BSP_Configuration;
extern rtems_cpu_table Cpu_table;
rtems_api_configuration_table BSP_RTEMS_Configura-tion;
rtems_interrupt_level bsp_isr_level;
②初始化CPU依賴信息表的所有人口為缺省值,除了下列兩項,其余都為NULL。
Cpu_table.do_zero_of_workspace =TRUE;
Cpu_table.interrupt_stack_size =RTEMS_MINIMUM_STACK_SIZE;
③ 調用bsp_start(),根據目標機環境重新配置RTEMS,為系統初始化任務建立標準C支持環境。
④ 調用內核初始化函數rtems_initialize_executive_ early(),初始化RTEMS和設備驅動程序。
⑤調用c_rtems_main(),創建并啟動多任務,運行用戶應用程序,直到調用rtems_shutdown_executive()退出RTEMS,才將控制返回BSP。
bsp_start()根據目標機環境重新配置RTEMS,為調用操作系統初始化函數準備一個合適的軟硬件環境。它的具體操作是:
①定義RTEMS全局變量。
unsigned char*work_space_start;
rtems_configuration_table BSP_Configuration;
rtems_cpu_table Cpu_table;
②修改CPU依賴信息表,為RTEMS系統初始化任務建立支持環境。
/*在執行系統初始化任務之前,設置存堆的開始地址和大小,建立C支持庫*/
Cpu_table.pretasking_hook=bsp_pretasking_hook;
/*在驅動程序初始化之后注冊設備名,打開標準輸人、標準輸出和標準錯誤文件*/
Cpu_table.postdriver_hook=bsp_postdriver_hook;
Cpu_table.do_zero_of_workspace=TRUE;
/*設置中斷堆棧的大小(16*1024)*/
Cpu_table.interrupt_stack_size=ONFIGURE_INTER-RUPT_STACK_MEMORY;
③檢查并設置工作區起始地址。
BSP_Configuration.work_space_start=work_space_start;
④設置時鐘嘀嗒頻率。
CPU_SPARC_CLICKS_PER_TICK=BSP_Configuration.microseconds_per_tick;
⑤結束返回boot_card()。
圖2描述了RTEMS系統初始化函數之間的調用關系。
3.2設備驅動程序實現
設備驅動程序的工作方式有輪詢和中斷兩種。無論采用哪一種方式,設備驅動程序的基本流程都是相同的。下面以時鐘設備驅動程序為例,簡單說明編寫RTEMS設備驅動程序的基本框架。
①聲明和定義常量和全局變量。
/*關于時鐘設備的常量參數*/
volatile rtems_unsigned32 Clock_driver_ticks;
extern int CLOCK_SPEED;
extern rtems_unsigned32 CPU_SPARC_CLICKS_PER_TICK;
/*定義時鐘驅動程序入口數據結構并初始化*/
#define CLOCK_DRIVER_TABLE_ENTRY{Clock_initialize,NULL,NULL,NULL,NULL,Clock_contr01}
②獲取接口參數。
rtems_device_major_number\
rtems_clock_major=~O;
rtems_device_minor_number \
rtems_clock_minor
③提供接口函數。
/*時鐘驅動程序初始化入口*/
rtems_device_driver Clock_initialize() {
/*安裝時鐘中斷向量,設置時鐘計數器和標度器的預設值;保存時鐘設備接口參數,以備系統使用*/ };
/*時鐘滴答中斷處理程序*/
rtems_isr Clock_isr() {
/*時鐘設備的計數器和標度器設值為周期運行模式*/ };
/*時鐘設備控制入口*/
nems—deviceLdriver Clock_control()
{
//設置時鐘滴答中斷處理方式
};
/*關閉時鐘設備*/
void Clock_exit()
{
//屏蔽時鐘滴答,停止時鐘計數
};
④啟動時鐘設備。
3.3 修改鏈接器命令腳本
鏈接器命令腳本為鏈接器提供鏈接的規則,對鏈接過程進行顯式地控制.修改鏈接器腳本,配置系統可用內存區域和定義可執行映像各個程序段在內存中的位置,如加載程序時代碼段(.text)從RAM地址。開始放置.
/*缺省值,可以修改*/
_PR()M_SIZE=2M;
_RAM_SIZE=4M;
_RAM_START_0x02000000;
_PROM-START=0x00000000;
/*最終可執行程序段的內存位置*/
SECTI()NS
{ .txt :
{ text_start=。;
*(.text)
.=ALIGN(16);
}》RAM
4 建立RTEMS可執行映像
BSP開發完成之后,與RTEMS的其他代碼,如CPU依賴層、超核、API以及標準應用程序模塊等,經由交叉編譯工具編譯連接之后,生成可以加載到目標機的RTEMS執行映像,如圖3所示。
結 語
BSP的開發對于嵌入式系統的移植具有重要意義.本文以SPARC體系微處理器ERC32為例,討論了RTEMS BSP的功能及其開發過程.實踐證明,在BSP的開發過程中,①選擇一個適當的BSP模板,②深刻理解模板BSP中的相關概念。這兩點相當重要。因為,選擇一個相近的BSP模板可大大減少工作量和復雜度.縮短移植周期;而深刻理解相關概念有助于根據具體目標硬件環境對模板BSP進行正確修改,達到預期目的。
責任編輯:gt
-
嵌入式
+關注
關注
5087文章
19145瀏覽量
306144 -
cpu
+關注
關注
68文章
10880瀏覽量
212204 -
微處理器
+關注
關注
11文章
2271瀏覽量
82555
發布評論請先 登錄
相關推薦
評論