OrangePi3 LTS 驱动开发-uart通信
kernel版本:orange-pi-5.10-media
5.1x版本,uart3默认是关闭的,需要在orangepiEnv.txt中添加overlays=uart3字样开启uart3。如果不添加,默认设置为开,需要更高dts中的配置。
1、修改sun50i-h6.dtsi文件,屏蔽以下内容
// uart3_rts_cts_pins: uart3-rts-cts-pins {// pins = "PD25", "PD26";// function = "uart3";// };
2、修改sun50i-h6-orangepi-3-lts.dts文件
添加一下内容
model = "OrangePi 3 LTS";
compatible = "xunlong,orangepi-3-lts", "allwinner,sun50i-h6";aliases {serial0 = &uart0;serial1 = &uart1;serial3 = &uart3;serial9 = &r_uart;i2c0 = &i2c0;spi1 = &spi1;ethernet0 = &emac;
};&uart3 {pinctrl-names = "default";pinctrl-0 = <&uart3_pins>;status = "okay";
};
替换编译的dtb,重启应该就默认开启uart3
App测试demo,orangepi里编写,直接gcc 编译运行即可。
usb转串口小板 tx rx接26pin的uart3 ,
电脑端用串口助手发送hello
香橙派3 发送hello world,会看到图示现象。
源码:
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>speed_t getBaudRate(int baudRate)
{switch(baudRate) {case 0: return B0;case 50: return B50;case 75: return B75;case 110: return B110;case 134: return B134;case 150: return B150;case 200: return B200;case 300: return B300;case 600: return B600;case 1200: return B1200;case 1800: return B1800;case 2400: return B2400;case 4800: return B4800;case 9600: return B9600;case 19200: return B19200;case 38400: return B38400;case 57600: return B57600;case 115200: return B115200;case 230400: return B230400;case 460800: return B460800;case 500000: return B500000;case 576000: return B576000;case 921600: return B921600;case 1000000: return B1000000;case 1152000: return B1152000;case 1500000: return B1500000;case 2000000: return B2000000;case 2500000: return B2500000;case 3000000: return B3000000;case 3500000: return B3500000;case 4000000: return B4000000;default: return -1;}
}int setParity(int fd,int dataBits,int stopBits,int parity)
{struct termios options;if (tcgetattr (fd, &options) != 0) {printf ("SetupSerial 1");return (-1);}options.c_cflag &= ~CSIZE;switch (dataBits) {case 7:options.c_cflag |= CS7;break;case 8:options.c_cflag |= CS8;break;default:fprintf (stderr, "Unsupported data size\n");return (-1);}switch (parity) {case 'n':case 'N':options.c_cflag &= ~PARENB; /* Clear parity enable */options.c_iflag &= ~INPCK; /* Enable parity checking */break;case 'o':case 'O':options.c_cflag |= (PARODD | PARENB);options.c_iflag |= INPCK; /* Disable parity checking */break;case 'e':case 'E':options.c_cflag |= PARENB; /* Enable parity */options.c_cflag &= ~PARODD;options.c_iflag |= INPCK; /* Disable parity checking */break;case 'S':case 's': /*as no parity */options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;break;default:fprintf (stderr, "Unsupported parity\n");return (-1);
}
switch (stopBits) {case 1:options.c_cflag &= ~CSTOPB;break;case 2:options.c_cflag |= CSTOPB;break;default:fprintf (stderr, "Unsupported stop bits\n");return (-1);
}/* Set input parity option */
if (parity != 'n')options.c_iflag |= INPCK;
tcflush (fd, TCIFLUSH);
options.c_cc[VTIME] = 0x01;
options.c_cc[VMIN] = 0xFF; /* Update the options and do it NOW */
//qd to set raw mode, which is copied from web
options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP| INLCR | IGNCR | ICRNL | IXON);
options.c_oflag &= ~OPOST;
options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
options.c_cflag &= ~(CSIZE | PARENB);
options.c_cflag |= CS8;if (tcsetattr (fd, TCSANOW, &options) != 0) {perror ("SetupSerial 3");return (-1);
}return 0;
}int serialOpen(const char *path, int baudRate)
{int fd;speed_t speed;/* Check arguments */
{speed = getBaudRate(baudRate);if (speed == -1) {printf("get Baud rate error\n");return -1;}
}
{fd = open(path, O_RDWR);if (fd == -1){printf("open serial error =%d\n",fd);return -1;}
}
/* Configure device */
{struct termios cfg;if (tcgetattr(fd, &cfg)){printf("tcgetattr() failed\n");close(fd);return -1;}cfmakeraw(&cfg);cfsetispeed(&cfg, speed);cfsetospeed(&cfg, speed);if (tcsetattr(fd, TCSANOW, &cfg)){printf("tcsetattr() failed\n");close(fd);return -1;}
}
setParity(fd,8,1,'N');
printf("open Success==%d\n",fd);
return fd;
}int serialWrite(int fd,char *writeData,int len)
{if (fd > 0){write(fd,writeData,len);}else{printf("[File]=%s[Function]=%s error\n",__FILE__,__FUNCTION__);return -1;
}
return 0;
}int serialRead(int fd,char *readData,int len)
{size_t size = 0;if (fd > 0){size = read(fd,readData,len);}else{printf("[File]=%s[Function]=%s error\n",__FILE__,__FUNCTION__);return -1;
}
return size;
}int serialClose(int fd)
{close(fd);return 0;
}void *uart_read_thread(void *arg){int fd = *((int *)arg);size_t size ; char r_data[256] = {0};while(1){size = serialRead(fd,r_data,256); //阻塞方式去读if (size > 0){printf("get data %s\n",r_data);}}åprintf("fd == %d in thread\n ",fd);
}int main(int argc,char *argv)
{int fd = 0;int ret;char w_data[] = "hello world\n";pthread_t m_read_thread ;fd = serialOpen("/dev/ttyS3",115200);if (fd > 0){printf("open ttyS3 ok\n");}else{printf("open ttyS3 fail\n");return -1;}ret = pthread_create(&m_read_thread,NULL,uart_read_thread,&fd);if (ret){perror("pthread_create error\n");return -1;}//pthread_join(m_read_thread,NULL);while (1){serialWrite(fd,w_data,strlen(w_data));sleep(2);}printf("hello world\n");
}