迅为rk3568开发板RS485收发切换 linux485驱动修改

本文详细描述了如何在迅为rk3568开发板上修改RS485驱动以实现收发切换,包括屏蔽原有设备树描述、添加新的串口描述以及在Linux内核驱动文件中集成收发控制功能,以解决实际通信中的延迟问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考链接:

  1. Linux RS485串口驱动修改方法–基于Rockchip及Amlogic验证
  2. linux驱动 内核层适配485驱动控制引脚

起因

迅为rk3568开发板用的SP3485E芯片,需要在应用程序中控制管脚的高低电平实现收发切换。
发送前先拉高电平,然后发送数据,数据发送完成后再拉低电平,使其处于接收状态。

在程序中,485发送数据后,根据波特率和数据长度计算延时时间,但是在实际应用中发现这个时间不太准确,而且不同的485设备,有的收到数据后延时10ms才返回数据,有的收到后是立即返回数据(延时很短)。如果写入后拉低电平的延时时间过长或过短都会导致通信失败。

在网上找了一些教程,将收发切换放到串口驱动程序中,不用在应用程序中控制。因为之前没有具体做过设备树和驱动程序修改,这里记录下过程。

修改过程

因为这里用的板子硬件固定,所以偷懒在驱动程序里直接根据设备树里的控制管脚来判断是否进行管脚的拉高拉低。
主要修改的有两个地方:一是设备树,二是驱动程序
设备树的修改:

1、设备树文件屏蔽原有的描述

迅为开发板默认的设备树里是将收发控制引脚单独加到了设备树文件里,需要先将其屏蔽掉

/* 把这段屏蔽掉
rk_485_ctl: rk-485-ctl {
            compatible = "topeet,rs485_ctl";
            gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
            pinctrl-names = "default";
            pinctrl-0 = <&rk_485_gpio>;
        };
*/

2、添加新的串口描述

&uart7 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&uart7m1_xfer>; // 迅为用的是uart7_m1,根据自己的实际情况修改
    rts-gpio = <&gpio0 22 GPIO_ACTIVE_HIGH>; // 这个就是收发控制引脚,如果自己画的底板,根据实际情况修改
    // rs485-rts-active-low;
    // rs485-rts-delay = <5 100>;
    linux,rs485-enabled-at-boot-time;
};

3、修改驱动文件

迅为开发板用的是8250的串口程序。这里一共需要修改以下3个文件。
/home/topeet/rk356x_linux/kernel/include/uapi/linux/serial.h
/home/topeet/rk356x_linux/kernel/drivers/tty/serial/8250/8250_dw.c
/home/topeet/rk356x_linux/kernel/drivers/tty/serial/8250/8250_port.c

修改serial.h文件

文件serial.h,在结构体serial_rs485的定义中,增加一个rts_gpio的整型变量,用来存储上收发控制引脚的gpio号.

struct serial_rs485 {
    __u32    flags;            /* RS485 feature flags */
#define SER_RS485_ENABLED        (1 << 0)    /* If enabled */
#define SER_RS485_RTS_ON_SEND        (1 << 1)    /* Logical level for
                               RTS pin when
                               sending */
#define SER_RS485_RTS_AFTER_SEND    (1 << 2)    /* Logical level for
                               RTS pin after sent*/
#define SER_RS485_RX_DURING_TX        (1 << 4)
#define SER_RS485_TERMINATE_BUS        (1 << 5)    /* Enable bus
                               termination
                               (if supported) */
    __u32    delay_rts_before_send;    /* Delay before send (milliseconds) */
    __u32    delay_rts_after_send;    /* Delay after send (milliseconds) */
    __u32    padding[5];        /* Memory is cheap, new structs
                       are a royal PITA .. */
    // 2023.11.13 新增
    __u32    rts_gpio; // 2023.11.13 新增
};

#endif /* _UAPI_LINUX_SERIAL_H */

修改8250_dw.c

文件8250_dw.c,一共需要修改2处,一处是增加头文件,一处是获取收发切换的管脚编号。.
1、增加头文件包含

#include <linux/gpio.h>
#include <linux/of_gpio.h>

在这里插入图片描述

2、在static int dw8250_probe()函数里,增加如下代码,用来获取收发控制引脚的编号。

 uart.port.rs485.rts_gpio = of_get_named_gpio(p->dev->of_node, "rts-gpio", 0);
    if(22 == uart.port.rs485.rts_gpio)
    {
        gpio_direction_output(uart.port.rs485.rts_gpio, 0);
        gpio_set_value(uart.port.rs485.rts_gpio, 0); // defalut low-level

    }

在这里插入图片描述

修改8250_port.c

文件8250_port.c,一共需要修改2处,一处是增加头文件,一处是发送前拉高,发送后拉低的控制。.
1、增加头文件包含

#include <linux/of_gpio.h>

在这里插入图片描述

2、增加收发切换控制代码。在函数serial8250_tx_chars中增加以下代码

int lsr; // 用于获取状态
int i;   // 用于循环计数

发送前先拉高

 if(22 == up->port.rs485.rts_gpio)
 {
         gpio_set_value(up->port.rs485.rts_gpio, 1);
         udelay(2); // 这个延时好像可以不用
  }

在这里插入图片描述

发送后,循环判断是否结束,结束后拉低。

1873                 if(22 == up->port.rs485.rts_gpio)
1874                 {
1875                         for(i = 0; i < 200; i++)
1876                         {
1877                                 mdelay(3);
1878                                 lsr = serial_in(up, UART_LSR);
1879                                 if(UART_LSR_TEMT == (lsr & UART_LSR_TEMT))
1880                                 {
1881                                         printk("[%d] wait finished: %d, lsr: %d\n", i, (lsr & UART_LSR_TEMT) == UART_LSR_TEMT, lsr);
1882                                         break;
1883                                 }
1884                         }
1885                         gpio_set_value(up->port.rs485.rts_gpio, 0);
1886                 }

在这里插入图片描述

全部修改完成后,重新编译生成boot.img文件,烧写到板子上。

RK3568开发板是基于Rockchip RK3568处理器的一个开发平台,主要用于嵌入式系统开发和媒体应用领域。该开发板具有丰富的硬件资源和灵活的扩展接口,适合各类嵌入式项目的开发和调试。 首先,RK3568开发板采用了Rockchip自家研发的RK3568处理器,该处理器采用了先进的ARM架构,具有强大的计算和图形处理能力。它基于22nm工艺制造,拥有六个Cortex-A55核心,最高主频可达1.8GHz,能够提供出色的性能和能效比。 其次,该开发板还配备了丰富的外设接口,包括多个USB接口、以太网口、HDMI接口等,方便用户连接外部设备。此外,还提供了各类扩展接口,如SPI、I2C、UART等,方便用户接入各类传感器、显示屏等外部硬件。 另外,开发板上还搭载了完整的软件开发环境,包括针对RK3568开发工具链、操作系统以及各类应用程序库。开发者可以利用这些工具进行应用程序的开发、调试和性能优化。同时,Rockchip还提供了丰富的开发文档和示例代码,帮助开发者快速上手。 总之,RK3568开发板是一款功能强大、资源丰富的开发平台,适用于嵌入式系统开发和媒体应用领域。它提供了高性能的处理器、丰富的硬件资源和完善的软件开发环境,为开发者提供了一站式的开发解决方案。无论是进行系统调试还是开发新的应用程序,该开发板都能够满足开发者的需求。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值