TI处理器CBUFF FIFO阈值配置:LVDS/CSI-2高速数据流控实战
2026/7/18 10:20:27 网站建设 项目流程

1. 高速接口数据流管理的核心挑战

在嵌入式图像处理、汽车摄像头或者工业视觉系统的开发中,我们经常需要处理来自图像传感器(Image Sensor)的海量像素数据。这些数据通过LVDS或MIPI CSI-2这类高速串行接口,以每秒数百兆甚至上千兆比特的速率涌入处理器。这就像一条汹涌澎湃的数据大河,而我们的处理系统(如DSP或SoC)则是下游的蓄水池和处理工厂。如果河水来得太猛太快,蓄水池(硬件缓冲区)来不及处理就会溢出,导致数据丢失,画面出现花屏或撕裂;如果河水断流,下游工厂就会“饿死”,处理流程中断。因此,如何精准地控制这条数据河的流量,确保其平稳、持续地流入处理单元,就成了嵌入式底层驱动开发中最核心也最棘手的问题之一。

德州仪器(TI)在其许多带有高速接口(HSI)模块的处理器中,提供了一个名为CBUFF(Circular Buffer)的硬件缓冲区,并配套了一套精密的寄存器配置机制,专门用来解决这个“控流”难题。这套机制的核心,就是一系列以CFG_DATA_LLx(Link List,链表)和CFG_DATA_LLx_THRESHOLD命名的寄存器。很多工程师在初次接触这些寄存器时,往往只关注数据格式、包长等“显性”参数,而对FIFO阈值这类“隐性”配置一知半解,结果就是系统在压力测试下频频出现偶发性丢帧或卡顿,排查起来犹如大海捞针。今天,我就结合自己踩过的坑,把这套数据流控制的“阀门”原理和配置实战讲透,让你在设计和调试LVDS/CSI-2数据通路时,心里更有底。

2. CBUFF FIFO:数据流中的关键“蓄水池”

要理解阈值配置,首先得搞清楚CBUFF在整个数据通路中的角色。你可以把它想象成连接数据源(如ADC Buffer或DMA)和数据消费者(LVDS/CSI-2协议引擎)之间的一个“蓄水池”或“中转仓库”。

数据写入侧(上游):通常是DMA控制器,它从内存或前级模块(如ADC)疯狂地搬运数据,并试图写入CBUFF。DMA的写入速度受总线带宽、仲裁等因素影响,可能是不稳定或突发的。

数据读出侧(下游):是LVDS或CSI-2的协议引擎(Protocol Engine),它按照固定的像素时钟频率,从CBUFF中读取数据,并串行化发送出去。这个读出速率相对稳定,由视频时序(如分辨率、帧率)决定。

CBUFF本身是一个先入先出(FIFO)的硬件队列。它的核心矛盾在于:写入速度和读出速度的动态匹配。理想情况下,写入均值等于读出均值,FIFO深度维持在一个半满的稳定状态。但现实是,DMA传输可能有延迟,或者协议引擎可能因行/帧消隐期而暂停读取,导致速度瞬时失配。

如果FIFO被写满(上溢),新来的数据无处可放,就会丢失。如果FIFO被读空(下溢),协议引擎无数据可发,输出就会产生错误(如CSI-2的ECC错误或LVDS的同步丢失)。CFG_DATA_LLx_THRESHOLD寄存器里的WR_THRESHOLD(写阈值)和RD_THRESHOLD(读阈值),就是用来主动管理这两种风险的关键“水位线”传感器和控制开关。

注意:这里的“LLx”(如LL17, LL18)指的是不同的数据链路(Link List)条目。在TI HSI的架构中,一个复杂的数据流(如一帧图像中的不同区域或不同虚拟通道的数据)可以被分解成多个链表条目依次描述。每个条目都有自己独立的配置寄存器组,包括数据属性(CFG_DATA_LLx)和流控阈值(CFG_DATA_LLx_THRESHOLD)。这意味着你可以为数据流的不同阶段设置不同的流控策略,非常灵活。

