Audio DSP boot 过程
笔记哥 /
04-08 /
12点赞 /
0评论 /
488阅读
在智能手机或智能手表等SoC上通常有一块专门的audio DSP(简称ADSP)来做音频处理。要做音频处理,ADSP首先要被boot起来。本文以CEVA BX2为例来讲讲ADSP的boot过程。
在上篇文章([Audio DSP 链接脚本文件解析](https://www.cnblogs.com/talkaudiodev/p/18788383 "发布于 2025-03-26 07:48"))里讲过链接脚本里用关键字ENTRY来设定程序的入口,且这个入口在crt0.c里会用到。ADSP boot过程在crt0.c里也有涉及。先看看crt0.c里有什么,然后再讲ADSP的boot。图1给出了crt0.c开始的几行示例代码。

图 1
上图中crt0.c是用简单汇编写的。最上面是在链接脚本里用关键字ENTRY来设定的程序入口,即 \_\_cxd\_inttbl\_start。下面是几种场景下的入口地址,主要包括boot时的入口地址(图中定义为0x10,即boot时ADSP从地址0x10处开始运行,然后调函数\_boot)、发生中断时的入口地址(图中定义为0x60,即发生中断时ADSP从地址0x60处开始运行,然后调函数\_critical\_handler)、产生异常(exception)时的入口地址(图中定义为0x70,即产生异常时ADSP从地址0x70处开始运行,然后调函数\_common\_handler)。
回到boot过程。整个SoC中AP最先起来,ADSP是被AP boot起来的。AP boot ADSP前要做一些准备工作,比如把ITCM的内容拷进ITCM里(ASIC设计时AP可以读写ADSP的ITCM,从ADSP看ITCM的起始地址是0x0,从AP看ADSP的ITCM起始地址被映射成另外一个值)。AP做完准备工作后,写寄存器,让ADSP从boot的起始地址0x10处运行,这样ADSP就从0x10处运行,开始boot过程了。前文写的,从0x10处运行时开始调\_boot函数。\_boot函数里首先把DTCM的内容拷进DTCM里等,最后调用大家熟悉的main()函数。Main函数里有一系列操作,包括cache相关的、中断控制单元(interrupt control unit, ICU)的相关的、IPC相关的、RTOS相关的等。可以用图2的流程图表示,需要说明的是cache、ICU和IPC没有先后顺序的,谁先谁后都可以,RTOS是一定要放在最后的。下面一一来介绍。

图 2
首先看cache。Cache就是内存缓冲区,速度快于外部memory,接近处理器。用cache来拉近外部memory和处理器之间的性能差异,提高整个系统的性能。Cache分为icache和dcache,icache用于code,dcache用于data。ADSP内部的ITCM和DTCM都很小,audio软件开发需要用到外部的memory(如DDR)来放一些非典型场景下的code和data,如果典型场景下的code和data ADSP内部memory放不下也要放外部memory上,因此ADSP需要cache来提高audio子系统的性能。Boot时需要对外部用到的memory配置一下cache属性。放code的memory配置一下icache属性,一般配成cacheable。放data的memory配置一下dcache属性。如果放的是常量等不需要核间交互的数据就需要配成cacheable,如果放的是需要核间交互的数据就需要配成uncachable。举例来说,某一块外部memory用于放AP发给ADSP的音频数据(AP先把音频数据放到指定的memory上,然后发IPC告诉ADSP起始地址和大小,ADSP收到IPC后就从指定地址上取音频数据),这块memory就要配成uncacheable。如果配成cacheable,当ADSP去取音频数据时,数据有可能还在cache里而不是在这块memory上,造成取到的数据是错误的。
中断相关的配置在ICU(interrupt control unit,中断控制单元)里。中断包括内部中断和外部中断。CEVA BX2内部中断共有9个(中断号是从0到8),比如定时器中断中断号为6,软中断中断号为8。外部中断支持分成几组,每组32个。通常外部中断不会超过32个,用一组就够了。外部中断号从9开始往上加。常见的外部中断包括IPC中断等。中断有中断向量表,表里放的是每个中断的中断服务程序(ISR)。中断服务程序通常很简洁,只有几行语句,包括清中断以及后续处理等。对于每个中断来说,会有些硬件配置,包括中断是电平触发还是沿触发。沿触发也包括是上升沿触发还是下降沿触发。在boot阶段要disable所有的中断,等boot完成再把需要使能的中断放开。前文crt0.c里讲到有几个不同场景下的入口地址,来中断就是其中之一。当有中断时,会从0x70处开始运行,调用\_common\_handler函数,在函数里会执行注册的中断服务程序。中断服务程序运行完后去做任务调度,执行优先级最高的那个任务。
IPC用于各个core之间的通信。IPC的本质是中断加ring buffer。一个core在跟另一个core通信前,先把要通信的数据以规定好的格式写进指定的ring buffer里,然后给对方发IPC中断。对方收到IPC中断后,从ring buffer里取出数据按照规定的格式做解析,完成一次完整的通信。对于IPC来说,boot时将各个IPC的中断服务程序注册到相应的中断向量表里,并enable这些中断。需要注意的是这些IPC中断在系统运行过程中是不能disable的。
最后看RTOS相关的。先是做RTOS的初始化,然后创建各种需要的task,如IPC task、idle task等。创建完各种task后,系统处于等待WFI(wait for interrupt)的idle task。
经过以上几步后ADSP 就算boot起来了。
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/2087
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利
- 相关联分享
- Audio DSP boot 过程