新聞中心
序言

尚志網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站開發(fā)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)建站2013年至今到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。
作為一臺計(jì)算機(jī)的基本輸入/輸出設(shè)備之一,串口在很多場合得到重視。但是Linux系統(tǒng)下,對于串口的使用并不像我們平時(shí)想象中的那樣簡單。在Linux系統(tǒng)下,上電之后,針對每一個串口都會開啟一個設(shè)備文件。通過串口訪問器可以實(shí)現(xiàn)終端的連接,實(shí)現(xiàn)與設(shè)備的通訊。然而,由于Linux系統(tǒng)系統(tǒng)的多用戶,多任務(wù)并發(fā)特性,串口的并發(fā)訪問很容易造成競爭,進(jìn)而導(dǎo)致系統(tǒng)異常,阻礙設(shè)備的訪問。本文旨在分享一些Linux串口獨(dú)占打開技巧,幫助用戶實(shí)現(xiàn)串口的順利連接。
一、串口設(shè)備特別之處
與其他的設(shè)備不同,串口有特別的地方。串口的寫操作可以直接進(jìn)入硬件緩沖區(qū),而實(shí)際的寫操作是異步完成的;串口的讀操作也是異步的,當(dāng)緩沖區(qū)有數(shù)據(jù)時(shí),Linux內(nèi)核會通知應(yīng)用程序調(diào)用指定的的讀緩沖函數(shù)。因此,每個串口都有獨(dú)立的讀寫緩沖區(qū),讀/寫操作互不干擾,此處不作深入討論。
二、串口獨(dú)占打開技巧
(1)文件IO模型
在使用Linux系統(tǒng)串口接口時(shí),首先要了解Linux的文件IO模型,并據(jù)此進(jìn)行串口數(shù)據(jù)通訊的設(shè)計(jì)。
在Linux系統(tǒng)中,IO與具體的設(shè)備無關(guān),對于系統(tǒng)任何一個文件都是可以操作的。對于Linux內(nèi)核來說,每一個打開的文件都會對應(yīng)一個結(jié)構(gòu)體,其中包含了打開這個文件的進(jìn)程信息、IO緩沖信息、FIFO緩沖、文件位置指針等信息。LINUX文件IO模型大概如下圖所示:

