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

news2024/11/25 22:30:22

请添加图片描述

  • 💌 所属专栏:【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.coloradmin.cn/o/2100626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】进程状态(RSDT 阻塞 僵尸 孤儿)

目录 进程状态 进程状态的查看 R和S 运行状态 T/t 暂停状态 kill命令 D &#xff08;disk sleep&#xff09;状态、 Z 状态&#xff08;僵尸状态&#xff09; 孤儿状态 运行状态 阻塞状态 进程状态 一个进程通常有三种状态 ◉ 就绪状态&#xff08;Ready&#xff0…

Qt 去掉QDialog对话框的问号

QT 对话框的问号是什么&#xff1f; QDialog默认的window flag中包含了Qt::WindowContextHelpButtonHint,这个flag意思是在窗口上提供“上下文帮助”按钮 使用方式/调用方式 void QWidget::setWhatsThis(const QString &)比如&#xff1a; ui->lineEdit_1->setWh…

用亚马逊AI代码开发助手Amazon Q Developer开发应用(上篇)

快用人工智能帮程序员写代码&#xff01;今天小李哥就来介绍亚马逊推出的国际前沿人工智能AI代码开发助手Amazon Q Developer。目前该代码助手在Hugging Face代码生成权威测试集SWE-bench中排名第一&#xff0c;可以根据我们的需求生成整个代码项目&#xff0c;并可以帮助我们解…

C++入门基础,看这篇就足够了!

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;Linux专栏&#xff1a;Linux &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 &#x1f308;C专栏&#xff1a;C 文章目录 0.前言1. C的关键字2.命名空间2.1 命名空间的定…

vue 中计算属性可以接收参数

代码中的value就是接收的参数 计算属性要接收参数要写在返回的时候 computed: {isButtonDisabled() {return (value) > {const num parseInt(value);return isNaN(num) || num < 0}},},//计算属性aaa(){return (value) >{写逻辑return 返回值}} 使用 <el-butto…

【数学建模】国赛论文写作技巧教学——模型假设与变量说明

一、模型假设 1、内容要求 模型假设是建立数学模型中非常关键的一步&#xff0c;这会关系到模型的成败和优劣。所以&#xff0c;应该细致地分析实际问题&#xff0c;从大量的变量中筛选出最能表现问题本质的变量&#xff0c;并简化它们的关系。由于假设一般不是实际问题直接提…

2024Hvv漏洞汇总(128个POC)

2024Hvv漏洞整理&#xff08;128个POC&#xff09; ​&#xff08;网上漏洞零零散散&#xff09;下面是收集到的且有POC的漏洞整理合集&#xff0c;鄙人分了三种格式供各位提取&#xff0c;下面贴上目录与图片&#xff0c;由于字数有点大&#xff0c;各位请移步网盘自行提取。…

MySQL 基础命令

目录 一、MySQL简介 1.MySQL 的主要特点包括 2.MySQL 的主要用途包括&#xff1a; 二、MySQL 基础命令 1. 基本操作 1.1 进入 1.2 选择数据库 1.3 修改密码 1.4 所有命令后面都要加 “;” 2. 创建 2.1 创建数据库 2.2 创建数据表 2.3 常见字段 3. 修改/更新 3.1…

[数据集][目标检测]街道乱放广告牌检测数据集VOC+YOLO格式114张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;114 标注数量(xml文件个数)&#xff1a;114 标注数量(txt文件个数)&#xff1a;114 标注类别…

关于LLC知识15

右手螺旋定则&#xff1a;四指指向电流的方向&#xff0c;拇指的方向就是磁通方向 变压器副边会产生一个和原磁通方向相反的磁通来阻碍它变大 这样原边绕组的电感量会变小&#xff1a;U/Ldi/dt对应的电流会变大 电感量越大&#xff0c;抑制电流能量越强 原边开路时候&#x…

【贪心算法】区间类算法题(整数替换、俄罗斯套娃、重构字符串等、C++)

