uart串口操作头文件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
int uart_option(char *dev_path, int speed, int option, char *buff, int len);
uart串口操作
#include "uart_sync_rtc.h"
#define FALSE -1
#define TRUE 0
static int OpenDev(char *Dev)
{
int fd = open(Dev, O_RDWR | O_NOCTTY);
if (-1 == fd)
{
perror("Can't Open Serial Port");
return -1;
}
else
return fd;
}
int speed_arr[] = {B38400, B19200, B115200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B115200, B9600, B4800, B2400, B1200, B300,};
int name_arr[] = {38400, 19200, 115200, 9600, 4800, 2400, 1200, 300, 38400,
19200, 115200, 9600, 4800, 2400, 1200, 300,};
void set_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {
if (speed == name_arr[i]) {
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0) {
perror("tcsetattr fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
static int set_Parity(int fd, int databits, int stopbits, int parity)
{
struct termios options = {0};
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
if ( tcgetattr( fd,&options) != 0) {
perror("SetupSerial 1");
return(FALSE);
}
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 (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB);
options.c_iflag |= INPCK;
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= INPCK;
break;
case 'S':
case 's':
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;break;
default:
fprintf(stderr,"Unsupported parity/n");
return (FALSE);
}
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits/n");
return (FALSE);
}
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd, TCIFLUSH);
options.c_cc[VTIME] = 150;
options.c_cc[VMIN] = 0;
if (tcsetattr(fd, TCSANOW, &options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
int uart_option(char *dev_path, int speed, int option, char *buff, int len)
{
int fd;
int nread;
fd = OpenDev(dev_path);
if (fd == -1)
return -1;
set_speed(fd,speed);
if (option == 1)
{
if ((nread = read(fd, buff, len))>0)
{
buff[nread + 1] = 0;
}
close(fd);
return nread;
}
else if (option == 2)
{
printf("------buff--->%s<--------/n",buff);
int num = strlen(buff);
printf("--------num---->%d<--------------/n",num);
if (num > 0)
{
printf("Wirte num not NULL./r/n");
nread = write(fd, buff, num);
if (nread == -1)
{
printf("Wirte sbuf error./n");
return -1;
}
printf("--nread---->%d<-----------/n",nread);
}
close(fd);
}
return 0;
}
gpio获取脉冲信号,并同步系统时间
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include "uart_sync_rtc.h"
#include <time.h>
#include <pthread.h>
#define GPIO1_26_DEV_NUM 290
int debug_mode = 0;
#define DEBUG_MSG(fmt, arg ...) \
if (debug_mode) printf("[DEBUG] system_rtc_sync " fmt , ##arg )
enum GPIO_EDGE_MODE{
GPIO_EDGE_MODE_NONE=0,
GPIO_EDGE_MODE_RISING,
GPIO_EDGE_MODE_FALLING,
GPIO_EDGE_MODE_BOTH,
};
enum GPIO_DIRECTION_MODE{
GPIO_DIRECTION_MODE_IN=0,
GPIO_DIRECTION_MODE_OUT,
};
static int gpio_export(int pin);
static int gpio_unexport(int pin);
static int gpio_direction(int pin, int dir);
static int gpio_write(int pin, int value);
static int gpio_read(int pin);
static int gpio_edge(int pin, int edge);
static int gpio_export(int pin)
{
char buffer[64];
int len;
int fd;
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0)
{
DEBUG_MSG("Failed to open export for writing!\n");
return(-1);
}
len = snprintf(buffer, sizeof(buffer), "%d", pin);
DEBUG_MSG("%s,%d,%d\n",buffer,(int)sizeof(buffer),len);
if (write(fd, buffer, len) < 0)
{
DEBUG_MSG("Failed to export gpio!");
return -1;
}
close(fd);
return 0;
}
static int gpio_unexport(int pin)
{
char buffer[64];
int len;
int fd;
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (fd < 0)
{
DEBUG_MSG("Failed to open unexport for writing!\n");
return -1;
}
len = snprintf(buffer, sizeof(buffer), "%d", pin);
if (write(fd, buffer, len) < 0)
{
DEBUG_MSG("Failed to unexport gpio!");
return -1;
}
close(fd);
return 0;
}
static int gpio_direction(int pin, int dir)
{
static const char dir_str[] = "in\0out";
char path[64];
int fd;
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);
fd = open(path, O_WRONLY);
if (fd < 0)
{
DEBUG_MSG("Failed to open gpio direction for writing!\n");
return -1;
}
if (write(fd, &dir_str[dir == GPIO_DIRECTION_MODE_IN ? 0 : 3], dir == GPIO_DIRECTION_MODE_IN ? 2 : 3) < 0)
{
DEBUG_MSG("Failed to set direction!\n");
return -1;
}
close(fd);
return 0;
}
static int gpio_write(int pin, int value)
{
static const char values_str[] = "01";
char path[64];
int fd;
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_WRONLY);
if (fd < 0)
{
DEBUG_MSG("Failed to open gpio value for writing!\n");
return -1;
}
if (write(fd, &values_str[value == 0 ? 0 : 1], 1) < 0)
{
DEBUG_MSG("Failed to write value!\n");
return -1;
}
close(fd);
return 0;
}
static int gpio_read(int pin)
{
char path[64];
char value_str[3];
int fd;
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_RDONLY);
if (fd < 0)
{
DEBUG_MSG("Failed to open gpio value for reading!\n");
return -1;
}
if (read(fd, value_str, 3) < 0)
{
DEBUG_MSG("Failed to read value!\n");
return -1;
}
close(fd);
return (atoi(value_str));
}
static int gpio_edge(int pin, int edge)
{
const char dir_str[] = "none\0rising\0falling\0both";
char ptr;
char path[64];
int fd;
switch(edge)
{
case GPIO_EDGE_MODE_NONE:
ptr = 0;
break;
case GPIO_EDGE_MODE_RISING:
ptr = 5;
break;
case GPIO_EDGE_MODE_FALLING:
ptr = 12;
break;
case GPIO_EDGE_MODE_BOTH:
ptr = 20;
break;
default:
ptr = 0;
}
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/edge", pin);
fd = open(path, O_WRONLY);
if (fd < 0)
{
DEBUG_MSG("Failed to open gpio edge for writing!\n");
return -1;
}
if (write(fd, &dir_str[ptr], strlen(&dir_str[ptr])) < 0)
{
DEBUG_MSG("Failed to set edge!\n");
return -1;
}
close(fd);
return 0;
}
typedef struct st_uart_sync_time_data{
time_t timesec;
int pre_flag;
}uart_sync_time_data;
uart_sync_time_data sync_data = {0};
pthread_rwlock_t rwlock;
void *uart_thread(void){
int gpio_fd, ret;
char uart_buff[64];
struct tm tm_time;
struct timeval stime;
while(1)
{
ret = uart_option("/dev/ttyS4", 115200, 1, uart_buff, 64);
if (ret > 0){
DEBUG_MSG("rtc_time: %s\n", uart_buff);
strptime(uart_buff, "UTC:%Y-%m-%dT%H:%M:%SZ", &tm_time);
pthread_rwlock_wrlock(&rwlock);
DEBUG_MSG("write sync_data\n");
sync_data.timesec = mktime(&tm_time);
sync_data.pre_flag = 1;
pthread_rwlock_unlock(&rwlock);
}
usleep(100000);
}
}
int main(int argc, char ** argv)
{
int gpio_fd, ret;
char buff[10];
int len;
struct tm tm_time;
struct timeval stime;
pthread_t pthid;
struct epoll_event evd;
struct epoll_event * events;
int epollfd;
if (argc == 2){
debug_mode = atoi(argv[1]);
}
gpio_unexport(GPIO1_26_DEV_NUM);
gpio_export(GPIO1_26_DEV_NUM);
gpio_direction(GPIO1_26_DEV_NUM, GPIO_DIRECTION_MODE_IN);
gpio_edge(GPIO1_26_DEV_NUM, GPIO_EDGE_MODE_RISING);
gpio_fd = open("/sys/class/gpio/gpio290/value",O_RDWR|O_NOCTTY|O_NDELAY);
if (gpio_fd < 0)
{
DEBUG_MSG("Failed to open value!\n");
return -1;
}
epollfd = epoll_create(10);
events = calloc (10, sizeof(struct epoll_event));
evd.data.fd = gpio_fd;
evd.events = EPOLLPRI;
epoll_ctl(epollfd,EPOLL_CTL_ADD,gpio_fd,&evd);
pthread_rwlock_init(&rwlock,NULL);
ret = pthread_create(&pthid, NULL, (void*)uart_thread, NULL);
if (ret == -1)
return ret;
DEBUG_MSG("uart thread id: %d\n", pthid);
while (1) {
int n = epoll_wait(epollfd,events,10,-1);
for (int i = 0;i < n;i++) {
if (events[i].events & EPOLLPRI) {
memset(buff,0x00,sizeof(buff));
read(events[i].data.fd,buff,sizeof(buff));
lseek(events[i].data.fd,0,SEEK_SET);
DEBUG_MSG("read buff\n");
pthread_rwlock_rdlock(&rwlock);
DEBUG_MSG("read sync_data\n");
if (sync_data.pre_flag)
{
stime.tv_sec = sync_data.timesec + 1;
stime.tv_usec = 0;
settimeofday(&stime, NULL);
DEBUG_MSG("set time sync\n");
sync_data.pre_flag = 0;
}
pthread_rwlock_unlock(&rwlock);
}
}
usleep(100);
}
DEBUG_MSG("wait thread\n");
pthread_join(pthid, NULL);
pthread_rwlock_destroy(&rwlock);
return 0;
}