單片機的TCP/IP的實現(xiàn)與UNIX的不同
由于指令的原因,以及資源上的原因,在UNIX上實現(xiàn)的TCP/IP協(xié)議的原代碼并不能夠直接移植到8位的單片機上。最早期的LINUX1.0版的內(nèi)核是最小的實現(xiàn)TCP/IP的操作系統(tǒng),它的程序的大小大概在1兆字節(jié)。而現(xiàn)在的紅旗LINUX,紅帽子LINUX,內(nèi)核多達幾十兆,整個系統(tǒng)要幾張光盤來裝。早期的LINIX因為小,而被移植到掌上電腦,PDA等產(chǎn)品中。 單片機的程序空間是極為有限的,直接尋址的空間僅64K字節(jié),這跟電腦的存儲空間相比要差幾個數(shù)量級。除了程序空間小之外,可用的內(nèi)存RAM也是非常小的,最多只能擴64K的RAM,而電腦的RAM至少在1兆以上。單片機的運算速度也極為有限,一般只有2MIPS,而電腦上的處理能力在100MIPS以上。
有些人提到有沒有必要在單片機上實現(xiàn)TCP/IP的問題。因為TCP/IP是一種標準,以太網(wǎng)也成為局域網(wǎng)的標準。在很多情況下運用以太網(wǎng)和TCP/IP,能夠簡化結(jié)構(gòu)。比如目前較熱的智能小區(qū),因為布線的原因,不能為每個家庭布很多線,而以太網(wǎng)的8芯雙絞是一定有的。例如寬帶上網(wǎng),是直接通過以太網(wǎng)的,如果你制造的設(shè)備,比如安全產(chǎn)品,遠程抄表產(chǎn)品,家居智能產(chǎn)品能夠走以太網(wǎng)的話,可以利用現(xiàn)成的以太網(wǎng)絡(luò)。但如果走其它網(wǎng)絡(luò),比如RS485、CAN單線、LONWORKS等,那么需要另外布線。布線是復(fù)雜的,還涉及到消防安全等。從成本看,用以太網(wǎng)實現(xiàn)聯(lián)網(wǎng)要比CAN、LONWORKS等更為便宜,集線器、交換機現(xiàn)在都非常便宜,而且將來有三網(wǎng)合一的趨勢,電話、電視、計算機三網(wǎng)合一。將來的趨勢可能是高速的以太網(wǎng)的天下,電話信號、電視信號、聯(lián)網(wǎng)都在以太網(wǎng)上跑。盡管目前還未能實現(xiàn),但是這種趨勢是不可避免的。
有網(wǎng)友提到就算要利用以太網(wǎng),也沒有必要跑TCP/IP。那么為什么要跑TCP/IP呢? TCP/IP是一標準,這個標準使得數(shù)據(jù)傳輸不一定是要局域網(wǎng),而可以在互聯(lián)網(wǎng)、跨地區(qū)跨國界。例如你在某一區(qū)域安裝了很多監(jiān)控產(chǎn)品,但數(shù)據(jù)中心可能不設(shè)在那個區(qū)域,而設(shè)在其他地區(qū)。TCP/IP有兩種協(xié)議TCP和UDP;TCP保證了數(shù)據(jù)傳輸?shù)恼_性,(如果你的數(shù)據(jù)只跑以及網(wǎng)層,那么你的數(shù)據(jù)完整性是要你的編程來保證的,校驗的計算。數(shù)據(jù)包的丟失需要你手工處理,而TCP把這些所有你要處理細節(jié)都幫你處理了。UDP可以面向廣播的、視頻的、音頻的等方面的應(yīng)用。實現(xiàn)TCP/IP的協(xié)議的好處是可以統(tǒng)一平臺,比如智能小區(qū)的產(chǎn)品,如果大家都遵守TCP/IP的協(xié)議,那么大家的產(chǎn)品才能兼容,假設(shè)一個大型的智能社區(qū),這個社區(qū)可能由多家設(shè)備供應(yīng)商進行建設(shè),可能有某些廠商做平臺、做軟件,一些廠商做硬件。如果大家遵守TCP/IP協(xié)議,各自的遠程抄表產(chǎn)品,智能防盜產(chǎn)品就有可能兼容,對地產(chǎn)開發(fā)商來說,可以選擇多個供應(yīng)商,有利于競爭,也避免某個廠家倒閉造成重大影響。
題外話說的多了,還是回到本章要談的內(nèi)容吧。由于單片機與電腦的差別很大,兩者的實現(xiàn)有很大的不同。在電腦里編寫TCP/IP程序,你可以不考慮代碼大小、代碼速度,但在單片機上這些都是你要考慮的問題。 綜合來說,單片機實現(xiàn)與UNIX實現(xiàn)TCP/IP有如下區(qū)別: ?。?)、操作系統(tǒng)。不論是WINDOWS、UNIX、LINUX,它們都有一個多任務(wù)操作系統(tǒng),這使得代碼編寫簡單化,而在單片機上,因為資源的原因而無法使用多任務(wù)操作系統(tǒng),這使得代碼結(jié)構(gòu)變?yōu)轫樞驁?zhí)行+硬件中斷的方式,而在電腦里卻可以并發(fā)地執(zhí)行。對程序執(zhí)行結(jié)構(gòu),單片機要考慮更多。
(2)、內(nèi)存分配。WINDOWS或UNIX的內(nèi)存分配是動態(tài)的,根據(jù)需要隨時分配,隨時撤消 。我們閱讀一些關(guān)于LINUX、UNIX的書,它們都是mbuf的存儲結(jié)構(gòu)。mbuf是一個存儲鏈,這個鏈可以動態(tài)地增加和減小。比如在數(shù)據(jù)包很少的情況下,UNIX分配一個2K字節(jié)的緩沖區(qū)可能就夠用了,但如果數(shù)據(jù)包很多,就有可能要分配64K甚至更多的緩沖區(qū),可分配的內(nèi)存要根據(jù)CPU的可用內(nèi)存來調(diào)整。 但是在單片機卻不能夠這樣做。一個最大的以太網(wǎng)數(shù)據(jù)包有1500多個字節(jié),分配一包的緩沖區(qū)就要1.5K字節(jié),而一般實現(xiàn)TCP/IP的單片機只外接一塊32K字節(jié)的RAM。而這32K字節(jié)的RAM要被各個協(xié)議所用,而不僅僅是存放收到的數(shù)據(jù)包。一般的做法是分配一個256×6=1536個字節(jié)的RAM來存放收到的以太網(wǎng)數(shù)據(jù)包。收到一包就處理一包。而UNIX卻可以收很多包才處理。在單片機里,存放收到的以太網(wǎng)數(shù)據(jù)包的RAM是固定的,而不是動態(tài)分配的。所有UNIX關(guān)于內(nèi)存管理、內(nèi)存分配、mbuf的結(jié)構(gòu)在單片機里并不適用。這些代碼對單片機是無用的。
(3)、指針。在電腦里,指針只有一種,就是指向某一地址的RAM,而在單片機里指針有幾種:
1、 指向外部RAM的指針 例uchar xdata *p 使用指令 movx @dptr 占二個字節(jié)
2、 指向程序ROM的指針 例uchar code *p 使用指令 movc 占二個字節(jié)
3、 指向內(nèi)部的RAM的指針 例uchar data *p 使用指令 mov @ri 占一個字節(jié)
4、 指向外部RAM的分頁指針 例uchar pdata *p 使用指令 movx @ri 占一個字節(jié)
5、 一般指針,可以指向以上的任何一種 占三個字節(jié)
6. 還有其它用于分組切換的指針。
在電腦里,所有程序都必須先放在RAM里才能運行,所以它的指針只有一種情況,就是指向RAM。而單片機的結(jié)構(gòu)和電腦的結(jié)構(gòu)有很大差別,指針類型很多,對指針運算的速度也不一樣,由于第5種指針"一般指針"運算很慢,同時又需要占用很多程序空間,這使得指針運算不能從UNIX源代碼直接移植到單片機上,而UNIX實現(xiàn)TCP/IP的源代碼中,用的最多的就是指針,而在單片機里一般要求少用指針,或使用特定類型的指針。這使用UNIX的源代碼需要作很多的改動。
(4)、參數(shù)傳遞。在UNIX實現(xiàn)的TCP/IP源代碼中,一般有很多的參數(shù)傳遞,而在單片機里允許傳遞的參數(shù)是有限的(因為受到內(nèi)部RAM的限制),同時參數(shù)傳遞的過程要浪費程序代碼空間,也降低單片機執(zhí)行速度。所以在單片機的實現(xiàn)里,一般不要做太多的參數(shù)傳遞,而多使用公共的全局變量來實現(xiàn)調(diào)用的過程。這種情況下,UNIX的一般源程序是相對獨立的,受其它函數(shù)或變量的影響很小,而單片機里各程序的相互依賴程度要大。因為在單片機里往往共享某一數(shù)據(jù)、某一變量。
(5)變量定義。UNIX和KEIL C51雖然都是C語言,但兩者又有所不同,對于一些變量的定義,兩者卻不能通用。例如,單片機的特殊寄存器定義,sfr sfr16 sbit等,在標準C里是沒有的。在標準C里支持的結(jié)構(gòu),在KEIL C里也有可能不支持,比如一些C++的語法。在處理上的特殊性,也可能不一樣,比如IP地址類型,在UNIX里一般將IP地址定義為數(shù)組:
uchar ip[4]; 而在單片機里,我的定義是
union IP_address_type{uchar bytes[4];
uint words[2];
ulong dwords;}
IP 被定義為共用體,而不是簡單的一個數(shù)組。為什么要這樣做,是因為單片機處理的特殊性,例如比較兩個IP地址IP1,IP2是否相等,如果使用數(shù)組,比較是麻煩的: 要寫成 if(IP1[0]==IP2[1])**IP1[1]=IP2[1]**…… 用共用體可以簡化為
if(IP1.dwords==IP2.dwords)…… 有時候,我們又要把IP地址按16位來計算,比如較驗和計算,那么IP地址按16位加可以寫成: IP.dwords[0]+ IP.dwords[1], 有時,我們又要對IP地址按字節(jié)賦值,比如IP地址從24C02里讀出來,需要按字節(jié)賦值:可以為 IP.bytes[0]=×× IP.bytes[1]=×× IP.bytes[2]=×× IP.bytes[3]=××
如果不作這樣的定義,運算將復(fù)雜很多。而且一些編譯會認為類型混亂而無法編譯。 在單片機里使用共用體會簡化很多。而在UNIX里要對這些值作改變,一般是利用指針進行的。在電腦里,用指針運算是方便的,而且速度也快,但在單片機里,卻不能夠方便地使用指針。 在UNIX里的一些結(jié)構(gòu)類型的定義都要被改寫。這樣也使得UNIX的源代碼不能直接用在單片機上。
(6)、協(xié)議支持。在UNIX里可支持比較完整的TCP/IP協(xié)議,但在單片機里無法做到,這是因為單片機根本沒有足夠的代碼空間來支持這些協(xié)議。一般在單片機里實現(xiàn)與需要有關(guān)的部分,而不使用的協(xié)議則一概不支持。例如文件共享SMB協(xié)議,在UNIX、WINDOWS都支持,但單片機上卻沒有必要。一般只能在單片機中實現(xiàn):ARP、IP,ICMP、TCP、UDP這些協(xié)議,而更高層的協(xié)議,http、smtp、ftp一般是不需要支持的。雖然有些單片機例如AVR上網(wǎng)方案實現(xiàn)了http、smtp、ftp協(xié)議,但我們認為實用性不太,因為AVR上網(wǎng)方案用的是MEGA103,而該芯片要150元左右,高昂的造價使得AVR上網(wǎng)方案沒有得到廣泛的應(yīng)用。單片機應(yīng)用的TCP/IP協(xié)議大多是為了完成數(shù)據(jù)采集和數(shù)據(jù)傳輸,而不是網(wǎng)頁瀏覽、文件傳輸這些功能。就對某一協(xié)議而言,例如ARP協(xié)議,UNIX系統(tǒng)支持以太網(wǎng)、令牌環(huán)等網(wǎng)絡(luò)的ARP,但單片機里只支持以太網(wǎng),也就是說,對于某一協(xié)議,也有可能要作簡化。IP包最大可以為65K,可以分段傳輸,而在單片機里根本無法容納如此大的數(shù)據(jù)包,因此一般是不支持分段的。單片機一般采用發(fā)送小數(shù)據(jù)包的方式,以避免分段。
(7)、硬件接口。在UNIX或WINDOWS里,對網(wǎng)卡驅(qū)動無一例外都是采用中斷方式。而在單片機的應(yīng)用中,大部份的方案都是查詢式的。因為電腦的處理速度快,一次中斷的處理時間也很短,不會影響系統(tǒng)內(nèi)的其它中斷。但在單片機里就不行了,處理一次中斷,收取一個數(shù)據(jù)包一般要幾毫秒的時間,這將封鎖其它中斷的產(chǎn)生(只有高優(yōu)先級的中斷可以執(zhí)行),而單片機往往還存在其它一些中斷,比如串口按收中斷,A/D條件中斷、鍵盤中斷等需要被執(zhí)行,這就使得消耗時間長的網(wǎng)卡中斷改為查詢式執(zhí)行。在電腦里,對網(wǎng)卡的驅(qū)動相對簡單,而在單片機里需要處理的事情更多。比如緩沖區(qū)溢出,閱讀一些驅(qū)動程序源代碼,你可能發(fā)現(xiàn)在電腦里的一些程序根本沒有處理溢出的代碼。因為電腦執(zhí)行快,網(wǎng)卡緩沖區(qū)的溢出幾乎是不會發(fā)生的,不要說10M網(wǎng)卡,就是100M網(wǎng)卡,電腦也能夠很快處理。電腦往往采用即插即用方式來驅(qū)動網(wǎng)卡,而單片機卻不能這樣做,因為即插即用要很多代碼來實現(xiàn),而使用跳線方式,電腦里驅(qū)動NE2000的網(wǎng)卡,一般都是用16位DMA的方式,而在單片機里卻只能用8位DMA方式。這也使用UNIX對網(wǎng)卡驅(qū)動的代碼不能直接移植。
評論