3. 核心寄存器详解:从数据描述到流控阈值

输入材料中给出了从LL17到LL23的多组寄存器,它们的结构高度相似。我们以CFG_DATA_LL18CFG_DATA_LL18_THRESHOLD这一组为例,进行深度拆解。理解了这一组,其他组触类旁通。

3.1 数据属性配置寄存器:CFG_DATA_LL18

这个寄存器(偏移地址0x108)定义了通过这条链表传输的数据包的所有基本属性。它就像一份“发货清单”,告诉硬件:要发什么货、怎么包装、发到哪里。

关键字段解析:

  1. LL18_SIZE (Bits 22-9)

    • 作用:配置本次传输的数据大小。这是最需要仔细计算的字段之一。
    • 单位样本数(Samples),而不是字节数。手册明确说明,一个Sample对应一个16位的CBUFF单元。这是很多人的第一个坑。如果你的数据是YUV422格式(每个像素16位),那么一个Sample就是一个像素。如果你的数据是RAW10(每个像素10位,但打包成16位存储),也需要按16位单元来计算。
    • 配置示例:假设你要传输一行1280像素的RGB565图像(每个像素16位)。那么LL18_SIZE就应该配置为1280。如果数据是32位对齐的(例如ARGB8888),但CBUFF单元是16位,那么你需要将32位数据视为2个Samples,LL18_SIZE应为像素数 * 2
  2. LL18_FMT (Bits 6-5)LL18_FMT_IN (Bit 8)

    • LL18_FMT:指定输出到LVDS/CSI-2线缆上的数据格式00代表16-bit,01代表14-bit,10代表12-bit。这决定了协议引擎如何将CBUFF中的16位单元映射到串行位宽上。例如,选择12-bit时,每个16位Sample的高12位会被发送,低4位被忽略。
    • LL18_FMT_IN:指定输入到CBUFF的数据对齐方式0表示128位对齐,1表示96位对齐。这告诉DMA或前级模块,数据在内存或总线上的组织方式。必须与数据源的实际对齐方式匹配,否则会导致数据错位。
    • 关联与陷阱FMT_INFMT不一定相同!FMT_IN关乎数据如何“存入”仓库(CBUFF),FMT关乎数据如何“取出”并发送。例如,数据源以128位块(8个16位Sample)提供RAW12数据,FMT_IN设为0。但输出时你想每Sample只发送12位以节省带宽,FMT就可设为10。硬件会自动处理位宽的转换和打包。
  3. LL18_LPHDR_EN (Bit 27)LL18_LPHDR_VAL (独立寄存器)

    • CSI-2模式LPHDR_EN置1,表示这个链表条目是一个新长数据包的开始。协议引擎在发送实际数据前,会先发送一个长包包头(Long Packet Header)。包头内容由LL18_LPHDR_VAL寄存器指定,通常包含数据标识(Data ID)、包长度(WC)等信息。这是构建符合MIPI CSI-2协议的数据流所必需的。
    • LVDS模式LPHDR_EN置1,表示这是一个新LVDS帧的开始。此时LL18_LPHDR_VAL通常被固定配置为0xBBBBBBBB,作为一个帧起始的同步标记或保留字段。
    • 实操心得:在连续传输一帧图像时,通常只在第一个链表条目(描述帧起始)设置LPHDR_EN=1,后续的条目(描述同一帧内的连续数据)设为0,以避免产生多余的包头,影响数据连续性。
  4. LL18_HS (Bit 2)LL18_HE (Bit 1)

    • CSI-2模式:分别控制是否在数据前后发送行同步(HSYNC)短包。用于标记图像的行开始和行结束。
    • LVDS模式HS标记该条目数据是LVDS帧内的第一个数据;HE标记是最后一个数据。用于帧同步。
    • 配置逻辑:对于一行图像数据,通常设置HS=1, HE=1。对于一帧内连续的多行数据块,可能第一行HS=1,中间行HS=0, HE=0,最后一行HE=1。这需要根据具体的传感器输出时序来设计。
  5. LL18_VALID (Bit 0)

    • 这是条目的“总开关”。只有设为1,该链表条目才会被硬件执行。在动态更新链表(如Ping-Pong Buffer)时,通过清零此位可以��全地禁用某个条目。

