💌 所属专栏:【BES2500x系列】
😀 作 者:我是夜阑的狗🐶
🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询!
💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘
您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!🤩 🤩 🤩
文章目录
- 前言
- 1 邮箱线程钩子函数注册
- 1.1 app_thread()
- 1.2 APP_MODUAL_ID_T
- 1.3 app_set_threadhandle()
- 总结
前言
大家好,又见面了,我是夜阑的狗🐶,本文是专栏【BES2500x系列】专栏的第14篇文章;
今天开始学习BES2500x系列的一天💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。
专栏地址:【BES2500x系列】, 此专栏是我是夜阑的狗对BES2500x系列开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。对了,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。
1 邮箱线程钩子函数注册
前面本来想学习 Battery
模块,但发现都是在讲解邮箱线程的创建,其实这是不冲突的,因为接下来 Battery
流程就会用到邮箱线程,正所谓知己知彼才能百战百胜。有时候自己读代码的时候,读着读着就发现有块地方搞不懂,不知道怎么来的,然后就箱去疯狂了解,直至搞懂为止。话不多说,那接下来就真正学习 Battery
模块具体是怎么跑的,让我们原文再续,书接上回吧。
从上一篇文章可知我们大费周章的了解了邮箱线程 app_thread 是如何创建的,这个线程将是以后应用模块修改与添加的主要线程。
1.1 app_thread()
知道这个线程流程之后,接下来就深入了解一下 Battery 模块是怎么运转的吧,首先看下app_thread 线程里面具体都做了什么吧。
- 代码
static void app_thread(void const *argument)
{while(1){APP_MESSAGE_BLOCK *msg_p = NULL; // 声明了一个指向 APP_MESSAGE_BLOCK 类型的指针 msg_p,并将其初始化为 NULL。if (!app_mailbox_get(&msg_p)) { // 从邮箱中获取消息,并将消息的指针存储在 msg_p 中if (msg_p->mod_id < APP_MODUAL_NUM) {if (mod_handler[msg_p->mod_id]) { //检查模块处理函数是否存在。如果模块处理函数存在,则进入条件语句中执行后续操作。int ret = mod_handler[msg_p->mod_id](&(msg_p->msg_body)); // 调用了模块处理函数,并将消息体作为参数传递给它。if (ret)TRACE(2,"mod_handler[%d] ret=%d", msg_p->mod_id, ret);}}app_mailbox_free(msg_p); // 释放了消息所占用的内存,防止内存泄漏。}}
}
- 参数/函数讲解
序号 | 参数/函数 | 说明 |
---|---|---|
1 | app_mailbox_get() | 从邮箱中获取消息,并将消息的指针存储在 msg_p 中 |
2 | app_mailbox_free() | 释放了消息所占用的内存,防止内存泄漏 |
3 | mod_handler[] | 各模块钩子注册的数组 |
总的来说,这段代码表示一个线程不断地从邮箱中获取消息,并根据消息中的模块 ID 找到对应的模块处理函数进行处理,然后释放消息所占用的内存。
1.2 APP_MODUAL_ID_T
从代码上可以看出在 app_thread 线程中,通过 app_mailbox_get() 不断的去获取邮箱信息,并传入 mod_handler[] 里面。这里需要看下 mod_handler 是什么类型的数组。
static APP_MOD_HANDLER_T mod_handler[APP_MODUAL_NUM];
这行代码定义了一个长度为 APP_MODUAL_NUM
的静态数组 mod_handler
,其元素类型为 APP_MOD_HANDLER_T
。根据代码中的命名约定,mod_handle
r 应该是一组模块处理函数的指针数组。
具体来说,mod_handler
数组存储了不同模块的处理函数的指针,其中数组的索引对应着模块的 ID
。这样,当收到一个消息时,可以通过消息中的模块 ID
直接在 mod_handler
数组中找到对应的处理函数,从而执行相应的操作。
- 代码
enum APP_MODUAL_ID_T {APP_MODUAL_KEY = 0, // 按键模块APP_MODUAL_AUDIO, // 音频模块APP_MODUAL_BATTERY, // 电池模块APP_MODUAL_BT, // 蓝牙模块APP_MODUAL_FM,APP_MODUAL_SD,APP_MODUAL_LINEIN,APP_MODUAL_USBHOST, // USB 主机模块APP_MODUAL_USBDEVICE, // USB 设备模块APP_MODUAL_WATCHDOG, // 看门狗模块APP_MODUAL_AUDIO_MANAGE, // 音频管理模块APP_MODUAL_ANC, // 主动降噪(Active Noise Cancellation)模块APP_MODUAL_VOICE_ASSIST, // 语音助手模块APP_MODUAL_SMART_MIC, // 智能麦克风模块
#ifdef __PC_CMD_UART__ APP_MODUAL_CMD, // 命令模块
#endif
#ifdef TILE_DATAPATHAPP_MODUAL_TILE,
#endifAPP_MODUAL_MIC, // 麦克风模块
#ifdef VOICE_DETECTOR_ENAPP_MODUAL_VOICE_DETECTOR, // 语音检测模块
#endif
#ifdef AUDIO_HEARING_COMPSATNAPP_MODUAL_HEAR_COMP, // 听力补偿模块
#endifAPP_MODUAL_OHTER, // 其他模块APP_MODUAL_NUM // 模块的数量
};
- 参数/函数讲解
序号 | 参数/函数 | 说明 |
---|---|---|
1 | APP_MODUAL_ID_T | 枚举各个模块的ID |
1.3 app_set_threadhandle()
看到数组下标时存储了不同模块的处理函数的 ID。
- 代码
int app_set_threadhandle(enum APP_MODUAL_ID_T mod_id, APP_MOD_HANDLER_T handler)
{if (mod_id>=APP_MODUAL_NUM)return -1;mod_handler[mod_id] = handler;return 0;
}
- 参数/函数讲解
此时全局搜索 mod_handler
,会找到 app_set_threadhandle()
接口。例如:
app_set_threadhandle(APP_MODUAL_BATTERY, app_battery_handle_process);
到这里就可以发现,各个模块会通过该函数注册自己的钩子函数,然后 app_thread()
会根据 get
的消息回调模块找对应的钩子函数进行处理。
总结
感谢观看,这里就是 Battery模块 – 邮箱线程 Battery 钩子函数注册的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹
也欢迎你,关注我。👍 👍 👍
原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!下期再见。🎉
更多专栏订阅:
😀 【LeetCode题解(持续更新中)】
🥇 【恒玄BES】
🌼 【鸿蒙系统】
💎 【蓝牙协议栈】
🎃 【死机分析】
👑 【Python脚本笔记】
🚝 【Java Web项目构建过程】
💛 【微信小程序开发教程】
⚽ 【JavaScript随手笔记】
🤩 【大数据学习笔记(华为云)】
🦄 【程序错误解决方法(建议收藏)】
🔐 【Git 学习笔记】
🚀 【软件安装教程】
订阅更多,你们将会看到更多的优质内容!!