当前位置: 首页 > article >正文

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

请添加图片描述

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

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

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

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

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

请添加图片描述

文章目录

  • 前言
  • 1 真正的 Battery 模块
      • 1.1 app_battery_open()
      • 1.2 APP_BATTERY_MEASURE_T
      • 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() 的调用作为切入点。

  • 代码
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;
}

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

  • 参数/函数讲解
序号参数/函数说明
1osTimerCreate(osTimerPeriodic)创建电池电量检测定时器
2osTimerCreate(osTimerOnce)创建出入盒定时器,这个定时器一般用于处理电池插拔事件的去抖动,以防止误触发。
3app_set_threadhandle()设置电池模块的线程处理函数。这个函数在电池状态发生变化时被调用,用于处理相关的逻辑。
4app_battery_event_process指定电池电量处理函数
5app_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 模块所用到全局变量。

  • 代码
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 里面,还要其他定制化的设置。

//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() 函数中,会分别开启电池电量检测定时器和出入盒定时器。接下来了解这两个定时器的创建过程吧,相信会看到一些意想不到的东西。

    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

  • 代码
// 定义一个静态函数,用于处理电池插拔事件的去抖动
// 该函数接收一个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;
  • 参数/函数讲解
序号参数/函数说明
1osTimerDef(APP_BATTERY,…)使用宏osTimerDef定义一个名为APP_BATTERY的定时器结构体,这一步是创建定时器的必要步骤,它将定时器和具体的处理函数关联起来

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

  • 代码
// === 定时器管理函数 ===
/// 定义一个定时器对象。
/// \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模块 – 创建电池检测定时器的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹

在这里插入图片描述

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

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

更多专栏订阅:

  • 😀 【LeetCode题解(持续更新中)】

  • 🥇 【恒玄BES】

  • 🌼 【鸿蒙系统】

  • 💎 【蓝牙协议栈】

  • 🎃 【死机分析】

  • 👑 【Python脚本笔记】

  • 🚝 【Java Web项目构建过程】

  • 💛 【微信小程序开发教程】

  • 【JavaScript随手笔记】

  • 🤩 【大数据学习笔记(华为云)】

  • 🦄 【程序错误解决方法(建议收藏)】

  • 🔐 【Git 学习笔记】

  • 🚀 【软件安装教程】



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


http://www.kler.cn/a/288532.html

相关文章:

  • 阿里巴巴通义灵码推出Lingma SWE-GPT:开源模型的性能新标杆
  • ReactPress技术揭秘
  • ISAAC SIM踩坑记录--ubuntu 22.04操作系统安装
  • 分享一个傻瓜式一键启动的加速器
  • 3.5【数据库系统】ER图
  • 计算机毕业设计必看必学35755flask旅游景区热度可视化平台原创定制程序,java、PHP、python、小程序、文案全套、毕设成品等
  • 利用Spring Boot的@Transactional注解保障业务数据的一致性
  • 2024 【Delphi 12】苹果ios开发环境配置(五星保姆级)
  • UML(ER) manual book
  • 深入理解Java序列化:从入门到实践
  • c++ std::advance 使用简介
  • MySQL库表设计规范
  • IMU助力预测青少年脊柱侧弯
  • Apache DolphinScheduler大规模任务调度系统对大数据实时Flink任务支持
  • TikTok运营:IP地址如何影响TikTok的内容运营?
  • 内存管理篇-20 Linux虚拟内存管理
  • 亚信安全荣获“2024年网络安全优秀创新成果大赛”优胜奖
  • 缓存预热有哪些方案?
  • Java面试题真题·项目介绍部分总结
  • 【测试】bug 相关知识点总结
  • 单片机原理图与PCB设计心得体会
  • 解决Qt Creator与MSVC不匹配的问题
  • WebView快速打开
  • 【Linux】FRP:内网穿透
  • 第十二章 rust中的项目管理
  • PHP一键创建全球参与探索现代在线投票系统