OneMO模组说|技术学堂-ML307A开发指南(一) OpenCPU模式网络初始化流程介绍

OpenCPU网络初始化流程至关重要,是模组正常连接服务器应用的前提。流程包含读取模组IMEI/SN、读取SIM卡IMSI/ICCID模组PDP激活状态三个环节本文介绍了ML307A模组OpenCPU模式网络初始化的相关接口、demo代码解析、demo运行示例以及常见问题

图1 网络初始化流程

一、相关接口

模组的IMEI/SN获取接口可在include\cmiot\cm_sys.h中查看SIM卡IMSI/ICCID获取接口可以在include\cmiot\cm_sim.h中查看,PDP激活状态查询可以在include\cmiot\cm_modem.h中查看。

1.1 获取模组IMEI

/**

 * @brief 获取模组IMEI

 *

 * @param [out] imei IMEI,长度16字节

 *

 * @return 

 *   = 0  - 成功 \n

 *   < 0  - 失败, 返回值为错误码

 *  

 * @details More details

 */

int32_t cm_sys_get_imei(char *imei); 

模组正常开机成功之后即可调用该接口获取模组IMEI,返回0表示获取成功,小于0表示获取失败;

1.2 获取模组SN

/**

 * @brief 获取模组SN

 *

 * @param [out] sn SN,长度32字节

 *

 * @return 

 *   = 0  - 成功 \n

 *   < 0  - 失败, 返回值为错误码

 *  

 * @details More details

 */

int32_t cm_sys_get_sn(char *sn); 

模组正常开机成功之后即可调用该接口获取模组SN,返回0表示获取成功,小于0表示获取失败;

1.3 获取SIM卡IMSI

/**

 * @brief 获取设备IMSI

 *

 * @param [out] imsi 存储IMSI,长度16字节,申请内存后传入

 * @return  

 *   = 0  - 成功 \n

 *   < 0  - 失败, 返回值为错误码.

 *  

 * @details More details

 *

 */

int32_t cm_sim_get_imsi(char* imsi);

模组正常开机且正常识别到SIM卡之后即可调用该接口获取SIM卡IMSI,返回0表示获取成功,小于0表示获取失败;

1.4 获取SIM卡ICCID

/* 获取ICCID示例,注意虚拟AT通道传入的指令为"AT*ICCID?\r\n" */

void cm_demo_iccid(void)

模组正常开机且正常识别到SIM卡之后即可调用该接口获取SIM卡ICCID,获取ICCID采用虚拟AT指令的方式进行获取,需要注意使用虚拟AT通道之前需要先进行虚拟通道初始化;

1.5 PDP状态查询

int32_t cm_modem_get_pdp_state(uint16_t cid)

模组开机后默认会自动进行第一路PDP激活,该接口调用虚拟AT指令进行激活查询,CID为PDP上下文编号,返回值为虚拟AT指令查询到的PDP状态,返回1表示激活成功,返回0表示激活失败。

二、demo代码解析

在SDK提供的demo中,已经实现模组IMEI/SN和SIM卡的IMSI/ICCID的获取,以及PDP激活状态查询,下面我们详细看一下cm_demo_main.c文件中相关部分的代码。

2.1 获取模组IMEI

#define CM_VER_LEN       65 /*< 存储长度> */

char buf[CM_VER_LEN] = {0};/*定义字符串buf并初始化为零 */

 int ret;

memset(buf, 0, CM_VER_LEN); /*存储的buf清零 */

    ret = cm_sys_get_imei(buf); /*调用函数获取IMEI 并存到buf*/

    if (ret == 0)

    {

        cm_demo_printf("IMEI:%s\n", buf);/*接口函数返回值等于0则获取正常,进行串口打印输出IMEI */

    }

    else

    {

        cm_demo_printf("IMEI ERROR\n");/*接口函数返回值不等于0则打印报错 */

    }

这里建立一个buf数组,用于存储IMEI字符串,先进行buf清空,然后获取IMEI,最后使用串口打印函数输出;

2.2 获取模组SN

  memset(buf, 0, CM_VER_LEN);/*存储的buf清零 */

    ret = cm_sys_get_sn(buf); /*调用函数获取模组SN并存到buf*/

    if (ret == 0)

    {

        cm_demo_printf("SN:%s\n", buf);/*接口函数返回值等于0则获取正常,进行串口打印输出SN */

    }

    else

    {

        cm_demo_printf("SN ERROR\n");/*接口函数返回值不等于0则打印报错 */

    }

先进行buf清空,然后获取模组SN,最后使用串口打印函数输出;

2.3 获取SIM卡IMSI

    memset(buf, 0, CM_VER_LEN);/*存储的buf清零 */

    ret = cm_sim_get_imsi(buf);/*调用函数获取SIM卡IMSI并存到buf*/

    if (ret == 0)

    {

        cm_demo_printf("IMSI:%s\n", buf);/*接口函数返回值等于0则获取正常,进行串口打印输出IMSI */

    }

    else

    {

        cm_demo_printf("IMSI ERROR\n");/*接口函数返回值不等于0则打印报错 */

    }

先进行buf清空,然后获取SIM卡IMSI,最后使用串口打印函数输出;

2.4 获取SIM卡ICCID

​

    /* 获取ICCID示例,注意虚拟AT通道传入的指令为"AT*ICCID?\r\n" */

