android 5.1 设备上使用 usb2com 时 【 tcgetattr() failed 】 错误问题解决

来源:互联网 发布:怎样下载电子表格软件 编辑:程序博客网 时间:2024/06/09 22:59

先利用Android 源码编译一个小测试程序:

//test_tty.c

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <fcntl.h>#include <termios.h>#include <errno.h>#include <pthread.h>#include <string.h>#include <stdbool.h>#include <termios.h>//#include <cutils/Log.h>//#include <utils/Log.h>//#define  LOG_TAG    "test_tty"#define READLENTH 256int uartOpen(char *uartDevicePath,int speed,int dataWidth,int nstopBit){//Infoint fd=-1;struct termios new_cfg,old_cfg; printf("uart path=%s\n",uartDevicePath);  //open devicefd=open(uartDevicePath,O_RDWR | O_NOCTTY );    if(fd==-1){        printf("open failed!\n");        return -1;    }//preserve the old configuration    if(tcgetattr(fd,&old_cfg)!=0){        printf("Old config preserve failed!\n");        return -1;    }//set modenew_cfg.c_cflag |=CLOCAL |CREAD;//set baudrateswitch(speed){case 1800:{cfsetispeed(&new_cfg,B1800);cfsetospeed(&new_cfg,B1800);}break;case 2400:{   cfsetispeed(&new_cfg,B2400);   cfsetospeed(&new_cfg,B2400);}break;  case 4800:{   cfsetispeed(&new_cfg,B4800);   cfsetospeed(&new_cfg,B4800);}break;  case 9600:{   cfsetispeed(&new_cfg,B9600);   cfsetospeed(&new_cfg,B9600);}break;  case 19200:{   cfsetispeed(&new_cfg,B19200);   cfsetospeed(&new_cfg,B19200);  }break;  case 38400:{   cfsetispeed(&new_cfg,B38400);   cfsetospeed(&new_cfg,B38400);}break;  case 57600:{   cfsetispeed(&new_cfg,B57600);   cfsetospeed(&new_cfg,B57600);}break;  case 115200:{   cfsetispeed(&new_cfg,B115200);   cfsetospeed(&new_cfg,B115200);}break;  default:{  cfsetispeed(&new_cfg,B115200);  cfsetospeed(&new_cfg,B115200);  }break;}//set size of datanew_cfg.c_cflag &=~CSIZE;switch(dataWidth){case 5:{new_cfg.c_cflag |=CS5;}break;case 6:{new_cfg.c_cflag |=CS6;}break;case 7:{new_cfg.c_cflag |=CS7;}break;case 8:{new_cfg.c_cflag |=CS8;}break;default :{new_cfg.c_cflag |=CS8;}break;}//set stopbitif(nstopBit == 2)new_cfg.c_cflag |=(CSTOPB);else if(nstopBit == 1)new_cfg.c_cflag &=~(CSTOPB);//set waittime outnew_cfg.c_cc[VTIME]=80;  // n * 100ms new_cfg.c_cc[VMIN]=0;//startif(-1==tcsetattr(fd,TCSANOW,&new_cfg)){printf("Uart setting failed!\n");return -1;}return fd;}int main(int argc, char *argv[]){    char buff[READLENTH] = {'\0'};    int nread = 0;    char path[20] = "/dev/ttyUSB0";         int fd = 0;        if(argc==2){        printf("%s\n", argv[1]);        memset(path, 0, strlen(path));        memcpy(path, argv[1], strlen(argv[1]));    }    fd = uartOpen(path, 115200, 8, 1);    if(fd<0){    printf("open error .....\n");        return -1;    }printf("runing .....\n");    if(  (nread = read(fd, buff, READLENTH)) > 0 ){         buff[nread+1] = '\0';            printf("\nLen: %d\n",nread);             printf("str: %s\n", buff);    }else{        printf("read no data..\n");    }close(fd);    return 0;}

//android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)#LOCAL_C_INCLUDES :=$(LOCAL_PATH)/includeLOCAL_MODULE := test_ttyLOCAL_SRC_FILES := test_tty.cLOCAL_LDLIBS := -lloginclude $(BUILD_EXECUTABLE)

如何编译参考: http://www.cnblogs.com/7725657/p/5546249.html

注意,测试代码默认打开使用 /dev/ttyUSB0,如果是其它设备节点, 需要指定  ./test_tty /dev/ttyUSBx 。运行效果是,代码会阻塞在read处,8s超时后返回。


一切正常,将这个代码用jni封装给上层用时发现报错: 

uART setting failed!

查看设备节点权限,发现 0666 没毛病。多次尝试未解决。于是去找其它代码。
然后找到了google 的 serialport-demo ,先试的apk,安装后发现可以正常使用,然后编译源码安装后,居然报错 (tcgetattr() failed)好神奇,开始怀疑编译环境的问题。 什么
serialport-demo的相关下载地址:
源码下载地址:  https://github.com/cepr/android-serialport-api   
apk 下载地址: https://code.google.com/archive/p/android-serialport-api/downloads


在找 tcgetattr() failed  解决办法时,幸运的找到了这篇文章: https://stackoverflow.com/questions/44805009/android-native-open-serial-port   根据这篇文章找到了这篇博客:http://m.blog.csdn.net/caojengineer/article/details/51838394  ,然后明白termios.h file which has changed after Android 19 or Android 21.  解决办法,就是把csdn这边博文里面的termios.h 文件copy 到jni 的目录下,重新编译一下so 。然后运行 ok ....


修改后的工程目录结构如下:


阅读全文
0 0
原创粉丝点击