概要:基于rv1126平台调试SIMCOM 7670C 4G模块。
1,内核配置及内核代码修改
1.1按照芯片data sheet修改kernel代码,添加PID和VID。
此处根据不同的芯片按照其datasheet进行修改。
1.2 内核配置修改
1.2.1 打开USB gadget的RNDIS功能
1.2.2使能 USB 串口 GSM、CDMA 驱动
1.2.3,使能USB network,配置rndis host
2.1 如果内核配置和代码修改正确,设备启动后,ifconfig -a可以看到usb0节点
2.2 用AT指令测试4G模块与主控是否通讯正常
发送如下指令,如果看到回复OK,就证明4G模块与主控通讯正常。
至此驱动层应该算调试OK了。
cat /dev/ttyUSB2 &
echo -e “at\r\n”>/dev/ttyUSB2
fd_Card1 = open("/dev/ttyUSB1", O_RDWR);//打开4G USB串口节点
iot_tty_set_speed(st_tty.fd_net, 115200); //串口配置,关回显
iot_tty_set_Parity(st_tty.fd_net, 8, 'N', 1);
//AT指令发送的函数
iot_tty_send(&st_tty, "AT+CSQ\r\n", &errcode, buf);
int iot_tty_send(tty_dev_t *tty, char *cmd, int *errcode, char *result)
{
char buf[MAX_AT_SIZE];
fd_set rdfds;
struct timeval tv;
int count = 0; //记录超时次数,多次无法获取结果直接退出了,避免发生阻塞
int i;
int ret;
int error_cnt = 0;
BOOL bRecv = FALSE; //是否已经接收过数据
char *ptr = NULL;
char cmd_tmp[64] = {0}; //去掉AT和? \r\n 只保留参数
*errcode = 0;
if((ptr=strstr(cmd, "\r")) != NULL)
{
memcpy(cmd_tmp, cmd, ptr - cmd); //去掉 \r
}
if((ptr=strstr(cmd_tmp, "?")) != NULL)
{
*ptr = '\0';
}
if((ptr=strstr(cmd_tmp, "AT")) != NULL) //去掉AT
{
sprintf(cmd_tmp, "%s",ptr + 2);
}
printf("send_at_cmd %s\n", cmd);
pthread_mutex_lock(&tty->mutex);
if(tty->fd_net > 0)
{
BOOL result_flag = FALSE; //用来判断是否获取到了所需要的命令
count = 0;
memset(buf, 0, sizeof(buf));
ret = write(tty->fd_net, cmd, strlen(cmd));
if(ret==-1)
printf("[lxr_test_send_at_cmd_fail][func=%s][LINE=%d]\n",__func__,__LINE__);
while((strstr(buf, "OK") == NULL && strstr(buf, "ERROR") == NULL) || (!result_flag)) //当返回结果存在ok/error,并且获取到对应命令的结果的时候才退出
{
memset(buf, 0, sizeof(buf));
FD_ZERO(&rdfds);
FD_SET(tty->fd_net, &rdfds);
tv.tv_sec = 20;
tv.tv_usec = 0;
//printf("[lxr_test_message][func=%s][LINE=%d]\n",__func__,__LINE__);
ret = select(tty->fd_net + 1, &rdfds, NULL, NULL, &tv);
//printf("[lxr_test_message][func=%s][LINE=%d]\n",__func__,__LINE__);
if(ret == 0)
{
mlog_write("4G module command executes timeout:%s",cmd_tmp);
printf("select %d, bRecv:%d, count:%d\n", ret, bRecv, count);
if(bRecv || (count >= 5)) //(已经接收过数据了,后续仍然有超时) 或者 (超时次数过多),则认为此次命令无ok或者error返回,当出错处理
{
*errcode = -1;
break;;
}
else
{
write(tty->fd_net, cmd, strlen(cmd));
}
count ++;
continue;
}
else if(ret < 0)
{
printf("select %d\n", ret);
pthread_mutex_unlock(&tty->mutex);
return DEV_TTY_SEND_ERR;
}
ret = read(tty->fd_net, buf, 128);
if(ret == 0)
{
error_cnt++;
if(error_cnt > 3) //可能是wifi模块被硬件复位了,这里只重新打开USB节点
{ //这里只重新打开节点
printf("AT read failed error_cnt:%d\n", error_cnt);
pthread_mutex_unlock(&tty->mutex);
return DEV_TTY_SEND_ERR;
}
}
else
{
error_cnt = 0;
}
bRecv = TRUE;
printf("line:%d AT ret = %d buf:%s,\n",__LINE__, ret, buf); //这里如果一定数量出错时,重新打开USB试试。
ptr=strstr(buf, cmd_tmp);
if(ptr != NULL)
{
result_flag = TRUE;
if(result)
{
memcpy(result, ptr, strlen(ptr));
}
}
if((ret == 1 && strcmp(buf, "\n") == 0)
|| (strstr(buf, "ZLTENOCELL") != NULL)
|| (strstr(buf, "CREG") != NULL)
|| (strstr(buf, "CGREG") != NULL)
|| (strstr(buf, "CEREG") != NULL)
) //换行和特定信号过滤
continue;
}
if(strstr(buf, "ERROR") != NULL)
{
ret = sscanf(buf, "%*[^0-9]%d", errcode);
if(!*errcode)
*errcode = -1;
// printf("串口返回错误:%s!", buf);
//mlog_write("Abnormal operation of 4G module:%s:%d",cmd_tmp, errcode);
printf("AT failed :%d--%s\n", *errcode,buf);
}
}
else
{
printf("ERROR ERROR ERROR !!! ====== tty->fd_net error\n");
pthread_mutex_unlock(&tty->mutex);
return -1;
}
pthread_mutex_unlock(&tty->mutex);
return 0;
}
send_at_cmd AT+CEREG?
line:113 AT ret = 31 buf:AT+CEREG? //获取服务状态
+CEREG: 0,1
OK
,
srv_status[1]
svr_mode->srv_status = Normal Service
send_at_cmd AT+CPIN? //卡是否正常
line:113 AT ret = 31 buf:AT+CPIN?
+CPIN: READY
OK
,
svr_mode->bSim = 1
send_at_cmd AT+CPSI? //判断网络模式
line:113 AT ret = 99 buf:AT+CPSI?
+CPSI: LTE,Online,460-00,0x2799,225199169,124,EUTRAN-BAND34,36275,3,0,16,31,31,3
OK
,
svr_mode->mode = 4G
send_at_cmd AT+CICCID//获取CCID号
line:113 AT ret = 48 buf:AT+CICCID
+ICCID: 89860040192032676363
OK
,
iccid_tmp:89860040192032676363 len=20
//下面是获取信号强度的AT指令
send_at_cmd AT+CSQ
line:113 AT ret = 28 buf:AT+CSQ
+CSQ: 16,99
OK
,
rssi:-101dBm, act:99
====>>>stat:Normal Service