cm_demo_iccid();

/* 获取ICCID示例,注意虚拟AT通道传入的指令为"AT*ICCID?\r\n" */

void cm_demo_iccid(void)

{  

/* 初始化AT虚拟通道,注册AT虚拟通道消息回调函数*/

    if(cm_virt_at_init(iccid_resp_cb)!=0)

{

/* 初始化AT虚拟通道接口返回值不等于0,则串口打印始化AT虚拟通道错误*/

       cm_demo_printf("cm_virt_at_init  err");  

        return;

}

/* 初始化AT虚拟通道接口返回值等于0则发送虚拟AT指令"AT*ICCID?\r\n"*/

    if(cm_virt_at_send((uint8_t *)"AT*ICCID?\r\n",strlen("AT*ICCID?\r\n")) < 0)

{

* AT虚拟通道发送数据接口返回值小于0则打印AT虚拟通道发送数据错误*/

        cm_demo_printf("cm_virt_at_send err");  

        return;

    }

osDelay(500);

/* AT指令发送完成后进行AT虚拟通道去初始化*/

    cm_virt_at_deinit();    

}

/* AT虚拟通道消息回调函数用于接收AT指令的返回值*/

void iccid_resp_cb(void * param)

{

/* 定义at_data字符串用于存储AT指令的返回值*/

unsigned char at_data[256]={0};

/* 将AT虚拟通道回调函数返回的字符串转换成整型数,不能转换则打印原始数据*/

    if(atoi(param) ==  0)

{    

/* 通过AT虚拟通道接收数据并存入at_data字符串*/   

        cm_virt_at_get(at_data,sizeof(at_data));

/* 打印AT指令返回值*/ 

        cm_demo_printf("%s\n", at_data);        

    }

    /* 将AT虚拟通道回调函数返回的字符串转换成整型数*,转换成功则打印ICCID*/

else if(atoi(param) == 1)

{

/* 通过AT虚拟通道接收数据并存入at_data字符串*/ 

        cm_virt_at_get(at_data,sizeof(at_data));

/* 打印AT指令返回值*/ 

        cm_demo_printf("*ICCID:%s\n", at_data);  

    }

}
​

调用函数cm_virt_at_init进行虚拟AT通道初始化,然后发送虚拟AT指令AT+ICCID?获取ICCID,通过虚拟AT通道的回调函数iccid_resp_cb打印获取到的ICCID;

2.5查询pdp激活状态

  /*  定义PDP查询次数整型变量并初始化为0*/ 

int pdp_time_out=0;

 while(1)

{ 

/* PDP查询次数大于10次则打印网络超时*/ 

        if(pdp_time_out>10) 

        {

            cm_demo_printf("network timeout\n");

            break;

        }

/* PDP状态查询为1则打印network ready并跳出循环*/ 

        if(cm_modem_get_pdp_state(1) == 1)

        {

            cm_demo_printf("network ready\n");        

            break;

        }

/* 延时1秒PDP查询次数加一*/ 

        osDelay(200);  

        pdp_time_out++;

    } 

以1秒的间隔循环查询PDP激活状态10次,如果次数超过则打印网络超时,如果PDP状态激活成功则打印网络准备好。

三、demo运行示例

上面提到在cm_demo_main.c中,已经实现读取模组IMEI/SN,SIM卡的IMSI/ICCID以及PDP激活状态查询,下面是cm_demo_main.c运行示例。

[05-04 17:49:19:868]CM OpenCPU Starts  //开机成功,opencpu程序开始运行,通过UART0,9600波特率进行打印

[05-04 17:49:19:883]SDK VERSION:ML307A_OpenCPU_Standard_1.3.1.2304071557_release  //SDK版本号获取

[05-04 17:49:19:964]fs total:262144,remain:184320  //文件系统信息获取

[05-04 17:49:19:995]heap total:1310716,remain:664352 //系统heap状态获取

[05-04 17:49:20:027]waiting for network...  //等待网络激活,超时时间设置为10秒

[05-04 17:49:25:240]network ready    //网络初始化成功打印

[05-04 17:49:26:279]Now:2023-5-4:17:49:27,Thursday  //获取当前时间

[05-04 17:49:26:311]SN:20209P1001531A000014 //SN号获取

[05-04 17:49:26:343]IMEI:864606060109344 //IMEI获取

[05-04 17:49:26:359]IMSI:460042726515520 //IMSI获取

[05-04 17:49:26:424]*ICCID: "89860407112270005520" //ICCID获取

[05-04 17:49:28:953]

[05-04 17:49:28:953]please input cmds:   

四、常见问题

  1. 为什么获取不到SIM卡IMSI和ICCID?

获取SIM卡IMSI和ICCID需要保证SIM卡电路设计正常,插拔卡方向正确,SIM卡硬件正常才能获取到IMSI和ICCID。

  1. 网络超时等待时间是否可以自行配置?

可以的,网络超时的时间间隔在不同的网络环境可能存在差异,可自行配置来保证有足够的时间来完成网络激活

  1. 是否所有的AT指令都可以采用虚拟AT指令?

   虚拟AT不完全支持OneMO AT手册中的指令,仅支持3GPP的AT指令。

  1. 激活PDP失败的原因?

   PDP是在开机读卡之后自动激活的,激活失败需要排查SIM卡是否存在欠费、机卡绑定、未激活问题。

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值