MIPI CSI-2驱动开发:时钟与协议引擎寄存器配置实战解析

📅 2026/7/19 9:13:16 👁️ 阅读次数 📝 编程学习
MIPI CSI-2驱动开发:时钟与协议引擎寄存器配置实战解析

1. 项目概述与核心价值

在嵌入式视觉系统,尤其是智能手机、汽车ADAS摄像头和工业相机模组的设计中,图像传感器与主处理器(如应用处理器、ISP或FPGA)之间的高速、可靠数据链路是决定整个系统性能与功耗的关键瓶颈。MIPI CSI-2(Camera Serial Interface 2)接口作为这一领域事实上的行业标准,其优雅的物理层与协议层设计,使得在有限的引脚数和严格的功耗预算下,实现每秒数Gbps的稳定视频流传输成为可能。然而,将一份冰冷的协议规范转化为一块稳定工作的硬件,其间的鸿沟往往由驱动工程师通过精确的寄存器配置来填补。这份工作远不止是“按手册填值”那么简单,它要求工程师深刻理解时钟树管理、协议状态机时序以及低功耗状态切换的微观细节。

很多人初次接触CSI-2驱动开发,面对动辄数十个、字段含义晦涩的配置寄存器,容易感到无从下手。手册上通常只告诉你每个比特位“是什么”,却很少解释“为什么”要这么设置,以及配置不当会导致怎样诡异的现象——比如图像偶尔出现撕裂、在特定光照下丢帧、或者系统待机电流莫名偏高几十毫安。时钟控制与协议引擎的寄存器配置,正是整个CSI-2接口稳定性的基石与功耗管理的闸门。它不像图像格式、分辨率设置那样直观,却从根本上决定了数据通道的“心跳”是否稳健、节律是否正常。一个配置不当的时钟,可能导致建立保持时间违例,引发偶发性数据错误;而协议超时参数设置不合理,则可能在复杂的总线交互中导致死锁或响应超时,让系统变得极不稳定。

本文将基于一份典型的处理器数据手册(以TI平台为例,但其原理具有普适性),深入解析CSI-2接口中时钟控制寄存器(CSI2_CLK_CTRL)协议引擎定时寄存器组(CSI2_TIMING1/2, CSI2_VM_TIMINGx, CSI2_CLK_TIMING)的配置逻辑。我不会仅仅翻译手册,而是结合多年在摄像头模组调试和平台驱动开发中踩过的坑,为你拆解每个关键配置位背后的设计意图、参数计算的工程方法,以及不同应用场景(如持续视频流、间歇性抓图、低功耗待机)下的配置策略差异。无论你是正在调试第一个摄像头驱动的嵌入式新手,还是希望优化现有系统功耗与稳定性的资深工程师,相信这些从实际项目中凝结出的细节与思考,都能为你提供直接的参考。

2. 时钟控制寄存器(CSI2_CLK_CTRL)深度解析

时钟是数字系统的脉搏,对于高速串行接口更是如此。CSI2_CLK_CTRL寄存器掌管着整个CSI-2接口时钟生成的生杀大权,从PLL的开关到低速时钟的精细分频,再到DDR时钟的节能策略,都由此寄存器控制。手册规定,该寄存器仅在接口使能位(IF_EN)为0时才能修改,这是一个重要的安全限制,防止运行时时钟突变导致数据混乱。

2.1 PLL电源控制:性能与功耗的权衡

寄存器的高位字段(bit 31-30的PLL_PWR_CMD和bit 29-28的PLL_PWR_STATUS)用于控制CSI-2专用PLL(锁相环)的电源状态。PLL的作用是将输入的参考时钟倍频到链路所需的高频时钟(例如,将几十MHz的晶振时钟倍频到用于高速数据传输的几百MHz甚至上GHz的DDR时钟)。

PLL_PWR_CMD是命令字段,写入后触发状态转换:

  • 0h (OFF):命令PLL关闭。这是最低功耗状态,但重新开启到稳定输出需要较长的锁相时间(通常几十微秒)。
  • 1h (PLL ON, HSDIV OFF):仅打开PLL核心,但后级的高速分频器(HSDIV)关闭。PLL本身已经锁定到目标频率,但无时钟输出。这种状态功耗介于完全关闭和全开之间,恢复输出速度较快。
  • 2h (PLL & HSDIV ON):PLL和高速分频器全部开启,产生完整的时钟输出。这是正常工作模式,功耗最高。
  • 3h (PLL & HSDIV ON, No output):PLL和分频器开启,但时钟不输出到CSI-2的复杂IO(Complex IO)。这是一种特殊的测试或中间状态,普通应用较少使用。

