Linux下的串列埠程式設計及非阻塞模式

2022-08-18 19:51:10 字數 4794 閱讀 9743

本篇介紹了如何在linux系統下向串列埠傳送資料。包括read的阻塞和非阻塞。以及select方法。

在linux系統下,開啟串列埠是通過使用標準的檔案開啟函式操作的。

#include

/* 以讀寫的方式開啟 */

int fd = open( "/dev/ttyusb0",o_rdwr);  

所有對串列埠的操作都是通過結構體 struct termios 和 幾個函式實現的。

tcgetattr          //

獲取屬性

tcsetattr   //

設定屬性

cfgetispeed    //

得到輸入速度

cfsetispeed    //

設定輸入速度

cfgetospeed    //

得到輸出速度

cfsetospedd    //

設定輸出速度

tcdrain //

等待所有輸出都被傳輸

tcflow //

掛起傳輸或接收

tcflush //

刷清未決輸入和輸出

tcsendbreak    //

送break字元

tcgetpgrp   //

得到前台程序組id

tcsetpgrp   //

設定前台程序組id

tcgetattr( 0,&oldstdio);  //獲取預設的配置選項 儲存到oldstdio結構體中
tcgetattr( fd,&oldstdio);  //獲取當前配置選項 儲存到oldstdio結構體中
tcsetattr( fd,tcsanow,&oldstdio);  //tcsanow 修改立即生效

cfgetispeed( &oldstdio);      //得到波特率
cfsetispeed(&oldstdio, b115200 )    //設定波特率為115200

即可使用read或open來操作串列埠的傳送與接收。  

測試**:

#include #include 

#include

#include

#include

int serial_send( int fd, char *data );

intmain()

tcgetattr( fd, &oldstdio);

cfsetispeed(&oldstdio, b115200);

tcsetattr( fd, tcsanow, &oldstdio);

tcflush( fd, tciflush );

num = serial_send( fd,"

serial baund is default \r\n");

close(fd);

return0;

}int serial_send( int fd, char *data )

在沒有資料讀取的時候,執行read函式會發生阻塞,執行下面的程式,在串列埠接收端沒有資料時,返回0,並不會發生阻塞。

#include #include 

#include

#include

#include

#include

const

char *serial_dev = "

/dev/ttyusb0";

typedef

struct

serial;

typedef

struct

vehicle;

vehicle serial_tx = };

serial serial_d = };

ints_fd;

int wait_flag = 0

;int serial_send( int fd, char *data );

int set_opt(int fd,int nspeed,int nbits,char nevent,int

nstop);

void * pthread_serial( void *arg )

;

s_fd = open( serial_dev, o_rdwr|o_noctty );

if( -1==s_fd )

pthread_exit(null);

ret = set_opt(s_fd,115200,8,'

n',1

);

if(ret == -1

)

while(1

)

else

}pthread_exit(null);

}int

main()

while(1

)

return0;

}int serial_send( int fd, char *data )

int set_opt(int fd,int nspeed,int nbits,char nevent,int

nstop)

bzero(&newtio,sizeof

(newtio));

//使能串列埠接收

newtio.c_cflag |= clocal |cread;

newtio.c_cflag &= ~csize;

newtio.c_lflag &=~icanon;//

原始模式

|=icanon;

//標準模式

//設定串列埠資料位

switch

(nbits)

//設定奇偶校驗位

switch

(nevent)

//設定串列埠波特率

switch

(nspeed)

//設定停止位

if(nstop == 1

) newtio.c_cflag &= ~cstopb;

else

if(nstop == 2

) newtio.c_cflag |=cstopb;

newtio.c_cc[vtime] = 1

; newtio.c_cc[vmin] = 0

; tcflush(fd,tciflush);

if(tcsetattr(fd,tcsanow,&newtio)!=0

)

return0;

}

可以使用select函式來判斷有沒有接收到資料。

int read_datas_tty(int fd,char *rcv_buf,int sec,int

usec)

else

if(retval)

else

}return1;

}

將上面的函式放到read前面呼叫即可。

下面是我用在小車上的**:

#include #include 

#include

#include

#include

#include

#include

"serial.h

"const

char *serial_dev = "

/dev/ttyusb0";

typedef

struct

vehicle;

typedef

struct

uart;

vehicle motor = };

uart serial_usb=;;

void * pthread_serial_rx( void *arg )

else

if( retval)

}else

if( num>100

)

}pthread_exit(null);

}void * pthread_serial( void *arg )

serial_usb.fd =fd;

serial_usb.sec = 0

; serial_usb.usec = 1

; serial_usb.veh = &motor;

pthread_create( &pthread_id, null, &pthread_serial_rx, ( void *)&serial_usb );

while( 0==pthread_kill(pthread_id,0

) )

usleep(

5000

); }

printf(

"receive thread is quited\r\n");

pthread_exit(null);

}int

main()

printf(

"%d\r\n

",sizeof

(vehicle));

//serial_send( serial_usb.fd, "this is ok\r\n" );

while( 0==pthread_kill(pthread_id,0

) )

printf(

"serial thread is quited\r\n");

return0;

}

sd

linux下串列埠的阻塞和非阻塞操作

有兩個可以進行控制串列埠阻塞性 同時控制read和write 乙個是在開啟串列埠的時候,open函式是否帶o ndelay 第二個是可以在開啟串列埠之後通過fcntl 函式進行控制。阻塞的定義 對於read,block指當串列埠輸入緩衝區沒有資料的時候,read函式將會阻塞在這裡,移植到串列埠輸入緩...

linux下串列埠的阻塞和非阻塞操作

有兩個可以進行控制串列埠阻塞性 同時控制read和write 乙個是在開啟串列埠的時候,open函式是否帶o ndelay 第二個是可以在開啟串列埠之後通過fcntl 函式進行控制。阻塞的定義 對於read,block指當串列埠輸入緩衝區沒有資料的時候,read函式將會阻塞在這裡,移植到串列埠輸入緩...

linux下串列埠的阻塞和非阻塞操作

有兩個可以進行控制串列埠阻塞性 同時控制read和write 乙個是在開啟串列埠的時候,open函式是否帶o ndelay 第二個是可以在開啟串列埠之後通過fcntl 函式進行控制。阻塞的定義 對於read,block指當串列埠輸入緩衝區沒有資料的時候,read函式將會阻塞在這裡,移植到串列埠輸入緩...