【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模块 -- 创建电池检测定时器的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹**

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

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

更多专栏订阅:

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

相关推荐
傻傻虎虎8 小时前
【系统架构设计】信息系统基础知识
系统架构
有颜有货9 小时前
低代码开发平台系统架构概述
低代码·系统架构
z2014z9 小时前
系统架构设计师教程 第5章 5.3 系统分析与设计 笔记
笔记·系统架构
辰哥单片机设计10 小时前
门磁模块详解(防盗感应开关 STM32)
stm32·单片机·嵌入式硬件·传感器
yrx02030711 小时前
stm32 IIC总线busy解决方法
stm32·单片机·嵌入式硬件
h1771134720512 小时前
基于区块链的相亲交易系统源码解析
大数据·人工智能·安全·系统架构·交友
钡铼技术物联网关12 小时前
Codesys 与 ARMxy ARM 工业控制器:工业控制的黄金组合
linux·运维·服务器·arm开发·硬件工程
Liii40312 小时前
【ARM】Cache深度解读
java·arm开发·spring
Liii40312 小时前
【ARM】中断的处理
arm开发·arm
辣香牛肉面13 小时前
十三 系统架构设计(考点篇)
系统架构