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");
}