【C語言實現串列埠通訊知識點整理(一)】執行緒、開啟串列埠、設定波特率、設定校驗位、互斥鎖等實現基本的通訊
部分程式碼借鑑地址: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)是個提供執行緒同步的基本鎖。讓上鎖後,其他的執行緒如果想要鎖上,那麼會被阻塞,直到鎖釋放後(說明,一般會把訪問共享記憶體這段程式碼放在上鎖程式之後。)。
如果,在鎖釋放後,有多個執行緒被阻塞,那麼,所有的被阻塞的執行緒會被設為可執行狀態。第一個執行的執行緒,取得鎖的控制權,上鎖。其他的執行緒繼續阻塞。