3.2 流控阈值配置寄存器:CFG_DATA_LL18_THRESHOLD

这个寄存器(偏移地址0x110)是数据流稳定的“定海神针”。它不关心数据内容,只关心CBUFF FIFO的“水位”。

核心字段深度剖析:

  1. LL18_WR_THRESHOLD (Bits 14-8)

    • 功能:配置CBUFF FIFO的写阈值。当FIFO中未被读取的数据量(即存量)达到或超过这个阈值时,CBUFF会向DMA发出“停止写入”的信号(通常是通过反压,如拉高DMA_READY信号或产生一个中断),从而暂停(Stall)DMA的写入操作
    • 目的防止FIFO上溢(Overflow)。这是保护机制,确保下游消费速度跟不上时,上游不会继续灌水导致数据丢失。
    • 值域与计算:该字段占7位,理论值范围0-127(0x7F)。复位默认值是0x3F(十进制63)。这个阈值代表的是FIFO中以16位Sample为单位的数量
    • 如何设置
      • 保守策略:设置一个较高的值(如100)。这给了FIFO较大的缓冲空间,能容忍DMA的突发写入,但风险是一旦FIFO接近满,DMA被暂停后,需要较长时间才能将水位降到阈值以下恢复写入,可能影响平均吞吐率。
      • 激进策略:设置一个较低的值(如32)。DMA会较早被暂停,使得FIFO水位维持在较低水平,响应更灵敏。但缓冲能力弱,对下游读取速度的瞬时波动更敏感。
      • 经验值:一个常见的起点是设置为FIFO总深度的一半到三分之二。假设CBUFF FIFO总深度为128个Sample,可以设置WR_THRESHOLD = 80(约62.5%深度)。这既提供了足够的缓冲,又留出了安全余量。必须结合你的DMA突发长度和协议引擎的“饥饿”容忍度来权衡
  2. LL18_RD_THRESHOLD (Bits 6-0)

    • 功能:配置CBUFF FIFO的读阈值。当FIFO中累积的数据量达到或超过这个阈值时,CBUFF才允许协议引擎开始从中读取数据并发送出去。
    • 目的防止FIFO下溢(Underflow),并优化启动延迟。这是启动机制,确保协议引擎一开始发送,就有足够连续的数据,避免刚发几个Sample就断粮。
    • 值域与计算:占7位,范围0-127。复位默认值是0。
    • 如何设置
      • 设为0:意味着FIFO中一有数据(哪怕只有1个Sample),协议引擎就开始发送。这延迟最低,但极容易因DMA写入的微小延迟而导致下溢,产生发送错误。除非你的DMA写入速度绝对稳定且远超读取速度,否则不建议设为0
      • 合理设置:通常设置为一个足以覆盖DMA最大延迟的数值。例如,如果DMA响应一次请求的最大延迟是传输20个Sample的时间,那么RD_THRESHOLD至少应设为20。对于视频流,考虑到行消隐期后DMA重新启动的延迟,可以设置为一行数据量的1/4或1/8。例如,一行1280像素,可以设置RD_THRESHOLD = 160(1280/8)。
    • 与WR_THRESHOLD的联动RD_THRESHOLD<WR_THRESHOLD是基本前提。它们之间形成了一个“缓冲区工作窗口”。当数据量低于RD阈值,不发送;当数据量在RD和WR阈值之间,正常收发;当数据量达到WR阈值,暂停写入。这个窗口的宽度决定了系统应对速度波动的能力。
  3. ll18dman (Bits 18-16)

    • 功能:当LPHDR_EN使能时(即一个新数据包/帧开始),CBUFF可以通过哪个硬件请求线(DMA HW Req line)向DMA控制器发起传输请求。
    • 作用:实现基于数据包的DMA触发。这对于动态调度不同数据源非常有用。例如,你可以将虚拟通道0的数据映射到DMA通道0(dman=0),虚拟通道1的数据映射到DMA通道1(dman=1),实现硬件级的流控和多路复用。
    • 配置:值0-6对应不同的硬件请求线,值7表示不触发DMA。需要与SOC的DMA控制器配置相匹配。

