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
再看看另一侧的串口终端是否收到数据: