部分代码借鉴地址:https://blog.csdn.net/wangqingchuan92/article/details/73497354/ 谢谢!
1.创建线程在线程内进行串口之间的收发
void CREAT_pthread(void)
{
pthread_t t0;
//创建线程1
if(pthread_create(&t0, NULL, print_a, NULL) == -1){
puts("fail to create pthread t0");
exit(1);
}else
{
printf("\n\nt0 create success!!!");
}
}
遇到的问题:在一开始创建线程的时候,调用了pthread_join()函数,主线程需要等子线程完成操作后才会执行。由于子线程是电视开机后一直在执行,随时会接收数据发送数据,因此导致主线程没办法执行,电视死机没办法正常操作。
// 等待线程结束
void * result;
if(pthread_join(t0, &result) == -1){
puts("fail to recollect t0");
//exit(1);
}
if(pthread_join(t1, &result) == -1){
puts("fail to recollect t1");
// exit(1);
}
2.打开串口
int OpenDev(char *Dev)
{
int fd = open(Dev,O_RDWR | O_NOCTTY | O_NONBLOCK);
if(-1 == fd)
{
perror("Can't Open Serial Port");
return -1;
} else
{
printf("Open com success!!!!!!!!!!!");
return fd;
}
}
|
对于open函数来说,第三个参数仅当创建新文件时(即 使用了O_CREAT 时)才使用,用于指定文件的访问权限位(access permission bits)。pathname 是待打开/创建文件的POSIX路径名(如/home/user/a.cpp);flags 用于指定文件的打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑位或逻辑构成。
O_RDONLY只读模式 O_WRONLY只写模式 O_RDWR读写模式
打开/创建文件时,至少得使用上述三个常量中的一个。以下常量是选用的:
1 2 3 4 5 6 |
|
3.设置波特率
unsigned int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
unsigned int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, };
void set_speed(int fd, unsigned int speed)
{
unsigned 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);
}
}
4.设置校验位()
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return 0;
}
bzero(&options,sizeof(options));
options.c_cflag |= CLOCAL | CREAD;
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 0;
}
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 | ISTRIP);
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= (INPCK | ISTRIP);
break;
case 'S':
case 's':
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default: fprintf(stderr,"Unsupported parity\n");
return 0;
}
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default: fprintf(stderr,"Unsupported stop bits\n");
return 0;
}
if (parity != 'n')
{
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH);
}
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return 0;
}
return 0;
}
5.读写加异常判断以及加锁
pthread_mutex_lock(&mutex_r);
memset(buff,0,30);
nread = read(fd,buff,sizeof(buff));
pthread_mutex_unlock(&mutex_r); //返回读到的字节数
------------------------------------------------------------------------------
pthread_mutex_lock(&mutex_w);
if((flag=write(fd,string,len)) != len)
{
printf("write error!!!\n");
}
pthread_mutex_unlock(&mutex_w); // //返回写入的的字节数
------------------------------------------------------------------------------
当pthread_mutex_lock()返回时,该互斥锁已被锁定。线程调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。
互斥锁提供一个可以在同一时间,只让一个线程访问临界资源的的操作接口。互斥锁(Mutex)是个提供线程同步的基本锁。让上锁后,其他的线程如果想要锁上,那么会被阻塞,直到锁释放后(说明,一般会把访问共享内存这段代码放在上锁程序之后。)。
如果,在锁释放后,有多个线程被阻塞,那么,所有的被阻塞的线程会被设为可执行状态。第一个执行的线程,取得锁的控制权,上锁。其他的线程继续阻塞。