4. 实战配置流程与参数计算示例

假设我们要为一个130万像素(1280x1024)的CMOS传感器配置CSI-2输出,帧率30fps,像素格式为RAW10(10位数据打包在16位中)。我们将使用一个链表条目(LL18)来描述一整行数据的传输。

4.1 第一步:确定基本参数与数据量

  • 分辨率:1280 x 1024
  • 像素位深:10-bit (RAW10),但存储和传输以16位单元进行。
  • 帧率:30 fps
  • 接口:MIPI CSI-2,1个数据通道(1 Lane)。
  • 计算一行数据的Sample数
    • 每像素对应1个16位Sample(尽管只用了10位)。
    • 一行数据量(Sample数) = 水平像素数 = 1280。
    • 因此,LL18_SIZE = 1280(十进制) =0x500(十六进制)。注意,该字段是14位(Bits 22-9),最大可表示16383,足够。

4.2 第二步:配置CFG_DATA_LL18寄存器

我们需要将计算出的值和模式选择填入寄存器。假设使用虚拟通道0,需要发送HSYNC包。

// 假设寄存器基地址为 HSI_BASE volatile uint32_t *reg_ll18 = (uint32_t*)(HSI_BASE + 0x108); uint32_t ll18_value = 0; // 1. 设置数据大小:1280个Samples (0x500) // Bits[22:9] = 0x500, 需要左移9位 ll18_value |= (0x500 << 9); // 2. 设置输入格式:假设数据源是128位对齐的(常见于DMA从内存搬运) // Bit[8] = 0 (128-bit aligned) // ll18_value |= (0 << 8); // 默认为0,可不设置 // 3. 设置输出格式:RAW10对应12-bit输出?这里需要澄清。 // RAW10在CSI-2中通常以10-bit格式传输,但CBUFF的FMT字段是12/14/16。 // 实际上,对于10-bit数据,通常仍选择16-bit输出格式,由协议引擎处理打包。 // 或者,有些实现中,FMT选择12-bit,高10位为有效数据。 // 这里假设我们选择16-bit输出,FMT=00。 // Bits[6:5] = 0b00 // ll18_value |= (0 << 5); // 默认为0,可不设置 // 4. 设置虚拟通道号:VC=0 // Bits[4:3] = 0b00 // ll18_value |= (0 << 3); // 默认为0,可不设置 // 5. 使能HSYNC和HEnd包:这是一行数据的开始和结束 // Bit[2] HS = 1 (发送HSYNC Start) // Bit[1] HE = 1 (发送HSYNC End) ll18_value |= (1 << 2) | (1 << 1); // 6. 使能长包包头(因为是CSI-2数据包) // Bit[27] LPHDR_EN = 1 ll18_value |= (1 << 27); // 7. 使能CRC校验(如果数据来自ADC Buffer,根据需求开启。此处假设不需要) // Bit[28] CRC_EN = 0 (默认) // 8. 最后,必须使能该链表条目 // Bit[0] VALID = 1 ll18_value |= 0x1; // 写入寄存器 *reg_ll18 = ll18_value;

4.3 第三步:配置长包包头值 (CFG_DATA_LL18_LPHDR_VAL)

对于CSI-2,长包包头(32位)包含:8位数据标识(Data ID),16位包长度(WC),8位ECC。

  • Data ID:包含虚拟通道号(VC)和数据类型(DT)。假设VC=0,DT for RAW10 = 0x2B。
    • 数据标识 = (VC << 6) | DT = (0 << 6) | 0x2B = 0x2B。
  • WC (Word Count):包数据长度,以字节为单位。注意,这里和LL18_SIZE单位不同!
    • 一行数据字节数 = Sample数 * 2字节/Sample = 1280 * 2 = 2560 字节。
    • WC = 2560。
  • ECC:包头错误校验码,由前面的24位(Data ID + WC)计算得出(通常硬件自动计算或可配置)。 假设我们手动配置一个包头,其中ECC先设为0(实际中可能由硬件填充或需计算)。
