Linux下的C程序实现串口读写,为什么select和read函数的返回值一直为0?

ABigBang 2011-10-28 11:52:59
外部的硬件环境是不是要求串口的2 3 号线相连?

#define BUFSIZE 100
int main(int argc, char **argv)
{
int fd,maxfd,Data;
int nCount,nTotal,i;
struct termios oldtio,newtio;
char dev[15]="/dev/ttyS0";


if((fd = open(dev,O_RDWR | O_NOCTTY ))<0)
{
printf("Can't Open Serial Port: %s!\n",dev);
exit(0);
}


// 保存原来的终端配置
tcgetattr(fd,&oldtio);

// 设置新的终端配置项
setTermios(&newtio,B115200);

// 刷新缓冲区
tcflush(fd, TCIFLUSH);

// 使能新的终端配置
tcsetattr(fd,TCSANOW,&newtio);

char buff[BUFSIZE];
struct timeval tv;
fd_set rfds,watchset;

//初始化
FD_ZERO(&rfds);
FD_ZERO(&watchset);
FD_SET(fd,&watchset);
tv.tv_sec=10;
tv.tv_usec=0;
maxfd = fd + 1;

sscanf(argv[1],"%d",nTotal);

for (i=0;i<nTotal;i++)
{
nCount=write(fd, argv[2], strlen(argv[2]));
printf("send data OK! count=%d\n",nCount);
sleep(1);
}


while(1)
{
rfds = watchset;
printf("maxfd=%d\n",maxfd);
lseek(fd,0,SEEK_SET);
bzero(buf,100);

if(Data=(select(maxfd,&rfds,NULL,NULL,&tv))>0)
{
if(FD_ISSET(fd,&rfds))
{
nCount=read(fd, buff, BUFSIZE);
printf("readlength=%d\n\r",nCount);
buff[nCount]='\0';
printf("%s\n\r",buff);
exit(0);
}
}
else printf("%d\n",Data);
}



//恢复原先的设置
tcsetattr(fd,TCSANOW,&oldtio);

close(fd);

return 0;
}
...全文
1496 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ABigBang 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 windman521 的回复:]
你以为串口是个水池子啊
倒点水进去,还能在抽出来?
[/Quote]

对,通常情况应该是起两个线程来分别进行写读。
我知道这样设计很不合理,但用来做个简单的测试应该没有问题吧?
ABigBang 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 qq120848369 的回复:]
我试了一下,没有问题,你检查一下你的终端设备文件是不是有什么设置问题.



C/C++ code
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <……
[/Quote]

这类对文件进行读写操作的没有问题,最初我进行的就是类似的尝试。
如果是设备文件设置有问题,指的是那些内容的设置呢?通过什么方法来调整呢?

另外使用perror来输出错误,经常出现illega lseek,
例如write后面使用perror 只有在第一次循环的时候,显示为 success 之后的都是illegal seek
是否金额以理解为指针位置有所偏移呢?
windman521 2011-10-29
  • 打赏
  • 举报
回复
你以为串口是个水池子啊
倒点水进去,还能在抽出来?
qq120848369 2011-10-28
  • 打赏
  • 举报
回复
我试了一下,没有问题,你检查一下你的终端设备文件是不是有什么设置问题.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int main()
{
int fd;

if((fd=open("./c.txt",O_CREAT|O_RDWR|S_IRUSR|S_IWUSR))==-1)
{
perror("open");
return 1;
}

const char *str="Hello World";

if(write(fd,str,strlen(str))!=strlen(str))
{
perror("write");
return 2;
}

if(lseek(fd,0,SEEK_SET)==-1)
{
perror("lseek");
return 3;
}

fd_set rSet,rec;
FD_ZERO(&rSet);
FD_SET(fd,&rSet);
rec=rSet;

int nfd;

while(true)
{
if( (nfd=select(fd+1,&rSet,NULL,NULL,NULL))>0 )
{
if(FD_ISSET(fd,&rSet))
{
char buffer[100];
int n;

if( (n=read(fd,buffer,100))>0 )
{
buffer[n]='\0';
printf("%s\n",buffer);
}
else if(n==0)
{
printf("EOF\n");
break;
}
else
{
perror("read");
return 4;
}
}
}
else if(nfd==0)
{
printf("out of time\n");
}
else
{
perror("select");
return 5;
}

rSet=rec;
}

return 0;
}

