前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >中国移动ML302模组(4G Cat.1 通信模组)TencentOS-tiny AT模组框架适配

中国移动ML302模组(4G Cat.1 通信模组)TencentOS-tiny AT模组框架适配

作者头像
杨源鑫
发布2021-03-30 10:49:40
1.4K0
发布2021-03-30 10:49:40
举报
文章被收录于专栏:嵌入式开发圈嵌入式开发圈

关于AT模组框架,之前学习TencentOS-tiny是有写过一篇文章的,链接如下:

还在用传统的方式驱动一个通信模组?不如一起来学习下TOS的AT模组框架吧!

最近查看了TencentOS-tiny官方仓库,发现device目录下并没有ML302这个模组的驱动,于是我就利用这个机会学习了模组驱动编写与AT模组框架适配,期间遇到了一些技术疑惑请教了世伟兄(mculover666),最后顺利的将代码提交到了TencentOS-tiny官方仓库;能够得以顺利的完成,得感谢世伟兄提供技术支持。

在此之前,我已经给TencentOS-tinyTencentOS-Tiny-IoT-Projects贡献了一些项目,如下所示,有兴趣可持续关注并提ISSUE。

ML302 4G Cat.1模组资料仓库地址:

代码语言:javascript
复制
https://gitee.com/morixinguan/open-source-of-cloud/tree/master/04.4G_Cat.1

ML302 TencentOS-tiny驱动仓库地址:

代码语言:javascript
复制
https://github.com/Tencent/TencentOS-tiny/tree/master/devices/ml302

ML302 4G Cat.1小熊派测试例程仓库地址:

代码语言:javascript
复制
https://github.com/Tencent/TencentOS-tiny/tree/master/board/BearPi_STM32L431RC/KEIL/tcp_through_ml302_4g_cat_1_module
https://github.com/Tencent/TencentOS-tiny/tree/master/examples/tcp_through_ml302_4g_cat_1_module

TencentOS-tiny官方仓库地址:

代码语言:javascript
复制
https://gitee.com/Tencent/TencentOS-tiny
https://github.com/Tencent/TencentOS-tiny

TencentOS-Tiny-IoT-Projects官方仓库地址:

代码语言:javascript
复制
https://gitee.com/Tencent/TencentOS-Tiny-IoT-Projects

在使用AT框架适配模组前,需要先用串口终端测试一下,于是我们找到了模组 的通信流程示例手册:

接下来根据手册要求发送以下指令来进行上电初始化,如果初始化流程没有问题的话,接下来就可以和远程服务器进行通信了,这里的测试平台我用的是中国移动OneNet。

1、移动4G Cat.1 ML302上电初始化流程
1.1、测试模块初始化正常
代码语言:javascript
复制
AT

OK
1.2、查询SIM卡状态
代码语言:javascript
复制
AT+CPIN?

+CPIN: READY

OK
1.3、查询协议栈是否打开
代码语言:javascript
复制
AT+CFUN?

+CFUN: 1

OK
1.4、查询当前信号质量
代码语言:javascript
复制
AT+CSQ

+CSQ: 31,99

OK
1.5、设置 GPRS的APN
代码语言:javascript
复制
AT+CGDCONT=1,"IP","CMIOT"

OK
1.6、激活PDP
代码语言:javascript
复制
AT+CGACT=1,1

+CGACT: 1,1

OK
2、建立TCP连接

测试连接移动OneNet云平台==>透传模式

2.1、进入透传模式
代码语言:javascript
复制
AT+MIPMODE=0,1

OK
2.2、连接服务器
代码语言:javascript
复制
AT+MIPOPEN=0,"TCP","183.230.40.33",80

OK
CONNECT OK
2.3、发送HTTP透传数据
代码语言:javascript
复制
POST /devices/604618155/datapoints?type=3 HTTP/1.1
api-key:NGSRfMY43gLebqieuaX4UfPgoac=     
Host:api.heclouds.com        
Content-Length:11

{"ppm":100}


以下为接收到服务器的信息回复
HTTP/1.1 200 OK
Date: Mon, 22 Mar 2021 09:00:30 GMT
Content-Type: application/json
Content-Length: 26
Connection: keep-alive
Server: Apache-Coyote/1.1
Pragma: no-cache