PLL_PWR_STATUS是只读的状态字段,反映了PLL控制模块的实际状态,与命令字段不一定立即同步,因为电源切换有延迟。

实操心得:在摄像头启动流程中,正确的顺序是先配置PLL相关参数(如倍频比),再发送PLL_PWR_CMD=2h开启命令。然后必须轮询PLL_PWR_STATUS,直到其变为2h,确认PLL已稳定锁定,才能进行后续操作。直接假设写入命令后立即生效,是导致启动失败或图像不稳定的常见原因。在低功耗场景下,当摄像头进入休眠时,可以发送PLL_PWR_CMD=0h关闭PLL以省电,但再次唤醒时需预留足够的PLL锁定时间(查手册中的PLL Lock Time参数),否则后续的数据传输会因时钟不稳而失败。

2.2 低功耗(LP)时钟与同步配置

Bit 21LP_RX_SYNC_ENABLE和 Bit 20LP_CLK_ENABLE共同管理低功耗模式下的时钟。

  • LP_CLK_ENABLE:这是低功耗时钟(TXCLKESC)的使能开关。当CSI-2接口处于LP(Low-Power)模式时,高速时钟关闭,数据通过单端信号以低速率传输,此时需要这个独立的LP时钟来同步LP传输。只有将此位置1,LP_CLK_DIVISOR的分频值才会生效。如果整个应用场景中完全不需要LP模式传输(例如,某些只使用HS模式的特殊配置),可以关闭它以节省一点点功耗。
  • LP_RX_SYNC_ENABLE:这个位定义了LP接收同步器的模式,其选择依据是CSI-2功能时钟(CSI2_CLK)的频率是否高于30MHz。若功能时钟≤30MHz,应设置为0(下降沿/上升沿同步);若>30MHz,则设置为1(上升沿/上升沿同步)。这本质上是根据时钟频率选择更可靠的同步器电路结构,以防止亚稳态。你需要根据你的系统主频来查表确定这个值,而不是随意设置。

Bit 12-0LP_CLK_DIVISOR是一个13位的分频器,用于从CSI-2功能时钟(CSI2_CLK)生成LP时钟(TXCLKESC)。其计算公式为:LP Clock Frequency = CSI2_CLK Frequency / (LP_CLK_DIVISOR)。手册规定输出频率必须在20 MHz到32 kHz之间。例如,若CSI2_CLK = 100 MHz,需要产生一个10 MHz的LP时钟,则LP_CLK_DIVISOR应设置为10。必须注意,分频值不能为0,有效范围是1-8191

2.3 高速(HS)时钟停止控制与DDR时钟策略

