bash 通过shell脚本控制串口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11204860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:36:28  来源:igfitidea点击:

Serial port control through a shell script

bashserial-port

提问by Adriano Carvalho

I am developing an orientation controller. I have a development board which communicates with the sensor (a compass) through I2C. Because the board is pretty limited (no OS), I developed a simple program to receive things like: (1) 'get 0' to read the sensor's register 0; (2) 'set 0 10' to set the sensor's register 0 with the value 10. For each of these cases the board returns: (1) 'Done: 10.' (register 0 has the value 10); (2) 'Done.'; and (3) 'error: ...' in case of error. With this, I am trying to develop a shell script (bash) to send commands and retrieve data in order to understand the sensor and develop the controller.

我正在开发一个方向控制器。我有一个通过 I2C 与传感器(指南针)通信的开发板。因为板子非常有限(没有操作系统),我开发了一个简单的程序来接收以下内容:(1)'get 0' 读取传感器的寄存器 0;(2) 'set 0 10' 将传感器的寄存器 0 设置为值 10。对于这些情况中的每一种,电路板都会返回: (1) 'Done: 10'。(寄存器 0 的值为 10);(2) '完成。'; 和 (3) 'error: ...' 以防出错。有了这个,我正在尝试开发一个 shell 脚本 (bash) 来发送命令和检索数据,以便了解传感器并开发控制器。

My problem is with the following code:

我的问题是以下代码:

# read device output in the background.
head -n 1 /dev/ttyUSB0 &
head=$!

# (#1): without the following stmt I get:
#   head: cannot open `/dev/ttyUSB0' for reading: : Protocol error
sleep 0.1

# send command to the device.
echo "get 0" > /dev/ttyUSB0

# (#2) wait for head.
while kill -0 $head 2>/dev/null ; do : ; done

I guess (#1) is caused by a read/write conflict between 'head' and 'echo', but I don't know why and I have no idea on how to solve it.

我猜(#1)是由“head”和“echo”之间的读/写冲突引起的,但我不知道为什么,也不知道如何解决。

Another issue is in (#2) where I would like to use a timeout. I've tried something like:

另一个问题是在 (#2) 中,我想使用超时。我试过这样的事情:

timeout 1 bash -c "while kill -0 $head 2>/dev/null ; do : ; done"

But I get: Timeout: aborting command ``bash'' with signal 9and the program gets stuck.

但我明白了:Timeout: aborting command ``bash'' with signal 9程序卡住了。

By the way, before the code above is executed I do initialize the serial port with:

顺便说一下,在执行上面的代码之前,我会使用以下命令初始化串行端口:

stty -F /dev/ttyUSB0 9600 cs8 -cstopb

EDIT: I don't want an interactive terminal. I want to use this routine as necessary. This routine is the necessary foundation of the controller (read/write sensor's registers) which later will be implemented in the board.

编辑:我不想要交互式终端。我想在必要时使用这个例程。该例程是控制器(读/写传感器的寄存器)的必要基础,稍后将在板上实现。

回答by Adriano Carvalho

To solve (#1) I modified the routine to use a fd:

为了解决(#1),我修改了例程以使用 fd:

# : the device filename, eg. /dev/ttyS0
# : number of lines to read before exit.

exec 3<>

head -n "" 0<&3 &
wait_pid=$!

cat - 1>&3

wait $wait_pid

exec 3>&-

EDIT: To solve (#2), instead of providing the routine with timeout support I delegate that responsibility to the caller. However, in case of timeout we need to clean up. For that I've added the following after wait_pid=$!:

编辑:为了解决(#2),我没有为例程提供超时支持,而是将该责任委托给调用者。但是,如果超时,我们需要清理。为此,我在之后添加了以下内容wait_pid=$!

trap="if kill -0 $wait_pid ; then kill -TERM $wait_pid ; fi"
trap "$trap" SIGINT SIGKILL SIGTERM