i.MX6ULL驱动开发 | 16 - 基于 UART 驱动框架发送/接收串口数据

Posted Mculover666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了i.MX6ULL驱动开发 | 16 - 基于 UART 驱动框架发送/接收串口数据相关的知识,希望对你有一定的参考价值。

i.MX6ULL在SOC级别的UART外设驱动已经由原厂编写好了,我们只需要在设备树中添加对应的节点即可使用。

一、在设备树添加节点

1. 设置UART3引脚

在iomucx节点中添加uart3子节点:

pinctrl_uart3: uart3grp 
	fsl,pins = <
		MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX	0x1b0b1
		MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX	0x1b0b1
	>;
;

检查一下这两个引脚有没有被使用。

已经被uart2用作rts和cts引脚,给它干掉:

2. 添加uart3节点

&uart3 
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart3>;
	status = "okay";
;

3. 测试是否生成设备文件

重新编译设备树:

make dtbs

使用新的设备树启动,查看是否生成对应的串口设备文件:

可以看到,系统已经有ttymxc2这个串口设备口,对应UART3,应用程序可以通过访问此设备实现对UART3的操作。

二、编写串口测试程序

Linux UART应用编程参考文章:Linux下串口收发通信

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <termios.h>
#include <string.h>

int uart_setup(int fd)

    struct termios newtio;

    // 获取原有串口配置
    if  (tcgetattr(fd, &newtio) < 0) 
        return -1;
    

    // 修改控制模式,保证程序不会占用串口
    newtio.c_cflag  |=  CLOCAL;

    // 修改控制模式,能够从串口读取数据
    newtio.c_cflag  |=  CREAD;

    // 不使用流控制
    newtio.c_cflag &= ~CRTSCTS;

    // 设置数据位
    newtio.c_cflag &= ~CSIZE;
    newtio.c_cflag |= CS8;

    // 设置奇偶校验位
    newtio.c_cflag &= ~PARENB;
    newtio.c_iflag &= ~INPCK; 

    // 设置停止位
    newtio.c_cflag &= ~CSTOPB;

    // 设置最少字符和等待时间
    newtio.c_cc[VTIME]  = 1;
    newtio.c_cc[VMIN] = 1;

    // 修改输出模式,原始数据输出
    newtio.c_oflag &= ~OPOST;
    newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    // 设置波特率
    cfsetispeed(&newtio, B115200); 
    cfsetospeed(&newtio, B115200);

    // 清空终端未完成的数据
    tcflush(fd,TCIFLUSH);

    // 设置新属性
    if(tcsetattr(fd, TCSANOW, &newtio) < 0) 
        return -1;
    

    return 0;


int uart_send(int fd, char *buf, int len)

    int count;

    count = write(fd, buf, len);

    return count == len ? len : -1;


int main(int argc, char *argv[])

    int fd;
    int ret;
    int count = 100;
    char send_buf[] = "Hello World!\\r\\n";

    if (argc != 2) 
        printf("usage: ./test_uart [device]\\n");
        return -1;
    

    /* 打开串口 */
    fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd < 0) 
        printf("open dev fail!\\n");
        return -1;
    

    /* 设置串口 */
    ret = uart_setup(fd);
    if (ret < 0) 
        printf("uart setup fail!\\n");
        close(fd);
        return -1;
    

    while (count--) 
        ret = uart_send(fd, send_buf, strlen(send_buf));
        if (ret < 0) 
            printf("send fail!\\n");
         else 
            printf("send ok!\\n");
        
        sleep(2);
    

    close(fd);

编译:

arm-linux-gnueabihf-gcc test_uart.c -o test_uart

运行:

./test_uart /dev/ttymxc2


再看看另一侧的串口终端是否收到数据:

以上是关于i.MX6ULL驱动开发 | 16 - 基于 UART 驱动框架发送/接收串口数据的主要内容,如果未能解决你的问题,请参考以下文章

i.MX6ULL驱动开发 | 08 -基于pinctrl子系统和gpio子系统点亮LED

i.MX6ULL驱动开发 | 08 -基于pinctrl子系统和gpio子系统点亮LED

i.MX6ULL驱动开发 | 09 -基于Linux自带的LED驱动点亮LED

i.MX6ULL驱动开发 | 34 - 基于SPI框架驱动spi lcd(st7789)

i.MX6ULL驱动开发 | 03-基于字符设备驱动框架点亮LED

i.MX6ULL驱动开发 | 34 - 基于SPI框架驱动spi lcd(st7789)