Bit 19HS_MANUAL_STOP_CTRL和 Bit 18HS_AUTO_STOP_ENABLE用于管理高速时钟的停止信号CSI2StopClk

  • 自动模式(HS_AUTO_STOP_ENABLE=1:协议引擎硬件会根据总线状态自动控制CSI2StopClk的断言和解除断言。这是最常用、最推荐的模式,能有效管理HS模式下的时钟门控,实现动态节能。
  • 手动模式(HS_AUTO_STOP_ENABLE=0:此时HS_MANUAL_STOP_CTRL位生效。软件可以手动将其置1来强制停止时钟,或置0来强制开启时钟。这种模式通常仅用于深度调试或某些极端低功耗控制场景,日常运行使用自动模式即可。

Bit 13DDR_CLK_ALWAYS_ON是一个关键的功耗性能权衡点。

  • 设置为0(默认):DDR时钟仅在发送HS数据包时才提供给外围设备(如传感器)。在数据包间隙的LP模式或空闲时段,DDR时钟会被关闭以节省功耗。这是最节能的模式。
  • 设置为1:DDR时钟始终发送给外围设备,无论数据通道处于HS还是LP模式。这消除了时钟启停带来的延迟和潜在的稳定性问题,对于某些对时钟连续性要求极高或初始化时序敏感的高端传感器可能有益,但会显著增加静态功耗。

2.4 LP NULL包生成机制

Bit 17-16LP_CLK_NULL_PACKET_SIZE和 Bit 15LP_CLK_NULL_PACKET_ENABLE用于控制LP模式下NULL包的生成。NULL包是一种不携带有效图像数据的空包,其作用是在LP传输结束后,帮助接收端清空其内部数据管道(FIFO),确保数据边界清晰。LP_CLK_NULL_PACKET_SIZE定义了NULL包的有效载荷大小(0-3字节)。在大多数标准兼容的应用中,建议启用此功能(ENABLE=1)并设置一个小的尺寸(如1字节),这有助于提高协议鲁棒性,尤其是在高带宽或复杂总线负载的情况下。

3. 协议引擎定时寄存器组精讲

如果说时钟控制寄存器设定了系统的“心跳”,那么协议引擎定时寄存器就定义了系统在各种交互场景下的“反应时间”和“耐心值”。配置不当,轻则性能下降,重则通信失败。

3.1 超时与强制停止定时器(CSI2_TIMING1)

这个寄存器主要管理总线 turnaround(转向)和强制停止的超时。

Bit 31TA_TO与 Bit 28-16TA_TO_COUNTER:Turn-Around超时计数器。当CSI-2总线需要从接收模式切换到发送模式(或反之)时,会发起一个Turn-Around(BTA)过程。TA_TO用于使能此超时计数器。如果使能,在发起BTA后,如果在TA_TO_COUNTER所定义的CSI2_CLK周期数内,方向切换未能成功完成,协议引擎会产生一个超时中断(TA中断),通知软件处理异常。TA_TO_COUNTER的值需要根据总线物理延迟和传感器响应时间来估算。例如,如果CSI2_CLK为100MHz(周期10ns),传感器最大响应时间为50us,那么至少需要设置TA_TO_COUNTER>= 50us / 10ns = 5000。通常,我们会设置一个足够大的安全值(如最大值8191),并结合Bit 30TA_TO_X16和Bit 29TA_TO_X8这两个倍乘因子来扩展超时范围TA_TO_X16TA_TO_X8可以组合使用(但注意它们是互斥的优先级编码,并非同时生效,具体优先级需查手册),实现1x, 8x, 16x的倍乘。假设TA_TO_COUNTER设为1000,若TA_TO_X16=1,则实际超时周期为1000 * 16 = 16000个时钟周期。

Bit 15FORCE_TX_STOP_MODE_IO与 Bit 12-0STOP_STATE_COUNTER_IO:强制停止状态计数器。当协议引擎需要强制总线进入停止状态时,会断言ForceTXStopMode信号。STOP_STATE_COUNTER_IO定义了该信号需要保持断言状态的CSI2_CLK周期数。STOP_STATE_X16_IOSTOP_STATE_X4_IO同样是倍乘因子。这个定时器确保了总线有足够的时间稳定地进入停止状态,避免状态切换过程中的冲突。其值通常与物理层特性相关,在未明确要求时,可采用默认值或参考平台推荐值。

3.2 HS发送与LP接收超时定时器(CSI2_TIMING2)

这个寄存器管理高速发送和低功耗接收的超时。

Bit 31HS_TX_TO与 Bit 28-16HS_TX_TO_COUNTER:HS发送超时计数器。当接口处于HS发送状态时,如果超过HS_TX_TO_COUNTER定义的时间仍未完成发送,会触发超时。注意,这里的时钟基准是BYTE_CLK(字节时钟),而非CSI2_CLK。BYTE_CLK频率与数据速率直接相关(例如,每条数据线1Gbps,则BYTE_CLK为1GHz/8=125MHz)。计算超时时间时需注意时钟域。例如,希望HS发送超时时间为1ms,BYTE_CLK为125MHz,则需要的周期数 = 1ms / (1/125MHz) = 125,000。这超出了HS_TX_TO_COUNTER的13位范围(最大8191)。此时就需要利用Bit 30HS_TX_TO_X64和Bit 29HS_TX_TO_X16。设置HS_TX_TO_COUNTER=1953(1953 ≈ 125000/64),并置HS_TX_TO_X64=1,即可实现约1ms的超时。

Bit 15LP_RX_TO与 Bit 12-0LP_RX_TO_COUNTER:LP接收超时计数器。原理与HS_TX类似,但用于LP接收模式,且时钟基准是CSI2_CLK。用于防止在LP模式下等待特定信号(如特定LP指令)时无限期阻塞。

避坑指南:超时计数器的设置是调试的难点。设置过短,在系统负载高或中断延迟大时容易引发误超时;设置过长,则系统在真正发生挂死时响应太慢。一个实用的方法是:初期调试时,将所有超时使能,并设置为一个非常大的值(利用倍乘因子),先保证功能正常。然后,在稳定工作的系统上,通过逻辑分析仪或性能计数器,测量关键操作(如BTA、一帧数据发送)的实际耗时,再据此设置一个留有20%-30%余量的安全超时值。同时,务必使能相应的超时中断,并在中断服务例程中记录错误,这是定位复杂总线问题的重要手段。

3.3 视频模式时序寄存器(CSI2_VM_TIMING1/2/3)

当CSI-2接口工作于视频模式(Video Mode)而非传统的基于数据包的“非视频模式”时,这三个寄存器用于定义视频帧的时序结构,对于直接生成或解析标准视频流至关重要。

  • CSI2_VM_TIMING1:定义水平时序。

    • HSA(Horizontal Sync Active):水平同步有效周期,单位是PPI Byte时钟周期数。对于典型的CMOS传感器,这对应HSYNC信号脉冲的宽度。
    • HFP(Horizontal Front Porch):水平前沿消隐期,在有效像素数据结束后、下一个HSYNC开始前的空白周期。
    • HBP(Horizontal Back Porch):水平后沿消隐期,在HSYNC结束后、有效像素数据开始前的空白周期。
    • 一行像素的总时间 = HBP + 有效像素宽度 + HFP + HSA。这些值必须与图像传感器输出的时序严格匹配。
  • CSI2_VM_TIMING2:定义垂直时序和同步窗口。

    • VSA(Vertical Sync Active):垂直同步有效周期,单位是行数。对应VSYNC信号脉冲的宽度。
    • VFP(Vertical Front Porch):垂直前沿消隐期。
    • VBP(Vertical Back Porch):垂直后沿消隐期。
    • WINDOW_SYNC:同步窗口。这是一个非常重要的容错参数。它定义了一个时间窗口(以BYTE时钟周期计),只要接收到的视频端口同步信号落在这个窗口内,就认为同步有效,不会产生“同步丢失”中断。这允许发送端和接收端时钟存在微小抖动或偏移。通常设置为4-15个周期,具体值取决于系统时钟精度和容忍度。
  • CSI2_VM_TIMING3

    • TL(Total Length):一行总的Byte时钟周期数。应等于HBP + 有效像素宽度 + HFP + HSA。注意其最大支持值为8192。
    • VACT(Vertical Active):一帧中有效图像数据的行数。

配置实战:配置这些参数前,必须从图像传感器的数据手册中找到其输出时序图和相关参数。例如,一个1080p@30fps的传感器,其典型参数可能是:有效像素1920,HBP=88, HFP=44, HSA=44, VBP=4, VFP=4, VSA=5。那么TL= 88+1920+44+44 = 2096,VACT=1080。将这些值填入对应寄存器即可。务必注意字节序和位宽,例如HFP是12位,最大4095,要确保计算值不溢出。

3.4 时钟时序寄存器(CSI2_CLK_TIMING)

这个寄存器专门控制DDR时钟与数据请求信号之间的时序关系,对于保证数据建立保持时间(Setup/Hold Time)至关重要。

  • DDR_CLK_PRE:在数据请求信号(data request)断言之前,DDR时钟需要提前多少个PPI Byte时钟周期开始运行。这确保了当时钟稳定后,数据请求才发出,避免第一个数据因为时钟不稳定而采样错误。
  • DDR_CLK_POST:在数据请求信号解除断言之后,DDR时钟还需要持续多少个PPI Byte时钟周期才停止。这确保了最后一个数据被可靠地锁存后,时钟才关闭。

这两个参数是典型的“前��”(Preamble)和“后导”(Postamble)时间设置。其具体值取决于物理层(PHY)的特性、PCB走线延迟以及接收端(Sensor或Processor)的时序要求。数据手册通常会给出一个推荐范围(例如,各4-8个周期)。如果CSI2_CLK_CTRL.DDR_CLK_ALWAYS_ON设置为1,则这两个参数无效,因为时钟始终存在。

经验之谈:在调试初期,如果遇到图像数据开头或结尾的几个像素颜色异常或错位,很大概率是DDR_CLK_PREDDR_CLK_POST设置不足。可以尝试逐步增大这两个值(例如从默认的1增加到4或8)进行测试。同时,用示波器或MIPI协议分析仪测量DDR_CLK数据有效信号之间的实际时序关系,是确定最佳值的金科玉律。

4. 虚拟通道FIFO配置与复杂IO控制

4.1 虚拟通道FIFO大小分配(CSI2_TX_FIFO_VC_SIZE / RX)

CSI-2协议支持最多4个虚拟通道(VC0-VC3),用于在同一物理链路上复用传输不同内容的数据流(如主图像、深度图、统计信息)。CSI2_TX_FIFO_VC_SIZECSI2_RX_FIFO_VC_SIZE寄存器分别用于配置发送和接收方向上,为每个虚拟通道分配的FIFO深度和起始地址。

每个VC的配置由两个字段组成:

  • VCx_FIFO_SIZE:分配给该VC的FIFO大小。其值0-8对应不同的深度等级(如0: 0 entries, 1: 32 entries, 2: 64 entries, ..., 8: 256 entries)。这里的entry是33位宽(32位数据+1位标识)。
  • VCx_FIFO_ADD:该VC的FIFO空间在总FIFO中的起始地址索引(以32个entry为单位递增)。

配置策略:总FIFO资源(例如256个entry)是固定的,需要根据各个虚拟通道的数据带宽和突发特性进行分配。高带宽、实时性要求高的视频流VC应分配更大的FIFO深度,以防止溢出。低带宽、间歇性的元数据VC可以分配较小的深度。关键原则是:分配的总大小不能超过物理FIFO总容量,且各VC的地址空间不能重叠。配置前,需要先禁用对应的虚拟通道。

4.2 复杂IO与ULPS控制(CSI2_COMPLEXIO_CFG2)

这个寄存器主要用于控制每条物理通道(Lane)的超低功耗状态(ULPS, Ultra-Low Power State)。ULPS是比LP模式更深的节能状态,通过将总线驱动到特定的静态电平来实现极低的漏电功耗。

寄存器为每条Lane(1-5)提供了两组控制信号:

  • LANEx_ULPS_SIG1:主要控制时钟Lane的ULPS进入/退出。
  • LANEx_ULPS_SIG2:主要控制数据Lane的ULPS进入/退出。

进入ULPS的条件非常严格,硬件会自动检查:1) Lane必须已处于Stop状态;2) CSI-2协议引擎内部没有待处理的数据;3) 协议引擎拥有总线控制权(未发送BTA)。只有条件满足时,写入1到相应位才会真正触发进入ULPS。因此,软件在请求进入ULPS后,必须回读该位的状态,直到确认变为1,才能认为ULPS已生效。退出ULPS的过程类似。

