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

ESP-ADF esp_dispatcher组件之audio_service子模块资源管理函数详解

目录

  • ESP-ADF esp_dispatcher组件之audio_service子模块资源管理函数详解
    • 内部数据结构
      • 结构体关系图
    • 资源管理函数分析
      • audio_service_create
      • audio_service_destroy

ESP-ADF esp_dispatcher组件之audio_service子模块资源管理函数详解

版本信息: v2.7-65-gcf908721

本章节分析的源码位于 /components/esp_dispatcher/audio_service.c 文件

内部数据结构

audio_service子模块内部定义了关键的结构体,用于实现音频服务管理:

/*** @brief 音频服务实现结构体*/
typedef struct audio_service_impl {service_ctrl                service_start;         // 服务启动函数service_ctrl                service_stop;          // 服务停止函数service_ctrl                service_connect;       // 服务连接函数service_ctrl                service_disconnect;    // 服务断开连接函数service_ctrl                service_destroy;       // 服务销毁函数service_callback            callback_func;         // 回调函数void                        *user_cb_ctx;          // 用户回调上下文char                        *service_name;         // 服务名称TaskHandle_t                task_handle;           // 任务句柄void                        *user_data;            // 用户数据
} audio_service_impl_t;

与此相关的公开结构体和类型定义包括:

// 音频服务状态
typedef enum {SERVICE_STATE_UNKNOWN,       // 未知状态SERVICE_STATE_IDLE,          // 空闲状态SERVICE_STATE_CONNECTING,    // 连接中状态SERVICE_STATE_CONNECTED,     // 已连接状态SERVICE_STATE_RUNNING,       // 运行状态SERVICE_STATE_STOPPED,       // 停止状态
} service_state_t;// 音频服务事件信息
typedef struct {int         type;       // 事件类型void       *source;     // 事件源void       *data;       // 事件数据int         len;        // 数据长度
} service_event_t;// 服务控制函数类型
typedef esp_err_t (*service_ctrl)(audio_service_handle_t handle);// 服务回调函数类型
typedef esp_err_t (*service_callback)(audio_service_handle_t handle, service_event_t *evt, void *ctx);// 音频服务配置
typedef struct {int                 task_stack;             // >0 服务任务栈大小; =0 不创建任务int                 task_prio;              // 服务任务优先级(基于FreeRTOS优先级)int                 task_core;              // 服务任务运行的核心(0或1)TaskFunction_t      task_func;              // 服务任务函数service_ctrl        service_start;          // 启动函数service_ctrl        service_stop;           // 停止函数service_ctrl        service_connect;        // 连接函数service_ctrl        service_disconnect;     // 断开连接函数service_ctrl        service_destroy;        // 销毁函数const char          *service_name;          // 音频服务名称void                *user_data;             // 用户数据
} audio_service_config_t;

结构体关系图

下面的图表展示了这些结构体之间的关系:

配置创建
使用(状态管理)
处理(事件通知)
audio_service_impl_t
+service_ctrl service_start
+service_ctrl service_stop
+service_ctrl service_connect
+service_ctrl service_disconnect
+service_ctrl service_destroy
+service_callback callback_func
+void* user_cb_ctx
+char* service_name
+TaskHandle_t task_handle
+void* user_data
audio_service_config_t
+int task_stack
+int task_prio
+int task_core
+TaskFunction_t task_func
+service_ctrl service_start
+service_ctrl service_stop
+service_ctrl service_connect
+service_ctrl service_disconnect
+service_ctrl service_destroy
+const char* service_name
+void* user_data
«enumeration»
service_state_t
UNKNOWN
IDLE
CONNECTING
CONNECTED
RUNNING
STOPPED
service_event_t
+int type
+void* source
+void* data
+int len

这个图表展示了音频服务的核心数据结构及其关系:

  1. audio_service_config_t 是创建音频服务时的配置结构体,包含任务参数和各种回调函数
  2. audio_service_impl_t 是音频服务的内部实现结构体,由配置创建而来
  3. 音频服务通过状态(service_state_t)和事件(service_event_t)管理其生命周期和通知机制
  4. 各种回调函数类型(service_ctrl, service_callback)定义了服务与应用程序的交互接口

资源管理函数分析

audio_service_create

audio_service_create函数用于创建音频服务实例,分配必要的资源。下面是其源码实现:

/*** @brief 创建音频服务实例* * 该函数完成以下主要操作:* 1. 分配音频服务实例内存* 2. 初始化服务结构体,复制配置参数* 3. 复制服务名称(如果提供)* 4. 创建服务任务(如果配置了任务栈)* * 资源创建失败时会进行适当的清理,避免资源泄漏* * @param config 配置参数,包含回调函数、任务参数等信息* @return audio_service_handle_t 成功返回服务实例句柄,失败返回NULL*/
audio_service_handle_t audio_service_create(audio_service_config_t *config)
{// 检查配置参数是否为NULLAUDIO_NULL_CHECK(TAG, config, return NULL);// 分配服务实例内存audio_service_handle_t impl = audio_calloc(1, sizeof(audio_service_impl_t));AUDIO_MEM_CHECK(TAG, impl, return NULL);// 初始化服务结构体impl->service_start         = config->service_start;impl->service_stop          = config->service_stop;impl->service_connect       = config->service_connect;impl->service_disconnect    = config->service_disconnect;impl->service_destroy       = config->service_destroy;impl->user_data             = config->user_data;// 复制服务名称(如果提供)if (config->service_name) {impl->service_name = audio_strdup(config->service_name);AUDIO_MEM_CHECK(TAG, impl, goto serv_failed);}// 创建服务任务(如果配置了任务栈)if (config->task_stack > 0) {if (pdPASS != xTaskCreatePinnedToCore(config->task_func,config->service_name,config->task_stack,impl,config->task_prio,&impl->task_handle,config->task_core)) {ESP_LOGE(TAG, "Create task failed on %s", __func__);goto serv_failed;}}return impl;// 失败处理部分
serv_failed:// 释放已创建的资源audio_free(impl->service_name);impl->service_name = NULL;audio_free(impl);impl = NULL;return impl;
}