文章目录 1. 前言2. 算法题1.整数替换2.俄罗斯套娃信封问题3.可被三整除的最大和4.距离相等的条形码5.重构字符串 1. 前言 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取当前状态下最优决策的算法。贪心算法通常用来解决最优化问题&#xff0c…

sqlite数据插入效率

一、程序效率测试 时间相关接口&#xff1a; int gettimeofday(struct timeval*tv, struct timezone *tz); 功能&#xff1a;得到从1970年1月1日0时0分0秒到现在的秒数。<可以利用该函数来计算一个程序的运行时间&#xff0c;只需在程序前后调用该函数&#xff0c;…

安捷伦Agilent N9344C手持频谱分析仪

安捷伦Agilent N9344C手持频谱分析仪 安捷伦Agilent N9344C手持频谱分析仪&#xff08;HSA&#xff09; 主要特性和功能 获得专为现场使用设计的性能&#xff1a;便携耐用&#xff0c;无风扇设计&#xff1b;无论白天还是夜晚均可显示清晰的画面&#xff1b;电池使用时间为 4 …

大模型开发转行全攻略:必备知识、技能与学习路径详解,大模型零基础入门到精通

引言 随着人工智能和大模型&#xff08;如GPT-4、BERT等&#xff09;技术的快速发展&#xff0c;越来越多的专业人士希望转行进入这一领域。大模型开发涉及复杂的技术体系和多样的应用场景&#xff0c;对从业者的知识和能力提出了较高要求。本文将详细解析转行大模型开发所需的…

CasaOS系统本地安装Gopeed高速下载软件并实现异地远程访问下载文件

文章目录 前言1. 更新应用中心2.Gopeed安装与配置3. 本地下载测试4. 安装内网穿透工具5. 配置公网地址6. 配置固定公网地址 前言 本文主要介绍如何在轻NAS系统CasaOS小主机中安装支持全平台的高速下载器Gopeed&#xff0c;并结合内网穿透工具配置公网地址实现远程访问本地主机…

java知识点——I/O输入输出处理(二)

读取字符流&#xff1a; 由于字符输入流的read()方法返回的是int类型的值&#xff0c;如果想获得字符就需要进行强制类型转换&#xff0c;所以输出语句中将变量len强转为了char类型。 public static void main(String[] args) throws IOException {//创建FileReader对象FileRe…

PHP一体化解决方案高效整合与优化学校管理系统小程序源码

一体化解决方案&#xff0c;让学校管理系统焕发新生✨ &#x1f3eb; 开篇&#xff1a;传统管理的瓶颈与挑战 在快节奏的教育时代&#xff0c;传统的学校管理系统是否让你感到力不从心&#xff1f;&#x1f914; 信息孤岛、流程繁琐、效率低下...这些问题是否正困扰着你的工作…

巴黎奥运会引发体育健身热潮:气膜体育馆成为新宠—轻空间

随着巴黎奥运会的成功举办&#xff0c;全球范围内掀起了一股体育健身的热潮。各地的健身场所迎来了前所未有的参与热情&#xff0c;其中&#xff0c;融合了体育、娱乐、休闲等多种业态的综合气膜体育馆因其独特的优势&#xff0c;迅速成为群众健身的新宠&#xff0c;成为了大众…

PHP一键创建全球参与探索现代在线投票系统

一键创建全球参与探索现代在线投票系统 &#x1f310;✨ &#x1f680; 开篇&#xff1a;解锁全球互动新纪元 在这个数字化飞速发展的时代&#xff0c;每一个声音都值得被听见&#xff0c;每一份意见都能跨越山海相连。想象一下&#xff0c;只需轻轻一点&#xff0c;就能发起…

如何读懂以太坊源代码

以下是一个学习以太坊源代码的清晰思路&#xff1a; 一、前期准备 基础知识储备&#xff1a; 熟悉区块链的基本概念&#xff0c;如区块、交易、共识机制、哈希函数等。了解 Go 语言&#xff08;以太坊主要使用 Go 语言编写&#xff09;的基本语法和编程概念。 工具准备&#x…