Bit 17LP_BUSY和 Bit 16HS_BUSY是两个非常有用的状态位,分别指示是否有VC配置为LP或HS模式且仍有未完成的操作。在系统准备进入全局低功耗状态(如系统休眠)前,检查这两个位是否为0,是确保安全关闭CSI-2接口的重要步骤。

5. 寄存器配置实战流程与常见问题排查

5.1 一个典型的摄像头初始化配置流程

  1. 关闭接口:确保CSI2_CTRL.IF_EN = 0
  2. 配置PLL:根据传感器输出数据速率和参考时钟,计算PLL倍频参数,并写入PLL配置寄存器。
  3. 配置时钟控制
    • 设置CSI2_CLK_CTRL.LP_CLK_DIVISOR,生成正确的LP时钟频率。
    • 根据功能时钟频率设置LP_RX_SYNC_ENABLE
    • 设置LP_CLK_ENABLE=1
    • 根据功耗策略选择DDR_CLK_ALWAYS_ON(通常设为0以省电)。
    • 设置HS_AUTO_STOP_ENABLE=1
    • 启用LP NULL包生成(LP_CLK_NULL_PACKET_ENABLE=1)。
  4. 配置协议定时
    • 根据系统时钟和容忍度,设置CSI2_TIMING1中的Turn-Around和Stop State超时值(初期可设大值)。
    • 根据数据速率和帧处理时间,设置CSI2_TIMING2中的HS发送和LP接收超时值。
    • 如果使用视频模式,从传感器手册获取时序参数,精确配置CSI2_VM_TIMING1/2/3
    • 根据PHY建议,设置CSI2_CLK_TIMING中的DDR_CLK_PRE/POST值。
  5. 配置虚拟通道与FIFO:根据数据流规划,分配CSI2_TX/RX_FIFO_VC_SIZE
  6. 配置Complex IO:设置数据Lane数量、极性等(通常在另一个寄存器CSI2_COMPLEXIO_CFG1)。
  7. 上电与使能
    • 发送PLL_PWR_CMD=2h,并轮询直到PLL_PWR_STATUS=2h
    • 最后,将CSI2_CTRL.IF_EN置1,使能整个接口。

