1. 项目概述:为什么需要深入理解SBL寄存器?
在嵌入式视觉系统开发中,图像信号处理器(ISP)扮演着将原始传感器数据“翻译”成高质量图像的关键角色。这个过程就像一条复杂的流水线,数据从传感器进来,经过CCDC(电荷耦合器件控制器)进行初步处理,然后可能进入预览引擎(PREVIEW)进行实时显示,或者进入缩放器(RESIZER)进行尺寸调整,同时还有H3A模块负责自动对焦(AF)、自动曝光(AE)和自动白平衡(AWB)的统计信息收集。这么多模块要协同工作,数据从哪里来、到哪里去、谁先谁后、会不会堵车,就成了一个必须解决的系统级问题。
TI的Camera ISP解决方案里,共享缓冲区逻辑(Shared Buffer Logic, SBL)就是这个解决交通拥堵的“智能交通指挥中心”。它不是一个处理图像数据的模块,而是一个数据流控制器和仲裁器。SBL通过一系列精心设计的寄存器,管理着ISP内部所有模块对系统内存(SDRAM)的读写请求。如果你只关注图像处理算法而忽略了SBL,很可能会遇到一些令人头疼的“玄学”问题:比如图像偶尔丢帧、预览画面卡顿、或者自动对焦突然失灵。这些问题往往不是算法本身有bug,而是数据流在SBL这里出现了瓶颈或冲突。
因此,掌握SBL寄存器,意味着你掌握了ISP数据流的“开关”和“监控面板”。你不仅能配置数据路径,还能实时观察各个模块的请求状态、发现缓冲区溢出(Overflow)等潜在故障。这对于调试复杂的图像处理流水线、优化系统性能、确保实时性至关重要。无论是驱动工程师、系统架构师,还是负责图像质量调优的算法工程师,深入理解SBL都是不可或缺的一课。
2. SBL架构与核心设计思路解析
要理解SBL寄存器,首先要明白它要解决什么问题。在一个典型的ISP流水线中,多个模块可能同时需要读写内存。例如,CCDC模块正在将一帧原始数据写入内存,而同时,预览引擎和缩放器可能需要从内存中读取上一帧的数据进行处理。如果没有一个中央协调机制,这些并发的内存访问请求就会产生冲突,导致数据损坏或系统死锁。
SBL的设计核心是一个基于请求(Request)的仲裁机制。它将ISP内部各个功能模块(CCDC、PREVIEW、RSZ等)抽象为“请求者”(Requestor)。每个请求者可以发起读请求(从内存读数据到模块)或写请求(将模块处理后的数据写入内存)。SBL内部为每个请求者都维护了独立的请求队列和状态寄存器。
2.1 SBL的模块化视图与数据流
从提供的寄存器列表可以看出,SBL管理的模块非常清晰:
数据源模块(生产者):负责产生数据并写入内存。
CCDC_WR_x: CCDC模块的写请求(输出处理后的原始数据)。PRV_WR_x: 预览引擎的写请求(输出预览图像)。RSZx_WR_x: 四个缩放器输出通道的写请求。H3A_AF_WR_x/H3A_AEAWB_WR_x: H3A统计模块的写请求。CSIA_WR_x/CSIB_WR_x: CSI接收器的写请求。
数据消费模块(消费者):需要从内存读取数据进行处理。
CCDC_FP_RD_x: CCDC坏点校正的读请求(读取校正表)。PRV_RD_x: 预览引擎的读请求(读取待处理的原始数据)。PRV_DK_RD_x: 预览引擎暗帧减除的读请求(读取暗帧数据)。RSZ_RD_x: 缩放器的读请求(读取待缩放的图像)。HIST_RD_x: 直方图模块的读请求。
全局状态与仲裁寄存器:
SBL_GLB_REG_0到SBL_GLB_REG_7: 这8个寄存器实时反映了SBL仲裁器当前正在处理或最近处理完的请求信息。它们是只读的,用于调试和监控数据流状态。SBL_PCR(Peripheral Control Register): 这是SBL中少数几个可读写的关键寄存器之一,包含了所有模块的缓冲区溢出状态标志。这是诊断数据流问题的第一现场。
2.2 地址与数据管理机制
细看每个读写请求寄存器(如SBL_CCDC_WR_0),你会发现它们都包含几个关键字段:
- ADDR (19:0): 这是写地址的高20位。为什么是高20位?这通常意味着地址是字节对齐的,低12位(4KB页面内偏移)由硬件自动管理,或者该地址指向的是一个更大的、对齐的内存块起始地址。在配置DMA或设置内存缓冲区时,必须确保地址符合SBL的对齐要求。
- BYTE_CNT (29:22):当前字节计数。这个字段在请求进行过程中动态变化,指示了当前传输已经完成了多少字节。监控这个字段可以判断一个传输请求是否卡住或进展缓慢。
- DATA_READY和DATA_SENT(对于写请求): 这是一对状态机标志。
DATA_READY=1: 模块内部数据已准备好,可以发起写请求。DATA_SENT=1: 数据已发送给SBL,正在等待写入内存完成。
- VALID,DATA_WAIT,DATA_AVL(对于读请求): 这是另一组状态标志。
VALID=1: 该读请求条目有效。DATA_WAIT=1: 模块正在等待数据。DATA_AVL=1: 数据已从内存到达SBL缓冲区,模块可以读取。
关键理解:SBL在这里充当了代理的角色。模块不直接与内存控制器对话,而是向SBL提交请求。SBL汇总所有请求,按照优先级(通常是固定的,如CCDC实时性最高)进行仲裁,然后代表模块与系统内存交互。这种设计隔离了模块与复杂的内存系统,简化了模块设计,并集中了流控逻辑。
3. 关键寄存器深度解析与实战配置
手册里列出了几十个SBL寄存器,但根据我的调试经验,真正需要频繁打交道、且最容易出问题的,主要集中在几个核心寄存器上。我们挑出最有代表性的几个,掰开揉碎了讲。
3.1 SBL_PCR:系统健康的“仪表盘”
SBL_PCR(外设控制寄存器) 是SBL模块中唯一一个用于清除错误状态的读写寄存器。它的每一位都对应一个模块的写缓冲区溢出标志。溢出是SBL相关调试中最常见的问题。
寄存器位域详解:
| 位域 | 名称 | 描述 | 调试意义 |
|---|---|---|---|
| 26 | CSIB_WBL_OVF | CSI-B 写缓冲区溢出 | 检查CSI-B输入数据率是否超过ISP处理能力或内存带宽。 |
| 25 | CSIA_WBL_OVF | CSI-A 写缓冲区溢出 | 同上,针对CSI-A端口。 |
| 24 | CCDCPRV_2_RSZ_OVF | CCDC/PRV 到 RSZ 输入溢出 | 重点!当缩放器输入源设为CCDC或预览引擎,且活动数据已出现在缩放器接口时,如果此时切换输入源,此位会置1。常见于需要多级缩放的场景(如先缩放到中间尺寸,再从内存读回进行二次缩放),如果时序没安排好,就会触发。 |
| 23 | CCDC_WBL_OVF | CCDC 写缓冲区溢出 | CCDC输出太快,下游(如内存)跟不上。检查内存带宽或DMA配置。 |
| 22 | PRV_WBL_OVF | 预览引擎写缓冲区溢出 | 预览输出数据积压。可能预览帧率设置过高,或后级处理(如显示)太慢。 |
| 21-18 | RSZx_WBL_OVF | 缩放器x写缓冲区溢出 | 某个缩放器输出通道堵塞。检查该通道输出尺寸、格式以及目标内存区域是否可正常写入。 |
| 17 | H3A_AF_WBL_OVF | H3A AF 写缓冲区溢出 | 自动对焦统计信息写入失败。可能AF算法处理太慢,未及时取走数据。 |
| 16 | H3A_AEAWB_WBL_OVF | H3A AE/AWB 写缓冲区溢出 | 自动曝光/白平衡统计信息写入失败。 |
关键操作:清除溢出标志手册明确说明:软件必须向溢出的位写1来清除它。这是一个典型的“写1清零”(W1C)操作模式。但这里有一个非常重要的细节:仅仅清除标志位并不能解决根本问题。如果导致溢出的根本原因(如带宽不足、时序错误)没有消除,该标志位很快又会被置起。
实战配置与检查代码片段(伪代码风格):
// 1. 定期检查PCR寄存器(例如在每帧中断服务程序中) uint32_t sbl_pcr_status = READ_REG(SBL_PCR_ADDR); // 2. 判断是否有溢出发生 if (sbl_pcr_status & (1 << 24)) { // CCDCPRV_2_RSZ_OVF printf(“[SBL ERROR] CCDC/PRV to Resizer input overflow detected!n”); // 这里需要检查RSZ_CNT寄存器的INPSRC配置,以及多级缩放时的帧同步逻辑 } if (sbl_pcr_status & (1 << 23)) { // CCDC_WBL_OVF printf(“[SBL ERROR] CCDC write buffer overflow! Check memory bandwidth.n”); } // 3. 清除所有溢出的标志位(写1清零) // 注意:只清除检测到的位,避免干扰其他位 WRITE_REG(SBL_PCR_ADDR, sbl_pcr_status & 0x07FF0000); // 位26-16是溢出标志位3.2 SBL_GLB_REG_x:实时数据流“监视器”
SBL_GLB_REG_0到SBL_GLB_REG_7这8个寄存器是只读的,它们像8个摄像头,实时拍摄SBL仲裁器内部8个请求通道的状态。在复杂的多模块并发场景下,这是定位数据流阻塞点的利器。
每个GLB_REG包含的核心信息:
- SRC_DST_M (6:2):源或目的模块。这个5位代码告诉你当前这个通道服务的是哪个模块。对照手册,
0x0代表CCDC输出,0x5代表缩放器输入,0x6代表缩放器1输出,以此类推。通过这个字段,你可以知道当前数据流是哪个模块在发起请求。 - DIRECTION (Bit 1):方向。
0表示这是一个读操作(模块从内存读),1表示这是一个写操作(模块向内存写)。结合SRC_DST_M,你就能完整描绘出一条数据路径,比如SRC_DST_M=0x5 (RESIZER输入)且DIRECTION=0,表示缩放器正在从内存读取图像数据进行缩放。 - SRC_DST_ID (8:7):模块内的请求者编号。像预览引擎、缩放器这些模块,内部可能有多个并行的处理流水线或缓冲区,这个ID用来区分是哪一个。例如,预览引擎有4个读请求寄存器(PRV_RD_0~3),当
SRC_DST_M=0x2且SRC_DST_ID=0x1,就对应SBL_PRV_RD_1这个寄存器的状态。 - VALID (Bit 0):有效位。这是最重要的标志。
1表示这个GLB_REG通道当前记录的信息是有效的、正在活动的请求。0则表示该通道空闲或信息无效。在调试时,你可能会发现某个模块的请求一直无法得到服务,其对应的VALID位可能永远为0,或者短暂变1后立刻变0(请求被异常终止)。
调试实战:定位一个预览图像卡顿的问题假设现象:预览画面不更新,卡住了。
- 第一步,查溢出:首先读取
SBL_PCR,检查PRV_WBL_OVF(位22)是否置位。如果置位,按上述方法清除并检查预览输出配置和内存路径。 - 第二步,查请求状态:如果PCR没有溢出,问题可能出在数据供给上。预览引擎需要先读入数据才能处理。我们读取
SBL_GLB_REG_0到7。 - 分析:假设我们在
SBL_GLB_REG_1中读到:VALID=1,DIRECTION=0(读),SRC_DST_M=0x2(PREVIEW输入),SRC_DST_ID=0x0。这说明预览引擎的请求者#0正在发起一个读请求,并且请求是有效的。 - 深入探查:接着,我们去查看对应的请求寄存器
SBL_PRV_RD_0。关注它的DATA_AVL(数据可用)和DATA_WAIT(等待数据)位。- 如果
DATA_WAIT=1且DATA_AVL=0,说明预览引擎在等数据,但数据还没从内存传到SBL。这可能意味着:- 内存访问延迟太大(系统总线繁忙)。
- 请求的地址错误,访问了无效内存区域。
- 源数据(比如CCDC)根本没有写入预期的内存地址。
- 如果
DATA_AVL=1,说明数据已经在SBL缓冲区了,但预览引擎没来取?这不太可能,通常硬件会自动处理。更可能是我们查看的时机不对。
- 如果
- 交叉验证:同时查看CCDC的写请求寄存器(如
SBL_CCDC_WR_0),确认DATA_SENT状态,确保数据生产者(CCDC)确实成功写入了预览引擎要读的地址。
通过这种PCR状态 + GLB_REG全局视图 + 具体请求寄存器状态的三层排查法,绝大多数SBL相关的数据流问题都能被定位。
3.3 SBL_SDR_REQ_EXP:非实时读请求的“节流阀”
这是一个非常实用且容易被忽略的寄存器。它专门用于管理PREVIEW、RESIZER和HISTOGRAM这三个模块的非实时读请求。
为什么需要“节流阀”?像预览、缩放、直方图计算这些操作,虽然对实时性有要求,但相比传感器数据输入(CCDC/CSI)的严格实时性,它们可以容忍一定的延迟。如果放任它们的读请求以最高速率爆发式地访问内存,可能会霸占系统总线,影响到更高优先级的实时数据写入(比如CCDC写入当前帧),从而导致整个系统的不稳定甚至溢出。
SBL_SDR_REQ_EXP寄存器通过插入延迟周期,将这些非实时请求“铺开”在时间线上,降低其瞬间带宽需求,给高优先级请求让出通路。
位域解析与配置计算:
- PRV_EXP (29:20): 预览引擎读请求扩展因子。它定义了允许两个连续读请求之间的最小功能时钟周期数。最大请求间隔 = 1 * PRV_EXP 个时钟周期。例如,设置
PRV_EXP = 100,则预览引擎最快每100个时钟周期才能发起一次256字节的读请求。 - RSZ_EXP (19:10): 缩放器读请求扩展因子。最大请求间隔 = 1024 * RSZ_EXP 个时钟周期。注意它的系数是1024,意味着对缩放器的节流可以更精细(因为缩放操作通常数据量更大,对带宽更敏感)。
- HIST_EXP (9:0): 直方图模块读请求扩展因子。最大请求间隔 = 1 * HIST_EXP 个时钟周期。
配置策略与实战建议:
- 默认值:上电后,这些字段通常为0,意味着没有额外限制,模块会以最大能力请求数据。在简单系统或带宽充裕时,这可能没问题。
- 何时需要调整:
- 系统同时运行多个高带宽外设(如视频编解码器、GPU)。
- 在调试中频繁遇到CCDC或CSI的写缓冲区溢出(
*_WBL_OVF),即使内存带宽理论值足够。 - 系统总线负载监控显示持续高占用率。
- 调整方法:这是一个典型的“试凑”优化过程。从一个较小的值开始(比如10),逐渐增大,同时监控PCR中的溢出标志和系统整体流畅度。可以使用一个简单的公式估算带宽需求:
预览读带宽 (字节/秒) ≈ (图像宽度 * 图像高度 * 每像素字节数 * 帧率) / (1 + PRV_EXP/平均请求间隔)。增大PRV_EXP会降低分母,从而降低该模块的带宽需求。 - 注意事项:设置过大(如上千)的EXP值会显著增加模块的读延迟,可能导致预览显示延迟增大或缩放处理跟不上帧率。需要在系统带宽和模块延迟之间取得平衡。
4. 典型模块的SBL配置与数据流实战
理解了单个寄存器,我们再把它们串起来,看看一个完整的模块数据流是如何通过SBL寄存器配置和监控的。我们以最常见的预览引擎(PREVIEW)处理通路为例。
4.1 预览引擎数据流全景
预览通路通常涉及两个方向的SBL请求:
- 读请求:从内存读取原始或半处理图像数据(源)。
- 写请求:将处理后的预览图像数据写回内存(目的)。
对应的寄存器组是:
- 读请求状态寄存器:
SBL_PRV_RD_0~SBL_PRV_RD_3(最多4个请求者)。 - 写请求状态寄存器:
SBL_PRV_WR_0~SBL_PRV_WR_3(最多4个请求者)。 - 暗帧读请求:
SBL_PRV_DK_RD_0~SBL_PRV_DK_RD_3(用于暗帧减除,可选)。
4.2 配置与调试步骤
步骤一:内存缓冲区规划这是SBL配置的基础。你必须为预览引擎的输入(读)和输出(写)在物理连续的内存中分配好缓冲区。假设我们处理QVGA (320x240) YUV422图像,一帧大小约为3202402 = 150KB。我们通常分配双缓冲甚至三缓冲来避免撕裂。
- 输入缓冲区地址:
0x8000_0000,0x8002_5800... - 输出缓冲区地址:
0x8010_0000,0x8012_5800...
关键点:确保地址是256字节对齐的(根据BYTE_CNT字段推测,这是SBL处理的一个自然边界),并且缓冲区大小足够容纳一帧数据加上可能的额外行(用于DMA突发传输)。
步骤二:初始化请求寄存器(通常由驱动/硬件自动完成)对于读请求,你需要设置ADDR字段(目标地址的高20位)和VALID位。但注意,这些寄存器是只读的。这意味着模块内部的DMA控制器或状态机会根据你配置给预览引擎本身的参数(如图像尺寸、起始地址)自动填充这些寄存器。你的工作是通过预览引擎的配置寄存器(非SBL寄存器)正确设置这些参数。
步骤三:实时监控与诊断当系统运行时,通过轮询或中断方式检查SBL寄存器来诊断问题。
场景诊断:预览输出花屏(数据错乱)
- 检查写地址:读取
SBL_PRV_WR_0的ADDR字段,确认它是否指向你预设的输出缓冲区地址0x8010_0000。如果地址错误,说明预览引擎的基地址寄存器配置有误。 - 检查写状态:观察
DATA_READY和DATA_SENT。正常的流程应该是:DATA_READY脉冲式变高(表示一帧或一块数据准备好),然后DATA_SENT随之变高并保持,直到传输完成。如果DATA_READY一直为高但DATA_SENT从未变高,说明SBL没有响应写请求,可能是仲裁器故障或总线错误。 - 交叉检查读端:同时查看对应的
SBL_PRV_RD_0。确保DATA_AVL在DATA_WAIT之后能正常变高,表示数据成功从源地址读取。如果读失败,预览引擎没有输入数据,自然无法产生正确的输出。 - 检查溢出标志:最后,永远别忘了
SBL_PCR。确认PRV_WBL_OVF和CCDCPRV_2_RSZ_OVF(如果预览数据来自CCDC)没有置位。
步骤四:性能调优
- 如果预览帧率不足,检查
SBL_SDR_REQ_EXP中的PRV_EXP值是否过大,限制了读带宽。 - 使用
SBL_GLB_REG_x观察预览请求的VALID位占空比。如果VALID位几乎常亮,说明预览请求持续占用仲裁通道,可能会阻塞其他低优先级模块。此时可能需要优化缓冲区管理,让预览引擎更高效地成块存取数据,减少请求次数。
5. 高级调试技巧与常见问题排查实录
基于多年的调试经验,SBL相关的问题往往有规律可循。下面我整理了一个快速排查清单和几个典型案例。
5.1 SBL问题快速排查清单
当出现图像异常、丢帧、系统卡顿时,按以下顺序检查:
- 第一步:检查所有溢出标志(
SBL_PCR)。- 任何
*_WBL_OVF或CCDCPRV_2_RSZ_OVF置1,都表明数据流有堵塞。立即记录下哪个模块溢出。
- 任何
- 第二步:清除溢出标志。向
SBL_PCR的溢出位写1清零。 - 第三步:确认数据源和目的。
- 对于出错的模块,通过
SBL_GLB_REG_x确认其当前请求的SRC_DST_M和DIRECTION是否符合预期。 - 核对对应的
SBL_*_RD_x或SBL_*_WR_x寄存器中的ADDR字段,确认地址是否正确指向了有效的、已初始化的内存缓冲区。
- 对于出错的模块,通过
- 第四步:分析请求状态。
- 写请求卡住(
DATA_READY=1但DATA_SENT=0):检查内存控制器配置、内存颗粒本身、或系统总线是否有其他主设备(如CPU、DSP)在频繁访问同一区域导致冲突。 - 读请求卡住(
DATA_WAIT=1但DATA_AVL=0):检查数据生产者(上游模块)是否成功写入了数据。例如,预览读卡住,就去查CCDC或上一个处理模块的写状态。
- 写请求卡住(
- 第五步:检查系统带宽与仲裁。
- 如果频繁出现溢出,且地址状态都正确,考虑调整
SBL_SDR_REQ_EXP,限制非实时模块的带宽。 - 检查系统时钟配置,确保ISP功能时钟(func clk)和内存时钟(如EMIF时钟)比例合理。内存时钟太慢是导致溢出的常见硬件原因。
- 如果频繁出现溢出,且地址状态都正确,考虑调整
5.2 典型案例分析
案例一:间歇性图像撕裂与CCDC_WBL_OVF溢出
- 现象:在1080p@30fps高分辨率模式下,图像偶尔出现横向撕裂,
SBL_PCR中CCDC_WBL_OVF位间歇性置1。 - 分析:CCDC作为实时数据源,其写缓冲区溢出意味着数据生产速度大于SBL写入内存的速度。在1080p高带宽场景下,内存子系统成为瓶颈。
- 排查:
- 检查内存(DDR)的时钟频率和带宽是否满足要求。计算CCDC数据率:1920x1080 x 30fps x 2字节/像素 ≈ 124 MB/s。确保DDR实际可用带宽远高于此值(需考虑总线开销和其他主设备占用)。
- 使用
SBL_GLB_REG_x观察,当溢出发生时,是否有其他模块(如多个RSZ同时工作,或HIST在大量读)的请求VALID位持续为高,占用了大量总线时间。 - 检查
SBL_SDR_REQ_EXP,是否对RSZ或HIST的节流不够(值太小),导致它们与CCDC争抢带宽。
- 解决:
- 优化内存访问:确保CCDC的输出缓冲区地址在DDR物理上是连续的,并且对齐到Cache Line大小,以最大化突发传输效率。
- 调整仲裁优先级:虽然SBL优先级通常是硬件固定的,但可以尝试通过
SBL_SDR_REQ_EXP进一步抑制非关键模块(如直方图)的请求频率。 - 降低源数据率:如果硬件带宽确实无法满足,可考虑降低传感器输出帧率或分辨率。
案例二:四倍缩放(4x Zoom)时,画面静止或花屏,CCDCPRV_2_RSZ_OVF置位
- 现象:启用缩放器的4倍缩放功能后,缩放输出画面异常,
SBL_PCR的位24 (CCDCPRV_2_RSZ_OVF) 被置位。 - 分析:手册中对这个位的描述非常关键。它指出,当缩放器输入源设置为CCDC或预览引擎,且需要进行两遍缩放(例如4倍缩放可能需要先缩2倍到内存,再读回缩2倍)时,如果时序同步出错,就会发生这种溢出。本质是第二遍缩放处理时,输入源(此时应是内存中的中间结果)还没有准备好,但缩放器已经开始了新一帧的处理。
- 排查:
- 确认缩放器配置:检查
RSZ_CNT寄存器的INPSRC位,确认在单遍和双遍缩放模式下配置是否正确。 - 检查帧同步:确保在启动第二遍缩放处理(从内存读中间结果)之前,第一遍缩放(从CCDC/PRV直接缩放并写内存)已经完全完成。这需要查询第一遍缩放写请求寄存器(如
SBL_RSZ1_WR_x)的DATA_SENT状态,或使用缩放器模块自身的中断标志。
- 确认缩放器配置:检查
- 解决:
- 实现严格的帧间同步逻辑。在驱动程序中,必须等待第一遍缩放的“帧完成”中断或DMA完成中断后,才能重新配置缩放器输入源为内存,并启动第二遍缩放。
- 考虑使用Ping-Pong缓冲区:为中间结果分配两个缓冲区。当缩放器正在从缓冲区A读取数据进行第二遍处理时,第一遍缩放可以将下一帧的中间结果写入缓冲区B。
案例三:开启多个缩放通道后,系统响应变慢,偶尔丢帧
- 现象:同���启用RSZ1输出到显示、RSZ2输出到编码器后,系统整体响应延迟增加,预览帧率下降。
- 分析:多个缩放通道同时工作,意味着SBL需要处理更多的并发写请求,并可能产生大量的内存读请求(如果缩放源来自内存)。这会急剧增加系统总线负载和SBL仲裁复杂度。
- 排查:
- 使用
SBL_GLB_REG_0~7同时监控多个通道。你会发现VALID位为1的通道数明显增多,且切换频繁。 - 检查各个
SBL_RSZx_WR_x的BYTE_CNT增长是否平滑。如果某个通道的BYTE_CNT长时间不变,说明该通道的写请求被阻塞。 - 监控
SBL_PCR,看是否出现RSZx_WBL_OVF。
- 使用
- 解决:
- 错峰处理:如果应用允许,不要同时启动所有缩放通道。可以采用分时复用,例如一帧处理显示预览,下一帧处理编码抓图。
- 降低输出规格:降低非关键通道的输出分辨率或帧率。例如,给编码器的流可以降低到720p或15fps。
- 优化内存布局:确保每个缩放通道的输入和输出缓冲区位于不同的DDR Bank或Page,减少内存访问冲突。
- 调整SBL节流:适当增大
SBL_SDR_REQ_EXP中RSZ_EXP的值,降低缩放器读请求的“攻击性”,为更高优先级的CCDC写请求让出带宽。
调试SBL问题,本质上是在调试一个并发的、实时的数据流系统。寄存器状态是表象,背后的根本原因往往是带宽不足、时序不同步、或资源配置冲突。掌握这些寄存器的含义,并结合系统级的分析,你就能从“黑盒”调试转变为有针对性的精准打击,大幅提升嵌入式视觉系统开发的效率和稳定性。