【BES2500x系列 -- RTX5操作系统】Battery模块 -- 创建电池检测定时器 --(十五)

  • 💌 所属专栏:【BES2500x系列】

  • 😀 作  者:我是夜阑的狗🐶

  • 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询!

  • 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!🤩 🤩 🤩

文章目录

  • 前言
  • [1 真正的 Battery 模块](#1 真正的 Battery 模块)
      • [1.1 app_battery_open()](#1.1 app_battery_open())
      • [1.2 APP_BATTERY_MEASURE_T](#1.2 APP_BATTERY_MEASURE_T)
      • [1.3 osTimerDef](#1.3 osTimerDef)
  • 总结

<<【系列文章索引】>>

前言

大家好,又见面了,我是夜阑的狗🐶,本文是专栏【BES2500x系列】专栏的第15篇文章;

今天开始学习BES2500x系列的一天💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。

专栏地址:【BES2500x系列】, 此专栏是我是夜阑的狗对BES2500x系列开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。

如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。


1 真正的 Battery 模块

从上一篇文章中已经知道邮箱线程中的钩子函数是通过 app_set_threadhandle() 函数注册到静态变量。接下来就让我们来看一下,在应用初始化 app_init()Battery 模块是怎么初始化的。话不多说,那接下来就真正学习 Battery 模块具体是怎么跑的,让我们原文再续,书接上回吧。

1.1 app_battery_open()

这里我们选取一个模块 APP_MODUAL_BATTERY(APP_MODULE_BATTERY) 来进行了解,由前面可知在系统初始化的时候 app_init 会对 Battery 模块进行初始化,也了解到充电检测执行流程如下步骤所示:

Step 1 、充电检测(电池状态,充电状态或是充电使用状态) ;

Step 2 、定时检测电量 ---> 可以通过中断方式检测当前电压值 ;

Step 3、将检测到的电压通过邮箱发送,并进行相应处理 ;

接下来让我们从 app_set_threadhandler() 的调用作为切入点。

  • 代码
c 复制代码
int app_battery_open(void)
{	
	// 开启电池模块初始化
    int nRet = APP_BATTERY_OPEN_MODE_INVALID;

    if (app_battery_timer == NULL)
    	// 创建电池电量检测定时器
        app_battery_timer = osTimerCreate (osTimer(APP_BATTERY), osTimerPeriodic, NULL);

    if (app_battery_pluginout_debounce_timer == NULL)
    	// 创建出入盒定时器
        app_battery_pluginout_debounce_timer = osTimerCreate (osTimer(APP_BATTERY_PLUGINOUT_DEBOUNCE), osTimerOnce, &app_battery_pluginout_debounce_ctx);
	
	// 标记电池状态
    app_battery_measure.status = APP_BATTERY_STATUS_NORMAL; 
#ifdef __INTERCONNECTION__
    app_battery_measure.currentBatteryInfo = APP_BATTERY_DEFAULT_INFO;
    app_battery_measure.lastBatteryInfo = APP_BATTERY_DEFAULT_INFO;
    app_battery_measure.isMobileSupportSelfDefinedCommand = 0;
#else
	// 设置电流等级
    app_battery_measure.currlevel = APP_BATTERY_LEVEL_MAX;
#endif
	// 电池状态信息
    app_battery_measure.currvolt = APP_BATTERY_MAX_MV;
    app_battery_measure.lowvolt = APP_BATTERY_MIN_MV;
    app_battery_measure.highvolt = APP_BATTERY_MAX_MV;
    app_battery_measure.pdvolt = APP_BATTERY_PD_MV;
    app_battery_measure.chargetimeout = APP_BATTERY_CHARGE_TIMEOUT_MIN;

    app_battery_measure.periodic = APP_BATTERY_MEASURE_PERIODIC_QTY;
    // 指定电池电量钩子函数
    app_battery_measure.cb = app_battery_event_process; 
    app_battery_measure.user_cb = NULL;

    app_battery_measure.charger_status.prevolt = 0;
    app_battery_measure.charger_status.slope_1000_index = 0;
    app_battery_measure.charger_status.cnt = 0;    
	
	// 设置处理函数, 注册邮箱线程对应ID的钩子函数
    app_set_threadhandle(APP_MODUAL_BATTERY, app_battery_handle_process);
	
	// 注册出入盒钩子函数并根据当前状态设置 pin 引脚
	if (app_battery_charger_indication_open() == APP_BATTERY_CHARGER_PLUGIN)
	{
		......
	}
	......
    return nRet;
}

注意:该函数并不是完整的函数,只截取部分代码

  • 参数/函数讲解
序号 参数/函数 说明
1 osTimerCreate(osTimerPeriodic) 创建电池电量检测定时器
2 osTimerCreate(osTimerOnce) 创建出入盒定时器,这个定时器一般用于处理电池插拔事件的去抖动,以防止误触发。
3 app_set_threadhandle() 设置电池模块的线程处理函数。这个函数在电池状态发生变化时被调用,用于处理相关的逻辑。
4 app_battery_event_process 指定电池电量处理函数
5 app_battery_charger_indication_open() 函数首先初始化充电器,然后尝试获取充电器状态,如果充电器已插入则立即返回状态。如果外部充电器检测配置有效且检测到外部充电器已插入,则将状态设置为已插入。最后,设置充电器中断处理函数并返回状态。

可以看到 app_battery_open() 接口里调用了 app_set_threadhandle() 来添加 battery 模块的钩子函数,其中 app_battery_handle_process() 就是该模块的钩子函数。

1.2 APP_BATTERY_MEASURE_T

我们知道 app_battery_open() 是由 app_init() 调用来初始化 battery 模块的,以下是 battery 模块所用到全局变量。

  • 代码
c 复制代码
struct APP_BATTERY_MEASURE_T
{
    uint32_t start_time; 		// 用于记录电池测量开始的时间
    enum APP_BATTERY_STATUS_T status; // 表示当前电池的状态
#ifdef __INTERCONNECTION__
    uint8_t currentBatteryInfo; // 存储当前电池信息
    uint8_t lastBatteryInfo;    // 用于存储上一次电池信息
    uint8_t isMobileSupportSelfDefinedCommand; 			// 用于表示移动设备是否支持自定义命令
#else
    uint8_t currlevel;          // 表示当前电池的电量级别
#endif
    APP_BATTERY_MV_T currvolt;  // 表示当前电池的电压值
    APP_BATTERY_MV_T lowvolt;   // 表示电池的低电压阈值
    APP_BATTERY_MV_T highvolt;  // 表示电池的高电压阈值
    APP_BATTERY_MV_T pdvolt;    // 表示电池的充电电压
    uint32_t chargetimeout;	    // 表示充电超时时间
    enum APP_BATTERY_MEASURE_PERIODIC_T periodic; 		// 表示电池测量的周期
    HAL_GPADC_MV_T voltage[APP_BATTERY_STABLE_COUNT]; 	// 用于存储电池的稳定电压值
    uint16_t index; 			// 用于索引电池的稳定电压值
    struct APP_BATTERY_MEASURE_CHARGER_STATUS_T charger_status; // 用于存储充电器的状态信息
    APP_BATTERY_EVENT_CB_T cb; 	// 电池事件回调函数
    APP_BATTERY_CB_T user_cb;  	// 用户定义的电池回调函数
};

从变量的初始化可以看到定制化的设置都在tgt_hardware.h 里面,还要其他定制化的设置。

c 复制代码
//battery info
#define APP_BATTERY_MIN_MV (3200)
#define APP_BATTERY_PD_MV  (3100)
#define APP_BATTERY_MAX_MV (4200)
  • 参数/函数讲解
序号 参数/函数 说明

1.3 osTimerDef

在电池初始化 app_battery_open() 函数中,会分别开启电池电量检测定时器和出入盒定时器。接下来了解这两个定时器的创建过程吧,相信会看到一些意想不到的东西。

c 复制代码
    if (app_battery_timer == NULL)
    	// 创建电池电量检测定时器
        app_battery_timer = osTimerCreate (osTimer(APP_BATTERY), osTimerPeriodic, NULL);

    if (app_battery_pluginout_debounce_timer == NULL)
    	// 创建出入盒定时器
        app_battery_pluginout_debounce_timer = osTimerCreate (osTimer(APP_BATTERY_PLUGINOUT_DEBOUNCE), osTimerOnce, &app_battery_pluginout_debounce_ctx);

注意:该函数并不是完整的函数,只截取部分代码

当我们滑到文件头部的时候就能看到似成相识的代码: osTimerDef

  • 代码
c 复制代码
// 定义一个静态函数,用于处理电池插拔事件的去抖动
// 该函数接收一个void类型的常量指针参数,通常用于传递需要的参数
static void app_battery_pluginout_debounce_handler(void const *param);

// 定义一个操作系统定时器,关联到app_battery_pluginout_debounce_handler函数
// 这个定时器用于在检测到电池插拔事件后进行延时处理,以过滤掉短暂的噪声信号
osTimerDef(APP_BATTERY_PLUGINOUT_DEBOUNCE, app_battery_pluginout_debounce_handler);

// 定义一个静态的定时器句柄,初始值为NULL
// 这个句柄用于在程序中唯一标识和操作APP_BATTERY_PLUGINOUT_DEBOUNCE定时器
static osTimerId app_battery_pluginout_debounce_timer = NULL;

// 定义一个静态函数app_battery_timer_handler,用于处理电池定时器事件
// 该函数接受一个void类型的常量指针参数,用于传递定时器事件相关的数据
// 由于定时器的处理函数往往需要在特定的时间间隔执行特定任务,因此定义为静态函数可以限制其作用范围,避免影响到其他模块
static void app_battery_timer_handler(void const *param);

// 使用宏osTimerDef定义一个名为APP_BATTERY的定时器结构体
// 该结构体关联到前面定义的app_battery_timer_handler函数
// 这一步是创建定时器的必要步骤,它将定时器和具体的处理函数关联起来
osTimerDef (APP_BATTERY, app_battery_timer_handler);

// 声明一个静态变量app_battery_timer,用于存储创建后的定时器实例的ID
// 在程序的其他部分,可以通过这个ID来操作定时器,例如启动、停止定时器
// 将其初始化为NULL,表示在程序的初始阶段,定时器实例还未被创建
static osTimerId app_battery_timer = NULL;
  • 参数/函数讲解
序号 参数/函数 说明
1 osTimerDef(APP_BATTERY,...) 使用宏osTimerDef定义一个名为APP_BATTERY的定时器结构体,这一步是创建定时器的必要步骤,它将定时器和具体的处理函数关联起来

没错,osTimerDef 与 邮箱线程 osThreadDef 创建流程原理是一样,这该死的熟悉感。让我们进去 osTimerDef 该宏在哪吧

  • 代码
c 复制代码
// === 定时器管理函数 ===
/// 定义一个定时器对象。
/// \param name      定时器对象的名称。
/// \param function  定时器回调函数的名称。
/// \note 可以修改: \b osTimerDef 的参数应当保持一致,但在每一个 CMSIS-RTOS 实现中,
///       宏体是特定于实现的。
#if defined (osObjectsExternal)  // 当对象是外部定义的
#define osTimerDef(name, function)  \
extern osTimerDef_t os_timer_def_##name // 外部声明定时器定义
#else                             // 定义对象时
#define osTimerDef(name, function)  \
uint32_t os_timer_cb_##name[5];     \ // 定义用于存储回调函数上下文的空间 
osTimerDef_t os_timer_def_##name =  \
{ (function), (os_timer_cb_##name) }  // 初始化定时器定义结构体
#endif
  • 参数/函数讲解

此宏定义用于创建定时器对象。功能如下:

1、定义或声明一个定时器对象 os_timer_def_##name

2、如果 osObjectsExternal 被定义,则仅声明对象并将其设为外部链接。

3、否则,定义对象并初始化其成员:回调函数为 function,上下文为数组 os_timer_cb_##name

可以在 osTimerDef 是在 cmsis_os.h 里的定义,到这里可以肯定的说这 osTimerDef 不就跟 osThreadDef 一样嘛,都是将线程函数赋值到结构体中,终于有种大彻大悟的感觉了。

<<【系列文章索引】>>


总结

**  感谢观看,这里就是 Battery模块 -- 创建电池检测定时器的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹**

**  也欢迎你,关注我。👍 👍 👍**

**  原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!下期再见。🎉**

更多专栏订阅:

订阅更多,你们将会看到更多的优质内容!!

相关推荐
超级码农ProMax3 小时前
STM32——“SPI Flash”
stm32·单片机·嵌入式硬件
Asa3193 小时前
stm32点灯Hal库
stm32·单片机·嵌入式硬件
碳学长5 小时前
2025系统架构师(一考就过):案例题之一:嵌入式架构、大数据架构、ISA
大数据·架构·系统架构
end_SJ5 小时前
初学stm32 --- 外部中断
stm32·单片机·嵌入式硬件
嵌入式小强工作室7 小时前
stm32 查找进硬件错误方法
stm32·单片机·嵌入式硬件
wenchm7 小时前
细说STM32F407单片机DMA方式读写SPI FLASH W25Q16BV
stm32·单片机·嵌入式硬件
逝灮8 小时前
【蓝桥杯——物联网设计与开发】拓展模块4 - 脉冲模块
stm32·单片机·嵌入式硬件·mcu·物联网·蓝桥杯·脉冲测量
云山工作室8 小时前
基于单片机的电梯声控系统设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设
憧憬一下9 小时前
PCIe_Host驱动分析_设备枚举
arm开发·嵌入式硬件·嵌入式·pcie·linux驱动开发
Asa31911 小时前
STM32-按键扫描配置
stm32·单片机·嵌入式硬件