更改 gpio 值时通知
Notify when gpio value is changed
我目前正在尝试仅使用 shell 脚本轮询 gpio 值。
我基本上是在使用/sys/class/gpio/gpioxx/value
之前用测试文件开发了脚本
这是我找到的解决方案:
#!/bin/bash
SCRIPT_DIR=$(dirname $(readlink -f [=10=]))
FILE_NAME=$SCRIPT_DIR"/fileTest"
while true
do
inotifywait -qq -e modify $FILE_NAME
read val < $FILE_NAME
echo $val
### do something here ###
done
这是在使用基本文件,但我在使用此解决方案时遇到两个问题。
1 - "modify" 事件在保存文件时触发,而不是在文件内容更改时触发。因此,如果我在文件中写入相同的值,事件就会被触发,但它不应该被触发。
2 - 我说这个解决方案不适用于 gpios,如果我使用一个简单的 ascii 文件它可以工作但是当我在 /sys/class/gpio/gpioxx/value 上使用 inotifywait 时它取决于。
如果我使用回声值 > /sys/class/gpio/gpioxx/value,则检测到事件,但如果我将引脚配置为输入并将其连接到 3v3 或 0V,则不会触发任何事件。
有人知道我如何仅使用脚本来触发此更改吗?
这是一个紧密循环的解决方案(占用更多资源),但如果您没有更好的办法,也可以解决问题:
gpio_value=$(cat /sys/class/gpio/gpio82/value)
while true; do
value=$(cat /sys/class/gpio/gpio82/value)
if [[ $gpio_value != $value ]]; then
gpio_value=$value
echo "$(date +'%T.%N') value changed to $gpio_value"
fi
done
示例输出:
13:09:52.527811324 value changed to 1
13:09:52.775153524 value changed to 0
13:09:55.439330380 value changed to 1
13:09:55.711569164 value changed to 0
13:09:56.211028463 value changed to 1
13:09:57.082968491 value changed to 0
我将它用于调试目的。
其实我平时用这个单线比较多:
printf " Press any key to stop...\n GPIO value: " ; until $(read -r -t 0 -n 1 -s key); do printf "3[2D$(cat /sys/class/gpio/gpio82/value) " ; done ; echo
同样,出于调试目的。
来自linux/Documentation/gpio/gpio-legacy.txt
:
"/sys/class/gpio/gpioN/edge"
... reads as either "none", "rising", "falling", or
"both". Write these strings to select the signal edge(s)
that will make poll(2) on the "value" file return.
所以你可以这样做:
echo input > /sys/class/gpio/gpioN/direction
echo both > /sys/class/gpio/gpioN/edge
现在,您必须找到在 /sys/class/gpio/gpioN/value
上调用 poll
(或 pselect
)的命令。 (如果我找到一个,我会更新我的答案)
您可以使用 libgpiod,它提供了一些有用的工具来监控 GPIO。但是,您需要使用 Linux 4.8.
中提供的新 GPIO API
我目前正在尝试仅使用 shell 脚本轮询 gpio 值。
我基本上是在使用/sys/class/gpio/gpioxx/value
之前用测试文件开发了脚本这是我找到的解决方案:
#!/bin/bash
SCRIPT_DIR=$(dirname $(readlink -f [=10=]))
FILE_NAME=$SCRIPT_DIR"/fileTest"
while true
do
inotifywait -qq -e modify $FILE_NAME
read val < $FILE_NAME
echo $val
### do something here ###
done
这是在使用基本文件,但我在使用此解决方案时遇到两个问题。
1 - "modify" 事件在保存文件时触发,而不是在文件内容更改时触发。因此,如果我在文件中写入相同的值,事件就会被触发,但它不应该被触发。
2 - 我说这个解决方案不适用于 gpios,如果我使用一个简单的 ascii 文件它可以工作但是当我在 /sys/class/gpio/gpioxx/value 上使用 inotifywait 时它取决于。
如果我使用回声值 > /sys/class/gpio/gpioxx/value,则检测到事件,但如果我将引脚配置为输入并将其连接到 3v3 或 0V,则不会触发任何事件。
有人知道我如何仅使用脚本来触发此更改吗?
这是一个紧密循环的解决方案(占用更多资源),但如果您没有更好的办法,也可以解决问题:
gpio_value=$(cat /sys/class/gpio/gpio82/value)
while true; do
value=$(cat /sys/class/gpio/gpio82/value)
if [[ $gpio_value != $value ]]; then
gpio_value=$value
echo "$(date +'%T.%N') value changed to $gpio_value"
fi
done
示例输出:
13:09:52.527811324 value changed to 1
13:09:52.775153524 value changed to 0
13:09:55.439330380 value changed to 1
13:09:55.711569164 value changed to 0
13:09:56.211028463 value changed to 1
13:09:57.082968491 value changed to 0
我将它用于调试目的。
其实我平时用这个单线比较多:
printf " Press any key to stop...\n GPIO value: " ; until $(read -r -t 0 -n 1 -s key); do printf "3[2D$(cat /sys/class/gpio/gpio82/value) " ; done ; echo
同样,出于调试目的。
来自linux/Documentation/gpio/gpio-legacy.txt
:
"/sys/class/gpio/gpioN/edge"
... reads as either "none", "rising", "falling", or
"both". Write these strings to select the signal edge(s)
that will make poll(2) on the "value" file return.
所以你可以这样做:
echo input > /sys/class/gpio/gpioN/direction
echo both > /sys/class/gpio/gpioN/edge
现在,您必须找到在 /sys/class/gpio/gpioN/value
上调用 poll
(或 pselect
)的命令。 (如果我找到一个,我会更新我的答案)
您可以使用 libgpiod,它提供了一些有用的工具来监控 GPIO。但是,您需要使用 Linux 4.8.
中提供的新 GPIO API