Tty

如何讀取 tty 直到 EOT 或 bash 中的其他字元?

  • February 24, 2020

我正在嘗試從微控制器發送和接收一些字元串數據,並在 linux 機器上使用 bash。

此時我的微控制器上的程式碼如下所示:

void UART_help_cmd_handler() 
{
   printf("Available commands:\n");
   printf("search - starts search and returns device addresses\n");
   printf("help - prints this help\n");

   // these characters can't stop cat
   EUSART2_Write(0);
   EUSART2_Write(0x03);
   EUSART2_Write(0x04);
}

這是linux方面:

#!/bin/bash
echo -ne '\x02help\x03' > /dev/ttyUSB0; cat /dev/ttyUSB0;

我也試過:

echo -ne '\x02help\x03' > /dev/ttyUSB0; stdbuf -i 0 -o 0 cat /dev/ttyUSB0

問題是我無法cat從微控制器方面停下來。

我嘗試-1從微控制器發送字元,我嘗試使用 0x03。

嗯,我想通了。為了獲得所需的行為(命令-> uart 和 bash 之間的響應),我寫了這樣的東西:

微控制器端:

void UART_help_cmd_handler() 
{
   // this delay prevents buffer overflow on linux side if bash is too slow
   // see "However" section below
   __delay_ms(100); 


   printf("Available commands:\n");
   printf("search - starts search and returns device addresses\n");
   printf("help - prints this help\n");

   // second newline to mark end of transmission
   // that cat command can read
   printf("\n");  
}

** 重擊端 **

#!/bin/bash

# send-command-read-response.sh

# send command 
# (in my case microcontroller needs 0x02 byte to find start of command 
$ and 0x03 byte for end of command

echo -ne "\x02${1}\x03" > /dev/ttyUSB0;

# read lines one by one until "" (empty line)
file="/dev/ttyUSB0"
terminator=""
while IFS= read line
do
   if [ "$line" = "$terminator" ]; then
       break
   else
       echo "$line"
   fi
done <"$file"

然而:

  • 當微控制器響應很快時 - 有時 bash 無法足夠快地執行“讀取”命令以在硬體 uart 緩衝區滿之前耗盡它,所以我不得不添加臟延遲
  • 如果我可以使用硬體流控制,也許可以解決“快速微控制器響應”問題,但我不確定
  • 我找不到在 bash 中以某種方式處理超時的方法(如果微控制器由於某些原因沒有響應)。

最後

  • 正如@mosvy 在我的問題下的評論中所寫 - bash 不是串列通信的正確工具
  • 如果可以進行硬體流控制,我認為可以在 bash 中處理兩種方式的串列通信。超時可以設置stty,但我認為歸檔這個需要付出太多努力。
  • 我寫了一個簡單的應用程序,它可以處理超時和其他錯誤。

我試圖避免使用 C/C++ 應用程序,因為我需要在一些接受 bash 腳本的大型 Web 應用程序中替換 bash 腳本,但是“不歡迎”額外的二進製文件。

引用自:https://unix.stackexchange.com/questions/569310