209 lines
4.6 KiB
C
209 lines
4.6 KiB
C
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
#include <fcntl.h>
|
||
#include <errno.h>
|
||
#include <termios.h>
|
||
#include "type_define.h"
|
||
#include "read_config.h"
|
||
#include <pthread.h>
|
||
speed_t match_com_bandrate(u32 bandrate)
|
||
{
|
||
switch (bandrate)
|
||
{
|
||
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 B0;
|
||
|
||
return B0;
|
||
}
|
||
}
|
||
|
||
int open_com_salve()
|
||
{
|
||
int fd;
|
||
simp_config_t config;
|
||
int ret = 0;
|
||
ret = open_config_file(&config, "config");
|
||
if (ret)
|
||
{
|
||
return -1;
|
||
}
|
||
char portname[MAX_CONFIG_LINE_LEN];
|
||
do
|
||
{
|
||
ret = read_config_file_string(&config, "uart_device", portname, MAX_CONFIG_LINE_LEN);
|
||
if (ret)
|
||
{
|
||
perror("read uart_device failed\n");
|
||
break;
|
||
}
|
||
u32 baudrate;
|
||
ret = read_config_file_u32(&config, "uart_baudrate", &baudrate);
|
||
if (ret)
|
||
{
|
||
perror("read uart_baudrate failed\n");
|
||
break;
|
||
}
|
||
fd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
|
||
if (fd == -1)
|
||
{
|
||
perror("com dev open failed");
|
||
break;
|
||
}
|
||
// 清除串口阻塞标志
|
||
if (fcntl(fd, F_SETFL, 0) == -1)
|
||
{
|
||
perror("fcntl failed");
|
||
break;
|
||
}
|
||
|
||
struct termios tty;
|
||
|
||
// 保存当前串口设置
|
||
if (tcgetattr(fd, &tty) != 0)
|
||
{
|
||
perror("tcgetattr失败");
|
||
break;
|
||
}
|
||
speed_t speed = match_com_bandrate(baudrate);
|
||
if (speed == B0)
|
||
{
|
||
ret = -1;
|
||
perror("baudrate not support");
|
||
break;
|
||
}
|
||
cfsetispeed(&tty, speed);
|
||
cfsetospeed(&tty, speed);
|
||
tty.c_cflag &= ~PARENB; // 无奇偶校验
|
||
tty.c_cflag &= ~CSTOPB; // 无两个停止位
|
||
tty.c_cflag &= ~CSIZE; // 清除字符大小
|
||
tty.c_cflag |= CS8; // 设置字符大小为8位
|
||
|
||
tty.c_cflag &= ~CRTSCTS; // 无硬件流控制
|
||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 无软件流控制
|
||
|
||
tty.c_cflag |= (CLOCAL | CREAD); // 禁用控制流,使能接收
|
||
|
||
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 非规范模式,关闭回显,不生成信号
|
||
|
||
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
|
||
|
||
tty.c_oflag &= ~OPOST; // 关闭输出处理
|
||
|
||
tty.c_cc[VMIN] = 1; // 读取字符的最小数量
|
||
tty.c_cc[VTIME] = 5; // 读取字符的超时时间(单位:0.1秒)
|
||
|
||
if (tcsetattr(fd, TCSANOW, &tty) != 0)
|
||
{
|
||
perror("tcsetattr失败");
|
||
ret = -1;
|
||
break;
|
||
}
|
||
|
||
} while (0);
|
||
close_config_file(&config);
|
||
if (ret)
|
||
{
|
||
return -1;
|
||
}
|
||
return fd;
|
||
}
|
||
|
||
void *read_thread_func(void *arg)
|
||
{
|
||
int dev_fd = *(int *)arg;
|
||
while (1)
|
||
{
|
||
char rx_buf;
|
||
read(dev_fd, &rx_buf, 1);
|
||
printf("[%c]", rx_buf);
|
||
}
|
||
}
|
||
|
||
void *write_thread_func(void *arg)
|
||
{
|
||
int dev_fd = *(int *)arg;
|
||
while (1)
|
||
{
|
||
write(dev_fd, "hello world\n", 11);
|
||
sleep(1);
|
||
}
|
||
}
|
||
int main()
|
||
{
|
||
int dev_fd = open_com_salve();
|
||
if (dev_fd == -1)
|
||
{
|
||
perror("open com slave failed");
|
||
return -1;
|
||
}
|
||
pthread_t read_thread;
|
||
pthread_create(&read_thread, NULL, read_thread_func, (void *)&dev_fd);
|
||
pthread_detach(read_thread);
|
||
pthread_t write_thread;
|
||
pthread_create(&write_thread, NULL, write_thread_func, (void *)&dev_fd);
|
||
pthread_detach(write_thread);
|
||
return 0;
|
||
}
|