Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用I2C GPIO扩展器&x27;在Linux AUART内核驱动程序中,用s引脚代替RTS来控制RS485方向?_C_Kernel Module_Gpio_Uart_I2c - Fatal编程技术网

如何使用I2C GPIO扩展器&x27;在Linux AUART内核驱动程序中,用s引脚代替RTS来控制RS485方向?

如何使用I2C GPIO扩展器&x27;在Linux AUART内核驱动程序中,用s引脚代替RTS来控制RS485方向?,c,kernel-module,gpio,uart,i2c,C,Kernel Module,Gpio,Uart,I2c,我正在创建一个基于NXP(飞思卡尔)I.MX287处理器的嵌入式系统。我使用的是一个核心处理板,它通过一个小型PCIe连接器连接到我的评估板 UART 0,3,4用作RS232,UART 1,2用作RS485。核心板在其引脚中不提供RTS信号,因此我必须使用I2C GPIO扩展器的引脚来控制RS485方向。GPIO扩展器模块还用于控制板上的一些其他设备 在用户空间中,我可以使用libi2c控制方向管脚,但我的客户要求我将方向管脚控制放在UART驱动程序中 问题: 1-如何与auart驱动程序内的

我正在创建一个基于NXP(飞思卡尔)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的用户空间调用才能正常工作)

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

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

如果有任何想法,我将不胜感激

另外,我对Linux内核的工作原理没有深入的了解,如果我的问题有点含糊,我很抱歉

编辑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
};
编辑2:

imx28.dtsi
文件中的
auart1\u 2pins\u a
auart2\u 2pins\u 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>;
};
auart2\u 2pins\u b:auart2-2pins@1 {
reg=;
fsl,pinmux ID=<
MX28_焊盘_AUART2_RX_AUART2_RX
MX28_焊盘_AUART2_TX_AUART2_TX
>;
fsl,驱动力=;
fsl,电压=;
fsl,上拉=;
};
auart1_2pins_a:auart1-2pins@0 {
reg=;
fsl,pinmux ID=<
MX28_焊盘_AUART1_RX_AUART1_RX
MX28_焊盘_AUART1_TX_AUART1_TX
>;
fsl,驱动力=;
fsl,电压=;
fsl,上拉=;
};
我正在使用内核4.14.13

下图显示了我试图实现的目标:

我对你的董事会一点也不熟悉,所以对这个答案有点怀疑,但我注意到你的文件中有一些有趣的东西

首先,您需要定义要用于在UART引脚MUX内切换方向的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>;
};
我无法确认您的
reg
和pin码,但我假设您是从董事会文档中获取的。如果没有,请确保为硬件找到可靠的来源

最后,我不知道为什么要使RTS线路处于低电平活动状态,大多数收发器都有一个DE/~RE输入,这意味着您需要使线路处于高电平活动状态才能驱动总线。也许你的司机不一样


您正在尝试的操作被记录为适用于其他板,因此我想,除非有bug,否则您应该能够使其正常工作。

您不需要太多。GPIO扩展器必须有自己的驱动程序(可能已经有了)。然后在DTS中定义它,并定义串行设备以使用mctrl GPIO(我不记得详细信息,但我相信只要定义了
rts gpios
和/或DTS中的其他行,它就会运行)。@0andriy:谢谢,我不知道DTS文件中有rts gpios选项。我会调查一下,让你知道我是否能找到答案。@0安德烈:我用新的结果更新了我的问题。如果您能听听您的想法,我将不胜感激。您有GPIO扩展器的驱动程序吗?顺便说一句,最好使用
libgpiod
@0andriy使用GPIOs:是的,pcf857x的驱动程序包含在内核源代码树中,我在menuconfig中进行了检查,它被选中进行构建。我可以通过i2c工具命令与芯片通信。我检查了内核引导日志,似乎驱动程序正在加载,但是对于rts-gpios,mctrl\u gpio\u to\u gpiod仍然返回NULL。Marcos G:很抱歉提供了误导性的信息。我的dts实际上包括
imx28.dtsi
文件,其中为I2C控制器定义了
pinctrl
。据我所知,我的dts描述应该在
dtsi
文件中的原始定义中添加一些属性,而不是替换它。对吗?Marcos G:但我仍然不理解将
MX28\u PAD\u I2C0\u SCL\u I2C0\u SCL
添加到uart控制器的pinmux中的部分。该引脚不应直接由uart驱动器控制。i2c控制器应该命令GPIO扩展器模块驱动其连接到RS485方向的引脚是的,我认为您应该包括
imx28.dtsi
,并对您自己的设备文件进行所需的任何更改。我的观点是,dtsi中的I2C部分应至少包括引脚、状态和驱动程序部分(您的部分仅包括驱动程序)。例如,关于UART pinmux,我认为您想要用于切换的pin应该包含在UART pinmux中。看看这个。我不完全确定这是强制性的,但从某种程度上说,参考它是有意义的。看看你在问题中添加的草图,我想我误解了你的意图。。。
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>;
};
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>;
        };
    };