本例程可实现自定波特率,发送次数,发送间隔,发送字符串,同时接收数据保存文件的功能.
代码如下
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>
#include <pthread.h>
#include <getopt.h>
#include <time.h>
#define msleep(n) usleep(n * 1000)
#define NONE "\033[m"
#define RED "\033[0;32;31m"
#define LIGHT_RED "\033[1;31m"
#define GREEN "\033[0;32;32m"
#define LIGHT_GREEN "\033[1;32m"
#define BLUE "\033[0;32;34m"
#define LIGHT_BLUE "\033[1;34m"
#define DARY_GRAY "\033[1;30m"
#define CYAN "\033[0;36m"
#define LIGHT_CYAN "\033[1;36m"
#define PURPLE "\033[0;35m"
#define LIGHT_PURPLE "\033[1;35m"
#define BROWN "\033[0;33m"
#define YELLOW "\033[1;33m"
#define LIGHT_GRAY "\033[0;37m"
#define WHITE "\033[1;37m"
volatile int fd;
fd_set rd;
char *dev = NULL;
char *baudrate = "115200";
char *buffer = "Welcome to linux ";
static int sleeptime = 1000;
int count = 10;
int send_forever = 0;
char msg[512];
int nread, retval;
unsigned long recvTotal = 0;
volatile int sendnum = 1, recenum = 1;
pthread_mutex_t mut;
volatile pthread_t thread[2];
volatile const int READ_THREAD_ID = 0;
volatile const int SEND_THREAD_ID = 1;
volatile int COM_READ_STATU = 1;
volatile int COM_SEND_STATU = 1;
struct timeval timeout = {0, 100};
static void print_usage(const char *pname)
{
printf("Usage: %s -d devname -b baudrate -s string -t time -c count"
"\nExample : %s -d /dev/ttymxc2 [-b 115200 -s forlinxsendata -t 1000 -c 0]"
CYAN "\n\t -d devname can list in /dev"
"\n\t -b baudrate ,can be nmit,default is 115200"
"\n\t -s sendstring ,can be nmit ,defalut is buffer"
"\n\t -t time interval for send,can be nmit,default is 1000ms,time <200ms is incorrent"
"\n\t -c count for send number,can be nmit,0 or >65535 is forever,default is 10" NONE
" \n",
pname, pname);
}
char* getcurrenttime()
{
struct tm *tm;
time_t time;
struct timeval tv;
char ret[50];
gettimeofday(&tv,NULL);
time = tv.tv_sec;
tm = localtime(&time);
sprintf(ret,"%02d:%02d:%02d-%03d",tm->tm_hour, tm->tm_min, tm->tm_sec,(int)tv.tv_usec/1000);
char *r=ret;
return r;
}
static 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 OpenDev(char *Dev)
{
speed_t speed;
int fdt;
struct termios oldtio, newtio;
speed = getBaudrate(atoi(baudrate));
fdt = open(Dev, O_RDWR | O_NONBLOCK | O_NOCTTY | O_NDELAY);
if (fdt < 0)
{
perror(Dev);
exit(1);
}
tcgetattr(fdt, &oldtio);
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = speed | CS8 | CLOCAL | CREAD;
newtio.c_cflag &= ~CSTOPB;
newtio.c_cflag &= ~PARENB;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
tcflush(fdt, TCIFLUSH);
tcsetattr(fdt, TCSANOW, &newtio);
tcgetattr(fdt, &oldtio);
return fdt;
}
void read_port(void)
{
FD_ZERO(&rd);
FD_SET(fd, &rd);
retval = select(fd + 1, &rd, NULL, NULL, &timeout);
switch (retval)
{
case 0:
break;
case -1:
perror("select");
break;
default:
if ((nread = read(fd, msg, sizeof(msg))) > 0)
{
recvTotal += strlen(msg);
printf("Dev= %s\tRecvTotal= %05ld Times= %05d RecvData= %s ", dev, recvTotal, recenum, msg);
char *msg1 = msg;
if (strcmp(msg1, buffer) == 0)
printf(LIGHT_GREEN "Success !" NONE "\n\n");
else
printf(RED "Failed !" NONE "\n\n");
memset(msg, '\0', sizeof(msg));
if (recenum < 65535)
{
recenum++;
}
else
{
recenum = 1;
}
}
break;
}
}
int start_thread_func(void *(*func)(void *), pthread_t *pthread, void *par, int *COM_STATU)
{
memset(pthread, 0, sizeof(pthread_t));
int temp;
if ((temp = pthread_create(pthread, NULL, func, par)) != 0)
{
printf("creat thread failed!\n");
exit(1);
}
else
{
int id = pthread_self();
printf("%s,creat thread %d success\n", dev, id);
}
return temp;
}
void *com_read(void *pstatu )
{
while (COM_READ_STATU)
{
pthread_mutex_lock(&mut);
read_port();
pthread_mutex_unlock(&mut);
}
pthread_exit(NULL);
}
void *com_send(void *p)
{
unsigned int j = 0;
unsigned long sendTotal = 0;
while (COM_SEND_STATU)
{
j = write(fd, buffer, strlen(buffer) + 1);
sendTotal += j;
sendTotal--;
printf("Dev= %s\tSendTotal= %05ld Times= %05d SendData= %s\n", dev, sendTotal, sendnum, buffer);
if (sendnum < 65535)
{
sendnum++;
}
else
{
sendnum = 1;
}
if(send_forever==0)
{
if(sendnum>count)
{
COM_SEND_STATU = 0;
msleep(sleeptime*2);
COM_READ_STATU = 0;
exit(0);
}
}
msleep(sleeptime);
}
pthread_exit(NULL);
}
void SignHandler(int iSignNo)
{
printf("SignHandler starting \n");
COM_SEND_STATU = 0;
COM_READ_STATU = 0;
printf("Capture signer no : %d \n", iSignNo);
exit(1);
}
int main(int argc, char **argv)
{
int next_option;
int devflag = 0;
const char *const short_opt = "hd:b:s:t:c:";
const struct option long_opt[] = {
{"devices", 1, NULL, 'd'},
{"baudrate", 1, NULL, 'b'},
{"string", 1, NULL, 's'},
{"time", 1, NULL, 't'},
{"count",1,NULL,'c'},
{NULL, 0, NULL, 0},
};
do
{
next_option = getopt_long(argc, argv, short_opt, long_opt, NULL);
switch (next_option)
{
case 'd':
dev = optarg;
devflag = 1;
break;
case 'b':
baudrate = optarg;
break;
case 's':
if (strlen(optarg) > 0)
buffer = optarg;
break;
case 't':
sleeptime = atoi(optarg);
if (sleeptime < 200 || sleeptime > 50000)
{
print_usage(argv[0]);
exit(1);
}
break;
case 'c':
count = atoi(optarg);
if (count ==0 || count >65535)
{
send_forever=1;
}
dev = optarg;
devflag = 1;
break;
case '?':
print_usage(argv[0]);
exit(1);
break;
case -1:
if (devflag)
break;
default:
print_usage(argv[0]);
exit(1);
}
} while (next_option != -1);
if (dev == NULL)
{
printf("Please input serial device name ,for exmaple /dev/ttymxc2.\n");
exit(1);
}
fd = OpenDev(dev);
if (fd > 0)
{
}
else
{
printf("Can't Open Serial Port %s \n", dev);
exit(0);
}
printf("\nWelcome to TTYTEST! Press Ctrl + 'c' to stop.\n\n");
pthread_mutex_init(&mut, NULL);
if (start_thread_func(com_read, (pthread_t *)&thread[READ_THREAD_ID], (int *)&COM_READ_STATU, (int *)&COM_READ_STATU) != 0)
{
printf("error to leave\n");
return -1;
}
msleep(sleeptime);
if (start_thread_func(com_send, (pthread_t *)&thread[SEND_THREAD_ID], (int *)&COM_SEND_STATU, (int *)&COM_SEND_STATU) != 0)
{
printf("error to leave\n");
return -1;
}
pause();
}
执行效果如下:
root@fl-imx6ull:~# ./ttytest
Usage: ./ttytest -d devname -b baudrate -s string -t time -c count
Example : ./ttytest -d /dev/ttymxc2 [-b 115200 -s forlinxsendata -t 1000 -c 0]
-d devname can list in /dev
-b baudrate ,can be nmit,default is 115200
-s sendstring ,can be nmit ,defalut is buffer
-t time interval for send,can be nmit,default is 1000ms,time <200ms is incorrent
-c count for send number,can be nmit,0 or >65535 is forever,default is 10
root@fl-imx6ull:~#