簡體   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