当前位置: 技术问答>linux和unix
急!!串口接收程序占有大量CPU,各位帮忙,来者有分!!!
来源: 互联网 发布时间:2015-02-06
本文导语: 我编写了一个读串口的守护程序,即用了一个死循环一直读串口,有数据就处理, 可是占用了99%的CPU资源,下面是源代码,各位高手看看有什么办法可以减少占有的 CPU资源,并且能及时的读取串口的数据,很急!各...
我编写了一个读串口的守护程序,即用了一个死循环一直读串口,有数据就处理,
可是占用了99%的CPU资源,下面是源代码,各位高手看看有什么办法可以减少占有的
CPU资源,并且能及时的读取串口的数据,很急!各位高手帮忙啊,谢谢了
#include
#include
#include
#include
#include
#include
#define BAUDRATE B19200
open_port(void)
{
int fd,speed;
struct termios newtio;
fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY);
if(fd==-1)
{
perror("open_port:Unable to open /dev/ttyS0");
}
tcgetattr(fd,&newtio);
bzero(&newtio,sizeof(newtio));
//setting c_cflag
newtio.c_cflag |= (CLOCAL|CREAD);
newtio.c_cflag &=~PARENB;
newtio.c_cflag &=~PARODD;
newtio.c_cflag &=~CSTOPB;
newtio.c_cflag &=~CSIZE;
newtio.c_cflag |=CS8;
newtio.c_oflag|=OPOST;
//setting c_iflag
newtio.c_iflag &=~(IXON|IXOFF|IXANY);
cfsetispeed(&newtio,BAUDRATE);
cfsetospeed(&newtio,BAUDRATE);
printf("speed=%dn",BAUDRATE);
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
return(fd);
}
main()
{
int fd,n,i;
unsigned char buff[256];
fd = open_port();
while(1){
n = read(fd,buff,256);
if(n>0){
//数据处理部分
}
}
close(fd);
}
可是占用了99%的CPU资源,下面是源代码,各位高手看看有什么办法可以减少占有的
CPU资源,并且能及时的读取串口的数据,很急!各位高手帮忙啊,谢谢了
#include
#include
#include
#include
#include
#include
#define BAUDRATE B19200
open_port(void)
{
int fd,speed;
struct termios newtio;
fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY);
if(fd==-1)
{
perror("open_port:Unable to open /dev/ttyS0");
}
tcgetattr(fd,&newtio);
bzero(&newtio,sizeof(newtio));
//setting c_cflag
newtio.c_cflag |= (CLOCAL|CREAD);
newtio.c_cflag &=~PARENB;
newtio.c_cflag &=~PARODD;
newtio.c_cflag &=~CSTOPB;
newtio.c_cflag &=~CSIZE;
newtio.c_cflag |=CS8;
newtio.c_oflag|=OPOST;
//setting c_iflag
newtio.c_iflag &=~(IXON|IXOFF|IXANY);
cfsetispeed(&newtio,BAUDRATE);
cfsetospeed(&newtio,BAUDRATE);
printf("speed=%dn",BAUDRATE);
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
return(fd);
}
main()
{
int fd,n,i;
unsigned char buff[256];
fd = open_port();
while(1){
n = read(fd,buff,256);
if(n>0){
//数据处理部分
}
}
close(fd);
}
|
static fd_set rfds;
static struct timeval tv;
static int retval;
unsigned char myread( int fd );
unsigned char
myread( int fd )
{
FD_ZERO(&rfds);
FD_SET(0, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(fd + 1, &rfds, NULL, NULL, &tv);
if (retval)
return read( fd .. );
}
static struct timeval tv;
static int retval;
unsigned char myread( int fd );
unsigned char
myread( int fd )
{
FD_ZERO(&rfds);
FD_SET(0, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(fd + 1, &rfds, NULL, NULL, &tv);
if (retval)
return read( fd .. );
}
|
main()
{
int fd,n,i;
unsigned char buff[256];
fd = open_port();
while(1){
n = read(fd,buff,256);
if(n>0){
//数据处理部分
}
usleep(1); //中间加一行
}
close(fd);
}
cpu占用率将会是百分之零点几。
{
int fd,n,i;
unsigned char buff[256];
fd = open_port();
while(1){
n = read(fd,buff,256);
if(n>0){
//数据处理部分
}
usleep(1); //中间加一行
}
close(fd);
}
cpu占用率将会是百分之零点几。
|
如果你想使用查询的方法的话, 就在循环里面加sleep, 但sleep(20)睡的
时间也太长了. :) usleep(0)就可以了。
如果你的程序是串口的守护进程, 不需要处理其它的并发输入的话, 还有一个
更简单的方法:
在你设置tty的时候, 加上:
newtio.c_cc[VMIN] = 1;
newtio.c_cc[VTIME] = 0;
就可以了. 这样你在串口fd上的read会阻塞直到有数据可读...
问题:
如果把newtio.c_cc[VMIN]设置为0的话,在这个fd上的select会不起作用!
即使有数据进来都会超时. 郁闷!
时间也太长了. :) usleep(0)就可以了。
如果你的程序是串口的守护进程, 不需要处理其它的并发输入的话, 还有一个
更简单的方法:
在你设置tty的时候, 加上:
newtio.c_cc[VMIN] = 1;
newtio.c_cc[VTIME] = 0;
就可以了. 这样你在串口fd上的read会阻塞直到有数据可读...
问题:
如果把newtio.c_cc[VMIN]设置为0的话,在这个fd上的select会不起作用!
即使有数据进来都会超时. 郁闷!
|
在循环里面加一个Sleep(20)
CPU全部被你独占了,你得释放
CPU全部被你独占了,你得释放
|
改用select系统调用,select的主要作用是监视一组描述符,如果某一被监视fd有数据可读(或可写、异常),则select返回,否则,调用select的进程会进入睡眠,不浪费CPU资源。
详细用法请:man 2 select
详细用法请:man 2 select
|
同意楼上的做法。如果串口没有数据时,阻塞,能够明显的较低cpu资源。
http://hackerbbs.uni.cc
http://hackerbbs.uni.cc
|
select
建议你看一下《UNIX高级编程》一书的相关章节。
建议你看一下《UNIX高级编程》一书的相关章节。