簡體   English   中英

在輸入中以固定數據無阻塞讀取

[英]Non blocking read with fixed data in input

我想使用串行端口與另一台設備txdev通信,問題是txdev正在異步發送數據,並且我不希望read函數阻塞,好消息是txdev正在發送固定大小的數據,但我沒有知道如何使用此技巧。 我在做什么是以下內容:

fd = open(DEVICE_NAME, O_RDWR | O_NOCTTY);
bzero(&termios_p, sizeof(termios_p));
termios_p.c_cflag = CS8|CSTOPB|CLOCAL|CREAD;
termios_p.c_iflag = IGNPAR;
termios_p.c_oflag  = 0;
termios_p.c_lflag = ~ICANON;
termios_p.c_cc[VMIN]=DATA_LENGTH;
termios_p.c_cc[VTIME]=10;

cfsetispeed(&termios_p, BAUDRATE);
cfsetospeed(&termios_p, BAUDRATE);  

tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&termios_p);

這篇文章中,我無法理解這會導致讀取被阻止,VTIME = 0也被阻止。

任何人都可以幫助我找出解決方案,我認為我必須使用中斷處理程序而不是read ,您是否同意?

第二個問題:由於發送方無法與接收方同步,因此有一個中斷處理程序將接收到的數據存儲在指定的緩沖區中(我不理解這是規范模式的情況,而非非規范模式的情況)或僅這樣做當達到read功能時,如果我錯了,請糾正我

和往常一樣,非常感謝。

我想使用串行端口與另一台設備txdev通信,問題是txdev正在異步發送數據,我不希望read函數阻塞,

您似乎誤解了Linux應用程序應如何讀取和寫入串行端口。 所有數據都在程序和UART之間進行緩沖。 您的程序不必總是准備就緒即可讀取數據,因為它們是脫機的。 OS(特別是UART設備驅動程序和tty子系統,其中包括行規程)可以做到這一點,並為程序緩沖數據。

根據定義,RS-232是異步通信鏈路。 字符/字節可以隨時傳輸。 消息包將在任何時間到達,因此應用程序將必須等待組成消息包的字節。 使用阻塞讀取就是這種情況。

接收串行數據的典型問題是如何對接收到的數據執行詞法掃描以識別完整的消息包。 文本消息(規范模式)僅使用ASCII行控制字符來分隔消息/行。 即使是固定長度的數據包也需要驗證(以確保消息實際上從正確的字節開始)。 請參閱此示例掃描固定長度的數據包

我認為我必須使用中斷處理程序而非讀取,您是否同意?

不,UART設備驅動程序已經在處理其中斷(或使用DMA)以捕獲從串行鏈路接收到的每個字節。

由於發送方無法與接收方同步,因此有一個中斷處理程序將接收到的數據存儲在指定的緩沖區上(我無法理解這是規范模式的情況,但不是非規范模式),或者僅在讀取功能時才這樣做到達了,

接收端的串行端口無需與字節級別的發送串行端口“同步”。 RS-232是異步通信鏈接:發送方可以/將隨時發送字符/字節,並且另一端必須准備好在設備驅動程序級別接收它(除非有硬件或軟件流控制)。 (而不是應用程序)。

操作系統始終緩沖接收到的數據。 應用程序的read() syscall只是從系統緩沖區到用戶緩沖區的復制操作。 此復制操作適用於規范和非規范模式。

“同步”通常是協議要在消息或數據包級別解決的問題。 主從是定義串行鏈接協議的常用配置。 主機發送查詢消息給從機。 從站必須始終准備好接收查詢。 從屬方可以用事務請求或數據捕獲或其他任何內容進行響應,或者可以通過NAK消息進行響應,以指示主控方沒有任何內容。 該請求-響應對話框旨在控制或調整兩個單元之間的數據流(和處理負載)。

附錄

我打算做的實際上是無限循環中的阻塞讀取(VTIME = 0 VMIN = DATA_LENGTH)

大概您將始終在發送設備之前啟動程序,以使第一個發送的DATA_LENGTH與程序的第一個讀取對齊。

在理想或受監視的情況下,這可能大部分時間都有效。
但是對於工業24/7應用程序,丟失消息幀對齊的可能性確實存在(例如,發送設備在傳輸過程中重新啟動),因此沒有有效手段來驗證和重新獲得消息幀對齊的方案是不夠的。

IOW串行端口的原始read()可能不會在緩沖區中返回對齊的消息(即buf [0]可能不包含消息的第一個字節)。
典型的termios配置是一個較小的VMIN(非零VTIME),它是基於在每個消息之后串行鏈接處於空閑狀態(短間隔)的前提。
但是該代碼應該健壯,以處理讀取時的所有/所有消息片段。 因此,可能需要多個read()來重構整個消息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM