引言
數(shù)據(jù)交換區(qū)是指程序執(zhí)行中使用到的各種數(shù)據(jù)所存放的內(nèi)存空間。本文提出了在μClinux操作系統(tǒng)下為嵌入式工業(yè)網(wǎng)絡(luò)服務(wù)器開(kāi)辟數(shù)據(jù)交換萄思想和解決方案。嵌入式工業(yè)網(wǎng)絡(luò)服務(wù)器項(xiàng)目的開(kāi)發(fā)目的是構(gòu)建一個(gè)以Client/Server模式工作的工業(yè)遠(yuǎn)程監(jiān)控系統(tǒng),其前端是一個(gè)嵌入式服務(wù)器,它安裝在工業(yè)現(xiàn)場(chǎng),可以與三菱PLC組成的控制系統(tǒng)接口,對(duì)該系統(tǒng)實(shí)施實(shí)時(shí)監(jiān)控。其中數(shù)據(jù)交換區(qū)部分起到承上啟下的樞紐作用,向上負(fù)責(zé)對(duì)客戶(hù)端交互現(xiàn)場(chǎng)設(shè)備數(shù)據(jù),向下負(fù)責(zé)與接口緩沖區(qū)交互設(shè)備實(shí)時(shí)數(shù)據(jù)。系統(tǒng)以Motorola公司的32位控制器Cold Fire5307為CPU,使用2個(gè)現(xiàn)代公司的HY57V641620型(4M×16bit)的SDRAM拼成4M×32位的SDRAM,使系統(tǒng)具有16 bytes的RAM空間。
1 μClinux操作系統(tǒng)
系統(tǒng)選取μClinux操作系統(tǒng)為開(kāi)發(fā)平臺(tái),為有2個(gè)SDRAM(4M×16bit)的嵌入式工業(yè)網(wǎng)絡(luò)服務(wù)器開(kāi)辟數(shù)據(jù)交換區(qū)。
Cold Fire 5307微處理器上可以運(yùn)行很多操作系統(tǒng),但是可以說(shuō)μClinux是最合適、性?xún)r(jià)比最高的操作系統(tǒng)。目前商用的實(shí)時(shí)操作系統(tǒng),如VxWorks和Nuclesus等價(jià)格比較昂貴,而且需要附加的C編譯器和相關(guān)的調(diào)試工具。而μCOS等免費(fèi)的實(shí)時(shí)操作系統(tǒng)又沒(méi)有很好的文件系統(tǒng)和TCP/IP協(xié)議的支持,就嵌入式工業(yè)網(wǎng)絡(luò)服務(wù)器的應(yīng)用特點(diǎn)而言,μClinux內(nèi)核采用模塊化設(shè)計(jì),很多功能塊可以獨(dú)立地加載或卸載,在設(shè)計(jì)內(nèi)核時(shí)可以把這些內(nèi)核模塊作為可選項(xiàng),編譯系統(tǒng)內(nèi)核時(shí)指定。一種較通用的做法是對(duì)μClinux內(nèi)核重新編譯,在編譯時(shí)仔細(xì)的選擇嵌入式系統(tǒng)所需要的功能支持模塊,同時(shí)刪除不需要的功能模塊。通過(guò)對(duì)內(nèi)核的重新配置,可以使系統(tǒng)運(yùn)行所需要的內(nèi)核顯著減小,從而縮減需要的控制器RAM和ROM資源。
μClinux同標(biāo)準(zhǔn)Linux的最大區(qū)別在于內(nèi)存管理,對(duì)SDRAM數(shù)據(jù)交換區(qū)的管理就屬于內(nèi)存管理范疇。標(biāo)準(zhǔn)Linux使用虛擬存儲(chǔ)器技術(shù),對(duì)于μClinux來(lái)說(shuō),其設(shè)計(jì)針對(duì)沒(méi)有MMU(memory management unit)的處理器。但μClinux仍然采用存儲(chǔ)器的分頁(yè)管理,系統(tǒng)在啟動(dòng)時(shí)把實(shí)際存儲(chǔ)器進(jìn)行分頁(yè)。在加載應(yīng)用程序時(shí)程序分頁(yè)加載。但是由于沒(méi)有MMU管理,所以實(shí)際上μClinux采用實(shí)存儲(chǔ)器管理策略(real memory management)。μClinux系統(tǒng)對(duì)于內(nèi)存的訪問(wèn)是直接的,它對(duì)地址的訪問(wèn)不需要經(jīng)過(guò)MMU,而是直接送到地址線上輸出,所有程序中訪問(wèn)的地址都是實(shí)際的物理地址。μClinux對(duì)內(nèi)存的管理從編譯內(nèi)核開(kāi)始,從而系統(tǒng)將在啟動(dòng)的初始化階段對(duì)內(nèi)存進(jìn)行分頁(yè),并且標(biāo)記已使用的和未使用的內(nèi)存。系統(tǒng)將在運(yùn)行應(yīng)用時(shí)使用這些分布內(nèi)存。另外由于采用實(shí)存儲(chǔ)器管理策略,用戶(hù)程序同內(nèi)核以及其他用戶(hù)程序在一個(gè)地址空間,程序開(kāi)發(fā)時(shí)要保證不侵犯其他程序的地址空間,以使得程序不至于破壞系統(tǒng)的正常工作,或?qū)е缕渌绦虻倪\(yùn)行異常。 2 數(shù)據(jù)交換區(qū)硬件架構(gòu)
系統(tǒng)采用Motorola公司的Cold Fire 5307型32位控制電路為CPU,用2個(gè)現(xiàn)代公司的HY57V641620型的SDRAM(4M×16bit)拼成4M×32位的SDRAM,使系統(tǒng)具有16M bytes的RAM空間。
Clod Fire系列微處理器是Motorola公司繼其M68K系列微處理器之后推出的新一代內(nèi)核的32位高位能嵌入式微處理器。Clod Fire系列微處理器繼承了M68K系列優(yōu)秀的指令集設(shè)計(jì)和CISC架構(gòu)的優(yōu)點(diǎn),融入了RISC架構(gòu),在速度和架構(gòu)之間得到了很好的平衡。Cold Fire 5307型微處理器運(yùn)行在外部總線時(shí)鐘45MHz,內(nèi)部總線時(shí)鐘90MHz,速率可達(dá)75MIPS。
與Flash存儲(chǔ)器相比較,SDRAM不具有掉電保存數(shù)據(jù)的特性,但其存取速度大大高于Flash存儲(chǔ)器,且具有讀/寫(xiě)的屬性。因此,SDRAM在系統(tǒng)中主要用于程序的運(yùn)行空間、數(shù)據(jù)交換區(qū)及堆棧區(qū)。當(dāng)系統(tǒng)啟動(dòng)時(shí),CPU首先從復(fù)位地址0x0處讀取啟動(dòng)代碼,在完成系統(tǒng)初始化后,程序代碼一般應(yīng)調(diào)入SDRAM中運(yùn)行 ,以提高系統(tǒng)的運(yùn)行速度,同時(shí),系統(tǒng)及用戶(hù)堆棧、運(yùn)行數(shù)據(jù)也都放在SDRAM中。SDRAM具有單位空間存儲(chǔ)容量大價(jià)格便宜的優(yōu)點(diǎn),已廣泛應(yīng)用在各種嵌入式系統(tǒng)中。SDRAM的存儲(chǔ)單元可以理解為一個(gè)電容器,總是傾向于放電,為避免數(shù)據(jù)丟失,必須定時(shí)刷新(充電)。
嵌入式工業(yè)網(wǎng)絡(luò)服務(wù)器項(xiàng)目中的數(shù)據(jù)交換區(qū)根據(jù)數(shù)據(jù)交換匹配置文件生成。向上負(fù)責(zé)與客戶(hù)端交互現(xiàn)場(chǎng)設(shè)備數(shù)據(jù),向下負(fù)責(zé)與接口緩沖區(qū)交互設(shè)備實(shí)時(shí)數(shù)據(jù)。每個(gè)SDRAM由4M×16bit的內(nèi)部Bank組成,這個(gè)Bank的選擇由SDRAM外部引腳BA0和BA1來(lái)完成,筆者將BA0和BA1都連接在Cold Fire 5307的高端地址線上;其他信號(hào)和Cold Fire 5307都一一對(duì)應(yīng)。UDQM和LDQM是SDRAM的高低字節(jié)片選信號(hào),因?yàn)槊總(gè)SDRAM都是16位架構(gòu),所以將二片SDRAM拼成32位時(shí),除數(shù)據(jù)線和這二個(gè)片選信號(hào)之外,其他信號(hào)線對(duì)二個(gè)SDRA來(lái)說(shuō)都是共用的。這二個(gè)信號(hào)分別接Cold Fire 5307的CAS0、CAS1和CAS2、CAS3。SDRAM與MCF5307的連接如圖1所示。
Cold Fire 5307可以支持二個(gè)Bank的SDRAM,在本系統(tǒng)中只使用了第一個(gè)Bank,另外一個(gè)Bank的控制信號(hào)懸空不使用。其中,SDRAM和FlashRom以及其他外設(shè)一同使用32位數(shù)據(jù)總線D0-D31;SDRAM映射到內(nèi)部物理地址,但是因?yàn)镾DRAM的特殊性,并不需要所有的地址線信號(hào)A0-A31,而是使用其中一部分信號(hào)線,這個(gè)地址映射的工作由DRAM控制器來(lái)完成;RAS0-RAS1是Bank片選信號(hào),本設(shè)計(jì)中只使用RAS0來(lái)片選所使用的SDRAM Bank;CAS0-CAS3是SDRAM 32位數(shù)據(jù)線中4個(gè)8位數(shù)據(jù)線(Byte)獨(dú)立的片選信號(hào);SCAS和SRAS分別是SDRAM的行、列地址鎖存信號(hào);DRAMW是DRAM寫(xiě)信號(hào);BCLK0是系統(tǒng)時(shí)鐘輸出,連接到SDRAM的時(shí)鐘輸入引腳CLK端;SCKE是SDRAM時(shí)鐘使能信號(hào),來(lái)使能輸入給SDRAM的時(shí)鐘信號(hào),高電平時(shí)SDRAM自動(dòng)進(jìn)入休眠狀態(tài)。
3 數(shù)據(jù)交換區(qū)軟件實(shí)現(xiàn)
服務(wù)器依據(jù)數(shù)據(jù)交換區(qū)配置文件生成設(shè)備數(shù)據(jù)交換區(qū)。服務(wù)器進(jìn)入運(yùn)行模式之后,首先檢查生成數(shù)據(jù)交換區(qū)與底層緩沖區(qū)的配置文件是否存在。如果不存在則打印錯(cuò)誤信息,存在則依據(jù)配置文件在系統(tǒng)SDRAM區(qū)開(kāi)辟數(shù)據(jù)交換區(qū)與底層緩沖區(qū)。接著系統(tǒng)檢查PLC通信協(xié)議交換是否存在,不存在則打印錯(cuò)誤信息,存在則將COM2口置為PLC通信端口。一切就緒之后,系統(tǒng)啟動(dòng)任務(wù)調(diào)度完成各種任務(wù)。數(shù)據(jù)交換區(qū)生成及使用流程圖如圖2所示,數(shù)據(jù)緩沖區(qū)生成子程序流程如圖3所示。
在2.4片μClinux內(nèi)核中,內(nèi)核引導(dǎo)時(shí),通過(guò)訪問(wèn)系統(tǒng)所有的物理內(nèi)存,然后調(diào)用各個(gè)子系統(tǒng)的初始化函數(shù)進(jìn)行初始化,允許初始化代碼分配私有的緩沖區(qū),并減少了留給常規(guī)系統(tǒng)操作的RAM數(shù)量。在2.4版μClinux內(nèi)核中,這種分配通過(guò)調(diào)用下列函數(shù)之一進(jìn)行:
分配內(nèi)存空間所使用的函數(shù)調(diào)用如下:
(1)函數(shù)malloc和calloc都用于分配動(dòng)態(tài)內(nèi)存空間的函數(shù)。
(2)函數(shù)malloc的參考size表示申請(qǐng)分配的內(nèi)存空間的大小,以字節(jié)計(jì)算;
(3)函數(shù)calloc的參數(shù)nmemb表示分配的內(nèi)存空間占的數(shù)據(jù)項(xiàng)數(shù)目。參數(shù)size表示每一個(gè)數(shù)據(jù)項(xiàng)的大小,以字節(jié)計(jì)算。也就是說(shuō),calloc函數(shù)分配大小為nmemb*size大小的內(nèi)存空間。
Calloc函數(shù)與malloc函數(shù)最大的區(qū)別是calloc函數(shù)被初始化所分配的內(nèi)存空間,把所有位置為0。調(diào)用成功時(shí),malloc函數(shù)為calloc函數(shù)的返回值都為被分配的內(nèi)存空間的指針;調(diào)用失敗時(shí),返回值為NULL。動(dòng)態(tài)內(nèi)存被釋放。
在C語(yǔ)言中,指針是處理許多數(shù)據(jù)結(jié)構(gòu)的關(guān)鍵。沒(méi)有指針,也許根據(jù)不能使用動(dòng)態(tài)內(nèi)存的諸多特性。在編寫(xiě)程序的時(shí)候,它允許程序員建立復(fù)雜的內(nèi)存系統(tǒng)。提高了處理未知內(nèi)容或者類(lèi)型數(shù)據(jù)的靈活性。在C中還有一點(diǎn)對(duì)字符串處理和數(shù)據(jù)的輸入輸出很重要。對(duì)指針的徹底了解有助于我們寫(xiě)出更好、更高效的代碼。
如果使用一種算法不夠,鏈表可以解決這個(gè)問(wèn)題。當(dāng)從未知大小的數(shù)據(jù)塊中讀入數(shù)據(jù)時(shí),用戶(hù)不得不把數(shù)據(jù)讀到內(nèi)存中。這是因?yàn)樘幚碜x入數(shù)據(jù)的函數(shù)必須把數(shù)據(jù)讀到一塊一定大小的內(nèi)存中。在讀入以后,必須找到一種接合分離數(shù)據(jù)的辦法。一般使用fgets()把數(shù)據(jù)讀到n個(gè)字節(jié)大小的內(nèi)存中。緩沖區(qū)是n+1個(gè)字節(jié)大,但是請(qǐng)注意必須使用1個(gè)字節(jié)放結(jié)束標(biāo)記。然后使用了一簡(jiǎn)單的鏈表保存數(shù)據(jù)。這個(gè)鏈表中一個(gè)特殊項(xiàng):一個(gè)名為iscontinuing的整型變量。如果這個(gè)變量有值,表示當(dāng)前結(jié)構(gòu)中的數(shù)據(jù)不是字符串最后的部分,最后的部分將包含在以后的結(jié)構(gòu)后。這個(gè)變量再把數(shù)據(jù)從內(nèi)存中調(diào)出來(lái),重新組裝的時(shí)候使用。
還有一種更明智的保存數(shù)據(jù)的方法。逐步處理數(shù)據(jù)直到達(dá)到數(shù)據(jù)末尾。首先要修改的是結(jié)構(gòu)的定義。在結(jié)構(gòu)中包含字符串。在結(jié)構(gòu)中定義一個(gè)指針,指向動(dòng)態(tài)申請(qǐng)的內(nèi)存區(qū)域。這樣做的好處是,字符串可以很長(zhǎng)。現(xiàn)在產(chǎn)生輸出的代碼更簡(jiǎn)單了。它做的所有的事情就是計(jì)算和顯示。不再需要合并字符串。因?yàn)橐呀?jīng)被合并。
4 結(jié)束語(yǔ)
數(shù)據(jù)交換區(qū)的生成和使用對(duì)嵌入式工業(yè)網(wǎng)絡(luò)服務(wù)器項(xiàng)目尤為重要,它是WEB服務(wù)器正常運(yùn)行的先決條件,起到承上啟下的樞紐作用。向上負(fù)責(zé)對(duì)客戶(hù)端交互現(xiàn)場(chǎng)設(shè)備數(shù)據(jù),向下負(fù)責(zé)與接口緩沖區(qū)交互設(shè)備實(shí)時(shí)數(shù)據(jù)。目前,該部分設(shè)計(jì)工作已經(jīng)完成,并在試運(yùn)行期間情況良好,達(dá)到預(yù)期效果。
作者:郝艷杰 胡榮強(qiáng) 唐 盛 來(lái)源:《EDN電子設(shè)計(jì)技術(shù)》