【BES2500x系列 -- RTX5操作系统】系统执行流程 -- 应用初始化 -- app_init() --(十二)

请添加图片描述

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

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

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

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

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

请添加图片描述


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

前言

  大家好,又见面了,我是夜阑的狗🐶,本文是专栏【BES2500x系列】专栏的第12篇文章;
  今天开始学习BES2500x系列的一天💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。
  专栏地址:【BES2500x系列】, 此专栏是我是夜阑的狗对BES2500x系列开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。对了,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站
  如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。


1 应用初始化 app_init()

  前面学习了嵌入式系统启动的基本流程,可以分为 引导程序系统初始化程序 这两部分,并系统初始化 中 main 函数进行了详细讲解。接下来就学习 main 函数中 应用初始化 具体是怎么跑的吧。话不多说,让我们原文再续,书接上回吧。

在这里插入图片描述

  从上一篇文章可以了解到系统的 main 函数是如何跑到的,并且在讲解 main 函数中各个函数的作用,接下来就看一下 main 中的应用初始化具体都干了些什么吧,可以在 app.cpp 文件中看到该 app_init 函数。

在这里插入图片描述

  • 代码

  这里由于 app_init 函数代码过多,这里不就放出来了,只讲解一下其中的各个函数作用。

/*
 * 函数名:app_init
 * 功能:应用程序初始化
 * 参数:无
 * 返回值:初始化结果,0表示成功,非0表示失败
 * 描述:本函数用于在应用程序启动时进行初始化操作,包括环境变量加载、电源键检测和USB插拔状态检查。
 */
int app_init(void)
{
    // 初始化返回值为成功
    int nRet = 0;
    // 定义并初始化nvrecord环境变量结构体指针
    struct nvrecord_env_t *nvrecord_env;
	......省略后续
	......
}

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

  • 参数/函数讲解

  app_init() 函数详细介绍,这些函数调用涉及到了蓝牙、存储、系统状态、电源管理以及音频等方面的初始化和配置:

序号函数说明
1app_bt_add_string_test_table()添加蓝牙字符串测试表的函数,用于在蓝牙测试中使用。
2nv_record_init()初始化 flash,用于存储一些系统配置和状态信息。
3factory_section_init()初始化工厂设置部分的函数,用于读取和设置设备的出厂默认参数。
4app_sysfreq_req()请求系统频率的函数,用于调整系统的工作频率以满足当前的性能需求。
5list_init()初始化链表数据结构,以便后续的数据操作和管理。
6app_os_init()初始化操作系统相关的资源和数据结构。
7app_status_indication_init()初始化应用程序状态指示的函数,用于在设备上指示当前的工作状态。
8app_battery_open()初始化电池管理模块,用于监控电池状态和电量,充电检测,并返回电池状态。
9hal_sw_bootmode_set()设置了软件引导模式为重启模式,以便系统在下次启动时执行重启操作。
10app_poweron_key_init()初始化开机按键的函数,用于检测用户的开机按键操作。
11app_bt_init()初始化蓝牙模块,包括协议栈的初始化和配置。
12af_open()初始化音频框架(Audio Framework)的函数,用于音频处理和管理。
13app_audio_open()初始化音频模块,包括音频设备的打开和配置。
14app_audio_manager_open()初始化音频管理器的函数,用于管理音频资源和会话。
15app_overlay_open()打开应用程序覆盖区的函数,用于加载和管理应用程序的覆盖资源。主要是创建一个互斥锁。
16nv_record_env_init()初始化环境变量的 flash。
17nvrec_dev_data_open()打开设备数据的非易失性记录(NV Record),用于存储和读取设备相关的数据信息。
18factory_section_open()用于打开工厂设置部分的函数,用于读取工厂设置的参数信息。
19nv_record_env_get()获取环境变量的 flash,用于读取环境变量信息。
20audio_process_init()初始化音频处理模块的函数,用于音频数据的处理和转换。
21app_bt_stream_volume_ptr_update(NULL)更新蓝牙音频流的音量指针,可能在音频设备或会话发生变化时调用。
22app_start_bt_module_thread()该函数创建并启动了一个用于初始化蓝牙模块的线程,并设置应用线程的优先级为高于正常优先级。
23btdrv_start_bt()启动蓝牙设备的函数,用于初始化和启动蓝牙协议栈。