{"errno":0,"error":"succ"}
2.4、退出数据模式,此时连接依然保持
代码语言:javascript
复制
+++
2.5、关闭连接,释放资源
代码语言:javascript
复制
AT+MIPCLOSE=0

0,CLOSE OK
2.6、退出透传模式
代码语言:javascript
复制
AT+MIPMODE=0,0

OK

我的串口调试助手显示如下:

为了调试方便,这里我用是透传数据的方式来上传数据到OneNet。

3、TencentOS-tiny AT模组框架适配

AT模组驱动位于TencentOS-tiny根目录下的device目录:

在这个目录下,已经适配了很多市面上常用的AT模组,如下所示,在这个目录下创建一个ML302的文件夹,向里面添加ML302模组驱动文件:

接下来根据其它模组的驱动套路添加对应的代码,完成ML302适配SAL层,这里我们根据官方文档描述,找到SAL相关适配的结构体:

代码语言:javascript
复制
//枚举===>协议类型,TCP、UDP
typedef enum sal_protocol_en {
    TOS_SAL_PROTO_TCP,
    TOS_SAL_PROTO_UDP,
} sal_proto_t;
//需要对接SAL的接口
typedef struct sal_module_st {
    int (*init)(void);

    int (*get_local_mac)(char *mac);

    int (*get_local_ip)(char *ip, char *gw, char *mask);

    int (*parse_domain)(const char *host_name, char *host_ip, size_t host_ip_len);

    int (*connect)(const char *ip, const char *port, sal_proto_t proto);

    int (*send)(int sock, const void *buf, size_t len);

    int (*recv_timeout)(int sock, void *buf, size_t len, uint32_t timeout);

    int (*recv)(int sock, void *buf, size_t len);

    int (*sendto)(int sock, char *ip, char *port, const void *buf, size_t len);

    int (*recvfrom)(int sock, void *buf, size_t len);

    int (*recvfrom_timeout)(int sock, void *buf, size_t len, uint32_t timeout);

    int (*close)(int sock);
} sal_module_t;

其中,send、recv、recv_timeout是TCP协议使用的收发接口,而sendto、recvfrom、recvfrom_timeout是UDP协议使用的收发接口,按照要求,实现模组对接SAL层常用的一些接口,然后将这个结构体注册到SAL上。

以init接口为例,我们要实现模组上电初始化要做的一些事情,具体指令请参考对应的手册:

代码语言:javascript
复制
static int ml302_init(void)
{
    printf("Init ML302 ...\n" );
    //测试模组是否上电
    if (ml302_wait_ok() != 0)
    {
        printf("ml302 start FAILED\n");
        return -1;
    }
    //关闭回显
    if (ml302_echo_close() != 0)
    {
        printf("ml302 echo close FAILED\n");
        return -1;
    }
    //测试SIM卡是否已经插上
    if (ml302_pin_ready() != 0)
    {
        printf("ml302 pin not ready\n");
        return -1;
    }
    //测试是否注网成功
    if(ml302_gsm_network_check() != 0)
    {
        printf("ml302 GSM network register status check fail\n");
        return -1 ;
    }
    //测试模组信号强度
    if (ml302_signal_quality_check() != 0)
    {
        printf("ml302 signal quality check status failed\n");
        return -1;
    }
    //设置APN
    if (ml302_set_gprs_apn() != 0)
    {
        printf("ml302 set gprs_apn failed\n");
        return -1;
    }
    //激活PDP
    if (ml302_activate())
    {
        printf("ml302 activate FAILED\n");
        return -1;
    }

    printf("Init ML302 Done\n" );
    return 0;
}

这么多指令里面,其实包含了三类AT指令:

  • 1、只需要判断是否返回OK的AT指令

ml302_wait_ok函数为例,这是第一类AT指令的实现,如下:

代码语言:javascript
复制
static int ml302_wait_ok(void)
{

    int try = 0;

    at_echo_t echo;
    /* 创建一个echo 对象,缓冲区为NULL,期望字符串为NULL */
    tos_at_echo_create(&echo, NULL, 0, NULL);
     /* 尝试检测10次,一旦有一次正常,返回 */
    while (try++ < 10)
    {
        /* 执行AT命令,超时时长1000ms */
        tos_at_cmd_exec(&echo, 1000, "AT\r\n");
        /* 判断执行结果是否为OK */
        if (echo.status == AT_ECHO_STATUS_OK)
        {
           return 0;
        }
    }
    return -1;
}
  • 2、需要判断是否OK,也需要解析执行结果的AT指令