volatile uint32_t *reg_lphdr = (uint32_t*)(HSI_BASE + 0x10C); uint32_t lphdr_value = 0; // 组装长包包头: [ECC(8) | WC(16) | Data ID(8)] // 假设 Data ID = 0x2B, WC = 2560 (0xA00) lphdr_value = (0x00 << 24) | // ECC 暂为0 (0x0A00 << 8) | // WC = 2560 (0x2B); // Data ID *reg_lphdr = lphdr_value;

4.4 第四步:���键!配置流控阈值 (CFG_DATA_LL18_THRESHOLD)

这是性能调优的核心。我们需要估算合理的读写阈值。

  • 已知条件

    • FIFO总深度(假设):128 Samples(根据常见设计)。
    • 一行数据量:1280 Samples。
    • DMA突发传输长度(假设):64 Samples(128字节,一个常见的Cache行对齐长度)。
    • 协议引擎读取速度:稳定,一行数据在行有效期内均匀读完。
  • 计算与策略

    1. 写阈值(WR_THRESHOLD)

      • 目标:防止上溢,同时尽量减少DMA暂停次数。
      • 考虑:DMA一次突发写入64 Samples。我们希望在一次突发写入后,FIFO水位不要超过安全线。同时,要留出空间应对DMA可能因总线竞争产生的延迟。
      • 设置WR_THRESHOLD = FIFO深度 - DMA突发长度 - 安全余量 = 128 - 64 - 16 = 48
      • 解释:当FIFO中数据达到48个Sample时,就暂停DMA。这样即使一个64 Sample的突发立刻到来,FIFO水位最高会到48+64=112,仍小于总深度128,有16个Sample的安全余量。我们将48写入Bits 14-8。
    2. 读阈值(RD_THRESHOLD)

      • 目标:防止下溢,确保协议引擎启动时有足够数据。
      • 考虑:协议引擎开始读取后,DMA需要时间响应并填充数据。这个延迟包括DMA启动延迟和首次传输延迟。
      • 设置RD_THRESHOLD = 估计的DMA响应延迟内消耗的Sample数 + 启动缓冲
      • 估算:假设DMA响应延迟最坏情况是消耗掉32个Sample的时间。为了更稳健,我们再加一些缓冲。
      • 设置RD_THRESHOLD = 32 + 16 = 48。但注意,RD_THRESHOLD必须小于WR_THRESHOLD。我们上面设置了WR=48,因此RD必须小于48。调整一下,设RD_THRESHOLD = 32
      • 解释:当FIFO中累积了32个Sample后,协议引擎才开始发送。这给了DMA一个“提前量”去准备数据。
    3. DMA请求线(ll18dman):假设使用DMA通道0,则设置为0。

volatile uint32_t *reg_threshold = (uint32_t*)(HSI_BASE + 0x110); uint32_t threshold_value = 0; // 1. 设置写阈值 WR_THRESHOLD = 48 (0x30) threshold_value |= (0x30 << 8); // Bits[14:8] // 2. 设置读阈值 RD_THRESHOLD = 32 (0x20) threshold_value |= (0x20 << 0); // Bits[6:0] // 3. 设置DMA请求线为0 // Bits[18:16] = 0 // threshold_value |= (0 << 16); // 默认为0,可不设置 // 写入寄存器 *reg_threshold = threshold_value;

4.5 第五步:启动与监控

配置完所有链表条目(本例只有一个LL18,实际一帧可能需要多个条目循环)后,使能HSI模块的DMA和协议引擎。然后,通过监控CBUFF的状态寄存器(如果有)或使用调试工具(如逻辑分析仪抓取DMA请求/应答信号、FIFO水位信号)来观察实际运行情况。

