💌 所属专栏:【BES2500x系列】
😀 作 者:我是夜阑的狗🐶
🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询!
💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘
您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!🤩 🤩 🤩
文章目录
- 前言
- [1 应用初始化 app_init()](#1 应用初始化 app_init())
-
-
- [1.1 app_os_init()](#1.1 app_os_init())
- [1.2 app_battery_open()](#1.2 app_battery_open())
- [1.3 app_audio_open()](#1.3 app_audio_open())
-
- 总结
前言
大家好,又见面了,我是夜阑的狗🐶,本文是专栏【BES2500x系列】专栏的第12篇文章;
今天开始学习BES2500x系列的一天💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。
专栏地址:【BES2500x系列】, 此专栏是我是夜阑的狗对BES2500x系列开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。对了,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。
1 应用初始化 app_init()
前面学习了嵌入式系统启动的基本流程,可以分为 引导程序
和 系统初始化程序
这两部分,并系统初始化 中 main
函数进行了详细讲解。接下来就学习 main
函数中 应用初始化
具体是怎么跑的吧。话不多说,让我们原文再续,书接上回吧。
从上一篇文章可以了解到系统的 main
函数是如何跑到的,并且在讲解 main
函数中各个函数的作用,接下来就看一下 main
中的应用初始化具体都干了些什么吧,可以在 app.cpp
文件中看到该 app_init 函数。
- 代码
这里由于 app_init
函数代码过多,这里不就放出来了,只讲解一下其中的各个函数作用。
c
/*
* 函数名:app_init
* 功能:应用程序初始化
* 参数:无
* 返回值:初始化结果,0表示成功,非0表示失败
* 描述:本函数用于在应用程序启动时进行初始化操作,包括环境变量加载、电源键检测和USB插拔状态检查。
*/
int app_init(void)
{
// 初始化返回值为成功
int nRet = 0;
// 定义并初始化nvrecord环境变量结构体指针
struct nvrecord_env_t *nvrecord_env;
......省略后续
......
}
注意:该函数并不是完整的函数,只截取部分代码
- 参数/函数讲解
app_init()
函数详细介绍,这些函数调用涉及到了蓝牙、存储、系统状态、电源管理以及音频等方面的初始化和配置:
序号 | 函数 | 说明 |
---|---|---|
1 | app_bt_add_string_test_table() | 添加蓝牙字符串测试表的函数,用于在蓝牙测试中使用。 |
2 | nv_record_init() | 初始化 flash,用于存储一些系统配置和状态信息。 |
3 | factory_section_init() | 初始化工厂设置部分的函数,用于读取和设置设备的出厂默认参数。 |
4 | app_sysfreq_req() | 请求系统频率的函数,用于调整系统的工作频率以满足当前的性能需求。 |
5 | list_init() | 初始化链表数据结构,以便后续的数据操作和管理。 |
6 | app_os_init() | 初始化操作系统相关的资源和数据结构。 |
7 | app_status_indication_init() | 初始化应用程序状态指示的函数,用于在设备上指示当前的工作状态。 |
8 | app_battery_open() | 初始化电池管理模块,用于监控电池状态和电量,充电检测,并返回电池状态。 |
9 | hal_sw_bootmode_set() | 设置了软件引导模式为重启模式,以便系统在下次启动时执行重启操作。 |
10 | app_poweron_key_init() | 初始化开机按键的函数,用于检测用户的开机按键操作。 |
11 | app_bt_init() | 初始化蓝牙模块,包括协议栈的初始化和配置。 |
12 | af_open() | 初始化音频框架(Audio Framework)的函数,用于音频处理和管理。 |
13 | app_audio_open() | 初始化音频模块,包括音频设备的打开和配置。 |
14 | app_audio_manager_open() | 初始化音频管理器的函数,用于管理音频资源和会话。 |
15 | app_overlay_open() | 打开应用程序覆盖区的函数,用于加载和管理应用程序的覆盖资源。主要是创建一个互斥锁。 |
16 | nv_record_env_init() | 初始化环境变量的 flash。 |
17 | nvrec_dev_data_open() | 打开设备数据的非易失性记录(NV Record),用于存储和读取设备相关的数据信息。 |
18 | factory_section_open() | 用于打开工厂设置部分的函数,用于读取工厂设置的参数信息。 |
19 | nv_record_env_get() | 获取环境变量的 flash,用于读取环境变量信息。 |
20 | audio_process_init() | 初始化音频处理模块的函数,用于音频数据的处理和转换。 |
21 | app_bt_stream_volume_ptr_update(NULL) | 更新蓝牙音频流的音量指针,可能在音频设备或会话发生变化时调用。 |
22 | app_start_bt_module_thread() | 该函数创建并启动了一个用于初始化蓝牙模块的线程,并设置应用线程的优先级为高于正常优先级。 |
23 | btdrv_start_bt() | 启动蓝牙设备的函数,用于初始化和启动蓝牙协议栈。 |
1.1 app_os_init()
接下来对 app_init
函数中个别函数进行讲解,app_os_init()
是一个应用程序操作系统初始化函数的实现
- 代码
c
/**
* 初始化操作系统环境
*
* 该函数负责初始化应用程序的操作系统环境它首先尝试初始化邮箱,然后创建一个应用线程
* 这是应用程序启动的入口点,确保操作系统环境正确初始化,以便应用程序能够正常运行
*
* @return 返回-1表示初始化失败,0表示成功
*/
int app_os_init(void)
{
// 初始化邮箱系统,如果失败则返回-1
if (app_mailbox_init())
return -1;
// 创建应用线程,如果创建失败则返回0
app_thread_tid = osThreadCreate(osThread(app_thread), NULL);
if (app_thread_tid == NULL) {
TRACE(0,"Failed to Create app_thread\n");
return 0;
}
return 0;
}
- 参数/函数讲解
序号 | 函数 | 说明 |
---|---|---|
1 | app_mailbox_init() | 初始化应用程序的邮箱,邮箱通常用于线程间的通信和消息传递。如果初始化失败,函数会返回非零值。 |
2 | osThreadCreate() | 创建了一个名为 app_thread 的线程,并将其标识符保存在 app_thread_tid 变量中。osThreadCreate 是操作系统提供的函数,用于创建一个新的线程。osThread 宏用于指定要创建的线程的名称。 |
总的来说,这个函数的作用是初始化应用程序的操作系统环境,包括初始化邮箱和创建一个新的线程用于应用程序的执行。
1.2 app_battery_open()
在应用初始化中,电池模块肯定必不可少的,接下来让我们来看看充电检测执行流程如下步骤所示:
Step 1 、充电检测(电池状态,充电状态或是充电使用状态) ;
Step 2 、定时检测电量 ---> 可以通过中断方式检测当前电压值 ;
Step 3、将检测到的电压通过邮箱发送,并进行相应处理 ;
- 代码
c
/*
* 函数功能:打开电池管理模块的初始化函数
*
* 描述:该函数负责初始化电池管理模块,包括创建定时器,设置电池测量参数,
* 配置外部充电器检测器和使能引脚,以及根据充电状态设置模块状态。
*
* 参数:无
*
* 返回值:电池模块打开模式,包括无效模式、正常模式、充电模式、上电充电模式
*/
int app_battery_open(void)
{
// 打印电池范围跟踪信息
APP_BATTERY_TRACE(3,"%s batt range:%d~%d",__func__, APP_BATTERY_MIN_MV, APP_BATTERY_MAX_MV);
// 初始化返回值为无效模式
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;
// 根据是否支持互联确定电池信息初始化
......
// 初始化电池电压参数
......
// 设置电池测量周期和回调函数
......
// 初始化电池充电状态参数
......
// 设置应用电池处理线程
app_set_threadhandle(APP_MODUAL_BATTERY, app_battery_handle_process);
// 配置外部充电器检测器引脚
if (app_battery_ext_charger_detecter_cfg.pin != HAL_IOMUX_PIN_NUM)
{
hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&app_battery_ext_charger_detecter_cfg, 1);
hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin, HAL_GPIO_DIR_IN, 1);
}
// 配置外部充电器使能引脚
if (app_battery_ext_charger_enable_cfg.pin != HAL_IOMUX_PIN_NUM)
{
// 它将初始化引脚的复用功能,并设置引脚为输出模式,输出高电平
hal_iomux_init((struct HAL_IOMUX_PIN_FUNCTION_MAP *)&app_battery_ext_charger_detecter_cfg, 1);
hal_gpio_pin_set_dir((enum HAL_GPIO_PIN_T)app_battery_ext_charger_detecter_cfg.pin, HAL_GPIO_DIR_OUT, 1);
}
// 检测并处理充电状态
if (app_battery_charger_indication_open() == APP_BATTERY_CHARGER_PLUGIN)
{
// 设置充电状态
app_battery_measure.status = APP_BATTERY_STATUS_CHARGING;
// 记录开始充电时间
app_battery_measure.start_time = hal_sys_timer_get();
// 配置充电器插入参数
......
// 根据充电器拔出重置配置返回值
......
}
else
{
// 设置正常状态
app_battery_measure.status = APP_BATTERY_STATUS_NORMAL;
// 配置充电器拔出参数
......
// 设置返回值为正常模式
......
}
// 返回电池模块打开模式
return nRet;
}
注意:该函数并不是完整的函数,只截取部分代码
- 参数/函数讲解
序号 | 函数 | 说明 |
---|---|---|
1 | osTimerCreate(osTimerPeriodic) | 创建电池电量检测定时器 |
2 | osTimerCreate(osTimerOnce) | 创建出入盒定时器,这个定时器一般用于处理电池插拔事件的去抖动,以防止误触发。 |
3 | app_set_threadhandle() | 设置电池模块的线程处理函数。这个函数在电池状态发生变化时被调用,用于处理相关的逻辑。 |
4 | hal_iomux_init() | 初始化GPIO引脚 |
5 | hal_gpio_pin_set_dir() | 设置对应的引脚,以及输出电平 |
1.3 app_audio_open()
这个函数的作用是初始化音频管理模块,并执行一些初始化操作,如铃声合并的初始化、设置线程处理函数、蓝牙音频流的初始化,并将初始化标志位置为 true。
- 代码
c
/**
* @brief 打开应用音频模块
*
* 该函数负责初始化应用音频模块。包括创建互斥量、内存池、音频列表等。
* 如果音频模块已经初始化,则直接返回。否则,执行一系列初始化操作。
*/
void app_audio_open(void)
{
// 检查音频模块是否已经初始化
if(app_audio_init)
{
// 如果已经初始化,直接返回
return;
}
// 创建音频队列互斥量
if (g_app_audio_queue_mutex_id == NULL)
{
g_app_audio_queue_mutex_id = osMutexCreate((osMutex(g_app_audio_queue_mutex)));
}
else
{
// 如果互斥量ID已经存在,则断言失败
ASSERT(0, "[%s] ERROR: g_app_audio_queue_mutex_id != NULL", __func__);
}
// 创建音频状态内存池
if (app_audio_status_mempool == NULL)
app_audio_status_mempool = osPoolCreate(osPool(app_audio_status_mempool));
// 确保内存池创建成功
ASSERT(app_audio_status_mempool, "[%s] ERROR: app_audio_status_mempool != NULL", __func__);
// 根据编译选项,可能创建音频队列
......
// 根据编译选项,可能初始化提示列表
......
// 初始化音频合并功能
app_ring_merge_init();
// 设置音频模块的处理线程
app_set_threadhandle(APP_MODUAL_AUDIO, app_audio_handle_process);
// 初始化蓝牙音频流
app_bt_stream_init();
// 标记音频模块已经初始化
app_audio_init = true;
}
注意:该函数并不是完整的函数,只截取部分代码
- 参数/函数讲解
序号 | 函数 | 说明 |
---|---|---|
1 | osMutexCreate() | 创建一个互斥锁,用于保护音频队列的访问。 |
2 | osPoolCreate() | 创建一个内存池,用于存储音频状态。 |
3 | app_ring_merge_init() | 初始化混合提示音功能。铃声合并通常用于在设备同时需要播放多个声音时,将它们合并成一个声音输出,以防止声音混叠或干扰。 |
4 | app_set_threadhandle() | 设置音频模块的线程处理函数。这个函数可能会在音频状态发生变化时被调用,用于处理相关的逻辑。 |
5 | app_bt_stream_init() | 这个函数调用可能是用于初始化蓝牙音频流功能。在蓝牙设备中,这个函数可能会设置蓝牙音频相关的参数和配置。 |
总结
** 感谢观看,这里就是 应用初始化 -- app_init() 的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹**
** 也欢迎你,关注我。👍 👍 👍**
** 原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!下期再见。🎉**
更多专栏订阅:
订阅更多,你们将会看到更多的优质内容!!