(2)串口用戶空間API
Linux下的串口讀寫相關(guān)的API接口有如下幾組:
– 打開串口:open
– 配置串口參數(shù):ioctl
– 讀:read
– 寫:write
– 關(guān)閉串口:close
其中需要注意的是,串口在讀寫數(shù)據(jù)時(shí),需要設(shè)置一個合適的讀寫超時(shí),否則會出現(xiàn)卡住現(xiàn)象。
(3)串口獨(dú)占打開
在Linux系統(tǒng)下,串口的打開方式是獨(dú)占方式。即每個串口只支持被一個程序打開,當(dāng)一個進(jìn)程打開一個串口時(shí),其他進(jìn)程無法打開此串口,直到打開這個串口的進(jìn)程關(guān)閉此串口之后,其他進(jìn)程才有機(jī)會打開此串口。因此,我們在設(shè)計(jì)應(yīng)用程序時(shí),要特別注意對串口進(jìn)行獨(dú)占文件IO訪問,防止出現(xiàn)結(jié)果混亂的現(xiàn)象。
接下來,我們以一個串口實(shí)際的使用場景作為例子,介紹串口獨(dú)占打開技巧。假設(shè)在底層,有一個嵌入式設(shè)備需要通過串口與PC機(jī)進(jìn)行通訊。因此,我們需要設(shè)計(jì)一個上位機(jī)程序,與此嵌入式設(shè)備進(jìn)行通訊。同時(shí),我們也要進(jìn)行編程,將相應(yīng)的系統(tǒng)接口封裝起來,供其他應(yīng)用程序調(diào)用。在具體的代碼實(shí)現(xiàn)中,需遵循如下的原則:
– 獨(dú)占串口,防止串口訪問沖突
– 進(jìn)行數(shù)據(jù)的接收和處理
– 設(shè)置讀寫超時(shí),避免出現(xiàn)卡死現(xiàn)象
三、串口數(shù)據(jù)的收發(fā)操作
在設(shè)計(jì)串口數(shù)據(jù)的發(fā)送操作時(shí),需要先打開串口設(shè)備,然后通過write函數(shù)將要發(fā)送的數(shù)據(jù)寫入串口緩沖區(qū),核對數(shù)據(jù)無誤后,可以將設(shè)備關(guān)閉。在實(shí)現(xiàn)的時(shí)候,根據(jù)需要,還可以添加等待數(shù)據(jù)傳輸完成的超時(shí)計(jì)時(shí)器。串口發(fā)送操作的示例代碼如下:
“`
#include
#include
#include
#include
int mn(void)
{
int fd;
if((fd = open (“dev/ttyS0”, O_RDWR | O_NONBLOCK))
{
perror(“open fled”);
return -1;
}
struct termios opt;
tcgetattr (fd, &opt);
cfsetispeed (&opt, B115200);
cfsetospeed (&opt, B115200);
opt.c_cflag |= CLOCAL;
opt.c_cflag |= CREAD;
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8;
opt.c_cflag &= ~PARENB;
opt.c_cflag &= ~CSTOPB;
tcsetattr (fd, TCSANOW, &opt);
sleep(5);
char buf[] = {0x31,0x32,0x33,0x34,0x35};
int len = write(fd,buf,sizeof(buf));
tcflush (fd, TCIOFLUSH);
close (fd);
return 0;
}
“`
在設(shè)計(jì)串口數(shù)據(jù)的接收操作時(shí),也需先打開串口,然后再讀取串口緩沖區(qū)中的數(shù)據(jù)。如果讀取的數(shù)據(jù)比較少,可以將read函數(shù)設(shè)置為非阻塞方式;如果讀取的數(shù)據(jù)較多,可以將read函數(shù)設(shè)置為阻塞方式,直到緩沖區(qū)中有足夠的數(shù)據(jù)可以讀取。數(shù)據(jù)的接收操作示例代碼如下:
“`
#include
#include
#include
#include
int mn(void)
{
int fd;
if((fd = open(“dev/ttyS0”, O_RDWR | O_NONBLOCK))
{
perror(“open fled”);
return -1;
}
struct termios opt;
tcgetattr (fd, &opt);
cfsetispeed (&opt, B115200);
cfsetospeed (&opt, B115200);
opt.c_cflag |= CLOCAL;
opt.c_cflag |= CREAD;
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8;
opt.c_cflag &= ~PARENB;
opt.c_cflag &= ~CSTOPB;
tcsetattr (fd, TCSANOW, &opt);
sleep(5);
char buf[1024] ={0};
int len = 0, total = 0;
while(1)
{
len = read(fd,buf,total + 1024);
if(len > 0)
{
total += len;
printf(“read total %d data is %s”, total, buf);
fflush(stdout);
}
else
printf(“no data to read\n”);
usleep(100);
}
tcflush (fd, TCIOFLUSH);
close (fd);
return 0;
}
“`
四、
相關(guān)問題拓展閱讀:
- LINUX控制臺怎么定向到串口終端
- linux串口讀取問題
LINUX控制臺怎么定向到串口終端
利用串口終端作為Linux控制臺,可以免去額外的鍵盤,顯示卡和顯示器,同時(shí)可將Linux主機(jī)作為一個任意用途的嵌入式黑匣。那么LINUX控制臺怎么定向到串口終端?下面跟著學(xué)習(xí)啦小編一起來了解一下吧。
LINUX控制臺怎么定向到串口終端
目的: 臺機(jī)已經(jīng)裝好Linux,顯示器有問題,平時(shí)一般都SSH控制,當(dāng)Linux網(wǎng)絡(luò)掛的時(shí)候,想通過串口來管理。
硬件:臺機(jī)自帶兩個串口(上面的是COM1) or ttyS0
目標(biāo)機(jī)器:安裝的CentOS 5.2 Linux 內(nèi)核2.6.18-92.1.22.el5和2.6.18-92.1.22.el5xen
客戶端: Windows XP SP3 IBM OEM. 安裝USB轉(zhuǎn)串口驅(qū)動。
需要把輸出定向到串口,一般有下面幾處:
BIOS中的設(shè)置
GRUB設(shè)置
/etc/inittab 設(shè)置
/etc/securetty 設(shè)置
BIOS中的設(shè)置
BIOS設(shè)置的作用我沒嘗試過,如果是可以連BIOS設(shè)置都可以定向到串口,那個強(qiáng)大了。也不知道如何去掉機(jī)器需要連鍵盤的限制。沒拿出顯示器所以沒看我臺機(jī)的BIOS,不過這個功能一般只有服務(wù)器級數(shù)帶猜別的機(jī)器有。【注1】臺機(jī)一般沒有串口重定向功能。
GRUB設(shè)置
這里的配置是為了把grub菜單定薯型向到串口,這樣你就可以在串口操作grub,選擇啟動項(xiàng),使用single mode等等。
同時(shí)也要給kernel參數(shù)加上console選項(xiàng)。
# cat /boot/grub/menu.lst
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/vg00/lv_root
# initrd /initrd-version.img
#boot=/dev/hdb1
serial –unit=0 –speed=word=8 –parity=no –stop=1
terminal –timeout=10 serial console
default=2
timeout=20
行皮#splashimage=(hd0,0)/grub/splash.xpm.gz =>這些在console下會工作不正常,注釋掉。
#hiddenmenu
title CentOS (2.6.18-92.1.22.el5)
root (hd0,0)
kernel /vmlinuz-2.6.18-92.1.22.el5 ro root=/dev/vg00/lv_root rhgb quiet
initrd /initrd-2.6.18-92.1.22.el5.img
title CentOS Serial – Console (2.6.18-92.1.22.el5)
root (hd0,0)
kernel /vmlinuz-2.6.18-92.1.22.el5 ro root=/dev/vg00/lv_root console=ttyS0,9600 console=tty0
initrd /initrd-2.6.18-92.1.22.el5.img
title CentOS Console – serial (2.6.18-92.1.22.el5)
root (hd0,0)
kernel /vmlinuz-2.6.18-92.1.22.el5 ro root=/dev/vg00/lv_root console=tty0 console=ttyS0,9600
initrd /initrd-2.6.18-92.1.22.el5.img
title CentOS Xen (2.6.18-92.1.22.el5xen)
root (hd0,0)
kernel /xen.gz-2.6.18-92.1.22.el5
module /vmlinuz-2.6.18-92.1.22.el5xen ro root=/dev/vg00/lv_root rhgb quiet xencons=off
module /initrd-2.6.18-92.1.22.el5xen.img
title CentOS Xen Serial – Console (2.6.18-92.1.22.el5xen)
root (hd0,0)
kernel /xen.gz-2.6.18-92.1.22.el5
module /vmlinuz-2.6.18-92.1.22.el5xen ro root=/dev/vg00/lv_root xencons=off console=ttyS0,9600 console=tty0
module /initrd-2.6.18-92.1.22.el5xen.img
title CentOS Xen Console – serial (2.6.18-92.1.22.el5xen)
root (hd0,0)
kernel /xen.gz-2.6.18-92.1.22.el5
module /vmlinuz-2.6.18-92.1.22.el5xen ro root=/dev/vg00/lv_root xencons=off console=tty0 console=ttyS0,9600
module /initrd-2.6.18-92.1.22.el5xen.img
title Other
rootnoverify (hd0,0)
chainloader +1
后面的console有順序關(guān)系,詳見下文【注2】,我常用串口所以console=tty0 console=ttyS0,9600這個順序的輸出信息比較多。
因?yàn)槲业臋C(jī)器有xen的內(nèi)核,xen默認(rèn)情況下會把串口做為xencons,所以這里設(shè)置xencons=off.
When multiple consoles are listed output is sent to all consoles and input is taken from the last listed console. The last console is the one Linux uses as the /dev/consoledevice.
/etc/inittab 設(shè)置
系統(tǒng)系統(tǒng)后,需要在串口上監(jiān)聽請求,所以要有個類似服務(wù)器的程序(agetty, mgetty etc)。
/etc/inittab中添加
s0:2345:respawn:/in/agetty -L -f /etc/issue.serial 9600 ttyS0 vt100
#s1:2345:respawn:/in/agetty -L -f /etc/issue.serial 9600 ttyS1 vt100
#S0:2345:respawn:/in/mgetty -r -x 9 ttyS0 ==> mgetty 用來調(diào)試比較好,log也豐富。
What is a getty?
A getty is is a program that opens a tty port, prompts for a login name, and runs the /bin/login command. It is normally invoked by init.
所以其他程序就不能再來占用ttyS0了,串口是獨(dú)占模式的吧。
vt100:
vt100 is the terminal emulation. You can use others, but VT100 is the most common or “standard”. Another widely used termial type is VT102.
OK都可以了,可以重啟server了。這里如果想測試下串口線,推薦先在Linux啟動下mgetty,因?yàn)樗膁ebug信息和log比較豐富,適合排錯和測試。
#mgetty –r –x 9 ttyS0
Log在/var/log/mgetty*中。
/etc/securetty設(shè)置
因?yàn)橐话阄覀兌际鞘褂胷oot登陸串口來維護(hù),所以需要設(shè)置root可以在COM1和COM2登陸。
在/etc/securetty中添加:
ttyS0
ttyS1
Windows客戶端連接可以用超級終端或者Putty。
注意啟動server的時(shí)候,putty就應(yīng)該去連接串口了,這樣才可以看到所有信息。
本來正常情況下,接下去kernel的boot信息應(yīng)該也會打到串口的。但是沒有,確定是Xen內(nèi)核的關(guān)系。
系統(tǒng)啟動起來后,過了init,agetty就起來了,這個時(shí)候就可以通過串口登陸了。(在/etc/securetty中需要添加ttyS0)
linux串口讀取問題
首先你確定你那串口是否有東西可讀? 就是你上面說的“一個文件不停的寫數(shù)據(jù)到串口”!你可以先不這樣讀取,你可以在終端巧陵上用cat試試是否有數(shù)據(jù)可讀:cat /dev/ttyS0
如果有的話,那你就檢查串口設(shè)置是否正確,如波特率,數(shù)據(jù)位,停止位,校驗(yàn)位等!
最后就是你讀取的函數(shù)了,看看先不要用printf打印字符串了,孝前戚先看看十六進(jìn)制是否有,然后再看字符等!
就是以上一些,你還可以參考Linux下串口文檔,百度上很多的……悔御
取設(shè)備描述符)的時(shí)候州猛瞎設(shè)置的是非阻塞方式。導(dǎo)致串口上沒數(shù)據(jù)的時(shí)候read也立即返回,但是你的while已經(jīng)把有效的數(shù)據(jù)讀走了,if里面讀到的一定是空的,所以什么也不打印。
建議
1. 在打開串口設(shè)備時(shí)使用阻知辯塞方式,不會冊空設(shè)置的話查查open系統(tǒng)調(diào)用的幫助,它有個flag;
2. 把while循環(huán)內(nèi)的if語句去掉。
另外,團(tuán)IDC網(wǎng)上有許多產(chǎn)品團(tuán)購,便宜有口碑
你串口有數(shù)據(jù)給讀嗎?
串口接了什么設(shè)備?
linux 串口獨(dú)占打開的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux 串口獨(dú)占打開,Linux串口獨(dú)占打開技巧:順利實(shí)現(xiàn)設(shè)備連接,LINUX控制臺怎么定向到串口終端,linux串口讀取問題的信息別忘了在本站進(jìn)行查找喔。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
文章題目:Linux串口獨(dú)占打開技巧:順利實(shí)現(xiàn)設(shè)備連接(linux串口獨(dú)占打開)
新聞來源:http://www.dlmjj.cn/article/dhogjcj.html


咨詢
建站咨詢