关键监控点

  • FIFO水位是否大部分时间在RD和WR阈值之间波动?
  • DMA是否频繁被暂停(Stall)?如果是,可能需要增大WR_THRESHOLD或优化DMA优先级。
  • 协议引擎是否曾因FIFO为空而停顿(下溢)?如果是,可能需要增大RD_THRESHOLD或检查DMA性能。

5. 常见问题排查与调试技巧

在实际项目中,配置不当会导致各种诡异问题。下面是一个典型的问题排查清单。

现象可能原因排查步骤与解决方案
图像随机出现单行/多行花屏或数据错位1.FIFO上溢:WR_THRESHOLD设置过高,或DMA突发过快,导致数据被覆盖。
2.链表SIZE计算错误:单位弄错(字节 vs Sample),或数值溢出。
3.数据对齐(FMT_IN)错误:源数据对齐方式与配置不符。
1.检查上溢:尝试显著降低WR_THRESHOLD(如设为20)。如果问题消失或变化,说明是流控问题。需重新评估DMA性能和FIFO深度,适当降低WR阈值或优化DMA传输模式(如减小突发长度)。
2.核对SIZE:确认LLx_SIZE是以16位Sample为单位。对于RAW10/12等格式,确认计算无误。用简单图案(如彩条)测试,核对接收端数据量。
3.验证对齐:确保FMT_IN与数据源(如内存中的图像缓冲区)的对齐方式一致。128位对齐是常见选择。
图像开始部分正常,后续出现断流、黑屏或绿色画面1.FIFO下溢:RD_THRESHOLD设置过低,或DMA延迟过大,导致协议引擎“饿死”。
2.DMA未正确触发llxdman配置错误,或DMA通道未正确初始化。
3.链表条目未循环或VALID位被错误清除
1.检查下溢:增大RD_THRESHOLD(如从0改为32)。如果图像能持续更久,则证实是下溢。需要分析DMA延迟原因(总线负载、仲裁优先级)。
2.检查DMA触发:使用示波器或芯片的GPIO toggle功能,监测DMA硬件请求线是否有信号。确认LPHDR_ENllxdman配置匹配。
3.检查链表状态机:如果是多条目循环,确认最后一个条目的NEXT_PTR指向第一个条目,且所有条目VALID=1。监控链表指针寄存器,看是否在循环。
CSI-2数据包解析错误(如ECC错误、同步丢失)1.长包包头(LPHDR)配置错误:WC或Data ID不正确。
2.HS/HE控制位错误:导致行同步包时序混乱。
3.FIFO下溢导致包不完整
1.解码包头:用MIPI协议分析仪抓取CSI-2数据,检查长包包头的WC和Data ID是否与配置一致。特别注意WC的单位是字节。
2.检查同步包:确认HS/HE只在需要时置位。对于连续的多行传输,中间行的HS/HE应为0。
3.结合下溢排查
LVDS输出无信号或信号不稳定1.LVDS帧首尾标识错误HS/HE在LVDS模式下配置错误,未正确标记帧开始和结束。
2.LPHDR_VAL静态值未配置:LVDS模式下,LPHDR_EN置1时,LPHDR_VAL需配置为0xBBBBBBBB
3.时钟或电气问题:非寄存器配置问题,需检查时钟源、串行器配置、差分线阻抗。
1.核对帧结构:确认用于帧开始和结束的链表条目正确设置了HS=1HE=1
2.检查静态头:确认CFG_DATA_LLx_LPHDR_VAL寄存器已写入0xBBBBBBBB
3.基础检查:测量LVDS时钟和数据线是否有差分信号输出。确认LVDS串行器的参考时钟和电源正常。
性能不达标,达不到理论带宽1.DMA频繁被Stall:WR_THRESHOLD设置过小,DMA有效工作时间被压缩。
2.FIFO深度成为瓶颈:对于高带宽数据,FIFO深度不足,即使优化阈值也无济于事。
3.总线带宽瓶颈:DMA读取内存的带宽不足。
1.优化阈值:在保证不上溢的前提下,尝试提高WR_THRESHOLD,给DMA更长的连续工作时间。
2.评估FIFO深度:这是硬件限制。如果计算出的理想工作窗口(WR-RD)大于FIFO深度,则需考虑降低分辨率、帧率或使用更深的FIFO型号。
3.系统级优化:确保图像缓冲区位于高速内存(如DDR),并配置DMA使用高效的总线主端口和突发传输。