5.2 常见问题排查速查表

现象可能原因排查步骤与解决方法
图像完全黑屏或全绿时钟未就绪或PLL未锁定1. 检查PLL_PWR_STATUS是否为2h。
2. 用示波器测量传感器时钟输入引脚是否有正确频率的时钟信号。
3. 检查LP_CLK_ENABLEDDR_CLK_ALWAYS_ON设置。
图像出现随机噪点、条纹数据建立保持时间不足,时钟不稳定1. 增大CSI2_CLK_TIMING中的DDR_CLK_PREDDR_CLK_POST值。
2. 检查PCB上时钟与数据线是否等长,差分对是否匹配。
3. 确认电源纹波是否在传感器和处理器要求范围内。
图像偶尔撕裂或丢帧FIFO溢出或协议超时1. 检查CSI2_TX/RX_FIFO_VC_SIZE分配是否合理,为高带宽VC增加深度。
2. 检查CSI2_TIMING2中的HS_TX_TO超时值是否过小,适当增大(利用倍乘因子)。
3. 检查系统中断延迟是否过长,导致数据无法及时搬出FIFO。
系统唤醒后摄像头不工作ULPS退出异常或状态机卡死1. 在进入休眠前,确认LP_BUSYHS_BUSY均为0。
2. 唤醒后,检查ULPS控制位状态是否已正确退出(回读为0)。
3. 尝试在唤醒流程中加入对CSI-2接口的软复位(如果支持)。
视频模式下行同步不稳定同步窗口WINDOW_SYNC设置过小1. 适当增大CSI2_VM_TIMING2.WINDOW_SYNC的值(如从4增加到8或12)。
2. 检查发送端(传感器)和接收端(处理器)的时钟源是否稳定,是否存在较大抖动。
Turn-Around操作失败Turn-Around超时时间不足1. 增大CSI2_TIMING1中的TA_TO_COUNTER值,并启用倍乘因子TA_TO_X16TA_TO_X8
2. 检查总线负载,确认在BTA过程中没有其他主设备争用。