下面的时序图展示了 audio_service_create 函数的执行流程:

应用程序 audio_service_create 内存管理 FreeRTOS任务系统 调用(config) 参数检查 audio_calloc(分配服务实例) 返回impl 初始化服务结构体 audio_strdup(复制服务名称) 返回service_name alt [有服务名称] xTaskCreatePinnedToCore(创建服务任务) 返回创建状态 alt [需要创建任务(task_stack > 0)] 返回impl 释放service_name 释放impl 返回NULL alt [创建成功] [创建失败] 应用程序 audio_service_create 内存管理 FreeRTOS任务系统

这个时序图清晰地展示了 audio_service_create 函数的执行流程,包括资源分配、结构体初始化、任务创建以及错误处理的过程。通过这个图可以直观地理解函数内部的调用关系和数据流向。

audio_service_destroy

audio_service_destroy函数用于销毁音频服务实例,释放所有资源。下面是其源码实现:

/*** @brief 销毁音频服务实例并释放所有资源* * 该函数完成以下主要操作:* 1. 调用服务的销毁函数(如果提供)* 2. 释放服务名称内存* 3. 清除任务句柄* 4. 释放服务实例内存* * 函数确保所有在audio_service_create中分配的资源都被正确释放* * @param handle 服务实例句柄* @return esp_err_t 成功返回ESP_OK,失败返回错误码*/
esp_err_t audio_service_destroy(audio_service_handle_t handle)
{// 检查句柄是否有效AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG);// 获取服务实例audio_service_impl_t *impl = (audio_service_impl_t *) handle;// 调用服务的销毁函数(如果提供)if (impl->service_destroy) {impl->service_destroy(handle);}// 释放服务名称内存audio_free(impl->service_name);impl->service_name = NULL;// 清除任务句柄impl->task_handle = NULL;// 释放服务实例内存audio_free(impl);impl = NULL;return ESP_OK;
}

下面的时序图展示了 audio_service_destroy 函数的执行流程:

应用程序 audio_service_destroy 服务销毁函数 内存管理 调用(handle) 参数检查 获取服务实例(impl) 调用服务销毁函数 返回结果 alt [有服务销毁函数] 释放service_name 清除task_handle 释放服务实例 返回ESP_OK 应用程序 audio_service_destroy 服务销毁函数 内存管理

这个时序图清晰地展示了 audio_service_destroy 函数的执行流程,包括调用服务销毁函数和释放资源的过程。通过这个图可以直观地理解函数内部的调用关系和资源释放顺序。

http://www.xdnf.cn/news/247393.html

相关文章:

  • RAGFlow上传3M是excel表格到知识库,提示上传的文件总大小过大
  • 基于Redis实现-附近商铺查询
  • UE实用地编插件Physical Layout Tool
  • MySQL | DQL语句-连接查询
  • linux 使用nginx部署next.js项目,并使用pm2守护进程
  • 加载ko驱动模块:显示Arm版本问题解决!
  • 小白如何入门Python爬虫
  • 【playwright】内网离线部署playwright
  • PMP-第九章 项目资源管理(一)
  • 机器学习实操 第一部分 机器学习基础 第8章 降维技术
  • 深度学习中卷积的计算复杂度与内存访问复杂度
  • 数字基带信号和频带信号的区别解析
  • ES6异步编程中Promise与Proxy对象
  • 小牛电动:荣登央视舞台,引领智能出行新潮流
  • c++26新功能——std::execution
  • 加密算法(一)-对称加密(DES、AES、3DES、Blowfish、Twofish)一篇了解所有主流对称加密,轻松上手使用。
  • mysql-窗口函数一
  • 链表系列一>合并 k 个升序链表
  • 【CV数据集】DIOR遥感目标检测数据集(含处理好的YOLO、COCO、VOC格式和相关配置文件下载链接)
  • 响应式布局,在飞帆平台中如此简单
  • 文件包含漏洞学习
  • PostgreSQL:pgAdmin 4 使用教程
  • 手撕哈希表
  • Android 移动开发:ProgressBar (水平进度条)
  • 【LeetCode Hot100】回溯篇
  • cua: 为 AI 智能体提供高性能虚拟环境
  • GTA5(传承/增强) 13980+真车 超跑 大型载具MOD整合包+最新GTA6大型地图MOD 5月最新更新
  • PyTorch 2.0编译器技术深度解析:如何自动生成高性能CUDA代码
  • 【Bootstrap V4系列】学习入门教程之 页面内容排版
  • 图像加密算法概述