调试心得

  1. 从简到繁:初始调试时,先用一个最简单的、固定的图案(如全红、棋盘格)进行测试。这能排除图像内容复杂度和传感器端的变量。
  2. 善用静态配置:在动态链表(Linked List)模式工作不稳定时,可以尝试先配置成静态模式(如果硬件支持),即只用一个链表条目循环发送固定数据。这能验证最基本的CBUFF到协议引擎的通路是否正常。
  3. 水位线可视化:如果芯片提供CBUFF FIFO的水位状态寄存器,一定要在调试代码中定期读取并打印或绘图。观察水位线在RD和WR阈值之间的波动情况,是调整阈值最直接的依据。
  4. 阈值设置不是一劳永逸的:���同的分辨率、帧率、DMA负载场景下,最优的阈值可能不同。在产品压力测试(高低温、复杂场景)时,需要重新审视和微调这些参数。

6. 高级应用:多虚拟通道与动态链表管理

在更复杂的应用中,例如多路摄像头数据复用(通过CSI-2的虚拟通道),或者发送一帧中包含多种数据类型(如图像数据+嵌入式数据),就需要用到多个链表条目(LL17-LL23)以及动态管理。

多虚拟通道示例: 假设要通过CSI-2交替发送来自两个摄像头的数据(VC0和VC1)。

  1. 配置LL18:描述VC0的一行数据。设置VCNUM=0LPHDR_EN=1(每帧开始),配置好对应的阈值。
  2. 配置LL19:描述VC1的一行数据。设置VCNUM=1LPHDR_EN=1
  3. 设置链表指针:将LL18的NEXT_PTR(通常在一个独立的链表控制寄存器中)指向LL19的地址,将LL19的NEXT_PTR指回LL18,形成一个环。
  4. 流控隔离:LL18和LL19有各自独立的THRESHOLD寄存器。这意味着你可以为两个数据流设置不同的流控策略。例如,如果VC0的数据优先级更高,可以给LL18设置更宽松的WR阈值(更大),给LL19设置更严格的WR阈值(更小),确保VC0的数据流更不易被阻塞。

动态链表管理: 在“乒乓缓冲”(Ping-Pong Buffer)场景中,CPU或另一个协处理器需要动态更新下一个要发送的数据块地址。

  1. 准备两套链表条目(例如LL18和LL19),分别指向Buffer A和Buffer B。
  2. 初始时,使能LL18(VALID=1),禁用LL19(VALID=0),链表指针环为 LL18 -> LL18。
  3. 当LL18描述的数据正在发送时,CPU可以安全地更新LL19中的SIZEDMA地址等参数,指向新的数据(Buffer B)。
  4. 在LL18的数据发送完成、下一次循环开始前,CPU将LL19的VALID置1,并将LL18的NEXT_PTR修改为指向LL19。这样,下一次传输就会自动跳转到新的数据块。
  5. 关键点在于时机,必须在硬件使用当前条目结束后、开始根据NEXT_PTR获取下一个条目之前,完成对下一个条目的更新和链接操作。这通常需要配合中断或状态轮询。

通过对CFG_DATA_LLxCFG_DATA_LLx_THRESHOLD这套寄存器的深入理解和精心配置,你就能真正驾驭LVDS/CSI-2高速数据流,在嵌入式视觉系统中构建出稳定、高效的数据传输通道。这不仅仅是照着手册填几个十六进制数,更是对系统实时性、稳定性和资源利用率的深度优化。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询