Linux上的脉冲计数器(我们从VK-G4计数器获得有关气流的信息)

家庭自动化过程中发现可用的VK-G4气体流量计具有一个有趣的功能:在初级放电装置中内置了一块磁铁,可以关闭安装在设备本身外部的簧片开关(即无需连接它即可)。煤气公司)。这甚至在柜台本身护照也有说明。没错,建议您使用“ IN-Z 61低频脉冲发生器”,但实际上,它只是安装在仪表上的磁簧开关,价格高昂。因此,决定使用最便宜的具有数字输出(即集成了施密特触发器)的霍尔传感器,而不是IN-Z 61。

从市场上购买了SS441A型霍尔传感器。根据SS44xA上数据表,第三位数字对其磁敏感度进行编码,从而确定传感器在燃气表上的物理位置。
作为控制系统,我使用运行Linux(香草内核4.2+)的单板Banana PI计算机。 SS44xA的物理连接非常简单:我们
将输出(-)连接到公共电线;
输出(+)连接到+ 5V(而不是+ 3.3V);
引脚(D)连接到GPIO端口,并通过4.7kΩ电阻拉至+ 3.3V。
但是,当我找不到可以仅计算给定GPIO端口上脉冲数的内核树内驱动程序时,我感到惊讶!我了解Linux不是实时操作系统,而只是计数低频脉冲...真的就是我遇到了这样的问题吗?
仔细查看了最新的内核资源后,发现了两个中间解决方案:
  1. 使用标准的UIO驱动程序。如果在应用程序中将这样的设备作为文件打开并写入相应的值,则从该设备进行的后续读取操作将被挂起,直到由于相应的GPIO上的信号电平变化而引起中断为止;
  2. gpio_keys. GPIO «» (button) «» (switch), , .

使用这些解决方案中的任何一个都将需要守护程序应用程序,该应用程序必须处于活动状态才能执行脉冲计数。这不是最佳解决方案,因为如果由于某种原因完成了此操作,我们可以跳过一定数量的脉冲,这对于记账目的非常关键。因此,为了最小化风险,决定编写我们自己的设备驱动程序,该设备驱动程序可以直接在内核级别运行。
因此,满足:一个驱动程序,可使用设备树技术配置任意GPIO线上的脉冲计数

前提条件
  • 使用的Linux内核版本4.x或更高版本
  • 用于构建它的内核头文件(通常位于目标系统上的/ usr / include / linux中)
  • -
  • Device Tree
  • Device Tree ( dtc)

对于我的工作,我使用来自Armbian的程序集,并且在他们的网站上,您还可以获取内核资源,并以此为基础编写了程序集。但是,原则上,对目标组件没有任何限制。
我不在这里描述外部模块的组装(以及什么?原则上,有很多这样的描述),因此我们相信您已经为内核组装了现成的counters.ko gpio-pulse.ko模块。我以Banana PI为例描述了进一步的过程,但可以类似地将其转移到任何其他平台。

打开连接器说明板在板上。我们对CON3连接器(GPIO接头)感兴趣。我们选择所需的任何触点并确定其功能(例如,我喜欢连接PH2插座端口的CON3连接器上的引脚12)。我们使用Allwinner A20数据表(GPIO多路复用功能表)进行检查-所选端口应支持中断的生成(在我的情况下,Multi 6列中为EINT2)。接下来,我们需要根据GPIO确定引脚号,该GPIO对应于选定的端口(PH2)。对我而言,直接在工作设备上确定它更容易:

#grep'(PH2)'/sys/kernel/debug/pinctrl/1c20800.pinctrl/pinmux-pins
引脚226(PH2):(MUX UNCLAIMED)(GPIO UNCLAIMED)

同时并确保该端口当前未被任何东西使用(MUX和GPIO UNCLAIMED)。

