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

news2024/11/24 17:06:20

请添加图片描述

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

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

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

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

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

请添加图片描述

文章目录

  • 前言
  • 1 应用初始化 app_init()
      • 1.1 app_os_init()
      • 1.2 app_battery_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 函数代码过多,这里不就放出来了,只讲解一下其中的各个函数作用。

/*
 * 函数名: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() 的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹

在这里插入图片描述

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

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

更多专栏订阅:

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

  • 🥇 【恒玄BES】

  • 🌼 【鸿蒙系统】

  • 💎 【蓝牙协议栈】

  • 🎃 【死机分析】

  • 👑 【Python脚本笔记】

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

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

  • 【JavaScript随手笔记】

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

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

  • 🔐 【Git 学习笔记】

  • 🚀 【软件安装教程】



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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033429.html

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

相关文章

Linux:多线程(三.POSIX信号量、生产消费模型、线程池、其他常见的锁)

上次讲解了&#xff1a;Linux&#xff1a;多线程&#xff08;二.理解pthread_t、线程互斥与同步、基于阻塞队列的生产消费模型&#xff09; 文章目录 1.POSIX信号量1.1引入1.2回顾加深理解信号量1.3信号量的操作接口 2.基于循环队列的生产消费模型2.1循环队列2.2整个项目 3.线程…

fastadmin自定义弹框,以及回调函数等问题,

效果图 1&#xff0c; 代码 弹框中使用弹框 弹框1代码主要代码 <div class"form-group ccol-xs-12 col-sm-2" style"text-align: right"><a href"#" data-url"{:url(user/add)}" class"btn btn-info" id"a…

Android逆向题解-boomshakalaka-3-难度5

这个app 是一个cocos游戏&#xff0c;没有用脚本实现&#xff0c;纯c实现。 题目描述:play the game, get the highest score 题目要求是玩游戏得到最高分就可以得到flag&#xff0c;是写到配置文件的&#xff0c;初始flag值看着是base编码的。 核心代码在so里面的ControlLay…

GPT-4o:开启多模态AI识别新纪元

GPT-4o功能简介 在人工智能的演变历程中&#xff0c;图像识别技术始终占据着核心地位。技术的发展日新月异&#xff0c;使得AI不仅能够识别图像内容&#xff0c;还能将其转化为文字描述。特别值得一提的是&#xff0c;OpenAI在春季发布的GPT-4o模型&#xff0c;将图像识别技术…

Spring项目:文字花园(一)

前言 实现登录注册功能。 ⽤⼾登录成功后, 可以查看所有⼈的博客. 点击 <<查看全⽂>> 可以查看该博客的正⽂内容. 如果该博客 作者为当前登录⽤⼾, 可以完成博客的修改和删除操作, 以及发表新博客 一.准备工作 1.1注入sql &#xff08;数据准备&#xff09; -- 建…

解决No module named ‘tensorflow‘

import tensorflow as tf ModuleNotFoundError: No module named tensorflow 安装合适的tensorflow版本 先查看自己的python版本 或者输入指令&#xff1b;python --version 安装兼容的tensorflow版本&#xff0c;安装指定版本的tensorflow pip install tensorflow-gpu2.3.0…

MVDream 论文学习

论文链接&#xff1a;https://arxiv.org/abs/2308.16512 代码链接&#xff1a;https://github.com/bytedance/MVDream 解决了什么问题&#xff1f; 3D 内容生成是现代游戏和媒体产业中的关键环节&#xff0c;然而这是一个劳动密集型的任务&#xff0c;创建一个 3D 资产就需要…

后端Web之HTTP协议基础介绍

目录 1.HTTP概念 2.HTTP请求协议 3.HTTP响应协议 4.HTTP协议解析 1.HTTP概念 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一种用于分布式、协作式和超媒体信息系统的应用层协议。它是万维网数据通信的基础&#xff0c;允许将超…

JVM由那些部分组成,运行流程是什么?

Java 虚拟机 (JVM) 是 Java 运行环境的核心部分&#xff0c;它负责执行 Java 字节码。JVM 由多个不同的组件组成&#xff0c;每个组件都负责不同的任务。下面我将详细介绍 JVM 的主要组成部分及其运行流程。 JVM 的组成部分 类加载器 (Class Loader)&#xff1a; 类加载器负责读…

数据结构 位运算

基础位运算 按位与&#xff08;AND&#xff09; 操作符&#xff1a;&两个位同时位1时&#xff0c;结果位1&#xff0c;否则为0 按位或&#xff08;OR&#xff09; 操作符&#xff1a;|主要有一位是1&#xff0c;那么结果就是1&#xff0c;只有两位都是0的时候&#xff0c;结…

C++ 115类和对象_this指针的用途

学习内容 类和对象_this指针的用途 1.解决名称冲突 2.返回对象本身用 *this 运行结果 代码 #include<iostream> using namespace std;//cout 在这里&#xff0c;没有它会报错//1.解决名称冲突//2.返回对象本身用 *thisclass Person { public:Person(int age){//形参名称…

【深度学习实践】基于深度学习的图像去雾算法-ChaIR-实践

本文介绍一个去雾算法ChaIR的使用方法&#xff0c;可以完成图像去雾&#xff0c;也可以用于图像去雨、去噪音等任务。本文不涉及论文原理&#xff0c;只包含源代码的跑通和使用。 先展示一下效果&#xff1a; 原图去雾 论文&#xff1a;Exploring the potential of channel …

ZAN与Mysten Labs合作推进Web3基础设施开发

Mysten Labs是一家Web3基础设施公司&#xff0c;也是Sui区块链的开发公司&#xff0c;今天宣布与蚂蚁数字科技的技术品牌ZAN建立合作伙伴关系。 通过整合Sui&#xff0c;ZAN旨在加速其Web3应用程序的开发和采用。该合作将专注于为Mysten Labs在两个关键领域提供技术支持&#…

Redis 缓存预热、雪崩、穿透、击穿

缓存预热 缓存预热是什么 缓存预热就是系统上线后&#xff0c;提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候&#xff0c;先查询数据库&#xff0c;然后再将数据缓存的问题&#xff01;用户直接查询事先被预热的缓存数据&#xff01;解决方案 使用 PostConstr…

day2-网络连接网卡配置原理

1.window网卡 理解&#xff1a; window 有 2 块网卡 本地网卡 192.168.13.253 用于连接外网 vmnet8 10.0.0.1(装虚拟机自动生成的 如果没有自动生成…) 虚拟机添加 2 块网卡&#xff1a; 第一块网卡 NAT 模式 添加网卡的时候设置 NAT 模式 2 个作用&#xff0c;用于连接 wi…

Linux服务管理-Nginx进阶

通常会通过rewrite将用户的80请求转化为443请求&#xff0c;也就意味着Nginx需要去做虚拟主机&#xff0c;一个80端口的虚拟主机和一个443端口的虚拟主机&#xff0c;当访问80端口的虚拟主机时返回一个信息让用户去访问443端口的虚拟主机。

技术证书认证-附考试答案-AIGC与大模型通识-英特尔大湾区科技创新中心证书认证

目录 课程简介 面向人群 考核步骤 试题答案 知孤云出岫主页 课程以及考试链接&#xff1a;AIGC与大模型通识 - 英特尔大湾区科技创新中心 【英特尔大湾区科技创新中心】公益新课《AIGC与大模型通识》上线官网&#xff01;首期结业认证进行中&#xff0c;提升AI应用技能&…

解决Element-ui el-tree数据与显示不对应的问题

如图&#xff1a; 后端返回的权限列表&#xff0c;并没有列表这一项&#xff0c;但是由于父节点 版本打包 为选中状态&#xff0c;导致所有子节点都为选中状态。 实现代码如下&#xff1a; <el-treeref"tree":data"records"show-checkboxnode-key&quo…

RuoYi-Vue新建模块

一、环境准备 附:RuoYi-Vue下载与运行 二、新建模块 在RuoYi-Vue下新建模块ruoyi-test。 三、父pom文件添加子模块 在RuoYi-Vue的pom.xml中,引入子模块。 <dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-test</artifactId>&…

【AI人工智能】文心智能体 - 你的专属车牌设计师

引言 自AI盛行以来&#xff0c;不断有各种各样的人工智能产品崭露头角。我们逐步跟着不断产生的人工智能来使自己的工作和生活变得更加智能化&#xff01;那么我们是否能够创造一款专属于自己的人工智能产品呢&#xff1f; 文心智能体平台就给我们提供了这样的机会&#xff0c…