2

OpenHarmony中AT模块的代码理解之三

 2 years ago
source link: https://os.51cto.com/article/704548.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
OpenHarmony中AT模块的代码理解之三-51CTO.COM
OpenHarmony中AT模块的代码理解之三
作者:再见南丫岛 2022-03-22 11:33:13
注册部分功能,就是将AT命令的添加到g_at_cmd_list的数组中。等到通过串口接收到的指令进行解析的时候,还会遍历存储在g_at_cmd_list中的指令的。所有这个结构体数组,后续还会用到。

546d63e83ce6ebafa05222172e3d47e97b301a.png

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

现在开启第三篇,核心内容是AT命令的注册。

1、AT命令结构体

typedef struct {
    hi_char *at_cmd_name;
    hi_s8   at_cmd_len;
    at_call_back_func at_test_cmd;
    at_call_back_func at_query_cmd;
    at_call_back_func at_setup_cmd;
    at_call_back_func at_exe_cmd;
} at_cmd_func;

hi_char *at_cmd_name;为命令字符串,不包含“AT”字符。

hi_s8 at_cmd_len;为字符串长度。

后面的四个回调函数,分别对应AT命令的四种类似:测试命令,查询命令,设置命令和执行命令。

14a2b398754c88eb2ce878b0d8c0b555fcb5bc.png

如:{“+RST”, 4, HI_NULL, HI_NULL, (at_call_back_func)at_setup_reset_cmd, (at_call_back_func)at_exe_reset_cmd}。

2、注册函数

hi_at_sys_cmd_register()这个函数中包含了很多注册的函数。每个函数又包含了一类的AT命令。

hi_void hi_at_sys_cmd_register(hi_void)
{
    hi_at_general_cmd_register();
#ifndef CONFIG_FACTORY_TEST_MODE
    hi_at_sta_cmd_register();
    hi_at_softap_cmd_register();
#endif
    hi_at_hipriv_cmd_register();
#ifndef CONFIG_FACTORY_TEST_MODE
#ifdef LOSCFG_APP_MESH
    hi_at_mesh_cmd_register();
#endif
    hi_at_lowpower_cmd_register();
#endif
    hi_at_general_factory_test_cmd_register();
    hi_at_sta_factory_test_cmd_register();
    hi_at_hipriv_factory_test_cmd_register();
    hi_at_io_cmd_register();
}

只取其中的一个,进行进一步的说明,拿这个函数hi_at_general_cmd_register()举例。函数中引用了AT命令的注册函数。

hi_at_register_cmd(g_at_general_func_tbl, AT_GENERAL_FUNC_NUM);

函数的参数有两个:结构体数组和结构体数组的长度。结构体数组就是第一部分中介绍的AT命令结构体。

const at_cmd_func g_at_general_func_tbl[] = {
    {"", 0, HI_NULL, HI_NULL, HI_NULL, (at_call_back_func)at_exe_at_cmd},
    {"+RST", 4, HI_NULL, HI_NULL, (at_call_back_func)at_setup_reset_cmd, (at_call_back_func)at_exe_reset_cmd},
    {"+MAC", 4, HI_NULL, (at_call_back_func)cmd_get_macaddr, (at_call_back_func)cmd_set_macaddr, HI_NULL},
    {"+HELP", 5, HI_NULL, HI_NULL, HI_NULL, (at_call_back_func)at_exe_help_cmd},
};

下面对注册函数的实现进行说明。

hi_u32 hi_at_register_cmd(HI_CONST at_cmd_func *cmd_tbl, hi_u16 cmd_num)
{
    hi_u32 ret = HI_ERR_FAILURE;
    hi_u8 i;
    if (cmd_tbl == HI_NULL || cmd_num == 0) {
        return HI_ERR_FAILURE;
    }
    ret = check_cmd_tbl(cmd_tbl, cmd_num);
    if (ret != HI_ERR_SUCCESS) {
        return ret;
    }
    at_cmd_func_list *cmd_list = at_get_list();
    for (i = 0; i < AT_CMD_LIST_NUM; i++) {
        if ((cmd_list->at_cmd_list[i] == HI_NULL) || (cmd_list->at_cmd_num[i] == 0)) {
            cmd_list->at_cmd_list[i] = cmd_tbl;
            cmd_list->at_cmd_num[i] = cmd_num;
            ret = HI_ERR_SUCCESS;
            break;
        }
        ret = check_name_and_callback(cmd_list, i, cmd_tbl, cmd_num);
        if (ret != HI_ERR_SUCCESS) {
            break;
        }
    }
    return ret;
}

其中几个核心函数的说明:

(1)check_cmd_tbl(cmd_tbl, cmd_num)。

确认需要注册的AT命令结构体中没有重复的指令。

(2)at_get_list()。

获取全局变量HI_PRV at_cmd_func_list g_at_cmd_list = { 0 }的指针。这个结构体数据中存储着已经注册的AT命令。

(3)check_name_and_callback(cmd_list, i, cmd_tbl, cmd_num)。

为检查要注册的AT命令是否有重复,避免重复注册。

(4)for (i = 0; i < AT_CMD_LIST_NUM; i++) {}去遍历g_at_cmd_list中已经存储到了第几个位置。如果遍历到空位置,则将要注册的AT命令结构体的指针进行存储。

cmd_list->at_cmd_list[i] = cmd_tbl;
cmd_list->at_cmd_num[i] = cmd_num;

注册部分功能,就是将AT命令的添加到g_at_cmd_list的数组中。等到通过串口接收到的指令进行解析的时候,还会遍历存储在g_at_cmd_list中的指令的。所有这个结构体数组,后续还会用到。

如果想要自己添加AT命令。可以仿照给出的通用规则,自己添加即可。这里不展开说明。

这篇文章,就先介绍到这里。

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

71eea7105a1cf9982d2996c42d853b97bd50ef.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK