繁体   English   中英

在Linux AUART内核驱动程序中,如何使用I2C GPIO扩展器的引脚而不是RTS来控制RS485方向?

[英]How to use I2C GPIO expander's pin instead of RTS to control the RS485 direction, in Linux AUART kernel driver?

我正在基于NXP(Freescale)的i.MX287处理器创建一个嵌入式系统。 我正在使用一个通过迷你PCIe连接器连接到我的评估板上的核心处理板。

UART 0、3、4用作RS232,而UART 1,2用作RS485。 核心板不在其引脚上提供RTS信号,因此我必须使用I2C GPIO扩展器中的引脚来控制RS485方向。 GPIO扩展器模块还用于控制板上的其他一些设备。

在用户空间中,我可以使用libi2c控制方向针,但是我的客户要求我将方向针控制放在UART驱动程序中。

问题:

1-如何与auart驱动程序中的i2c设备进行交互? (可能吗)

2-如果可能,那么如何防止i2c-0总线被​​内核阻塞? (我还需要对libi2c的userspace调用才能正常工作)

我在Google上搜索了很多,但是大多数情况是关于如何使用I2C驱动程序或如何在sysfs中激活GPIO引脚的,我能够做到所有这些。

libi2c用于用户空间,所以我不能在这里调用它。 我也知道在内核中打开文件(/ dev / i2c-0)并对其进行读写不是一个好主意。 我试图了解什么是处理此问题的最佳方法,而又不会引起任何并发访问问题。

我将不胜感激

PS-

编辑1:根据@ 0andriy的建议,我编辑了DTS文件,并将以下内容添加到/arch/arm/boot/dts/my_dts_file.dts

/dts-v1/;
#include "imx28.dtsi"

/ {

// some definitions

apbx@80040000 {    
    i2c0: i2c@80058000 {
        pca8575: gpio@20 {
            compatible = "nxp,pca8575";
            reg = <0x20>;   // PCA8575PW Address -0-0-0
            gpio-controller;
            #gpio-cells = <2>;
        };
    };

    auart1: serial@8006c000 {
        pinctrl-names = "default";
        pinctrl-0 = <&auart1_2pins_a>;
        linux,rs485-enabled-at-boot-time;
        rs485-rts-delay = <0 0>;        // in milliseconds
        rts-gpios = <&pca8575 4 GPIO_ACTIVE_LOW>;
        rs485-rts-active-low;
        status = "okay";
    };

    auart2: serial@8006e000 {
        pinctrl-names = "default";
        pinctrl-0 = <&auart2_2pins_b>;
        linux,rs485-enabled-at-boot-time;
        rs485-rts-delay = <0 0>;        // in milliseconds
        rts-gpios = <&pca8575 5 GPIO_ACTIVE_LOW>;
        rs485-rts-active-low;
        status = "okay";
    };
};

// some definitions
};

然后重建内核。 我还编辑了mxs_auart_init_gpios -auart.c驱动程序中的mxs_auart_init_gpios函数,以在启动时打印所有auart GPIO的引脚说明。 但是gpiod = mctrl_gpio_to_gpiod(s->gpios, i)始终为NULL。 未在/sys/class/gpio/下添加pca8575 GPIO控制器

root# ls /sys/class/gpio
export       gpiochip128  gpiochip64   unexport
gpiochip0    gpiochip32   gpiochip96

编辑2:

来自imx28.dtsi文件的auart1_2pins_aauart2_2pins_b

auart2_2pins_b: auart2-2pins@1 {
reg = <1>;
fsl,pinmux-ids = <
        MX28_PAD_AUART2_RX__AUART2_RX
        MX28_PAD_AUART2_TX__AUART2_TX
    >;
    fsl,drive-strength = <MXS_DRIVE_4mA>;
    fsl,voltage = <MXS_VOLTAGE_HIGH>;
    fsl,pull-up = <MXS_PULL_DISABLE>;
};

auart1_2pins_a: auart1-2pins@0 {
    reg = <0>;
    fsl,pinmux-ids = <
            MX28_PAD_AUART1_RX__AUART1_RX
            MX28_PAD_AUART1_TX__AUART1_TX
        >;
    fsl,drive-strength = <MXS_DRIVE_4mA>;
    fsl,voltage = <MXS_VOLTAGE_HIGH>;
    fsl,pull-up = <MXS_PULL_DISABLE>;
};

我正在使用内核4.14.13

下图演示了我要实现的目标: 在此处输入图片说明

我对您的董事会完全不熟悉,因此请稍作调整,但我注意到您的文件中有一些有趣的事情。

首先,您需要定义要用于在UART pinmux内部切换方向的I2C引脚:

auart2_2pins_b: auart2-2pins@1 {
reg = <1>;
fsl,pinmux-ids = <
        MX28_PAD_AUART2_RX__AUART2_RX
        MX28_PAD_AUART2_TX__AUART2_TX
        MX28_PAD_I2C0_SCL__I2C0_SCL
    >;
    fsl,drive-strength = <MXS_DRIVE_4mA>;
    fsl,voltage = <MXS_VOLTAGE_HIGH>;
    fsl,pull-up = <MXS_PULL_DISABLE>;
};

确保您仔细检查要使用的引脚名称,但我不确定这是正确的名称。

然后,您似乎缺少了I2C控制器的pinctrl

i2c0: i2c@80058000 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c0_pins_a>;
        status = "okay";

        pca8575: gpio@20 {
            compatible = "nxp,pca8575";
            reg = <0x20>;   // PCA8575PW Address -0-0-0
            gpio-controller;
            #gpio-cells = <2>;
        };
    };

我无法确认您的reg和您的密码,但我假设您是从董事会文档中获取的。 如果没有,请确保找到硬件的可靠来源。

最后,我不确定为什么要使RTS线路为低电平有效,大多数收发器都有DE /〜RE输入,这意味着您需要使线路为高电平来驱动总线。 也许你的司机不一样...

您正在尝试做的事情被证明可以在其他主板上使用,所以我想除非有错误,您应该能够使它工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM