Linux 2.6.23。接收错误。读取函数返回-1

时间:2012-04-21 11:44:33

标签: linux embedded embedded-linux

请参阅以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <termios.h>

#define BAUDRATE    B115200
#define SER_DEVICE  "/dev/ttyS0"
#define FALSE       0
#define TRUE        1


int main()
{
int fd,c,res,i,n;
struct termios oldtio,newtio;
unsigned char buf[255] = "WELCOME TO THE WORLD OF LINUX PROGRAMMING\n";
unsigned char buf2[255]= {"\0"};
//Opening a Device for Reading Writing.
//O_NOCTTY : - The Port Never Becomes the Controlling Terminal of the Process.
//O_NDELAY : - Use NON-Blocking IO. on some system this also means Deactivating the DCD line.

fd=open("/dev/ttyS0",O_RDWR | O_NOCTTY | O_NDELAY);

if(fd<0)
{
printf("\nError in opening the File\n");
exit(0);
}
else
{
printf("File Opened  SuccessFull..HurraYYY !!!!1\n");
}

//printf("--------------Test Begin---------------\n");

//Save Current Serial Port Settings

tcgetattr(fd,&oldtio);
//clear the struct for New port settings
memset(&newtio,0,sizeof(newtio));

//Baud rate : Set bps rate .
//You could also use cfsetispeed and cfsetospeed.
//CRTSCTS : Output Hardware Flow control
//CS8 : 8n1(8bit No Parity 1 Stopbit)
//CLOCAL : local connection no modem control
//CREAD : Enable Receiving character
//printf("Setting Configuration for Port");
newtio.c_cflag |= (BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD);

//IGNPAR : Ignore bytes with parity error.
//ICRNL : map CR to NL 
//printf("Setting Parity\n");
newtio.c_cflag |= (IGNPAR | ICRNL);

//RAW output
//printf("Raw Output\n");
newtio.c_oflag = 0;
//printf("Enabling Canonical format \n");
//ICANON : Enable canonical input.
newtio.c_lflag |= ICANON;
//printf("Initialising Char\n");
//Initialise all characters
newtio.c_cc[VMIN] = 1;   /*Blocking read until one character arrives*/
newtio.c_cc[VTIME] = 0;  /*Inter character timer unused*/

/*
Now clean the Modem Line and Activate the Settings for the Port.
*/
tcflush(fd,TCIFLUSH);
printf("Flushing Lines\n");
tcsetattr(fd,TCSANOW,&newtio);


n=write(fd,&buf,42);
printf("n=%d",n);


for(i=0;i<sizeof(unsigned int);i++);

for(i=0;i<sizeof(unsigned int);i++);
for(i=0;i<sizeof(unsigned int);i++);
for(i=0;i<200;i++)
printf("");
n=0;
n = read(fd,&buf2,42);
if(n==-1)
{
printf("\nError in Receiving");
}
else
printf("Received String = %s",buf2);

/*
Restore the Old Port Setting
*/

tcsetattr(fd,TCSANOW,&oldtio);

printf("==============TEST END==============\n");

close(fd);
}

我能够传输超级终端上出现的字符串。但函数读取返回值为-1。 我发现的可能性是: 1.接收配置错误。 2.需要或不需要回退。

我尝试了循环回来,但它不起作用。 我在while(1)

中执行了代码
  
    

传输ans接收...如果读取返回东西!= -1 ..break从循环。但那不起作用。     在读/写周期中应该添加的最小延迟是多少。

  

我在MPC 8641d处理器上执行此代码。

请你的建议对我很重要。

希望你的证据!!!! :)

2 个答案:

答案 0 :(得分:2)

要知道read()失败的详细原因,您需要查看全局变量errno中存储的值(这在read页面中有说明)。一种简单的方法是在打印失败消息时使用perror()而不是printf() - perror()将附加一个人类可读的字符串,告诉您原因。

答案 1 :(得分:1)

在此之前阅读John Zwinck的答案;)

有关errno:http://www.gnu.org/software/libc/manual/html_node/Checking-for-Errors.html

的背景信息

详细说明特定错误WRT的重要性:不是所有的“错误”都意味着“你做错了什么”或“这个连接无法读取”。它们可能只是意味着此时无法读取此连接,例如,如果errno在非阻塞连接上是EAGAIN。

这意味着您必须弄清楚错误是什么,如果是这样,那么如何处理它。然后你必须专门测试errno,例如:

#include <errno.h>

int bytes = read(...);
if (bytes == -1) {
// example of an error which may happen under normal conditions
// for certain kinds of file descriptors:
    if (errno == EAGAIN) {
        // handle appropriately
    } else {
        // this is a real error which should not happen
    }
}

您可以通过打印errno的int值并查看errno.h来查找常量。实际上,它们实际上位于errno.h包含的文件中,例如/usr/include/asm-generic/errno.h和errno-base.h。我系统中前者的随机示例:

#define ECOMM 70 /* Communication error on send */

所以perror()或strerror()会(可能)报告“发送时的通信错误”,但无论如何,这个的int值是70. 不要在你的代码中使用它 ,它们可以因实施而异; #include <errno.h>并使用常量ECOMM