ml302_signal_quality_check函数为例,这是第一类AT指令的实现,如下:

代码语言:javascript
复制
static int ml302_signal_quality_check(void)
{
    int rssi, ber;
    at_echo_t echo;
    char echo_buffer[32], *str;

    int try = 0;
     /* 尝试检测10次,一旦有一次正常,返回 */
    while (try++ < 10)
    {
        /* 创建echo对象,传入一个缓冲区存放AT命令执行结果 */
        tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL);
        /* 执行AT命令,超时时长1000ms */
        tos_at_cmd_exec(&echo, 1000, "AT+CSQ\r\n");
        /* 判断执行结果是否返回了OK */
        if (echo.status != AT_ECHO_STATUS_OK)
        {
            return -1;
        }
        /* 从AT指令的执行结果中解析提取CSQ值进行判断 */
        str = strstr(echo.buffer, "+CSQ:");

        if (!str)
        {
            return -1;
        }

        sscanf(str, "+CSQ:%d,%d", &rssi, &ber);

        if (rssi != 99)
        {
            return 0;
        }
    }

    return -1;
}
  • 3、模组主动上报的数据处理

这一类AT指令对应TCP/IP协议栈接收数据的上报机制,使用AT框架的事件机制进行处理,也就是我们前面提到的这个事件:

代码语言:javascript
复制
at_event_t ml302_at_event[] =
{
    { "+MIPURC: \"recv\",", ml302_incoming_data_process },
};

这个对应下发处理的事件回调函数需要我们自己来实现,如ml302_incoming_data_process,实现如下:

代码语言:javascript
复制
__STATIC__ void ml302_incoming_data_process(void)
{
    uint8_t data;
    int channel_id = 0, data_len = 0, read_len;
    uint8_t buffer[128];

    /*
      //模组上报的数据格式
     +MIPURC: "recv",<sockid>,<datalen>
     <data content>
    */

    /* 读取解析socket id */
    while (1)
    {
        if (tos_at_uart_read(&data, 1) != 1)
        {
            return;
        }

        if (data == ',')
        {
            break;
        }

        channel_id = channel_id * 10 + (data - '0');
    }
    /* 读取解析数据长度 */
    while (1)
    {
        if (tos_at_uart_read(&data, 1) != 1)
        {
            return;
        }

        if (data == '\r')
        {
            break;
        }

        data_len = data_len * 10 + (data - '0');
    }

    if (tos_at_uart_read(&data, 1) != 1)
    {
        return;
    }
    /* 根据解析出的数据长度和缓冲区的长度,循环读取数据内容,写入到对应 socket id 的channel中 */
    do
    {
#define MIN(a, b)   ((a) < (b) ? (a) : (b))
        read_len = MIN(data_len, sizeof(buffer));

        if (tos_at_uart_read(buffer, read_len) != read_len)
        {
            return;
        }

        if (tos_at_channel_write(channel_id, buffer, read_len) <= 0)
        {
            return;
        }

        data_len -= read_len;
    }
    while (data_len > 0);

    return;
}

模组适配完毕后,编写对接后台例程,由于篇幅限制,详细代码请访问TencentOS-tiny官方仓库获取。

测试例程效果如下:

OneNet平台展示效果:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式云IOT技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、移动4G Cat.1 ML302上电初始化流程
    • 1.1、测试模块初始化正常
      • 1.2、查询SIM卡状态
        • 1.3、查询协议栈是否打开
          • 1.4、查询当前信号质量
            • 1.5、设置 GPRS的APN
              • 1.6、激活PDP
              • 2、建立TCP连接
                • 2.1、进入透传模式
                  • 2.2、连接服务器
                    • 2.3、发送HTTP透传数据
                      • 2.4、退出数据模式,此时连接依然保持
                        • 2.5、关闭连接,释放资源
                          • 2.6、退出透传模式
                          • 3、TencentOS-tiny AT模组框架适配
                          相关产品与服务
                          TencentOS Server
                          TencentOS Server 是腾讯云推出的 Linux 操作系统,它旨在为云上运行的应用程序提供稳定、安全和高性能的执行环境。它可以运行在腾讯云 CVM 全规格实例上,包括黑石物理服务器2.0。
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档