1. ADSP21593双核FIRA加速器入门指南
第一次接触ADSP21593的双核FIRA加速器时,我被它的硬件架构深深吸引。这款芯片属于SC594家族,搭载了两个SHARC+核心和两组独立的FIRA硬件加速器。与单核的ADSP21569相比,21593的算力理论上翻倍,但外设资源是共享的,这就带来了独特的开发挑战。
FIRA(FIR Accelerator)是ADI专门为音频处理设计的硬件加速模块,它能够高效完成FIR滤波运算。在开发文档的第2842页详细描述了它的工作原理,简单来说分为三个关键步骤:首先通过FIR_CTL1寄存器配置通道数,然后在内存中设置TCB(传输控制块),最后通过FIR_CHNPTR寄存器启动加速器。
TCB本质上是一个结构体数组,包含了DMA传输所需的所有参数。这里有个容易混淆的概念:文档中提到的"通道数"实际上指的是需要连续执行的FIR运算次数。比如配置两个通道,就相当于让加速器连续处理两组数据。
2. 两种驱动方式深度对比
2.1 官方驱动库API方案
ADI提供的驱动库封装了底层操作,使用起来相对简单。从示例代码可以看到,主要流程是:
- 定义ADI_FIR_CHANNEL_INFO结构体数组
- 通过adi_fir_Open初始化设备
- 用adi_fir_CreateTask创建任务
- 调用adi_fir_QueueTask将任务加入队列
这种方式的优点是接口规范,内置了完善的错误检查机制。但实测发现性能开销较大,200阶FIR滤波需要约2200个时钟周期。分析源码发现,驱动库在每次操作前都会进行参数校验,并且地址转换需要多层函数调用。
2.2 寄存器直写方案
直接操作寄存器可以获得最佳性能。核心代码非常简洁:
*pREG_FIR0_CHNPTR = (uint32_t)uiFIR_CHNPTR; *pREG_FIR0_CTL1 = uiFIR_GCTL;同样的200阶滤波仅需130个时钟周期,性能提升近17倍!但这种方式需要开发者手动配置所有TCB字段:
- FIR_COEFCNT:滤波器系数个数
- FIR_INBASE:输入数据首地址
- FIR_OUTBASE:输出缓冲区地址
- FIR_CTL2:控制参数组合值
特别要注意地址转换问题。在21593架构中,需要将地址右移2位并加上0xA000000偏移量。这是因为SHARC+核心使用字节寻址,而FIRA硬件设计沿用了旧架构的4字节寻址方式。
3. 双核协同开发实战技巧
3.1 核间资源分配策略
21593的两个SHARC+核心分别对应FIRA0和FIRA1。在adi_fir_config_SC59x.h头文件中,需要明确配置:
#define ADI_FIR_PROCESSING_CORE_SELECT_BOTH_SHARCS核心1应使用FIRA0(设备号0),核心2使用FIRA1(设备号1)。如果配置错误,驱动库会通过断言检查报错。
3.2 内存地址映射难题
双核开发最棘手的问题是内存地址映射。每个核心的L1内存有独立的系统地址:
- 核心1:0x28240000-0x28400000
- 核心2:0x28A40000-0x28BA0000
在直接操作寄存器时,必须进行地址转换。我最终采用的方案是:
#define CORE2_ADDR_OFFSET 0x28A40000 #define TO_SYSTEM_ADDR(addr) ((((uint32_t)(addr))>>2)|CORE2_ADDR_OFFSET)3.3 性能优化关键点
通过实测对比发现:
- 避免频繁任务创建:尽量复用已配置的TCB
- 使用BURST传输模式:设置BITM_FIR_CTL1_BURSTEN
- 预取使能:配置BITM_FIR_CTL1_PFB_EN
- 编译优化:Release模式比Debug模式快2-3倍
4. 调试经验与常见陷阱
在开发过程中踩过几个典型的坑:
- DMA传输完成检测:必须检查FIR_DMASTAT寄存器的ACDONE位
- 浮点精度问题:硬件加速结果与软件计算可能存在1e-7量级差异
- 核间同步:当双核共享输入/输出缓冲区时需要额外同步机制
- 中断冲突:FIRA运算期间应禁用相关中断
一个特别隐蔽的问题是TCB对齐要求。经过反复测试发现,TCB结构体必须32字节对齐,否则会导致不可预知的运算错误。解决方法是在定义时添加对齐属性:
__attribute__((aligned(32))) uint32_t FIRA_TCB[12];对于实时性要求高的应用,建议采用寄存器直写+地址优化方案。在我的音频处理项目中,优化后的版本能够同时处理8路192kHz/24bit音频流,CPU负载仍低于30%。