LM93主机错误状态寄存器深度解析:硬件监控芯片实战配置与调试 📅 2026/7/27 12:02:21 1. 从寄存器手册到实战LM93主机错误状态寄存器的深度解析在服务器主板、高端工作站或者工业控制器的研发与维护过程中硬件健康监控Hardware Health Monitoring, HHM是保障系统长期稳定运行的基石。这不仅仅是软件层面弹出一个“温度过高”的警告框那么简单其背后是一套由专用监控芯片如TI的LM93驱动的、实时的、硬件级的“哨兵”系统。这套系统的核心输出之一就是主机错误状态寄存器Host Error Status Registers。很多工程师拿到LM93几百页的数据手册看到密密麻麻的寄存器表往往感到无从下手尤其是面对48h到4Fh这一系列错误状态寄存器时只知道它们很重要却不清楚如何将其转化为实际的产品力。今天我们就抛开枯燥的寄存器列表从一个资深硬件工程师的视角深入LM93主机错误状态寄存器的内部逻辑。我会结合多年在服务器硬件监控固件BMC/IPMI开发中踩过的坑为你拆解这些寄存器每一位背后的设计意图、实战中的配置陷阱以及如何利用它们构建一个既灵敏又可靠的系统健康预警体系。无论你是正在设计监控方案的硬件工程师还是负责系统稳定性调优的软件工程师理解这些寄存器的“脾气”都能让你在问题发生前就听到系统的“心跳异常”。2. 主机错误状态寄存器系统健康的“神经中枢”在深入每个比特位之前我们必须先建立对主机错误状态寄存器组的整体认知。它不是孤立的几个寄存器而是LM93芯片整个监控逻辑的最终输出和状态汇总点。2.1 核心功能与设计哲学主机错误状态寄存器组地址48h至4Fh的核心功能是集中报告所有被监控参数的异常状态。你可以把它想象成一个控制中心的警报面板上面有几十个指示灯每个灯代表一种特定的故障类型如CPU1温度超限、12V电压欠压、风扇1停转等。LM93内部的各种比较器、数字逻辑单元就是背后的传感器和判断电路它们持续工作一旦发现异常就点亮面板上对应的那盏灯。这种集中报告机制的设计哲学在于效率与可靠性。系统软件如BMC固件或主机操作系统驱动无需轮询数十个独立的极限值寄存器进行比较只需定期读取这几个集中的状态寄存器就能一次性获知所有监控项的健康状况。更重要的是这些寄存器中的任何一个比特被置位变为1都会联动触发LM93状态控制寄存器Status/Control Register中的HOST_ERR主错误标志位。这为系统提供了一个最高优先级的硬件中断信号源使得软件能够以近乎实时的方式响应硬件故障。2.2 寄存器组概览与关联逻辑主机错误状态寄存器并非单一寄存器而是一个按功能分组的寄存器集合。根据数据手册其结构如下寄存器地址寄存器名称主要监控内容48hH_Error Status 14个温度区域超限、VRD电压调节器过热49hH_Error Status 2模拟电压输入 AD_IN1 ~ AD_IN8 超限4AhH_Error Status 3模拟电压输入 AD_IN9 ~ AD_IN16 超限4BhH_Error Status 4SCSI终端保险丝、动态Vccp错误、远程二极管故障4ChH_P1_PROCHOT Error Status处理器1的PROCHOT热节流事件与程度4DhH_P2_PROCHOT Error Status处理器2的PROCHOT事件与程度4EhH_GPI Error Status通用输入口 GPIO0 ~ GPIO7 的低电平错误4FhH_Fan Error Status风扇1至风扇4的转速过低错误这里有一个至关重要的细节需要理解B_Error Status寄存器组。在LM93中存在两套几乎完全相同的错误状态寄存器“H”Host系列和“B”BMC系列。它们监控相同的信号源但地址不同并且可能具有独立的睡眠掩码Sleep Masking配置。通常“H”系列供主机CPU通过SMBus读取而“B”系列供板载管理控制器BMC读取。这种双副本设计为冗余监控和权责分离提供了硬件基础。在本文中我们聚焦于主机侧H的寄存器但其原理完全适用于BMC侧。2.3 “写1清零”机制与状态锁存这是主机错误状态寄存器最需要警惕的特性之一也是很多新手容易栽跟头的地方。数据手册明确写道“Once a bit is set... it is not automatically cleared by the LM93 if the error event goes away. Each bit must be cleared by software. If software attempts to clear a bit while the error condition still exists, the bit does not clear.”这意味着什么状态锁存错误状态位一旦被置位就会像触发器一样锁存住即使外部故障条件已经消失比如温度降回了安全范围该位依然保持为1。这确保了软件不会错过任何瞬态故障对于诊断间歇性问题至关重要。写1清零Write-1-to-Clear清除错误位的唯一方法是向该位写入1。注意是向你想清除的特定比特位写入1而不是向整个寄存器写入0。向寄存器写入0是无效操作。条件清除如果你尝试清除一个位时对应的硬件错误条件依然存在那么清除操作会失败该位在写入后仍保持为1。这防止了软件错误地“掩盖”正在发生的真实故障。实战操作示例 假设我们读取寄存器48hH_Error Status 1的值为0x03二进制0000 0011。这表示Bit 0 (ZN1_ERR) 和 Bit 1 (ZN2_ERR) 被置位即Zone 1和Zone 2温度超限。错误做法write_byte(0x48, 0x00)。这不会清除任何错误位。正确做法write_byte(0x48, 0x03)。向Bit 0和Bit 1写入1LM93内部逻辑会检查ZN1和ZN2的当前温度。如果温度已恢复正常在设定的高低限范围内则这两个位被清零如果温度仍然超限则位保持不变。这个机制要求软件在清除错误前必须先尝试解决根本问题如增加风扇转速或至少确认故障是瞬时的。3. 睡眠掩码Sleep Masking智能的节能与静默策略在移动设备或服务器节能状态下一些非关键的错误报警可能不需要触发以免造成不必要的系统唤醒或日志污染。LM93通过睡眠掩码机制实现了这种智能化的错误管理。3.1 睡眠状态与掩码级别LM93识别几种系统睡眠状态S1, S3, S4/S5这些状态通常由主机通过睡眠状态控制寄存器Sleep State Control Register告知芯片。对于主机错误状态寄存器中的每一个错误位数据手册的“Sleep Masking”列定义了其在各种睡眠状态下的行为S3, S4/5通常表示错误在该睡眠状态下被屏蔽不会置位。例如VRD1_ERR的掩码列为“S3, S4/5”意味着当系统进入S3或更深度的睡眠状态时即使VRD1_HOT信号有效该错误位也不会被置位从而不会触发HOST_ERR中断唤醒系统。S1*, S3*, S4/5*带星号(*)的状态表示可选屏蔽。是否屏蔽取决于另一个寄存器——睡眠状态掩码寄存器Sleep State Mask Registers的配置。这提供了更精细的控制粒度。例如ZN1_ERRZone 1温度错误的掩码列为“S3*, S4/5*”。工程师可以通过配置掩码寄存器决定在S3状态下是忽略CPU温度报警允许深度睡眠还是继续保持监控确保睡眠安全。3.2 实战配置考量与陷阱配置睡眠掩码是一个在“节能”与“安全”之间寻找平衡点的过程。场景一服务器待机S3/Suspend-to-RAM在S3状态内存供电保持其他部件大部分关闭。此时CPU温度监控ZN1_ERR, ZN2_ERR可能仍需保持因为内存仍在工作且恢复时CPU将快速启动。但风扇错误FANx_ERR和部分电压监控如显卡供电可以被屏蔽因为相关硬件已下电。这时你需要将ZN1_ERR和ZN2_ERR在睡眠状态掩码寄存器中对应的位设为0即S3状态下不屏蔽。将FAN1_ERR~FAN4_ERR以及非关键电压通道错误位的掩码设为1即S3状态下屏蔽。场景二深度关机S5/Soft Off在S5状态除了待机电源其余全部关闭。理论上所有硬件监控都可以屏蔽。但一个最佳实践是至少保留一个关键GPIO的错误监控不被屏蔽。这个GPIO可以连接机箱入侵开关Chassis Intrusion或电源故障信号。这样即使在完全关机状态下如果机箱被非法打开或电源出现严重异常LM93依然能通过这个GPIO事件置位错误位如果配置了相应GPIO为错误输入并在下次上电时由BMC或主机软件读取该锁存的状态从而记录下关机期间发生的安全事件。常见陷阱掩码覆盖不全只配置了主要错误忽略了像GPIx_ERR这样的通用错误。如果某个GPIO连接了重要传感器在睡眠时被意外触发可能导致系统被无意义的中断唤醒。状态切换时的延迟当系统从睡眠状态唤醒时软件需要及时更新LM93的睡眠状态寄存器。如果更新延迟可能导致芯片仍处于睡眠掩码模式从而错过唤醒初期发生的真实错误。PROCHOT错误掩码特别注意PH1_ERR和PH2_ERRPROCHOT超用户设定值错误的掩码列是“S3, S4/5”。这意味着在睡眠状态下即使PROCHOT被触发也不会报告此类错误。这通常是合理的因为睡眠时CPU功耗极低PROCHOT不应发生。但如果你的设计允许在低功耗状态下进行后台计算就需要重新评估此配置。4. 关键错误状态位详解与实战配置理解了框架和机制后我们深入到几个最具代表性的错误状态位看看在真实项目中如何配置和应对。4.1 温度监控错误ZNx_ERR—— 以Zone 1为例寄存器48h的Bit 0 (ZN1_ERR) 监控“Zone 1”温度。Zone 1通常连接至CPU1的内部热敏二极管Remote1/Remote1-引脚。触发逻辑当从Zone 1读取的温度值来自寄存器50h或54h高于Processor 1 High Temp Limit寄存器79h或低于Processor 1 Low Temp Limit寄存器78h时此位被置位。配置实战设定阈值这是最关键的一步。以CPU为例高温限值79h应设定在比CPU的Tjmax结温最大值低10-15°C的位置为系统响应留出缓冲。例如CPU的Tjmax为100°C那么79h可设为85°C0x55。低温限值78h在大多数应用中可设为0°C或一个极低值如0x80代表-128°C即禁用低限报警因为CPU温度过低通常不是问题。选择温度源你需要决定使用未滤波温度50h还是滤波后温度54h进行比较。这由特殊功能控制寄存器1BCh的LCFE1位控制。LCFE10使用未滤波数据响应快但可能因噪声产生误报LCFE11使用滤波数据更稳定但响应有延迟。对于CPU温度监控我通常建议开启滤波LCFE11因为CPU温度本身不会突变滤波可以避免因测量噪声导致的频繁误报警。关联风扇控制温度错误不仅用于报警还可关联到风扇增强Fan Boost功能。寄存器80h设置了Zone 1的Fan Boost温度阈值。当Zone 1温度超过此阈值时LM93会强制所有PWM输出为100%全力散热。这个阈值80h应略低于高温错误阈值79h。例如高温错误设85°CFan Boost可设80°C。这样系统会在触发严重错误报警前先尝试最大风冷进行自救。注意数据手册提到如果高温限值寄存器被设置为0x80则会屏蔽该通道的错误报告。这是一个重要的“禁用”功能。在初始化时如果你暂时不想启用某个温度通道的监控可以将其高限设为0x80而不是简单地设一个很大的值。4.2 电压监控错误ADINx_ERR—— 以12V输入为例假设AD_IN1通道用于监控12V主电源电压。其错误状态位是寄存器49h的Bit 0 (AD1_ERR)。触发逻辑当AD_IN1的电压读数寄存器56h高于AD_IN1 High Limit91h或低于AD_IN1 Low Limit90h时此位被置位。配置实战理解读数转换LM93的ADC读数是比例值。数据手册指出“Voltages are presented at ¾ full scale for the nominal voltage. Therefore, at nominal voltage, each register reads C0h.” 这意味着对于标称电压寄存器读数为0xC0十进制192。ADC是8位满量程255。所以实际电压值 (寄存器读数 / 192) * 标称电压。对于12V标称电压正常读数应为0xC0。如果读数为0xF0240则计算电压 (240/192) * 12V 1.25 * 12V 15V。设定合理限值ATX电源规范要求12V的波动范围通常在±5%到±10%。我们按±10%的容差来设定。高限值91h12V * 1.10 13.2V。换算成寄存器值(13.2V / 12V) * 192 1.1 * 192 211.2取整为2110xD3。低限值90h12V * 0.90 10.8V。换算(10.8V / 12V) * 192 0.9 * 192 172.8取整为1730xAD。配置迟滞Hysteresis这是防止电压在阈值附近波动时错误位频繁跳变的關鍵。通过寄存器BCh的VH[2:0]位电压迟滞控制可以设置一个迟滞窗口。例如设置VH3表示迟滞为3个ADC计数。对于12V通道一个ADC计数代表的电压变化是 12V / 192 ≈ 0.0625V。3个计数就是约0.1875V。触发过程电压从正常下降到10.8V低限173时AD1_ERR置位。恢复过程电压必须回升到 10.8V 0.1875V 10.9875V 以上并且软件执行清除操作后错误状态才会真正消失如果自动比较则需超过此值才不算错误。这避免了电压在10.8V上下轻微抖动导致的警报风暴。4.3 风扇转速错误FANx_ERR—— 智能策略避免误报寄存器4Fh的Bit 0 (FAN1_ERR) 监控风扇1的转速。触发逻辑当风扇转速计数值寄存器6Eh/6Fh高于设定的风扇转速限制值寄存器B4h/B5h时此位置位。注意这里是“高于”限制值表示错误因为转速计数值与转速成反比转速越低计数周期越长计数值越大。配置实战与重大陷阱理解转速计算与限制值设定风扇转速RPM (1350000 * 2) / (COUNT * P)其中P是风扇每转的脉冲数通常为2COUNT是14位的转速计数值来自B4h/B5h。因此限制值TLIMIT设定的是一个计数值上限对应的是最低允许转速RPM下限。假设你希望风扇1的转速不能低于2000 RPM风扇脉冲数P2。计算COUNT限值COUNT (1350000 * 2) / (2000 * 2) 1350000 / 2000 675。将6750x2A3写入风扇转速限制寄存器B4h低字节0xA3和B5h高字节0x02。避免误报的核心技巧数据手册中有一句非常关键但容易被忽略的话“Errors are never generated for a fan if its limit is set to 3FFFh.”将限制值设为0x3FFF最大值可以禁用该风扇的转速错误监控。在以下情况必须使用此技巧风扇停转支持许多主板支持在低负载时完全关闭风扇PWM0%。如果风扇被软件关闭其转速计数值会读回0x3FFF表示停转或信号无效。此时如果你设置了正常的转速下限如675那么一旦风扇关闭FANx_ERR会立即置位产生误报。正确的做法是在通过PWM控制关闭某个风扇前先将其对应的风扇转速限制寄存器如B4h/B5h设置为0x3FFF以屏蔽错误当需要重新开启风扇时再将其恢复为正常的限制值。风扇不存在或未连接如果某个风扇接口未使用也应将其限制值设为0x3FFF。Smart Tach模式寄存器BDh的STEx位可以启用智能转速计模式。此模式下LM93会进行更复杂的信号处理可能有助于滤除某些类型的噪声但在普通4线PWM风扇应用中通常保持禁用0即可。4.4 PROCHOT错误PHx_ERR—— 监控处理器热节流这是监控CPU健康状况的高级功能。以处理器1为例其错误状态在寄存器4Ch。触发逻辑Bit 0-6 (T0-TMAX)这些位报告PROCHOT信号在过去一个监控周期内的活动占比分为几个等级0%, ≥12.5%, ≥25%, ≥50%, ≥75%, 100%。它们用于衡量热节流的严重程度但不会触发HOST_ERR主错误。Bit 7 (PH1_ERR)这是关键的错误位。当Current P1_PROCHOT寄存器67h的值超过用户在P1_PROCHOT User Limit寄存器B0h中设定的阈值时此位置位并且会触发HOST_ERR。配置实战理解PROCHOT监控周期寄存器67h的值代表上一个“PROCHOT监控间隔”内的活动百分比。这个间隔由PROCHOT时间间隔寄存器配置通常可设为几秒到几十秒。它反映了该时间段内CPU因过热而被强制降频的时间比例。设定用户限制值B0h这是你定义的“可接受”的热节流程度。例如你可以认为PROCHOT活动率偶尔低于5%是正常的可能是瞬时高负载但持续高于5%就需要报警。阈值计算百分比 (寄存器值 / 256) * 100%。要设置5%的阈值寄存器值 5% * 256 / 100% 12.8取整为13 (0x0D)。将0x0D写入B0h寄存器。行动策略当PH1_ERR置位时表明CPU在过去一个监控周期内有超过5%的时间处于热节流状态。系统软件应将其视为一个严重预警并采取行动如记录详细日志包括当前温度、PROCHOT活动率历史。尝试提升所有系统风扇到更高转速档位。如果可能通过ACPI或其他接口通知操作系统降低负载。如果持续发生可能需要触发更高级别的管理警报如发送SNMP Trap或点亮前面板警示灯。5. 软件交互流程与最佳实践理解了硬件寄存器后构建稳定可靠的监控软件同样重要。以下是一个典型的主机端或BMC监控服务与LM93错误状态寄存器交互的流程和最佳实践。5.1 初始化配置流程系统上电或复位后在开始监控前必须对LM93进行正确的初始化配置。禁用全局中断可选但推荐在配置过程中暂时屏蔽LM93的中断输出防止未配置完成时的误触发。这可以通过配置相关控制寄存器实现。配置各通道上下限根据硬件设计依次配置所有温度、电压、风扇转速的上下限寄存器78h~AFh, B4h~BBh。对于未使用的通道务必将其高限寄存器设置为0xFF电压或0x80温度或将风扇转速限值设为0x3FFF以屏蔽错误报告。配置迟滞与滤波根据系统噪声情况设置寄存器BCh中的电压迟滞(VH)和温度滤波使能位(LCFE1,LCFE2,FCFE1,FCFE2)。配置睡眠掩码根据产品定义的睡眠策略配置睡眠状态掩码寄存器决定在S1/S3/S4-S5状态下哪些错误需要被屏蔽。清除所有残留错误状态向所有主机错误状态寄存器48h-4Fh写入0xFF以清除可能在上电过程中因电压不稳而产生的残留错误位。使能全局中断与启动监控完成配置后使能LM93的中断输出并开始周期性的状态轮询。5.2 错误处理与状态轮询循环监控软件应运行在一个独立的、高优先级的线程或任务中。中断响应将LM93的ALERT#引脚连接到主机或BMC的中断输入。当任何错误置位导致HOST_ERR有效时触发硬件中断。中断服务程序ISR应快速读取状态控制寄存器确认HOST_ERR然后立即读取主机错误状态寄存器组48h-4Fh以确定具体错误源。ISR内只做标记和记录复杂处理交给主循环。轮询策略即使没有中断也应建立周期性的轮询例如每秒一次。轮询时顺序读取48h-4Fh寄存器。比较高效的做法是先读取一个“影子寄存器组”软件中维护的副本然后与当前读取值进行比较。只有发生变化的位才需要进一步处理。错误处理逻辑新错误产生根据错误位查询对应的当前值寄存器如温度值50h、电压值56h、风扇转速6Eh等获取错误发生时的快照。将错误类型、时间戳、相关数值记录到非易失性日志如BMC的SEL中。然后根据预定义的策略采取行动如提升风扇转速、记录事件、发送警报。错误恢复当检测到某个错误位从1变为0通常是在软件尝试清除后表明对应的故障条件已消失。应记录一个“恢复”日志条目。清除错误状态在确认已记录错误并采取初步措施后软件应尝试清除错误位。必须遵循“写1清零”原则。向对应寄存器写入当前读取到的错误位图即哪些位是1就向哪些位写1。清除后稍作延迟如10ms再次读取该寄存器确认位已被清除。如果清除失败说明硬件故障仍然存在应升级警报级别。5.3 调试与诊断技巧强制触发测试在研发阶段需要测试整个监控链路的正确性。可以通过软件临时调低某个电压的高限值使其低于当前读数来模拟电压过高错误。观察ADINx_ERR是否置位、HOST_ERR是否有效、中断是否触发、软件日志是否正确记录。测试完成后务必恢复正确的限值。理解“粘滞”错误如果某个错误位无法清除首先用万用表或示波器检查对应的硬件信号如温度传感器电压、风扇转速信号确认故障是否真实存在。其次检查对应的上下限寄存器配置是否合理例如是否不小心将高限设得过低。利用PROCHOT历史位T0~TMAX位提供了PROCHOT活动的历史分级信息。在诊断散热问题时不仅要看PHx_ERR还应检查这些位。如果T50或T75频繁置位即使PHx_ERR未触发用户限值设得较高也表明系统存在潜在的散热瓶颈。GPIO错误的多用途GPIx_ERR非常灵活。除了连接标准的故障信号如电源模块的PG_FAIL还可以连接自定义的传感器或逻辑电路。例如可以连接一个水冷系统的漏液检测传感器当检测到漏液时拉低GPIO从而触发一个高优先级的硬件错误警报。6. 常见问题排查与实战陷阱实录在实际项目中与LM93主机错误状态寄存器打交道总会遇到一些“坑”。这里记录几个典型问题和我的解决思路。问题一风扇明明转得很好但FANx_ERR频繁误报。排查首先读取风扇转速值寄存器如6Eh/6Fh将其转换为RPM确认是否真的低于设定下限。检查风扇转速限制寄存器如B4h/B5h的值确认计算和写入是否正确。最关键的一步检查风扇控制模式。如果你使用的是PWM线性控制并且PWM占空比设置得较低例如低于30%某些风扇在低电压/低占空比下启动特性不佳可能转速不稳定或无法达到标称的最低转速。此时即使风扇在“转”其转速也可能低于你设定的软件下限。用示波器查看风扇的TACH引脚输出波形确认脉冲是否干净有无噪声或畸变。解决调整下限根据风扇规格书中的“最低启动占空比”和“最低运行转速”重新计算并设置一个更合理的、更低的转速限制值。启用风扇软启动有些BIOS/BMC固件有风扇软启动功能在启动时以高占空比驱动风扇片刻确保其顺利启动再降至目标转速。检查布线风扇TACH信号线是否过长是否靠近噪声源如开关电源必要时增加上拉电阻或滤波电容。问题二系统进入S3睡眠后无法被某些硬件事件唤醒。排查确认唤醒事件是否配置为通过LM93的ALERT#中断触发。检查与该事件相关的错误位例如用于唤醒的机箱入侵GPIO对应的GPIx_ERR的睡眠掩码配置。如果该错误位在S3状态下被屏蔽了Sleep Masking列包含S3且睡眠状态掩码寄存器对应位为1那么即使事件发生错误位也不会置位自然无法触发HOST_ERR和中断。确认系统进入S3时主机是否正确写入了S3状态到LM93的睡眠状态控制寄存器。解决重新审查睡眠掩码策略。对于希望用于唤醒系统的错误源如电源按钮、机箱入侵、网络唤醒等确保其在目标睡眠状态S3下的错误位不被屏蔽。在系统进入睡眠状态的ACPI代码路径中加入对LM93睡眠状态寄存器写入操作的确认和日志。问题三电压监控误差大在阈值附近频繁报警/恢复。排查使用高精度数字万用表测量被监控点的实际电压与LM93读取的ADC值通过公式换算进行对比确认是否存在固定的偏移误差。检查PCB布局ADC输入走线是否远离数字噪声源是否添加了足够的滤波电容通常是一个0.1uF的陶瓷电容靠近LM93引脚。检查VH电压迟滞寄存器的配置。如果设为0则没有任何迟滞电压在阈值上的任何微小抖动都会导致错误位反复跳变。解决如果存在固定偏移可以在软件端进行校准即在计算电压的公式中加入一个修正系数。确保硬件滤波电路设计合理。合理设置迟滞值。根据电源的纹波和噪声水平设置一个合适的VH值。例如对于12V输入如果噪声峰峰值约为100mV那么可以设置迟滞为2-3个ADC计数约125-187mV这样可以有效滤除噪声引起的误触发。问题四清除错误状态位写1后该位立刻又被置起。排查这是最典型的“故障持续存在”现象。首先读取对应的当前值寄存器温度、电压、转速等确认当前值是否仍然超出你设定的上下限。检查上下限寄存器本身的值是否在软件的其他地方被意外修改了。对于电压通道特别注意迟滞的影响。假设电压低限设为1.0V迟滞VH3对应约0.05V。当电压跌至0.99V触发错误后电压需要恢复到1.0V 0.05V 1.05V以上错误条件才被认为“消失”此时写1清除才能成功。如果电压只恢复到1.02V清除操作会失败。解决首要任务是解决硬件层面的根本故障。如果故障是瞬态的且已恢复但错误位因迟滞无法清除可以临时调宽限值例如将低限调低一些然后执行清除操作操作成功后再将限值恢复。数据手册的应用笔记也提到了这种方法。