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


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

猜你喜欢

转载自blog.csdn.net/Mculover666/article/details/124147474