现在,您可以创建设备树配置。Linux内核的源代码在arch / arm / boot / dts文件夹中,提供了一些设备的示例,对于Banana,PI文件称为sun7i-a20-bananapi.dts,
在其中进行了以下更改:
/ {
        model = "Banana Pi BPI-M1";
        compatible = "sinovoip,bpi-m1", "allwinner,sun7i-a20";

...

        counters {
                compatible = "gpio-pulse-counter";
                gas-meter@0 {
                    label = "Gas meter";
                    pinctrl-names = "default";
                    pinctrl-0 = <&ext_counter_bananapi>;
                    /* CON3, pin 12: PH2 - pin 226 (Multi6 function: EINT2) */
                    /* bank: 226 / 32 = 7, pin into the bank 226 % 32 = 2 */
                    gpios = <&pio 7 2 GPIO_ACTIVE_LOW>;
                    interrupt-parent = <&pio>;
                    interrupt-names = "counter-edge-falling";
                    interrupts = <2 IRQ_TYPE_EDGE_FALLING>; /* PH2 / EINT2 */
                };
        };

&pio {
        ...

        /* External counter */
        ext_counter_bananapi: counter_pins@0 {
                allwinner,pins = "PH2";
                allwinner,function = "gpio_in";
                allwinner,drive = <SUN4I_PINCTRL_10_MA>;
                allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
        };
};


节点中的gpios参数计算如下:
  • 首先是指向pio标签的链接;
  • 接下来是存储库编号,其中包含所需的GPIO端口。对于Allwinner A20,每个存储区包含32个端口,因此存储区号定义为GPIO引脚除以32的整数部分;
  • 接下来是银行内的密码。因为 每个存储体有32个引脚,则该值计算为GPIO引脚除以32的余数;
  • 最后一个参数指示哪个信号电平被认为是活动的

节点中的interrupts参数计算如下:
  • 第一个参数指示GPIO控制器的中断号(对于EINT2,它将为2)
  • 第二个参数是IRQ_TYPE_EDGE_FALLING,它允许在信号从高电平变为低电平时生成中断(因为我们有一个集电极开路传感器并拉至+ VCC)

我们编译修改后的设备树文件:
dtc -I dts -O dtb sun7i-a20-bananapi.dts > sun7i-a20-bananapi.dtb

使用生成的sun7i-a20-bananapi.dtb,我们覆盖/boot/dtb/sun7i-a20-bananapi.dtb中的文件。将
内核模块counters.ko gpio-pulse.ko 写入/ lib / modules / $(uname -r)/内核/驱动程序并加载目标系统。在加载的目标系统上,我们给出命令
depmod -a

然后重新启动。之后,我们看一下dmesg命令的输出:
# dmesg
...
[    4.745570] counters: Class driver loaded.
[    4.749235] gpio_pulse: Device #0 gas-meter: IRQ: 53 GPIO: 226
...

太好了,模块已加载且正常运行。我们首先以编程方式检查功能:
# cat /sys/class/counters/counter0/values/count
0
# echo 1 > /sys/class/counters/counter0/values/pulse
# cat /sys/class/counters/counter0/values/count
1
# echo 1 > /sys/class/counters/counter0/values/pulse
# echo 1 > /sys/class/counters/counter0/values/pulse
# cat /sys/class/counters/counter0/values/count
3

(我们通过软件模仿了一个信号)。

现在,我们连接霍尔传感器,并通过在其上放一些磁铁(例如,从冰箱上的磁性标签上)确保其可操作性。

后记


最后,我有时间发布图片。所以:

实际上是传感器。它的敏感部分是没有斜角的那一侧(也就是说,我们将其按最小的放电压力压到仪表上)。


然后我们用电工胶带固定传感器。


为获得强度,将一块泡沫切入燃气表中以适应凹槽的大小,然后将传感器固定到其上。

然后我们用电工胶带将其和电线固定


好。这就是结果。


对于紧固件的决定,请不要踢脚,因为 房屋仍在维修和固定中,实际上是一个原型。

Source: https://habr.com/ru/post/zh-CN386647/


All Articles