linux-t4lu:/home/owenliang/csdn/cAndCpp # ./main   
Hello World
EOF

qq120848369 2011-10-28
  • 打赏
  • 举报
回复
没见过同一个进程写一个文件再去读的,我等试试再告诉你。
ABigBang 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 qq120848369 的回复:]
Data=select(maxfd,&rfds,NULL,NULL,&tv) 返回0是超时。

read返回0是对端关闭。
[/Quote]

哦,对,是少了对括号。
select 的0是返回超时,是由于没有可读写或错误的文件,read 如果返回0,表示已到达文件尾或是无可读取的数据。综上原因问题应该是,文件描述符fd指向的文件的数据无法读取。但是write 是成功的,返回了字节数。为什么会没有文件可读呢?

可不可以详细解释下?谢谢!
qq120848369 2011-10-28
  • 打赏
  • 举报
回复
if( (Data=(select(maxfd,&rfds,NULL,NULL,&tv))>0) 少了一个括号。
qq120848369 2011-10-28
  • 打赏
  • 举报
回复
 select() and pselect() return the number of file descriptors contained in the three returned descriptor sets (that is, the total num‐
ber of bits that are set in readfds, writefds, exceptfds) which may be zero if the timeout expires before anything interesting happens.


 ssize_t read(int fd, void *buf, size_t count);
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number.
qq120848369 2011-10-28
  • 打赏
  • 举报
回复
Data=select(maxfd,&rfds,NULL,NULL,&tv) 返回0是超时。

read返回0是对端关闭。
ABigBang 2011-10-28
  • 打赏
  • 举报
回复
write 写入成功
为什么
nCount=read(fd, buff, BUFSIZE)和
Data=select(maxfd,&rfds,NULL,NULL,&tv) 是0啊?

是代码的问题还是硬件原因?
课程背景Modbus 协议是工业自动化控制系统中常见的通信协议,协议的全面理解是个痛点。本课程主讲老师集10多年在Modbus协议学习、使用中的经验心得,结合当前物联网浪潮下Modbus协议开发的痛点,推出这套面向Modbus 协议初学者的课程。本课程不同于以往市面课程只是协议讲解无实现代码,而是采用讲解与实践并重的方式,结合STM32F103ZET6开发板进行手把手编程实践,十分有利于初学者学习。涵盖了学习者在Modbus协议方面会遇到的方方面面的问题,是目前全网首个对Modbus协议进行全面总结的课程。课程名称   协议讲解及实现>>课程内容1、Modbus 协议的基础。2、Modbus协议栈函数编程实现。3、Modbus协议在串行链路编程实现。4、Modbus协议在以太网链路编程实现。5、常见问题的解决方法。带给您的价值通过学习本课程,您可以做到如下:1、全面彻底的理解Modbus协议。2、理解在串行链路,以太网链路的实现。3、掌握Modbus协议解析的函数编程方法,调试工具的使用。4、掌握多个串口,网口同时运行同一个Modbus协议栈的方法。5、掌握Modbus协议下,负数,浮点数等处理方法。讲师简介许孝刚,山东大学工程硕士,副高职称,技术总监。10多年丰富嵌入式系统开发经验,国家软考“嵌入式系统设计师”。2017年获得“华为开发者社区杰出贡献者”奖励。

19,612

社区成员

发帖
与我相关
我的任务
社区描述
系统使用、管理、维护问题。可以是Ubuntu, Fedora, Unix等等
社区管理员
  • 系统维护与使用区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