深入解析UART/IrDA/CIR多模通信模块:从原理到嵌入式实战
1. 项目概述从“串口”到“多面手”的通信核心在嵌入式开发的世界里串口通信UART就像一位沉默寡言但绝对可靠的老朋友。无论是调试信息输出、传感器数据读取还是两个微控制器之间的简单对话都离不开它。但如果你认为UART仅仅是那个9600波特率、8-N-1格式的简单接口那就太小看它了。今天我们就以德州仪器TI一款高度集成的UART/IrDA/CIR模块为蓝本深入拆解这个看似基础实则内藏乾坤的通信核心。这个模块将传统的异步串行通信、红外数据协会IrDA标准以及消费电子红外CIR遥控功能巧妙地集成在同一个硬件框架内通过寄存器配置实现模式切换堪称嵌入式系统中的“通信瑞士军刀”。它的核心价值在于“一体多用”与“高效管理”。在资源受限的嵌入式环境中用一个硬件模块覆盖三种主流通信需求有线串行、红外数据、红外遥控极大地节省了芯片面积和功耗。更重要的是其内置的64字节FIFO先入先出缓冲区和精心设计的中断/DMA机制将CPU从繁琐的字节级轮询中解放出来允许系统以更高的效率处理突发数据流。无论是工业现场需要稳定传输的传感器网络还是消费电子中要求快速响应的遥控器亦或是医疗设备中可靠的生命体征数据上传这个模块都能提供坚实的硬件基础。接下来我将带你从功能特性、工作原理到实际嵌入式应用中的配置要点和避坑指南进行一次彻底的剖析。2. 模块核心功能与模式解析2.1 三位一体的工作模式这个UART/IrDA/CIR模块的核心魅力在于其多模操作能力。它不是三个独立硬件的简单拼凑而是通过一套可配置的硬件逻辑复用数据通路和状态机实现了三种截然不同的通信协议。2.1.1 UART模式经典的异步串行通信这是模块的“本职工作”。它完全兼容16C750标准这意味着为传统16550或16C750 UART编写的驱动程序经过少量适配即可在此运行。其功能全面得超乎想象宽范围波特率支持从300 bps到3.6864 Mbps的速率覆盖了从古老调制解调器到高速蓝牙模块转换的几乎所有场景。自动波特率检测这是一个极为实用的功能尤其在需要与未知设备通信的场合如某些Bootloader。模块能在1200 bps到115.2 Kbps范围内自动检测对方速率无需软件反复尝试。灵活的帧格式数据位5-8位、校验位奇、偶、标志、空格、无和停止位1, 1.5, 2位均可编程提供了与各种老式或特殊设备对接的可能性。硬件流控制通过RTS请求发送和CTS清除发送信号线实现了基于硬件的流量控制能有效防止接收端FIFO溢出导致的数据丢失。它还支持更复杂的自动RTS/CTS以及软件流控制XON/XOFF字符。调制解调器控制虽然并非所有UART实例都引出全部引脚但模块内部支持完整的调制解调器信号CTS, RTS, DSR, DTR, RI, DCD为通过电话线等媒介进行远程通信提供了可能。2.1.2 IrDA模式标准化的红外数据通信IrDA模式将UART的电气信号转换为红外光脉冲。它并非简单的电平转换而是实现了完整的IrDA物理层协议支持多种速率涵盖SIR慢速红外最高115.2kbps、MIR中速红外0.576Mbps和1.152Mbps和FIR快速红外4Mbps。注意VFIR16Mbps不被支持。专用帧处理与UART的字节流不同IrDA以帧为单位。模块硬件会自动添加帧起始序列xBOF可变数量的起始标志和帧结束符EOF并负责CRC校验的生成与验证。这大大减轻了CPU的负担。错误检测硬件可检测帧错误、CRC错误、非法符号FIR模式下和中止模式SIR/MIR并将错误信息写入专用的8条目状态FIFO供软件查询。2.1.3 CIR模式消费电子红外遥控这是为电视、空调遥控器等应用量身定做的模式。其设计思路与UART/IrDA有显著不同自由数据格式不强制规定具体的编码协议如NEC、RC-5而是提供了一个灵活的“载波调制”引擎。开发者可以配置载波频率通常为38kHz、40kHz等和占空比1/2, 5/12, 1/3, 1/4从而生成或解析几乎任何私有红外协议的数字波形。核心工作是调制与解调发送时模块将TX FIFO中的数据位0或1调制成指定频率和占空比的脉冲串输出。接收时则从被调制的红外信号中解调出数据位放入RX FIFO。协议的具体逻辑如引导码、地址码、命令码、重复码完全由软件处理硬件提供了最基础的“搬运工”功能。模式选择实操要点模式切换通过配置MDR1寄存器的MODE_SELECT位域实现。关键点在于切换模式后部分引脚功能会随之改变见下表。例如在UART模式下UARTx_RTSn引脚是请求发送信号在IrDA/CIR模式下它变成了SDShutdown关闭信号用于控制外部红外收发器的电源。如果在设计电路或初始化代码时忽略了这一点可能导致信号错乱通信失败。表UART引脚功能复用对照表模式TXD/IRTX/RCTX 引脚RXD/IRRX/RCRX 引脚RTSn/SD 引脚CTS 引脚UARTTXD (发送数据)RXD (接收数据)RTSn (请求发送)CTS (清除发送)IrDAIRTX (红外发送)IRRX (红外接收)SD (关闭控制)未使用CIRRCTX (遥控载波发送)RCRX (遥控载波接收)SD (关闭控制)未使用2.2 模块集成与时钟架构该模块在芯片内部通过L4低速外设互连总线与系统核心如MPU子系统、PRU-ICSS连接。它具备独立的DMA请求线TX和RX各一条和中断线可直接与EDMA控制器和中断控制器协作实现高效数据搬运。时钟管理是稳定通信的基石。模块使用两套时钟功能时钟FCLK通常为48MHz是模块内部逻辑如波特率发生器、状态机工作的主时钟。所有通信时序都源于此时钟的分频。接口时钟ICLK用于寄存器访问的总线时钟频率可能不同如UART0为26MHzUART1-5为100MHz。这两套时钟由电源、复位和时钟管理PRCM模块提供和控制。波特率生成的秘密UART的波特率由功能时钟分频得到。计算公式本质是波特率 FCLK / (16 * 分频因子)。模块的DLL除数锁存器低字节和DLH除数锁存器高字节寄存器共同组成这个16位的分频因子。例如当FCLK48MHz目标波特率为115200时理论分频因子 48,000,000 / (16 * 115200) ≈ 26.04。取整为26后实际波特率为 48,000,000 / (16 * 26) ≈ 115384.6误差约为0.16%在异步通信可接受的范围内。模块的预置波特率表如文档中Table 21-6就是根据这个计算预先列出的常用值及其误差。时钟配置避坑指南使能顺序务必先确保PRCM模块为UART提供了正确的功能时钟和接口时钟然后再去操作UART的寄存器进行配置。否则对寄存器的写入可能无效或导致不可预知的行为。睡眠模式下的禁忌当UART进入睡眠模式为省电停止内部时钟时绝对禁止写入DLL和DLH寄存器来修改波特率。必须在退出睡眠模式后再进行修改。一个稳妥的做法是在进入睡眠前通过IER寄存器禁用睡眠模式修改波特率再重新使能睡眠。IrDA/CIR的时钟分频IrDA和CIR模式对时钟分频有特殊要求。例如IrDA SIR模式采用3/16编码即一个数据位用3/16个载波周期表示其分频计算需额外考虑这个编码因子。务必参考文档中的IrDA波特率表Table 21-7来设置正确的分频器值。3. FIFO管理与数据流优化实战3.1 FIFO机制深度解读64字节的TX/RX FIFO是这个模块提升性能的关键。你可以把它想象成邮局柜台和邮筒。没有FIFO时CPU就像邮局职员必须亲自处理每一封信字节的收寄读写效率低下。有了FIFOCPU可以一次性把一堆要寄的信数据扔进邮筒TX FIFO然后就去忙别的或者等邮筒里积累了一定数量的来信RX FIFO数据后一次性取走处理。这极大地减少了CPU的中断开销。3.1.1 触发级别的艺术FIFO不会每收到一个字节就打扰CPU一次。它通过“触发级别”来决定何时发出中断或DMA请求。这个触发级别是可编程的且针对TX和RX独立设置。RX FIFO触发当接收FIFO中的数据量达到或超过预设的触发级别时模块会产生接收中断或DMA请求通知CPU/EDMA来批量取走数据。例如设置触发级别为16字节那么模块会在收到第16个字节时才产生一次中断CPU一次可以读取最多16字节而不是中断16次。TX FIFO触发当发送FIFO中的空闲空间达到或超过预设的触发级别时模块会产生发送中断或DMA请求通知CPU/EDMA可以继续填充数据。例如设置触发级别为8字节空间当FIFO因数据发出而空出8字节位置时产生中断CPU可以一次性写入最多8字节。触发级别的设置寄存器有些复杂主要涉及FCR、TLR和SCR寄存器基础设置FCR[7:6]和FCR[5:4]分别用于设置RX和TX的触发级别但选项有限如RX只有8, 16, 56, 60四档。精细控制为了获得更灵活的触发值如4字节步进或1字节步进需要使用TLR寄存器并结合SCR[6]和SCR[7]位。具体组合逻辑文档中已有详细表格编程时需要仔细对照。3.1.2 三种工作模式抉择根据应用场景和数据流特性可以选择不同的FIFO工作模式中断模式最常用的模式。使能FIFOFCR[0]1并开启相应中断通过IER寄存器。当FIFO达到触发级别时硬件自动产生中断CPU在中断服务程序中进行批量数据读写。这是平衡性能和CPU占用率的首选。轮询模式禁用FIFOFCR[0]0并关闭中断。CPU需要不断读取线路状态寄存器LSR来检查“接收数据就绪”DR或“发送保持寄存器空”THRE位。这种方式CPU负担最重只适用于对实时性要求极高、数据量极小的场景或者简单的调试输出。DMA模式高性能模式的代表。模块直接与EDMA控制器配合在FIFO触发时发起DMA请求由DMA引擎在内存和FIFO之间搬运数据完全不需要CPU介入。这对于高速、大数据量的连续传输如文件传输、图像数据流至关重要。3.2 DMA模式配置详解与陷阱模块支持DMA模式0和模式1文档指出模式2和3不支持。模式0通常意味着DMA功能被禁用或处于一种简单状态。我们主要关注模式1。3.2.1 发送DMA的“水位线”逻辑发送DMA的请求逻辑是“低水位线”触发。假设TX FIFO总深度为64字节。你通过TLR寄存器设置一个触发空间数比如TX_Trigger_Spaces 8。模块内部计算一个阈值TX_DMA_Threshold 64 - TX_Trigger_Spaces 56。当TX FIFO中的数据量被发送出去使得剩余数据量低于这个阈值56字节时换言之FIFO中的空闲空间达到或超过触发空间数8字节时TX DMA请求线被拉高。EDMA控制器响应请求开始向FIFO写入数据。它应该被编程为一次传输TX_Trigger_Spaces8字节。当写入8字节后FIFO数据量增加空闲空间减少如果空闲空间又小于8字节DMA请求线被拉低直到数据再次被发送到空闲空间8字节。这种机制确保了DMA以“块”的方式高效填充FIFO避免了频繁的单个字节DMA请求。3.2.2 接收DMA的“高水位线”逻辑接收DMA的请求逻辑是“高水位线”触发。你通过TLR寄存器设置一个触发数据量比如RX_Trigger_Level 16。当RX FIFO中累积的数据量达到或超过这个触发级别16字节时RX DMA请求线被拉高。EDMA控制器响应请求从FIFO中读取数据。它同样应该被编程为一次传输RX_Trigger_Level16字节。读取16字节后FIFO数据量下降如果低于触发级别DMA请求线被拉低直到新数据到来使其再次达到触发级别。3.2.3 DMA配置的致命陷阱阈值与DMA传输量不匹配这是最常见的问题。如果你在UART模块设置TX触发空间为8但在EDMA控制器里却配置每次传输16字节会发生什么第一次DMA触发EDMA试图写入16字节但FIFO只有8字节空闲空间会导致数据丢失或DMA错误。必须保证EDMA传输数量 UART FIFO触发级别。流控制下的阈值冲突当使能硬件流控制RTS/CTS时存在两个阈值一个是用于产生中断/DMA的FIFO触发阈值RX_FIFO_TRIG另一个是用于控制对方停止发送的流控制阈值RX_FIFO_TRIG_HALT。文档明确警告必须保证RX_FIFO_TRIG_HALT RX_FIFO_TRIG。如果流控制阈值更小假设FIFO触发设为16流控制阈值设为8。当FIFO收到8字节时RTS信号就可能变高假设低有效让对方停止发送。但此时FIFO未达到16字节的DMA触发点DMA不会启动搬运而对方已停止发送FIFO中的数据量永远达不到16字节系统就会“饿死”在这个状态。DMA模式与寄存器配置的耦合DMA模式的使能涉及FCR[3]和SCR[0]、SCR[2:1]等多个位。它们的组合决定了最终生效的模式。编程时务必遵循文档中的真值表例如想用DMA模式1要么设置SCR[0]0且FCR[3]1要么设置SCR[0]1且SCR[2:1]01。混乱的配置会导致DMA无法正常工作。4. 中断系统与电源管理精讲4.1 多层次中断优先级与处理模块的中断系统设计得非常精细特别是在UART模式下它将7种中断事件划分为6个优先级确保重要事件得到优先响应。4.1.1 UART模式中断优先级详解中断标识寄存器IIR的[5:1]位指明了当前最高优先级的中断类型[0]位IT_PENDING表示是否有中断挂起。最高优先级1级- 接收线路状态错误包括溢出错OE、帧错FE、奇偶校验错PE和线路中断BI。这些错误直接影响数据的完整性需要最高优先级处理。清除方法对于FE/PE/BI读取RHR寄存器对于OE读取LSR寄存器。第二优先级2级- 接收超时或数据就绪当RX FIFO中有数据但未达到触发级别且一段时间没有新数据到来时会产生接收超时中断防止数据“滞留”在FIFO中。如果FIFO被禁用则每个字节接收完成都会产生数据就绪DRDY断。清除方法读取RHR寄存器直到中断条件消失。第三优先级3级- 发送保持寄存器空当TX FIFO为空或低于触发级别时产生通知CPU可以发送新数据。清除方法向THR寄存器写入数据直到中断条件消失。第四优先级4级- 调制解调器状态变化CTS、RTS、DSR、DTR、RI、DCD等信号状态发生变化。清除方法读取MSR寄存器。第五优先级5级- XOFF/特殊字符中断在软件流控制启用时接收到XOFF字符或接收到编程设定的特殊字符如帧分隔符时触发。第六优先级6级- CTS/RTS/DSR引脚变化仅当这些引脚从有效低电平变为无效高电平时触发。这是一个边沿触发的中断。4.1.2 IrDA与CIR模式中断IrDA模式有8种中断但没有优先级任何中断产生都会拉高中断线。需要软件读取IIR来判别具体是哪个事件如“状态FIFO中断”、“发送完成”、“接收到EOF”等。CIR模式则只使用了其中的一个子集主要是RHR、THR、接收停止、接收溢出和发送状态中断。中断处理编程心得查询与清除进入中断服务程序后应在一个循环中读取IIR寄存器直到其IT_PENDING位变为1表示无更高优先级中断挂起。根据IIR[5:1]的值判断中断源并执行相应的清除操作。很多初学者的问题在于只处理了事件但没按规范清除中断标志导致中断持续触发系统卡死。FIFO与中断的配合在使能FIFO的中断模式下RHR中断和THR中断的触发条件与FIFO的触发级别紧密相关。务必理解“达到触发级别”才中断的逻辑而不是“非空即中断”。唤醒中断的特殊性这是一个独立于上述优先级系统的中断。通过设置SCR[4]使能后当模块从睡眠模式被唤醒如检测到RX引脚有活动时不会改变IIR而是将SSR[1]位置1。处理完唤醒事件后必须先清除SCR[4]位再重新置位才能捕获下一次唤醒事件。这是一个容易遗漏的步骤。4.2 低功耗电源管理策略在电池供电的嵌入式设备中UART模块的功耗管理至关重要。4.2.1 模块级睡眠模式UART模式通过设置IER[4]且EFR[4]1使能睡眠模式。当RX线空闲、TX FIFO和移位寄存器空、RX FIFO空、且只有THR中断挂起时模块进入睡眠内部功能时钟和波特率时钟停止功耗大幅降低。任何RX引脚活动、写入TX FIFO或调制解调器引脚状态变化都会唤醒它。IrDA/CIR模式通过设置MDR1[3]使能睡眠模式进入和唤醒条件与UART模式类似。4.2.2 系统级智能空闲Smart Idle这是更高级的省电机制。模块通过SYSC[4:3]配置为空闲模式并与PRCM模块进行“空闲请求-空闲确认”握手。当CPU判断UART暂时无事可做时可以请求模块进入智能空闲状态。模块完成当前操作后会确认进入空闲PRCM可以关闭其时钟域。当有预定的事件如RX引脚检测到起始位发生时模块会向系统发出唤醒请求时钟恢复模块继续工作。这些可唤醒事件在WER寄存器中配置。4.2.3 自动时钟门控通过设置SYSC[0]AUTOIDLE模块可以在检测到接口寄存器访问或内部无活动时自动门控其时钟实现动态功耗节省。低功耗设计警告睡眠模式与波特率修改互斥绝对不要在睡眠模式下修改DLL和DLH寄存器来改变波特率。因为此时功能时钟可能已停止写操作会导致不可预知的结果。安全的做法是先禁用睡眠模式IER[4]0修改波特率再重新使能睡眠。智能空闲的配置依赖要使能智能空闲和唤醒功能除了配置UART本身的SYSC和WER寄存器还必须正确配置PRCM模块中对该UART实例的时钟和电源域设置。这是一个系统级工程需要查阅芯片的PRCM章节。IrDA模式下的唤醒缺陷文档的“警告”部分明确指出在IrDA模式下唤醒接口的实现基于SIDLEACK信号的跳变而非电平状态。当配置在智能空闲模式时这可能导致系统被短暂唤醒无法达到预期的深度省电效果。在追求极致低功耗的IrDA应用中需要评估这个影响或许需要考虑采用轮询或外部中断来替代模块内部的唤醒机制。5. 嵌入式应用实战从配置到调试5.1 初始化流程与寄存器配置序列编写一个健壮的UART/IrDA/CIR驱动初始化的顺序至关重要。以下是一个通用的初始化步骤框架以UART模式为例模块使能与软复位// 1. 确保PRCM已为UART提供时钟此部分依赖具体SoC的PRCM驱动 // 2. 访问UART模块基地址进行软复位 UART_REG-SYSC | (1 1); // 设置SOFTRESET位 while(!(UART_REG-SYSS 0x1)); // 等待复位完成SYSS[0] RESETDONE软复位会将大部分寄存器恢复为默认值是一个好的起点。模式选择与FIFO配置// 3. 选择UART模式 (假设MDR1寄存器地址偏移为0x20) UART_REG-MDR1 0x0; // MODESELECT 0, UART模式 // 4. 禁用FIFO和中断进行关键寄存器配置 UART_REG-FCR 0x0; // 禁用FIFO UART_REG-IER 0x0; // 禁用所有中断 // 5. 设置波特率 (以115200为例假设FCLK48MHz) // 除数 48,000,000 / (16 * 115200) 26.0416 ≈ 26 UART_REG-LCR | (1 7); // 设置DLAB位为1以访问DLL/DLH UART_REG-DLL 26; // 写入分频因子低字节 UART_REG-DLH 0; // 写入分频因子高字节 UART_REG-LCR ~(1 7); // 清除DLAB位线路控制与FIFO精细设置// 6. 设置数据格式8位数据无校验1位停止位 UART_REG-LCR 0x03; // 8位数据1位停止位无校验 // 7. 如果需要使能并配置FIFO UART_REG-FCR 0xC1; // 使能FIFO (BIT0)TX FIFO复位(BIT2)RX FIFO复位(BIT1) // 8. 通过TLR设置自定义触发级别例如RX触发为16字节TX触发为8字节空间 // 假设使用TLR的4字节步进模式RX16字节(0x4) TX8字节空间(0x2) UART_REG-TLR (0x4 4) | (0x2); // TLR[7:4] for RX, TLR[3:0] for TX UART_REG-SCR | (1 7); // SCR[7]1, 使用TLR的RX触发值 UART_REG-SCR | (1 6); // SCR[6]1, 使用TLR的TX触发值 // 注意需根据SCR[6:7]和TLR的组合逻辑仔细计算此处仅为示例。中断与DMA配置// 9. 如果使用中断使能所需中断 UART_REG-IER 0x07; // 使能RHR中断(BIT0) THR中断(BIT1) 接收线路状态中断(BIT2) // 10. 如果使用DMA配置DMA模式 UART_REG-FCR | (1 3); // FCR[3]1, 使能DMA模式 (假设为模式1且SCR[0]0) // 11. 在系统级配置EDMA控制器使其传输长度与UART的FIFO触发级别匹配。5.2 典型问题排查实录在实际开发中你会遇到各种奇怪的问题。下面是我踩过的一些坑和解决方法问题1通信完全无反应发送和接收都失败。检查顺序时钟与电源首先确认PRCM是否正确配置UART模块的时钟和电源域是否已经打开。用示波器测量功能时钟引脚如果有或通过寄存器读取时钟状态。引脚复用这是最容易被忽略的一点芯片的引脚通常复用多种功能。你必须检查PinMux引脚复用控制器确保你使用的UARTx_TXD和UARTx_RXD引脚已经正确配置为UART功能而不是GPIO或其他外设功能。波特率双方设备波特率是否一致计算分频因子时是否考虑了时钟源的实际频率可能是分频后的用示波器测量TXD引脚测量一个位的时间例如115200波特率下一位约为8.68us验证实际波特率。软复位状态确保软复位已完成检查SYSS寄存器且没有在复位过程中或复位后立即进行配置。问题2能发送数据但接收不到或接收数据乱码。排查思路电气连接与电平检查TX和RX是否交叉连接本机TX接对端RX。确认双方的电平标准一致如都是3.3V TTL电平。如果电平不匹配需要电平转换芯片。帧格式确保数据位、停止位、校验位设置与对端设备完全一致。一个常见的错误是一端8-N-1另一端7-E-1。FIFO与中断/DMA如果使能了FIFO和中断检查触发级别是否设置合理。如果触发级别设得过高如60而对方只发送几个字节则永远不会触发接收中断数据“沉默”在FIFO里。可以通过查询LSR寄存器的DR位或直接读取RHR来验证是否有数据。流控制如果使能了硬件流控RTS/CTS检查这两根线是否连接正确且信号有效。如果CTS始终为无效状态例如默认上拉后为高而低电平有效发送端会一直等待无法发送。问题3高速通信时出现数据丢失。解决方案启用FIFO并增大触发级别这是最基本的方法。将RX FIFO触发级别提高让CPU/EDMA一次处理更多数据减少中断上下文切换的开销。使用DMA对于持续的高速数据流中断模式可能无法跟上。切换到DMA模式并确保EDMA的传输带宽足够。关键点计算最大可持续波特率下的字节速率确保EDMA的响应和搬运速度高于此速率。优化中断服务程序如果必须用中断确保ISR尽可能短小精悍。只做最必要的操作如从FIFO搬数据到内存缓冲区标志位的处理和业务逻辑放到主循环或任务中。检查缓冲区溢出读取LSR寄存器的OE溢出错误位。如果置位说明RX FIFO已满但仍有新数据到来导致数据丢失。此时需要提高CPU处理速度或降低波特率。问题4从UART模式切换到IrDA模式后红外通信不正常。排查要点引脚模式切换确认MDR1寄存器已正确设置为IrDA模式。更重要的是检查PinMux配置确保IRTX和IRRX引脚功能被激活并且SD引脚被正确配置为输出以控制外部红外收发器的使能。外部收发器IrDA需要外部红外发光二极管和接收管。检查电路连接是否正确供电是否正常。可以用手机摄像头大部分对红外光敏感粗略检查发射管是否在闪烁。IrDA编码确认SIR/MIR/FIR模式选择正确且波特率设置符合该模式下的分频表Table 21-7。SIR模式使用的是3/16编码其脉冲宽度与UART的位时间不同。帧结构IrDA是帧传输确保你的软件协议正确处理了硬件自动添加的BOF和EOF并正确解析了状态FIFO中的错误信息。通过以上从理论到实践从功能到调试的全面解析相信你已经对这款高度集成的UART/IrDA/CIR模块有了深刻的理解。它的强大之处在于将灵活性多模式、高效性FIFO/DMA和可靠性错误检测、流控制融为一体。在实际项目中仔细阅读芯片勘误表严格遵循初始化序列善用其丰富的状态寄存器进行调试你就能让这个“通信多面手”在各种嵌入式场景中稳定可靠地工作。