我需要编写一个可以读写COM端口的批处理脚本(在我的例子中是COM1)。
我知道我可以使用
将数据发送到COM端口echo hello > COM1
我可以使用
读取进入文本文件的数据type COM1 > sample.txt
我希望不断将进入COM端口的数据捕获到文本文件中,并根据刚才在COM端口上读取的数据将命令发送到COM端口。有没有办法在批处理脚本中执行此操作?
在bash脚本中执行此操作会更容易/更好吗?我怎么用bash做的?
修改 我想读的数据是系统启动到UEFI shell的输出。然后,当它到达那里时,输入一些命令并捕获这些命令的输出。然后,启动OS(捕获引导的输出),向Linux shell输入更多命令并捕获它们的输出。它不包含确切数量的字符。
如果bash脚本是唯一的答案,那就没问题。我可以解决这个问题。我目前正在使用cygwin在Windows 7中运行bash版本4.1.10(4)。
答案 0 :(得分:3)
使用批处理脚本来处理一些不同的事情会让我相信批处理脚本和标准的Windows命令行工具无法解决任何问题。从set /P
读取时,COM1
会立即返回,type COM1
之类的内容将逐行复制大块的串行数据。
使用Cygwin bash我好运。这是一个简单的脚本,它接收来自COM1
的行并回送它们。当它收到以“退出”开头的行时退出。您可以使用串行链路另一端的终端仿真器或仅使用echo quit > COM1
等语句对其进行测试。
CR="$(echo -e '\r')"
exec 4<> /dev/com1
cat <&4 | while :
do
IFS="$CR" read -r line
case "$line" in
quit*)
echo "goodbye$CR" >&4
break
;;
*)
echo "recieved line: $line"
echo "recieved line: $line$CR" >&4
;;
esac
done
CR
变量包含回车符,在此示例中用于将其从输入行中剥离并用于在通过串行线输出CR LF时终止行。根据您的BIOS行为的准确程度,您可能需要也可能不需要在自己的脚本中执行此操作。
exec 4<> /dev/com1
行至关重要。这将打开COM端口一次以进行读写。 Windows只允许COM端口打开一次,因此如果不这样做,则无法读取和写入COM端口。 4
表示分配给文件描述符4,exec
语句使其为脚本的其余部分保持打开状态。
cat <&4 |
部分也很重要。不幸的是,在Cygwin bash中似乎存在一个错误,如果文件描述符读取超过行尾,它将尝试倒回文件描述符。这适用于文件,但它不适用于串行端口,因此数据会丢失。要解决此问题,脚本会从管道读取,而bash足够聪明,不会尝试倒回。
设置IFS="$CR"
的原因是如前所述在一行的末尾剥去回车符,并且在读取时不剥离任何东西。 read
命令使用IFS字符串将输入行拆分为单词。您可以使用它来获得优势,并将其设置为不同的值,以便更容易解析BIOS输出。
其余细节非常简单。 -r
的{{1}}选项会导致它不会特别处理read
个字符。根据BIOS期望的行结束类型,您可以使用三种不同的方式编写echo语句:
\
这个脚本没有做的一件事是设置COM端口参数,如波特率和流量控制。这可能最好使用普通echo "Both CR and LF line ending$CR" >&4
echo -n "CR only line ending$CR" >&4
echo "LF only line ending" >&4
命令完成。 Cygwin具有等效的MODE COM1
命令,但它似乎不支持所有参数。
另一个完全不同的选择是使用Expect。如果您发现很难让bash解析并对BIOS的输出作出适当的响应,那么您可以考虑使用它。这种事情就是它的设计目标,尽管如果你还不熟悉TCL,还有一些学习曲线。它可以作为标准的Cygwin包使用。
答案 1 :(得分:0)
从串口读取数据的标准方法是不:
type COM1 > sample.txt
也不:
copy COM1 sample.txt
如果该数据具有标准的EndOfFile标记,就像Ctrl-Z字符一样。
如果该数据以行结尾,以CR + LF或CR字符结尾,那么阅读它们的标准方法是:
set /P "var=" < COM1
如果该数据的不是分隔符,例如CR或CR + LF,那么您必须指定此类数据的确切格式:
编辑:回复评论
使用重定向输入执行set /P
命令时,它不等待数据。在这种情况下,它会立即返回,并且不会更改变量。
我们可能会尝试等待从串口收到的下一个字符,然后执行set /P
命令;这样,set /P
应该正确读取以CR或CR + LF结尾且不包含控制字符的输入行。
这是代码:
set "key="
for /F "delims=" %%K in ('xcopy /W "%~F0" "%~F0" ^< COM1 2^> NUL') do (
if not defined key set "key=%%K"
)
set /P "line=" < COM1
set "line=%key:~-1%%line%"
echo Line read from COM1: "%line%"
尝试并报告结果。对不起,我无法在计算机上尝试从COM1读取输入信息。