uclinux多線程應(yīng)用-串口與網(wǎng)絡(luò)通信

0. 前言
本文我們?cè)O(shè)計(jì)一個(gè)簡(jiǎn)單的實(shí)例--嵌入式串口協(xié)議處理系統(tǒng),來(lái)實(shí)現(xiàn)串口與網(wǎng)口數(shù)據(jù)間的傳輸。說(shuō)白了,就是把從串口讀取到的數(shù)據(jù)發(fā)向網(wǎng)絡(luò),把從網(wǎng)絡(luò)讀取到的數(shù)據(jù)發(fā)向串口。在系統(tǒng)發(fā)送和接收以太網(wǎng)數(shù)據(jù)的時(shí)候,需要在這之前建立連接。
并且由于在實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)傳向串口和串口數(shù)據(jù)發(fā)向網(wǎng)絡(luò)的過(guò)程是同時(shí)進(jìn)行,這就需要用到多線程技術(shù)。對(duì)于串口通信和TCP/IP協(xié)議就不過(guò)多介紹,下面直接講如何做一些簡(jiǎn)單的編程,需要有一點(diǎn)C語(yǔ)言基礎(chǔ)。
1. Linux下線程編程的接口函數(shù)
Linux系統(tǒng)下的多線程遵循POSIX線程接口,稱(chēng)為pthread。
編寫(xiě)Linux下的多線程程序,需要使用頭文件pthread.h,連接時(shí)需要使用庫(kù)libpthread.a?(在Makefile里添加LDLIBS += -lpthread即可)。
#include <pthread.h>
分別實(shí)現(xiàn)了串口轉(zhuǎn)網(wǎng)絡(luò)和網(wǎng)絡(luò)串口功能以后,下面需要把兩個(gè)功能分別添加進(jìn)各自的線程。
這里分別命名為task和task2。
void task(int *counter);?
void task2(int *counter);
用函數(shù)pthread_create來(lái)創(chuàng)建一個(gè)線程,返回0則表示創(chuàng)建成功:
pthread_create( &thrd , NULL , (void*) task , (void*) &gCounter );
用pthread_join等待線程結(jié)束(當(dāng)然程序中是要讓線程無(wú)限循環(huán)的):
pthread_join(thrd, NULL);
當(dāng)面這些都實(shí)現(xiàn)以后,在Linux下編譯,生成目標(biāo)文件,下載到開(kāi)發(fā)板準(zhǔn)備運(yùn)行。
2. 程序編寫(xiě)
2.1 網(wǎng)絡(luò)程序的編寫(xiě)
由于μClinux攜帶了RTL8019驅(qū)動(dòng)和TCP/IP協(xié)議,因此,在μClinux下實(shí)現(xiàn)網(wǎng)絡(luò)功能就顯得比較的簡(jiǎn)單。
2.1.1 服務(wù)器端的程序
2.1.2 客戶端程序
2.2 串口程序的編寫(xiě)
在μClinux下的串口實(shí)現(xiàn),由于它已經(jīng)帶了串口的驅(qū)動(dòng)程序,只需要在應(yīng)用的時(shí)候?qū)⑵浯蜷_(kāi)就可以。這里,我們使用默認(rèn)的115200Hz的頻率,8位數(shù)據(jù)位,無(wú)奇偶校驗(yàn),1位停止位,無(wú)數(shù)據(jù)流控制。
代碼如下:
int fd;?
fd=open("/dev/ttyS0",O_RDWR);
其中open函數(shù)表示打開(kāi)設(shè)備文件,因?yàn)長(zhǎng)inux是以文件方式管理設(shè)備的,要打開(kāi)一個(gè)設(shè)備,只需要用打開(kāi)文件的函數(shù)就可以了。
而串口在Linux里位于dev文件夾下,串口0、串口1依次對(duì)應(yīng)ttyS0、ttyS1。
O_RDWR表示以可讀寫(xiě)方式打開(kāi)設(shè)備。
fd存儲(chǔ)設(shè)備號(hào),如所有欲檢查的權(quán)限都通過(guò)了則返回0值,表示成功,只要有一個(gè)權(quán)限被禁止則返回-1。
同樣的,將數(shù)據(jù)寫(xiě)入串口的話,我們使用write函數(shù):
int fd;
write(fd,buf,num);
這里fd表示已經(jīng)打開(kāi)的設(shè)備號(hào),這里是串口0,buf表示需要發(fā)送的數(shù)據(jù),而num則表示發(fā)送的數(shù)據(jù)量。如果發(fā)送失敗則返回-1,錯(cuò)誤代碼寫(xiě)人errno中。如果write順利,則返回實(shí)際寫(xiě)入的字節(jié)數(shù)。
2.3 完整的程序
好了,上面的一些解釋介紹,下面的完整的源代碼:
好了,按照上面的步驟編譯運(yùn)行,然后同時(shí)打串口調(diào)試助手和網(wǎng)絡(luò)調(diào)試助手,都設(shè)置成定時(shí)發(fā)送模式,我都設(shè)置成10ms,二者不斷發(fā)送接收數(shù)據(jù),測(cè)試了一下,在一個(gè)局域網(wǎng)內(nèi),數(shù)據(jù)的丟失量的非常小的.
對(duì)于UDP協(xié)議這算正?,F(xiàn)象, 至此我們的這個(gè)多線程示例算是成功完成!