5.3 调试工具与技巧

  • 逻辑分析仪/协议分析仪:配备MIPI CSI-2解码功能的仪器是终极调试利器。它能直观地显示物理层的LP/HS状态、数据包内容、虚拟通道信息,以及精确的时序关系,是定位协议层问题的必备工具。
  • 示波器:用于测量时钟频率、信号质量(眼图)、电源纹波。对于时序问题,测量DDR_CLK与数据线之间的延迟至关重要。
  • 软件调试:充分利用处理器的中断状态寄存器。使能所有超时中断(TA、HS_TX_TO、LP_RX_TO等),并在中断服务程序中记录详细的错误上下文(如错误发生时的计数器值、状态机状态),这对于复现偶发性故障极为有效。
  • 寄存器读写验证:对于关键寄存器(如PLL状态、ULPS控制位),坚持“写入-延迟-回读验证”的模式,确保配置生效,避免因总线写操作未完成导致的配置不一致问题。

寄存器配置是连接抽象协议与具体硬件的桥梁,理解每个比特位背后的物理意义和系统级影响,是写出稳定、高效、低功耗CSI-2驱动的关键。它没有太多炫酷的算法,更多的是对细节的耐心打磨和对原理的深刻把握。希望这篇结合了手册解读与实战经验的解析,能帮助你更从容地驾驭CSI-2接口,让图像数据流在你的系统中稳定、流畅地奔腾。