1.1 app_os_init()

  接下来对 app_init 函数中个别函数进行讲解,app_os_init() 是一个应用程序操作系统初始化函数的实现

  • 代码
/**
 * 初始化操作系统环境
 * 
 * 该函数负责初始化应用程序的操作系统环境它首先尝试初始化邮箱,然后创建一个应用线程
 * 这是应用程序启动的入口点,确保操作系统环境正确初始化,以便应用程序能够正常运行
 * 
 * @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;
}
  • 参数/函数讲解
序号函数说明
1app_mailbox_init()初始化应用程序的邮箱,邮箱通常用于线程间的通信和消息传递。如果初始化失败,函数会返回非零值。
2osThreadCreate()创建了一个名为 app_thread 的线程,并将其标识符保存在 app_thread_tid 变量中。osThreadCreate 是操作系统提供的函数,用于创建一个新的线程。osThread 宏用于指定要创建的线程的名称。

  总的来说,这个函数的作用是初始化应用程序的操作系统环境,包括初始化邮箱和创建一个新的线程用于应用程序的执行。

1.2 app_battery_open()

  在应用初始化中,电池模块肯定必不可少的,接下来让我们来看看充电检测执行流程如下步骤所示:

  Step 1、充电检测(电池状态,充电状态或是充电使用状态) ;
  Step 2、定时检测电量 —> 可以通过中断方式检测当前电压值 ;
  Step 3、将检测到的电压通过邮箱发送,并进行相应处理 ;

  • 代码
/*
 * 函数功能:打开电池管理模块的初始化函数
 * 
 * 描述:该函数负责初始化电池管理模块,包括创建定时器,设置电池测量参数,
 *       配置外部充电器检测器和使能引脚,以及根据充电状态设置模块状态。
 *       
 * 参数:无
 *       
 * 返回值:电池模块打开模式,包括无效模式、正常模式、充电模式、上电充电模式
 */
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;
}

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

  • 参数/函数讲解
序号函数说明
1osTimerCreate(osTimerPeriodic)创建电池电量检测定时器
2osTimerCreate(osTimerOnce)创建出入盒定时器,这个定时器一般用于处理电池插拔事件的去抖动,以防止误触发。
3app_set_threadhandle()设置电池模块的线程处理函数。这个函数在电池状态发生变化时被调用,用于处理相关的逻辑。
4hal_iomux_init()初始化GPIO引脚
5hal_gpio_pin_set_dir()设置对应的引脚,以及输出电平

1.3 app_audio_open()

  这个函数的作用是初始化音频管理模块,并执行一些初始化操作,如铃声合并的初始化、设置线程处理函数、蓝牙音频流的初始化,并将初始化标志位置为 true。

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

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

  • 参数/函数讲解
序号函数说明
1osMutexCreate()创建一个互斥锁,用于保护音频队列的访问。
2osPoolCreate()创建一个内存池,用于存储音频状态。
3app_ring_merge_init()初始化混合提示音功能。铃声合并通常用于在设备同时需要播放多个声音时,将它们合并成一个声音输出,以防止声音混叠或干扰。
4app_set_threadhandle()设置音频模块的线程处理函数。这个函数可能会在音频状态发生变化时被调用,用于处理相关的逻辑。
5app_bt_stream_init()这个函数调用可能是用于初始化蓝牙音频流功能。在蓝牙设备中,这个函数可能会设置蓝牙音频相关的参数和配置。

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

请添加图片描述


总结

  感谢观看,这里就是 应用初始化 – app_init() 的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹

在这里插入图片描述

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

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

更多专栏订阅:



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

评论 124
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是夜阑的狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值