|
我的测试环境是用PC的串口和另一台嵌入设备通信,我发送多少数据它就完整的返回多少数据;
现在出现的问题每向串口write几十次数据都会有一次write不成功,不成功的几率在%2;而且在write不成功时,write函数也不会返回错误值,这样我的程序就无法知道这次write是否成功了.
不知为什么会有这样的问题,该如何解决这个问题呢?哪位大虾能提供一点帮助
- #include <stdio.h> /*标准输入输出定义*/
- #include <stdlib.h> /*标准函数库定义*/
- #include <string.h>
- #include <unistd.h> /*Unix 标准函数定义*/
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h> /*文件控制定义*/
- #include <errno.h> /*错误号定义*/
- #include <sys/ioctl.h>
- #include <signal.h>
- #include <termios.h> /*PPSIX 终端控制定义*/
- //
- // 串口设备信息结构
- //
- typedef struct tty_info_t {
- int fd; // 串口设备ID
- char name[24]; // 串口设备名称,例:"/dev/ttyS0"
- struct termios ntm; // 新的串口设备选项
- struct termios otm; // 旧的串口设备选项
- }
- TTY_INFO;
- ///////////////////////////////////////////////////////////////////////////////
- // 初始化串口设备并进行原有设置的保存
- TTY_INFO *readyTTY(int id) {
- TTY_INFO *ptty;
- ptty = (TTY_INFO *)malloc(sizeof(TTY_INFO));
- if(ptty == NULL)
- return NULL;
- memset(ptty,0,sizeof(TTY_INFO));
- sprintf(ptty->name,"/dev/ttyS%d",id);
- //
- // 打开并且设置串口
- //
- ptty->fd = open(ptty->name, O_RDWR | O_NOCTTY |O_NDELAY);
- if (ptty->fd <0) {
- free(ptty);
- return NULL;
- }
- //
- // 取得并且保存原来的设置
- //
- tcgetattr(ptty->fd,&ptty->otm);
- return ptty;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // 清理串口设备资源
- int cleanTTY(TTY_INFO *ptty) {
- //
- // 关闭打开的串口设备
- //
- if(ptty->fd>0) {
- tcsetattr(ptty->fd,TCSANOW,&ptty->otm);
- close(ptty->fd);
- ptty->fd = -1;
- free(ptty);
- ptty = NULL;
- }
- return 0;
- }
- int total_read = 0;
- size_t readn(int fd,void *vptr,size_t len) {
- int nleft,nread;
- char *ptr;
- ptr = vptr;
- nleft = len;
- while(nleft > 0) {
- ioctl(fd, FIONREAD, &nread);
- if(nread > 0) {
- if((nread = read(fd,ptr,nleft)) < 0) {
- if(errno == EINTR)
- nread = 0;
- else
- return -1;
- } else if(nread == 0)
- break;
- nleft-= nread;
- ptr += nread;
- printf("read %d bytes\n",nread);
- total_read += nread;
- } else {
- usleep(100);
- }
- }
- return len - nleft;
- }
- size_t writen(int fd,const void *vptr,size_t len) {
- int n;
- size_t left = len;
- const void *ptr = vptr;
- int i;
- for(i = 0; i < len; i++) {
- unsigned char *c = (char *)(vptr + i);
- printf("%x ",*c);
- }
- while(left > 0) {
- if((n = write(fd,ptr,len)) > 0) {
- left -= n;
- ptr += n;
- }
- if(n < 0 && errno != EINTR) {
- return -1;
- }
- }
- return len;
- }
- static int setTTYArbitraryAttrib(TTY_INFO *ptty) {
- struct termios *newtio = &ptty->ntm;
-
- if(tcgetattr(ptty->fd,newtio) != 0) {
- perror("tcgetattr");
- return -1;
- }
-
- bzero(newtio,sizeof(struct termios));
- newtio->c_cflag &=~CSIZE;
- newtio->c_cflag |= CS8; //8位数据位
- newtio->c_cflag &= ~PARENB; /* Clear parity enable */
- newtio->c_iflag &= ~INPCK; /* Enable parity checking */
- newtio->c_cflag &= ~CSTOPB;
- newtio->c_cc[VTIME] = 0;
- newtio->c_cc[VMIN] = 1;
- newtio->c_cflag |= (CLOCAL|CREAD);
- newtio->c_cflag |= CLOCAL | CREAD;
- newtio->c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
- newtio->c_oflag &= ~OPOST;
- newtio->c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
- cfsetispeed(newtio,B9600);
- cfsetospeed(newtio,B9600);
- tcflush(ptty->fd,TCIFLUSH);
- if(tcsetattr(ptty->fd,TCSANOW,newtio) != 0) {
- perror("tcsetattr");
- return -1;
- }
- return 0;
- }
- static void sig_int(int n) {
- printf("total_read:%d\n",total_read);
- exit(0);
- }
- int main(int argc,char **argv) {
- TTY_INFO *ptty;
- int nbyte,i;
- char send_buf[] = {
- 0xFF,0xFF,0xFF,0xFF,
- 0x11,0x11,
- 0x22,
- 0x00,0x01,
- 0x05,
- 0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x05,
- 0x53,0x02,0x02,0x01,0x01,
- 0x03
- };
- char recv_buf[26];
- signal(SIGINT,sig_int);
- ptty = readyTTY(0);
- if(ptty == NULL) {
- printf("readyTTY(0) error\n");
- return 1;
- }
- setTTYArbitraryAttrib(ptty);
- while(1) {
- if(writen(ptty->fd,send_buf,sizeof(send_buf)) < 0) {
- printf("writen failed\n");
- return -1;
- } else {
- printf("writen successfully\n");
- }
- nbyte = readn(ptty->fd,recv_buf,sizeof(recv_buf));
- if(nbyte < 0) {
- perror("readn");
- return -1;
- }
- for(i = 0; i < nbyte; i++) {
- unsigned char c = recv_buf[i];
- printf("%x ",c);
- }
- printf("\n");
- }
- cleanTTY(ptty);
- return 0;
- }
复制代码 |
|