gpt4 book ai didi

c - 在Linux AUART内核驱动中,如何使用I2C GPIO扩展器的管脚代替RTS来控制RS485方向?

转载 作者:行者123 更新时间:2023-12-04 12:27:47 24 4
gpt4 key购买 nike

我正在创建一个基于 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 驱动程序或如何激活 sysfs 中的 GPIO 引脚,而我能够完成所有这些。

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

我会很感激任何想法

P.S. - 我对 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
};

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

下未添加 pca8575 GPIO Controller
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

下图展示了我正在努力实现的目标: enter image description here

最佳答案

我对你们的董事会一点都不熟悉,所以对这个答案持保留态度,但我注意到你们的文件中有一些有趣的东西。

首先,您需要定义要用于切换 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 Controller 的 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 输入,这意味着你需要让线路处于高电平状态才能驱动总线。也许您的驱动程序不同...

你正在尝试做的事情被记录为适用于其他董事会,所以我想除非有错误,否则你应该能够让它工作。

关于c - 在Linux AUART内核驱动中,如何使用I2C GPIO扩展器的管脚代替RTS来控制RS485方向?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57536768/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com