找回密码
 立即注册

使用微信账号登录

只需一步,快速开始

BES2300x笔记(1) -- SDK代码架构与Battery模块

2021-5-3 17:45| 发布者: 后来| 查看: 2209| 评论: 6|原作者: 文化人|来自: CSDN

摘要: 一、前言 拿到恒玄的SDK源码之后,结合文档花了一些时间研究,这篇就先介绍下代码的框架和模块之间的解耦处理。 二、代码架构 1、 根据SDK的目录可以看出,BES采用的是RXT RTOS(嵌入式实时操作系统),并且用了ARM ...

哈喽大家好,这是该系列博文的第一篇~ 篇~

<<【系列博文索引】快速通道 >>

首先上一个链接:参考链接

一、前言

拿到恒玄的SDK源码之后,结合文档花了一些时间研究,这篇就先介绍下代码的框架和模块之间的解耦处理。

二、代码架构

1、 根据SDK的目录可以看出,BES采用的是RXT RTOS(嵌入式实时操作系统),并且用了ARM的CMSIS_RTOS API接口;
在这里插入图片描述
2、 我们知道程序运行开始的地方是RTX_CM_LIB.H里面的_main_init(),主要是进行内核初始化、堆栈的设置、main线程的创建和开启内核等。
在这里插入图片描述
3、 第一个线程os_thread_def_main就是main,接着看,在main.cpp文件中。
在这里插入图片描述
4、 app_os_init()里有线程创建,这是CMSIS的风格,开发过STM32应该比较熟悉,用来定义线程、定时器和邮箱通讯等;
app_thread_tid = osThreadCreate(osThread(app_thread), NULL);
在这里插入图片描述
5、 app_thread为线程loop函数,OSThread其实是一个宏,就是取地址而已
#define osThread(name) &os_thread_def_##name
在这里插入图片描述
一般在文件开头会看到这样的定义:osThreadDef其实也是一个宏
osThreadDef(app_thread, osPriorityHigh, 1, 2048, “app_thread”);
在这里插入图片描述

这里就是给一个结构体变量初始化赋值,然后把os_thread_def_app_thread的地址传给os_thread()。结构体类型是:
在这里插入图片描述
所以OSThreadDef是设置线程名、优先级以及堆栈大小,通过osThread获取配置的结构体变量的指针,然后作为参数传入OSThreadCreate()。
6、 以上创建了另一个重要线程:app_thread,这个线程将是以后应用模块修改与添加的主要线程。

7、 下面我们看一下app_thread线程里面的具体做了什么:
if (mod_handler[msg_p->mod_id])
int ret = mod_handler[msg_p->mod_id] (&(msg_p->msg_body));

在这里插入图片描述
8、 我们可以看到在app_thread线程中,通过app_mailbox_get()反复的在获取邮箱信息,并传入mod_handler[]里面。
static APP_MOD_HANDLER_T mod_handler[APP_MODUAL_NUM];
在这里插入图片描述
看其数据类型是一个函数指针数组,再看其数组下标的定义:
在这里插入图片描述
在这里插入图片描述
9、 全局搜索mod_handler,会找到app_set_threadhandle()接口。
在这里插入图片描述
到此,我们了解了各个模块会注册自己的回调函数,然后app_thread()会根据get的消息回调模块对应的API进行处理。

10、 我们现在选取一个模块APP_MODUAL_BATTERY(APP_MODULE_BATTERY),从app_set_threadhandle的调用入手,继续研究模块的架构。
在这里插入图片描述
可以看到app_battery_open()接口里调用了
app_set_threadhandle(APP_MODUAL_BATTERY, app_battery_handle_process);
其中,app_battery_handle_process()就是BATTERY模块的回调处理函数。
11、 app_battery_open()是由app_init()调用,初始化battery模块。其中battery模块用到的全局变量为
在这里插入图片描述
从变量的初始化,我们看到定制化的设置都在tgt_hardware.h里面,还有其他定制化的设置。
在这里插入图片描述
12、 在app_battery_handle_process()里面,我们可以看到:
在这里插入图片描述
通过全局搜索APP_BATTERY_STATUS_OVERVOLT,发现是通过app_battery_irqhandler发出的事件
在这里插入图片描述
app_battery_measure.cb在app_battery_open()中有定义:
app_battery_measure.cb = app_battery_event_process;

在这里插入图片描述
上图可以看到是通过app_battery_event_process把模块的消息放到邮箱中。
13、 回到app_battery_irqhandler()
在这里插入图片描述
在这里插入图片描述

通过搜索,我们发现app_battery_timer_handler是定时器APP_BATTERY的回调函数,

至此,就搞明白了battery模块的流程:
app_battery_open()配置定时器,对结构体进行初始化,注册事件回调和模块处理函数
—>定时调用app_battery_timer_handler()来获取电池的电压值
—>再通过app_battery_irqhandler()将转换之后的电压值与初始值比较,通过 app_battery_event_process发出不同的电池状态
—>在app_battery_event_process()把消息放入邮箱中
—>最后app_thread线程取出消息,调用对应模块的app_battery_handle_process()接口进行处理

14、 我们再回到app_battery_timer_handler()看下hal_gpadc_open()接口。
在这里插入图片描述
可以看到,传入的回调函数指针,赋值给了 gpadc_event_cb[channel] ,另外,用到驱动的地方,要加互斥锁。
15、 通过搜索gpadc_event_cb,进入hal_gpadc_irq_handler()接口;
在这里插入图片描述
通过上图,看到 gpadc_event_cb调用了app_battery_irqhandler,并传入了ADC扫描的值。
16、 继续往下就是hal_gpadc_adc2volt()——> hal_gpadc_adc2volt_calib()等ADC底层接口
在这里插入图片描述

17、 另外,通过搜索hal_gpadc_irq_handler()接口,也可以找到hal_gpadc_irq_control()中断获取的流程
在这里插入图片描述

三、后续扩展

类比BATTERY模块,可以继续学习其他模块,比如按键、BT都是同样的机制。

1

路过

雷人

握手

鲜花

鸡蛋

刚表态过的朋友 (1 人)

发表评论

最新评论

引用 13670015363 2021-10-25 15:14
SDK哪里可以下载
引用 13670015363 2021-10-25 15:13
研究的很透彻,学习中
引用 100个理由/ty 2021-10-10 08:28
学习了
引用 吉永良 2021-9-29 14:38
看了一遍,学习得不透彻,以后再学!
引用 喜欢≠爱 2021-6-4 12:23
学习了
引用 音魅蓝牙测试仪 2021-6-3 16:16
不错

查看全部评论(6)

小黑屋|手机版|我爱蓝牙网 - 52Bluetooth

GMT+8, 2024-4-25 02:03 , Processed in 0.172922 second(s), 32 queries , Gzip On, MemCached On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

返回顶部