Linux/uClinux下的RS-485通信驱动程序实现

   这篇文章描述如何在Linux/uClinux操作系统下实现RS-485的通信驱动程序。提供一种可借鉴的驱动程序设计方法。

1.RS-485总线

         RS-485是半双工的通信,它一般使用异步的串口与RS-485驱动芯片连接,在提供一条方向控制信号来控制RS-485驱动芯片的收发数据。

        在总线型的半双工通信中,收发是不可同时进行,且总线上某一时刻只能有一个在发送,其他处于接收状态。因此精确地控制RS-485驱动芯片的发送时间比较 重要(因为可以通过通信双方的协商,发送的控制时间可以远大于实际发送数据占用的时间),在我们提供一种通用的RS-485通信接口(不知道对方在收到数 据后多久会发送数据回来)时,尤为重要。

2.带控制器的串口

        在我们使用的串口中,一般我们是使用处理器(单片机、ARM7、ARM9)的片上串口。而处理器给他的外设串口发送一个字节的时间远小于串口发送这个字节 到它的TXD线所需要的时间。因此我们在控制RS-485驱动芯片时不能以处理器发送完一个字节就将RS-485驱动芯片的状态转换为接收(不发送)。

        对非操作系统,我们可以在程序代码中填入等待,以此来达到我们对RS-485数据收发较为精确(绝对精确较困难、也没有必要)的控制。

        例如:以MSC-51单片机为例,发送一个字节。12时钟周期的指令周期,时钟12MHz,指令时间1us。8位、无校验、1停止、波特率9600的串口 参数,则发送一个字节的时间约为1042us。而发送数据的指令为“SBUF=发送字节”。这个指令的执行时间也就一个指令周期1us,因此我们需要等待 1041us。

                      ;RS-485发送使能

                     MOV SBUF,A                  ;A存放要发送的数据

                     ;等待1041us

                     ;RS-485发送禁止

        为会提高处理器的效率,我们就考虑用定时器来取代等待延时。

3.Linux/uClinux下的驱动设计

        对RS-485驱动器的驱动,实际就是char型设备的驱动。RS-485是通过串口来控制的,因此驱动程序的主体是串口的驱动。我们这里讨论的重点不在此。

        根据上面非操作系统下的实现方法,我们在Linux/uClinux下使用处理器的硬件定时器作为定时器来计算需要延迟的时间。在Linux/uClinux下软件定时器的精度不能满足要求。

int rs485_open(struct inode* i,struct file* file){
        ...
        // 注册定时器中断
        // 设置RS-485为接收状态
        ...
}

static ssize_t rs485_write(struct file *file, char *buf, size_t count, loff_t *offset){
        ...
        // 拷贝数据到内核内存
        // 配置定时器到需要的延时时间
        // 启动定时器
        // 开启串口发送中断
        // 设置RS-485为发送状态
        ...
}

static void timer_handler(int irq, void * dev_id, struct pt_regs * regs){
        // 设置RS-485为接收状态
        // 关闭定时器
        ...
}   

你可能感兴趣的:(linux应用,485驱动,LINUX)