移远EC20串口使用阻塞问题
今天我们郭工使用我写的EC20程序发现了一个严重的问题,就是运行一段时间后会出现丢数据的情况。使用供应商的程序却能很好的运行我很奇怪,仔细看了供应商的历程发现他们用的是select机制。
我突然有个灵感是不是我的读取串口导致了串口阻塞?一查果然是。
Linux下直接用read读串口可能会造成堵塞,或数据读出错误。然而用select先查询com口是否可读则可以避免这个问题。但是也会引起另一个问题,那就是会使使用select的线程在没有收到数据时像休眠阻塞一样。因为select是在 一定的时间内循环的去判断串口是否可读。
之前的旧程序
int main()
{unsigned int i;int return_value = 0;unsigned long startCount = 0;//开机计时 重启后30分钟不变化unsigned char Signal_Strength_temp;unsigned char WIFIName_temp[33];int TFcardState;//卡状态 int I_temp;GS_PC_str.RevBufLen = 0;//串口初始化 115200 bps,8 N 1GS_PC_str.fd = Serial_Open("/dev/ttyHS0", B115200, EIGHT_BIT, PARITY_NONE, ONE_BIT, FLOW_CONTROL_NONE);if(GS_PC_str.fd<0){printf("serial open fail\n");return 0;}else{printf("serial open success fd = %d\n",GS_PC_str.fd);}//卡状态TFcardState = Hk_Camera_Get_SD_State(&GS_TF_state);printf("return_value = %d\n", TFcardState);printf("state->f_blocks = %d\n", GS_TF_state.f_blocks);printf("state->f_bavail = %d\n", GS_TF_state.f_bavail);printf("state->used_percent = %d\n", GS_TF_state.can_used_percent);//配置自己的IP地址 HK_Camera_Init_Internet_Ip("192.168.1.5");//拨号状态 GS_Call_state = Hk_Camera_Data_Call();//开启摄像头功能Hk_Camera_Paramete_Init();Hk_Camera_Init_Camera("192.168.1.64", 13851, 0, 3);//开启第1(1~4)Hk_Camera_Start_Camera_Communicate();while(1){//读取信号强度GS_Signal_Strength = Hk_Camera_Get_Signal_Strength();printf("Signal Strength = %d\n", GS_Signal_Strength); if(GS_Signal_Strength>99){Signal_Strength_temp = 98;}else{Signal_Strength_temp = GS_Signal_Strength;}//拨号状态 GS_Call_state = Hk_Camera_Get_Call_Data_State();//读IMEI号 IMEI[0]=0x31; IMEI[1]=0x39; IMEI[2]=0x30; IMEI[3]=0x38; IMEI[4]=0x30; IMEI[5]=0x35; IMEI[6]=0x31; IMEI[7]=0x34;IMEI[8]= 0;//判定摄像头是否在线 GS_camera_state = Hk_Camera_Get_Camera_State_By_Id(0); romdatasCopeToRamDataS("摄像:", WIFIName_temp);//0~4if(GS_camera_state == 1 ){//CURRENT_STATE_NO_CONNECTromdatasCopeToRamDataS("无", WIFIName_temp+5);//5~8 }else if(GS_camera_state == 14 ){//摄像正常romdatasCopeToRamDataS("正常", WIFIName_temp+5);//5~8 }else{//没有配置romdatasCopeToRamDataS("中断", WIFIName_temp+5);//5~8 }//TF卡状态 13romdatasCopeToRamDataS(";TF:",WIFIName_temp+9);//9~12if(TFcardState == (-1)){romdatasCopeToRamDataS(" 无 ",WIFIName_temp+13);//13~16 }else{romdatasCopeToRamDataS("正常",WIFIName_temp+13);//13~16} //卡状态romdatasCopeToRamDataS("\n拨号:", WIFIName_temp+17);//17~22if(GS_Call_state == 0){//CURRENT_STATE_DATA_CALL_SUCCESSromdatasCopeToRamDataS("正常", WIFIName_temp+23);//23~26}else if(GS_Call_state == 3){//CURRENT_STATE_SIM_CARD_ERRORromdatasCopeToRamDataS("SIM", WIFIName_temp+23);//23~26}else if(GS_Call_state == 5){//CURRENT_STATE_DATA_CALL_SERVER_ERRORromdatasCopeToRamDataS("失败", WIFIName_temp+23);//23~26}else if(GS_Call_state == 7){//CURRENT_STATE_INIT_DATA_CALL_ERRORromdatasCopeToRamDataS("失败", WIFIName_temp+23);//23~26}else if(GS_Call_state == 9){//CURRENT_STATE_CANT_GET_DATA_CALL_INFOromdatasCopeToRamDataS("失败", WIFIName_temp+23);//23~26}else if(GS_Call_state == 10){//CURRENT_STATE_HAVE_DATA_CALLromdatasCopeToRamDataS("拨号", WIFIName_temp+23);//23~26} else{//CURRENT_STATE_START_DATA_CALL_ERRORromdatasCopeToRamDataS("失败", WIFIName_temp+23);//23~26}romdatasCopeToRamDataS("C", WIFIName_temp+27);//27~27 //123456WIFIName_temp[28] = (startCount%1000)/100+'0';WIFIName_temp[29] = (startCount%100)/10+'0';WIFIName_temp[30] = (startCount%10)+'0';WIFIName_temp[31] = 0;printf("IMEI = %s\n", IMEI);printf("WIFIName_temp = %s\n", WIFIName_temp);printf("信号强度 = %d\n", Signal_Strength_temp);GS_PC_str.SendBufLen =WX_3_SendData(Signal_Strength_temp,IMEI, WIFIName_temp,GS_PC_str.sendBuf);if(GS_PC_str.SendBufLen == 0){printf("转换数据错误 字节数= 0\n"); usleep(1000000);}else if(GS_PC_str.SendBufLen >500){printf("转换数据错误 字节数>500\n");usleep(1000000);}else{printf("转换数据正常 字节数%d\n",GS_PC_str.SendBufLen ); Serial_Send(GS_PC_str.fd, GS_PC_str.sendBuf, GS_PC_str.SendBufLen);//发送数据 usleep(1000000);I_temp = Serial_Receive(GS_PC_str.fd, GS_PC_str.RevBuf, 500);//读接收数据if(I_temp>0){printf("主板回应字节数:%d\n",I_temp);}else{printf("主板没有回应\n");}}//计数 startCount++;if(startCount>999){startCount=999; }}return 0;
}
因为直接去read串口会出现后面串口堵塞再也不会发生任何数据和接收数据直接堵死。
修改后如下
int main()
{unsigned int i;fd_set fdset;struct timeval timeout = {3, 0};int iRet;int return_value = 0;unsigned long startCount = 0;//开机计时 重启后30分钟不变化unsigned char Signal_Strength_temp;unsigned char WIFIName_temp[33];int TFcardState;//卡状态 int I_temp;GS_PC_str.RevBufLen = 0;//串口初始化 115200 bps,8 N 1GS_PC_str.fd = Ql_UART_Open("/dev/ttyHS0", 115200, FC_NONE);if(GS_PC_str.fd<0){printf("serial open fail\n");return 0;}else{printf("serial open success fd = %d\n",GS_PC_str.fd);}ST_UARTDCB dcb = {.flowctrl = FC_NONE, //none flow control.databit = DB_CS8, //databit: 8.stopbit = SB_1, //stopbit: 1.parity = PB_NONE, //parity check: none.baudrate = B_115200 //baudrate: 115200};iRet = Ql_UART_SetDCB(GS_PC_str.fd, &dcb);printf("SET DCB ret: %d\n", iRet);iRet = Ql_UART_GetDCB(GS_PC_str.fd, &dcb);//卡状态TFcardState = Hk_Camera_Get_SD_State(&GS_TF_state);printf("return_value = %d\n", TFcardState);printf("state->f_blocks = %d\n", GS_TF_state.f_blocks);printf("state->f_bavail = %d\n", GS_TF_state.f_bavail);printf("state->used_percent = %d\n", GS_TF_state.can_used_percent);//配置自己的IP地址 HK_Camera_Init_Internet_Ip("192.168.1.5");//拨号状态 GS_Call_state = Hk_Camera_Data_Call();//开启摄像头功能Hk_Camera_Paramete_Init();Hk_Camera_Init_Camera("192.168.1.64", 13851, 0, 3);//开启第1(1~4)Hk_Camera_Start_Camera_Communicate();while(1){//读取信号强度GS_Signal_Strength = Hk_Camera_Get_Signal_Strength();printf("Signal Strength = %d\n", GS_Signal_Strength); if(GS_Signal_Strength>99){Signal_Strength_temp = 98;}else{Signal_Strength_temp = GS_Signal_Strength;}//拨号状态 GS_Call_state = Hk_Camera_Get_Call_Data_State();//读IMEI号 IMEI[0]=0x31; IMEI[1]=0x39; IMEI[2]=0x30; IMEI[3]=0x38; IMEI[4]=0x30; IMEI[5]=0x35; IMEI[6]=0x31; IMEI[7]=0x34;IMEI[8]= 0;//判定摄像头是否在线 GS_camera_state = Hk_Camera_Get_Camera_State_By_Id(0); romdatasCopeToRamDataS("摄像:", WIFIName_temp);//0~4if(GS_camera_state == 1 ){//CURRENT_STATE_NO_CONNECTromdatasCopeToRamDataS("无", WIFIName_temp+5);//5~8 }else if(GS_camera_state == 14 ){//摄像正常romdatasCopeToRamDataS("正常", WIFIName_temp+5);//5~8 }else{//没有配置romdatasCopeToRamDataS("中断", WIFIName_temp+5);//5~8 }//TF卡状态 13romdatasCopeToRamDataS(";TF:",WIFIName_temp+9);//9~12if(TFcardState == (-1)){romdatasCopeToRamDataS(" 无 ",WIFIName_temp+13);//13~16 }else{romdatasCopeToRamDataS("正常",WIFIName_temp+13);//13~16} //卡状态romdatasCopeToRamDataS("\n拨号:", WIFIName_temp+17);//17~22if(GS_Call_state == 0){//CURRENT_STATE_DATA_CALL_SUCCESSromdatasCopeToRamDataS("正常", WIFIName_temp+23);//23~26}else if(GS_Call_state == 3){//CURRENT_STATE_SIM_CARD_ERRORromdatasCopeToRamDataS("SIM", WIFIName_temp+23);//23~26}else if(GS_Call_state == 5){//CURRENT_STATE_DATA_CALL_SERVER_ERRORromdatasCopeToRamDataS("失败", WIFIName_temp+23);//23~26}else if(GS_Call_state == 7){//CURRENT_STATE_INIT_DATA_CALL_ERRORromdatasCopeToRamDataS("失败", WIFIName_temp+23);//23~26}else if(GS_Call_state == 9){//CURRENT_STATE_CANT_GET_DATA_CALL_INFOromdatasCopeToRamDataS("失败", WIFIName_temp+23);//23~26}else if(GS_Call_state == 10){//CURRENT_STATE_HAVE_DATA_CALLromdatasCopeToRamDataS("拨号", WIFIName_temp+23);//23~26} else{//CURRENT_STATE_START_DATA_CALL_ERRORromdatasCopeToRamDataS("失败", WIFIName_temp+23);//23~26}romdatasCopeToRamDataS("C", WIFIName_temp+27);//27~27 //123456WIFIName_temp[28] = (startCount%1000)/100+'0';WIFIName_temp[29] = (startCount%100)/10+'0';WIFIName_temp[30] = (startCount%10)+'0';WIFIName_temp[31] = 0;printf("IMEI = %s\n", IMEI);printf("WIFIName_temp = %s\n", WIFIName_temp);printf("信号强度 = %d\n", Signal_Strength_temp);GS_PC_str.SendBufLen =WX_3_SendData(Signal_Strength_temp,IMEI, WIFIName_temp,GS_PC_str.sendBuf);/*GS_PC_str.SendBufLen = 49;I_temp = Serial_Receive(GS_PC_str.fd, GS_PC_str.RevBuf, 250);//读接收数据 if(I_temp>0){printf("主板回应字节数:%d\n",I_temp);}else{printf("主板没有回应\n");}//计数 startCount++;if(startCount>999){startCount=999; }usleep(1000000); Serial_Send(GS_PC_str.fd, GS_PC_str.sendBuf, GS_PC_str.SendBufLen);//发送数据*/startCount++;if(startCount>999){startCount=999; }FD_ZERO(&fdset); FD_SET(GS_PC_str.fd, &fdset); iRet = select(GS_PC_str.fd + 1, &fdset, NULL, NULL, &timeout);if (-1 == iRet){printf("< failed to select >\n");exit(-1);}else if (0 == iRet){// no data in Rx bufferprintf("< no data >\n");timeout.tv_sec = 3;timeout.tv_usec = 0;}else{// data is in Rx dataif (FD_ISSET(GS_PC_str.fd, &fdset)) {do {memset(GS_PC_str.RevBuf, 0x0, sizeof(GS_PC_str.RevBuf));iRet = Ql_UART_Read(GS_PC_str.fd, GS_PC_str.RevBuf, 100);printf("> read(uart)=%d:%s\n", iRet, GS_PC_str.RevBuf);} while (100 == iRet);}}usleep(1000000);iRet = Ql_UART_Write(GS_PC_str.fd, GS_PC_str.sendBuf, GS_PC_str.SendBufLen);printf("< write(fd=%d)=%d\n", GS_PC_str.fd, iRet);}return 0;
}
这样就能很正常的运行,美中不足就是没数据时会"卡"3秒。所以建议使用多线程去写串口
移远EC20串口使用阻塞问题相关推荐
- 移远EC20模块通过物理串口连接PC或者MCU,通过AT命令进行控制
关键词:移远 EC20 UART 物理串口 1.8V AT命令 MCU PC 控制 概述:EC20一般通过USB和运行Windows的PC.运行安卓或Linux的嵌入式平台进行连接,以 ...
- ec20驱动_物联网基础:移远EC20固件升级
使用移远 QFlash_V4.14 工具升级移远 EC20 4G模块固件 1 准备工作 1.1 EC20 USB驱动安装 安装过程参考移远官方手册:<Quectel_LTE&5G_Win ...
- 4G模块使用记录移远EC20、BC20
目录 0. 概述 硬件连接 -- UART 休眠管脚的使用 硬件连接 -- USB USB线序定义 驱动安装 抓取模组log 模组型号和SIM卡 模组区别 本地卡和漫游卡 SIM卡和APN 1. EC ...
- 海思3531添加移远EC20 4G模块
在linux下加载驱动有两种常用方法:静态加载和动态加载. 静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调用.静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新编译和下载内核,效率 ...
- 物联网基础:移远EC20固件升级
使用移远 QFlash_V4.14 工具升级移远 EC20 4G模块固件 1 准备工作 1.1 EC20 USB驱动安装 安装过程参考移远官方手册:<Quectel_LTE&5G_Win ...
- 移远EC20 4G模块LTE开发板三网通模块 MQTT阿里云物联网
摘自:移远EC20 4G模块LTE开发板三网通模块 MQTT阿里云物联网STM32代码-电脑看 地址:https://www.bilibili.com/video/BV1EJ411P7CR?from= ...
- 树莓派烧写OpenWrt系统后外接华为ME909或移远EC20 4G LTE模块实现4G软路由即MiFi
By Mcuzone 关键词:OpenWrt 4G LTE 软路由 华为ME909s 移远 EC20 树莓派 Raspberry Pi 3B 4B WiFi 热点 SSID ...
- 移远EC20设置RNDIS模式拨号上网
背景 4G模块原本使用QMI方式拨号上网,客户反馈某种定制卡不能上网,切换下拨号模式看下设备能不能正常上网: 过程 openwrt中如果使用RNDIS模式上网需要在kernel配置中使能以下项: Km ...
- OpenHarmony3.1适配移远EC20模组4G上网功能
OpenHarmony3.1适配移远EC20模组4G上网功能 一.概述 通过阅读本篇文档,您将学习到如何适配移远EC20模组到OpenHarmony3.1(以下简称OHOS),并添加4G上网功能. 本 ...
- 【openwrt】使用4G模块 移远EC20/25(2)pppd拨号与配置
[openwrt]使用4G模块 移远EC20/25 :2)pppd拨号与配置 参考 Raspberrypi -- 实现 EC20 4G模块PPP拨号上网_梦小羊的博客-CSDN博客 添加链接描述 == ...
最新文章
- UVA10970大块巧克力
- 浅谈C++的virtual 动态绑定。
- [SQL]批量修改存储过程视图
- AngularJS中Directive指令系列 - 基本用法
- spring AOP 取得web的session
- [转帖]看完这篇文章你还敢说你懂JVM吗?
- Python豆瓣书籍信息爬虫
- 求大佬解决0x00881340 处有未经处理的异常(在 ConsoleApplication1.exe 中): 0xC0000005: 写入位置 0x00993B8C 时发生访问冲突。
- 《SAP从入门到精通》——第1章 SAP系统基本概念 1.1 SAP公司及其产品介绍
- redis 下载源地址
- 用三元组存储稀疏矩阵,实现其快速转置及矩阵相乘
- aic值检验 p值_R语言入门之独立性检验
- WPF的介绍和XAML语言
- 腾讯大王卡 蚂蚁宝卡 区别 哪个好
- 【转】我在赶集网工作的两个月总结
- amd锐龙笔记本cpu怎么样_AMD发布两款锐龙笔记本CPU
- SAP系统核心模块都有哪些?
- 应用宝发布apk问题
- 【Linux】U盘安装Ubuntu 18.04之启动盘制作工具选择
- 《遥感导论》2001年高等教育出版社出版,作者梅安新、彭望琭、秦其明、刘慧平