輕型PPP協(xié)議在μC/OS-II操作系統(tǒng)中的實(shí)現(xiàn)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
摘要:針對(duì)實(shí)時(shí)操作系統(tǒng) μC/OS-II沒(méi)有自己的網(wǎng)絡(luò)協(xié)議棧,提出了基于 ARM7TDMI處理器的 μC/OS-II操作系統(tǒng)上輕型 PPP協(xié)議的設(shè)計(jì)與實(shí)現(xiàn),對(duì) μC/OS-II與處理器相關(guān)的代碼部分進(jìn)行了修改與編譯,實(shí)現(xiàn)了 μC/OS-II在 ARM開發(fā)板上移植,為 PPP協(xié)議的設(shè)計(jì)與實(shí)現(xiàn)提供了系統(tǒng)軟件開發(fā)平臺(tái)。通過(guò)編寫了 PPP協(xié)議main主模塊、LCP模塊、PAP模塊、NCP模塊和PPP等模塊代碼,在μC/OS-II操作系統(tǒng)中實(shí)現(xiàn)了輕型 PPP協(xié)議。通過(guò)測(cè)試,驗(yàn)證了 ARM開發(fā)板的 PPP協(xié)議的網(wǎng)絡(luò)通信功能。
1 引言
隨著嵌入式技術(shù)的發(fā)展,讓嵌入式設(shè)備接入 Internet,實(shí)現(xiàn)網(wǎng)絡(luò)資源共享,是未來(lái)發(fā)展的必然趨勢(shì),μC/OS-II操作系統(tǒng)中沒(méi)有完備的網(wǎng)絡(luò)協(xié)議棧[1,2],要實(shí)現(xiàn)嵌入式設(shè)備網(wǎng)絡(luò)通信,必須要有自己的網(wǎng)絡(luò)協(xié)議。鑒于目前 PPP協(xié)議使用的普遍性和廣泛性[3,4],本文提出了基于 ARM7TDMI處理器的 μC/OS-II操作系統(tǒng)上 PPP協(xié)議的設(shè)計(jì)與實(shí)現(xiàn)。通過(guò) PPP協(xié)議在 μC/OS-II上的實(shí)現(xiàn)[5,6],能讓嵌入式設(shè)備接入 Internet,進(jìn)行信息互訪,為未來(lái)的“普適計(jì)算”的發(fā)展提供了一個(gè)有利條件。
2 μC/OS-II移植實(shí)現(xiàn)
2.1編寫 ARM7TDMI的啟動(dòng)程序
啟動(dòng)代碼是芯片復(fù)位后進(jìn)入 C語(yǔ)言的 main()函數(shù)前執(zhí)行的一段代碼,啟動(dòng)代碼主要有 4個(gè)文件: Vectors.s、Init.s、Target.c和 Target.h。Vectors.s主要包括了異常向量表、堆棧初始化 InitStack和中斷服務(wù)程序與 C程序的接口。而 Init.s主要是指系統(tǒng)初始化代碼,執(zhí)行的順序是初始化堆棧,目標(biāo)設(shè)備初始化和執(zhí)行 Main模塊。對(duì)于 Target.c和 Target.h來(lái)說(shuō),主要包含了異常處理程序和目標(biāo)板初始化程序。
2.2 μC/OS-II的移植
OS_CPU.H中函數(shù)軟中斷 SWI機(jī)制[7],為了使底層接口函數(shù)與處理器狀態(tài)無(wú)關(guān),同時(shí)在對(duì)底層函數(shù)調(diào)用不需要知道函數(shù)的位置,因此在 uC/OS移植中,使用軟中斷指令 SWI[1]作為底層接口,通過(guò)不同的功能號(hào)來(lái)區(qū)分不同的函數(shù),其軟功能分配號(hào)如表 1所示。
用軟中斷作為操作系統(tǒng)的底層接口就需要在 C語(yǔ)言中使用 SWI指令。在 ADS中,有一個(gè)關(guān)鍵字_swi,用它聲明一個(gè)不存在的函數(shù),若在用戶任務(wù)中調(diào)用這個(gè)函數(shù)就在調(diào)用這個(gè)函數(shù)的任務(wù)代碼中地方插入一條 SWI指令,并且指定了功能號(hào)。
OS_CPU.H中關(guān)中斷 OS_ENTER_CRITICAL()和開中斷 OS_EXIT_CRITICAL()都是用來(lái)保護(hù)臨界資源代碼[8]。移植使用軟中斷指令 SWI使處理器進(jìn)入管理模式和 ARM指令狀態(tài),并通過(guò)調(diào)用功能號(hào) 0x02和 Ox03來(lái)關(guān)中斷和開中斷。但在 C語(yǔ)言中,仍然使用 OS_ENTER_CRITICAL()關(guān)中斷,而使用 OS_EXIT_CRITICAL()開中斷。
OS_CPU.H中通過(guò)使用結(jié)構(gòu)常量 OS_STK_GROWTH中值來(lái)指定堆棧的生長(zhǎng)方式:當(dāng) OS_STK_GROWTH置為 1時(shí),表示在堆棧存儲(chǔ)時(shí),是從上到下的方式存儲(chǔ)。當(dāng) OS_STK_GROWTH置為 0時(shí),表示在堆棧存儲(chǔ)時(shí),是從下向上的方式存儲(chǔ)。
OS_CPU_A.S中OS_TASK_SW()是在μC/OS-II中從低優(yōu)先級(jí)任務(wù)切換到最高優(yōu)先級(jí)任務(wù)時(shí)被調(diào)用的。在 ARM移植使用軟中斷指令 SWI使處理器進(jìn)入管理模式和 ARM指令狀態(tài),并調(diào)用功能號(hào) 0實(shí)現(xiàn) OS_TASK_SW()的功能。但在 C語(yǔ)言中,仍然使用 OS_TASK_SW()函數(shù)進(jìn)行任務(wù)切換功能。
OS_CPU_A.S中 OSStartHighRdy():在多任務(wù)環(huán)境下, OSStart()最終調(diào)用 OSStartHighRdy()函數(shù)運(yùn)行多任務(wù)啟動(dòng)優(yōu)先級(jí)最高的任務(wù)。移植中使用軟中斷指令 SWI使處理器進(jìn)入管理模式和 ARM指令狀態(tài),并使用功能號(hào) 1實(shí)現(xiàn) OSStartHighRdy()功能。在調(diào)用 OSStartHighRdy()函數(shù)之前, OSTCBHighRdy指向的是優(yōu)先級(jí)最高的任務(wù)的任務(wù)控制塊。
OS_CPU_C.C中斷服務(wù)子程序的算法如下: void XxxISR(void) {OS_ENTER_CRITICAL()或直接給變量 OSIntSum賦 1;
清除中斷源(與具體的外設(shè)有關(guān));通知中斷控制器中斷結(jié)束:VICVectAddr=0;開中斷:OS_EXIT_CRITICAL();用戶處理程序;}
OS_CPU_C.C中任務(wù)堆棧的初始化函數(shù) OSTaskStkInit() OS_STK *OSTaskStkInit() {模擬帶參數(shù)(pdata)的函數(shù)調(diào)用;
模擬 ISR向量;按照預(yù)先所設(shè)定的寄存器值初始化堆棧結(jié)構(gòu);返回棧頂指針給調(diào)用該函數(shù)的函數(shù);}
3 輕型 PPP協(xié)議的設(shè)計(jì)與實(shí)現(xiàn)
PPP協(xié)議軟件模塊主要通過(guò)各層協(xié)商機(jī)制完成數(shù)據(jù)鏈路的建立、配置、測(cè)試、以及在鏈路連接建立后,將收到的 PPP數(shù)據(jù)幀解析,根據(jù)協(xié)議字段將數(shù)據(jù)信息交由不同的上層模塊進(jìn)行處理;同時(shí)可根據(jù)系統(tǒng)的需要,將上層模塊傳來(lái)的信息打包成不同的PPP數(shù)據(jù)幀發(fā)送出去。
Main主模塊:該模塊控制著整個(gè) PPP守護(hù)進(jìn)程的程序流程。當(dāng)PPP連接成功后,它使 PPP守護(hù)進(jìn)程進(jìn)入休眠狀態(tài),一直到管理員斷開或者外部事件引起斷開時(shí)它負(fù)責(zé)斷開 PPP連接。在 PPP成功建立連接后,建立一個(gè)信號(hào)量,由 PPP模塊處理任務(wù)不斷檢測(cè)這個(gè)信號(hào)量;若檢測(cè)到有調(diào)制解調(diào)器中斷復(fù)服務(wù)程序發(fā)來(lái)的信號(hào)量,則進(jìn)行PPP數(shù)據(jù)幀的發(fā)送或接收。
LCP模塊:該階段是通過(guò)交換配置數(shù)據(jù)包來(lái)建立和配置數(shù)據(jù)鏈路,發(fā)送 LCP REQ數(shù)據(jù)包,將會(huì)收到客戶端的發(fā)送過(guò)來(lái)的 LCP ACK數(shù)據(jù)包,客戶端還要回 REQ數(shù)據(jù)包,服務(wù)器端接受到 LCP REQ后,則向客戶端同樣發(fā)送一個(gè) LCP ACK數(shù)據(jù)包,至此鏈路協(xié)商正式結(jié)束。
認(rèn)證協(xié)商模塊( PAP):認(rèn)證階段是可選的,如果在鏈路建立協(xié)商階段,服務(wù)器發(fā)送的第一個(gè) LCP REQ數(shù)據(jù)包中含有了認(rèn)證的數(shù)據(jù)選項(xiàng),而且其數(shù)據(jù)選項(xiàng)一直沒(méi)有被對(duì)方拒絕并且得到確認(rèn),則進(jìn)入認(rèn)證協(xié)商階段;否則,進(jìn)入網(wǎng)絡(luò)層協(xié)商階段。
網(wǎng)絡(luò)層協(xié)商模塊(NCP):NCP協(xié)商的主要目的是服務(wù)器首先讓客戶端確認(rèn)自身的 IP地址,然后給客戶端動(dòng)態(tài)分配一個(gè)合法的 IP地址。網(wǎng)絡(luò)層協(xié)商 NCP每次請(qǐng)求數(shù)據(jù)包必須含有服務(wù)器端的 IP選項(xiàng),并且此選項(xiàng)最終被確認(rèn)。在客戶端回送了對(duì)服務(wù)器端的確認(rèn)數(shù)據(jù)包后,開始進(jìn)入客戶端向服務(wù)器端申請(qǐng)動(dòng)態(tài)分配 IP地址的階段,所以客戶端繼續(xù)向服務(wù)器端發(fā)送含有客戶端 IP地址且值為 0的 NCP REQ數(shù)據(jù)包,服務(wù)器端接受到這個(gè)數(shù)據(jù)包后,從 IP地址池中取出一個(gè)合法的 IP地址,發(fā)送了一個(gè) NCP NAK數(shù)據(jù)包。在該數(shù)據(jù)包中,客戶端 IP地址的數(shù)據(jù)選項(xiàng)中填入了從 IP地址池中取出的 IP地址的值,即給客戶端動(dòng)態(tài)的分配 IP地址的值。隨后,客戶端將接收到的 NCP NAK中的 IP地址值作為下一次回送的 NCP REQ中的客戶端的 IP地址值的選項(xiàng)。當(dāng)服務(wù)器端再接收到此 NCP REQ數(shù)據(jù)包后,便發(fā)送 NCP ACK數(shù)據(jù)包,至此整個(gè) PPP協(xié)商過(guò)程結(jié)束,鏈路建立成功。
PPP模塊:在協(xié)商好網(wǎng)絡(luò)協(xié)議,可以進(jìn)行數(shù)據(jù)的傳輸。為了更實(shí)時(shí)的進(jìn)行數(shù)據(jù)傳輸,在這里為 PPP協(xié)議模塊建立一個(gè)信號(hào)量,當(dāng)發(fā)生 modem接受事件時(shí),當(dāng) Modem接收到數(shù)據(jù)時(shí)引發(fā)處理器的外部中斷。在外部中斷 0處理函數(shù)中,將接收到的數(shù)據(jù)存入串口緩沖區(qū)中,如果緩沖區(qū)的數(shù)據(jù)已組成了一個(gè)完整的 PPP數(shù)據(jù)幀,則由中斷服務(wù)子程序通過(guò) μC/OS-II所提供的 OSSemPost()向任務(wù) PPP模塊任務(wù)發(fā)送一個(gè)信號(hào)量。
對(duì)PPP模塊任務(wù)來(lái)說(shuō),通過(guò) OSSemPend()函數(shù)等待由Modem中斷服務(wù)程序發(fā)出的信號(hào)量,當(dāng)接收到這個(gè)信號(hào)量后,說(shuō)明有事件發(fā)生;再次判斷這個(gè)事件是什么事件,若是接送事件,則調(diào)用 Receive()接收PPP數(shù)據(jù)幀,放到 SRAM接收緩沖區(qū),若接收后,判斷接收緩沖區(qū)是否正確地接收到數(shù)據(jù),若正確地接收到PPP數(shù)據(jù)幀時(shí),則調(diào)用 PPPInput()進(jìn)行對(duì)PPP數(shù)據(jù)幀的解析。若幀類型是 IP則調(diào)用 IP數(shù)據(jù)包的處理例程;若幀類型是 LCP則調(diào)用LCP數(shù)據(jù)幀的處理例程;若幀類型是 PAP、NCP則分別調(diào)用這兩種類型數(shù)據(jù)包的處理例程。若是發(fā)送事件,則調(diào)用Send()發(fā)送PPP數(shù)據(jù)幀。
4 輕型 PPP協(xié)議模塊的測(cè)試和性能分析
根據(jù)點(diǎn)對(duì)點(diǎn)通信的特點(diǎn),分別在 PC和ARM板兩端安裝一個(gè)Modem,通過(guò)一個(gè)交換機(jī),或直接用電話線連接起來(lái)。由 PC端通過(guò)撥號(hào)軟件,進(jìn)行與 ARM開發(fā)板端的連接后,分別通過(guò)雙方的協(xié)商,建立數(shù)據(jù)通信;在ARM開發(fā)板端,建立一個(gè)Test_task測(cè)試任務(wù)模塊,將一個(gè)信息“ hello world”封裝成 UDP包,再經(jīng) PPP模塊的封裝,發(fā)送到 PC機(jī)端,PC機(jī)端若與ARM板連接成功,在 Modem狀態(tài)對(duì)話框中,能夠正確的顯示出對(duì)方所發(fā)送來(lái)的字符數(shù)和自己發(fā)送給對(duì)方字節(jié)數(shù)以及連接狀態(tài);若 PC端顯示出這個(gè)信息,說(shuō)明PPP模塊得以實(shí)現(xiàn)。通過(guò)測(cè)試后,其 Modem狀態(tài)連接圖如圖 1所示。
從PC端的Modem狀態(tài)連接圖可知,該 PC機(jī)端已經(jīng)通過(guò)了相互協(xié)商,建立連接,處于數(shù)據(jù)幀的接收狀態(tài)。已經(jīng)正確地接收到由 ARM開發(fā)板所發(fā)送的PPP數(shù)據(jù)幀,進(jìn)行了相互通信,表明 ARM板上PPP協(xié)議成功的得到了實(shí)現(xiàn)。
5 結(jié)束語(yǔ)
本文作者創(chuàng)新點(diǎn)在于從uCOS—II內(nèi)核工作原理入手 ,以ARM開發(fā)板為平臺(tái),簡(jiǎn)述了系統(tǒng)硬件平臺(tái) ARM7TDMI處理器的體系結(jié)構(gòu)和相應(yīng)的指令集。對(duì)與處理器相關(guān)的代碼部分進(jìn)行了修改與編譯,實(shí)現(xiàn)了μC/OS-II在ARM開發(fā)板上移植;在該系統(tǒng)平臺(tái)上重點(diǎn)的介紹了輕型PPP協(xié)議設(shè)計(jì)與實(shí)現(xiàn)的具體過(guò)程,主要對(duì)main主模塊、LCP模塊、PAP模塊、NCP模塊和PPP模塊等五個(gè)方面的設(shè)計(jì)與代碼編寫。通過(guò)測(cè)試,驗(yàn)證了ARM開發(fā)板的PPP協(xié)議的網(wǎng)絡(luò)通信功能。
可可