十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
在嵌入式開發(fā)或者物聯(lián)網(wǎng)領(lǐng)域中,常常需要使用串口進(jìn)行設(shè)備間的通信。Linux操作系統(tǒng)中提供了多種讀取串口數(shù)據(jù)的方法,其中最常用的是使用串口讀取函數(shù)來讀取串口數(shù)據(jù)。然而,使用這種方式讀取數(shù)據(jù)并不是更好的選擇,因為當(dāng)讀取時間過長時,程序會被阻塞,導(dǎo)致程序失去響應(yīng)。

成都創(chuàng)新互聯(lián)長期為近千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為巴楚企業(yè)提供專業(yè)的網(wǎng)站設(shè)計制作、成都網(wǎng)站建設(shè),巴楚網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
針對這個問題,Linux提供了一種名為poll()函數(shù)的機(jī)制,該函數(shù)可以異步地讀取串口數(shù)據(jù),并且不會導(dǎo)致程序阻塞。本文將介紹如何使用poll()函數(shù)來讀取串口數(shù)據(jù)。
一、串口的打開和設(shè)置
在使用poll()函數(shù)之前,需要完成對串口的打開,并對串口進(jìn)行必要的設(shè)置。下面是打開和設(shè)置串口的相關(guān)代碼實現(xiàn):
“`
#include
#include
#include
#include
#include
#define SERIAL_DEVICE “/dev/ttyUSB0”
#define BAUD_RATE B115200
int serial_fd;
int open_serial_device(const char *device_name, baudrate_t baudrate)
{
int fd = open(device_name, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd
perror(“open()”);
return -1;
}
struct termios options;
tcgetattr(fd, &options);
cfmakeraw(&options);
cfsetispeed(&options, baudrate);
cfsetospeed(&options, baudrate);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
tcsetattr(fd, TCSANOW, &options);
return fd;
}
“`
其中,SERIAL_DEVICE指定了串口的設(shè)備路徑,BAUD_RATE指定了波特率。在打開串口后,需要對串口進(jìn)行必要的設(shè)置,主要包括設(shè)置波特率、數(shù)據(jù)位、校驗位和停止位等參數(shù)。
二、使用poll()函數(shù)讀取串口數(shù)據(jù)
完成串口的打開和設(shè)置后,下一步就是使用poll()函數(shù)來異步地讀取串口數(shù)據(jù)。下面是對poll()函數(shù)的介紹:
“`
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
“`
poll()函數(shù)用來監(jiān)聽文件描述符的變化,可以監(jiān)聽不同的事件類型,包括讀、寫、異常等事件。其中,參數(shù)fds是一個結(jié)構(gòu)體指針數(shù)組,用來存放要監(jiān)聽的文件描述符;參數(shù)nfds表示fds數(shù)組中的元素個數(shù);參數(shù)timeout表示poll()函數(shù)的超時時間,單位為毫秒。如果timeout為-1,表示永遠(yuǎn)等待事件的發(fā)生。
下面是使用poll()函數(shù)讀取串口數(shù)據(jù)的相關(guān)代碼:
“`
#include
#include
#define READ_BUFFER_SIZE 256
int poll_file_descriptor(int serial_fd) {
struct pollfd fds[1];
int ret;
char read_buffer[READ_BUFFER_SIZE];
int read_length;
fds[0].fd = serial_fd;
fds[0].events = POLLIN;
while (1) {
ret = poll(fds, 1, -1);
if (ret
return -1;
if (fds[0].revents & POLLIN) {
read_length = read(serial_fd, read_buffer, READ_BUFFER_SIZE);
if (read_length
perror(“read()”);
return -1;
}
printf(“Read %d bytes from serial\n”, read_length);
}
}
}
“`
其中,使用poll()函數(shù)實現(xiàn)串口數(shù)據(jù)的讀取主要包括步驟:
1. 創(chuàng)建一個poll()結(jié)構(gòu)體數(shù)組,設(shè)定要監(jiān)聽的文件描述符和事件類型;
2. 使用poll()函數(shù)監(jiān)聽文件描述符的變化,讀取事件發(fā)生時,進(jìn)行數(shù)據(jù)的讀取和處理;
在本實現(xiàn)中,創(chuàng)建一個fd_struct結(jié)構(gòu)體,fd屬性表示要監(jiān)聽的文件描述符,events屬性表示監(jiān)聽的事件類型。
三、測試結(jié)果
使用上述代碼編譯生成可執(zhí)行文件,并執(zhí)行該文件,可以監(jiān)聽串口數(shù)據(jù)的變化,并對讀取的數(shù)據(jù)進(jìn)行處理和輸出。下面是一個測試結(jié)果的示例:
“`
Read 50 bytes from serial
Read 48 bytes from serial
Read 51 bytes from serial
Read 40 bytes from serial
“`
可以看到,使用poll()函數(shù)讀取串口數(shù)據(jù)可以實現(xiàn)異步讀取,不會導(dǎo)致程序阻塞,可以提高設(shè)備間通信的效率和穩(wěn)定性。
結(jié)論
相關(guān)問題拓展閱讀:
linux通過內(nèi)核訪問硬件,一般不允許直接訪問硬件,除非你編寫的是驅(qū)動程序。驅(qū)動程序帶沒型必須是內(nèi)核模塊類的,直接掛載在內(nèi)核的鉤子(hook)上,有特殊的編寫規(guī)則。
如蠢猜何通過內(nèi)核模塊訪問串口,要include kernel.h,里面有相應(yīng)接口函數(shù)察團(tuán)。
關(guān)于linux用poll讀取串口的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guā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è)提供云主機(jī)、虛擬主機(jī)、域名注冊、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。