F2837xD内存保护与ECC机制:嵌入式系统可靠性的硬件基石

发布时间:2026/7/22 17:56:47
F2837xD内存保护与ECC机制:嵌入式系统可靠性的硬件基石 1. 项目概述为什么我们需要深入理解F2837xD的内存保护与ECC在工业电机驱动、新能源汽车电控或者高精度数字电源这类对实时性和可靠性要求近乎苛刻的嵌入式应用里系统崩溃的代价是巨大的。你可能遇到过一些“玄学”问题程序偶尔跑飞、某个变量的值莫名其妙被篡改、或者双核通信时数据对不上。很多时候这些问题的根源并非软件逻辑错误而是更深层的硬件内存访问冲突或由宇宙射线、电磁干扰引发的内存位翻转Bit Flip。TMS320F2837xD这款TI的明星级双核C2000微控制器其设计目标就是应对这些严苛的挑战。它内置了一套相当完善的内存保护单元MPU和错误校正码ECC机制但这套机制如果理解不透、配置不当不仅不能成为守护神反而可能成为系统不稳定的新源头。我经历过一个真实的项目调试当时CLA控制律加速器和CPU1共享一块LSRAM本地共享RAM做数据交换。初期测试一切正常但在EMC电磁兼容测试中系统会间歇性进入NMI不可屏蔽中断异常。排查了很久最终发现是配置疏忽我们为这块共享RAM使能了ECC但在初始化时CLA在CPU1完成整个内存块的ECC初始化RAMINIT之前就尝试去读取数据。这导致ECC逻辑读到了未初始化的内存内容随机值触发了不可纠正的ECC错误直接拉起了NMI。这个坑让我深刻意识到仅仅知道这些安全机制“存在”是远远不够的必须透彻理解其工作原理、触发条件以及软硬件协同的细节。本文将以一个资深嵌入式工程师的视角结合数据手册SPRUHM8K和实战经验为你彻底拆解F2837xD的内存保护与ECC纠错机制。我们会从最根本的“为什么”出发探讨每种保护规则的设计意图然后深入到寄存器配置、中断处理、错误注入测试等实操层面最后分享那些数据手册里不会写的配置陷阱和调试心得。无论你是正在评估这款芯片的架构师还是已经深陷调试泥潭的工程师相信这些内容都能为你提供清晰的路径和实用的参考。2. 内存保护机制深度解析谁可以访问哪里内存保护的核心是权限管理。在F2837xD这样的多主控CPU1, CPU2, CLA, DMA系统中内存就像一栋有多个房间内存块的大楼每个房间有不同的用途程序、数据和不同的钥匙持有者。内存保护单元就是这栋楼的保安系统严格执行访问规则。2.1 内存保护的基本架构与设计哲学F2837xD的内存空间主要分为几类每个CPU子系统的专属RAM如CPU1的M0, M1, LS0-LS5、两个CPU共享的全局RAMGSx以及CLA专用的程序/数据RAM。保护机制围绕这些内存的“归属权”Mastership和“配置用途”展开。其设计哲学非常清晰隔离性确保关键数据如电机控制的状态变量不被其他非相关任务或核心意外修改。确定性非法访问必须被立即、确定性地拦截并留下明确的“案发现场”证据地址、标志位而不是产生不可预知的行为。可调试性提供丰富的状态寄存器让开发者能在问题发生时快速定位是“谁”在“哪里”做了“什么”非法操作。理解这个设计意图你就能明白为什么会有那么多细分规则而不是一个简单的“全有或全无”的开关。2.2 CPU与CLA共享RAM的访问规则矩阵本地共享RAMLSRAM是CPU和CLA交互的“主战场”也是最容易配置出错的地方。其访问权限完全取决于LSRAM被配置为何种模式。我们可以用一个表格来清晰展示这个复杂的规则矩阵内存配置模式CPU 读访问CPU 写访问CPU 取指访问CLA 数据读访问CLA 数据写访问CLA 取指访问配置为 CPU 专属 RAM✅ 允许✅ 允许✅ 允许❌ 违规 (非主控)❌ 违规 (非主控)❌ 违规 (非主控)配置为 CLA 程序 RAM❌ 违规 (非主控)❌ 违规 (非主控)❌ 违规 (非主控)❌ 违规 (非主控)❌ 违规 (非主控)✅ 允许配置为 CLA 数据 RAM✅ 允许✅ 允许✅ 允许✅ 允许✅ 允许❌ 违规 (非主控)核心要点与实战解析“非主控访问违规”的本质当CLA试图访问配置为CPU专属的LSRAM时触发的是“非主控”违规。这意味着CLA根本不是这块内存的“主人”。这种违规的处理非常严厉——对于CLA的取指违规甚至会触发MSTOP主控停止直接挂起CLA的执行这对于防止错误代码在CLA中失控运行至关重要。配置的排他性“程序RAM”和“数据RAM”的配置对CLA和CPU的权限影响是相反的。这要求你在系统设计初期就必须明确每一块LSRAM的用途。例如如果你将LS0配置为CLA程序RAM那么CPU就完全无法通过任何方式访问这块内存即使你想通过CPU去初始化这块内存里的程序代码也不行。正确的做法是先用CPU通过DMA或其他方式将CLA程序代码加载到配置为“CLA数据RAM”的内存中然后切换配置模式为“CLA程序RAM”最后启动CLA。调试访问的“特权”手册中明确提到所有保护规则在调试器访问时均被忽略。这是一个非常重要的特性但也可能带来误导。当你通过CCSCode Composer Studio查看或修改一个被保护的内存区域时操作是成功的这可能会让你误以为硬件保护没有生效。实际上保护只对CPU、CLA、DMA在正常运行时的访问有效。这个特性方便了调试但也要求你在判断保护是否生效时必须通过运行时代码触发访问而不是静态的调试器读写。2.3 DMA访问保护的双重逻辑DMA的访问保护逻辑比CPU/CLA更复杂一层因为它引入了“主控权”和“写保护位”的双重检查。主控权检查针对GSRAM只有对某块GSRAM拥有主控权Mastership的CPU子系统其DMA才被允许向该内存写入。例如如果GS0被配置为CPU1主控那么只有CPU1的DMA可以向GS0写数据CPU2的DMA进行写操作会触发“非主控DMA写保护违规”。写保护位检查DMAWRPROTx即使DMA拥有主控权它仍然可能被禁止写入。每个内存块都有一个对应的DMAWRPROTx位通常在MEMCFG寄存器中。当该位被置1时对应内存块对本子系统的DMA写入也是保护的。这实现了更细粒度的控制你可以允许CPU核心自由读写某块关键数据区但同时禁止DMA可能用于高速、批量的数据搬运写入防止DMA传输错误覆盖关键数据。一个典型的应用场景在电机控制中CPU1负责核心的FOC磁场定向控制算法其关键的控制参数如PID系数、电流环参考值存放在GSRAM中。你可以设置DMAWRPROT位禁止CPU1的DMA写入该区域。这样即使DMA通道配置错误试图将ADC采集的原始数据直接搬运到控制参数区也会被硬件拦截而CPU1核心自身的算法更新则不受影响。2.4 访问违规的硬件处理流程与软件响应当硬件检测到一次访问违规时它会执行一个标准化的“流水线”操作。理这个流程对编写健壮的错误处理程序至关重要。动作拦截对于写违规本次写操作被静默忽略数据不会写入内存。对于读/取指违规返回的数据是未定义的可能是垃圾数据但更重要的是后续的流程。现场保留违规发生的内存地址会被立即锁存到对应的“访问违规地址寄存器”中例如CPU1_WRITE_ACCESS_VIOLATION_ADDR。同时在对应的“访问违规标志寄存器”中一个特定的位会被置起。这是事后调试的黄金信息。中断触发如果相应的访问违规中断在中断使能寄存器中被使能则会产生一个访问违规中断通常是一个可配置的中断源如ACCESS_VIOLATION_INT。软件处理策略 在访问违规中断服务程序ISR中你应该立即读取并保存地址寄存器和标志寄存器的值。这些寄存器可能在下次违规时被覆盖。分析违规类型通过检查标志寄存器确定是CPU写、CPU读、CLA取指还是DMA写违规。结合地址分析查看锁存的地址定位到是哪个变量、数组或代码段引发了问题。这常常能直接指向一个错误的指针或越界访问。执行安全措施根据违规的严重性你可以选择记录错误日志、复位相关外设、或将系统切换至安全状态如关闭PWM输出。清除标志位在ISR退出前必须手动清除已处理的违规标志位否则该中断将持续触发。重要提示访问违规中断的优先级通常需要设置得比较高。因为非法访问往往意味着程序逻辑已经出现了严重错误如栈溢出破坏内存、野指针需要及时处理以防止更严重的后果如数据永久性损坏。3. ECC与奇偶校验内存数据的“贴身保镖”如果说内存保护是防止“坏人”闯入那么ECC错误校正码和奇偶校验就是防止内存里的数据自己“变坏”位翻转。在存在电磁干扰、辐射或随着芯片老化内存单元可能发生单比特甚至多比特错误。ECC/奇偶校验就是为此设计的硬件安全网。3.1 SECDED ECC原理与实现细节F2837xD对专属RAM如M0, M1, LSx配置为专属时使用SECDED ECC。这是一种非常经典且高效的编码方案。SECDED含义Single Error Correction, Double Error Detection。即单比特错误可纠正双比特错误可检测。工作原理简述在写入32位数据时内存控制器不仅存储数据本身还会根据这32位数据以及其地址的低位地址偏移量计算出一个7位的ECC校验码实际是3组7位码共21位但逻辑上如此理解并一同存储。当读取数据时控制器会再次根据读出的数据和地址计算ECC码并与存储的旧ECC码进行比较。如果新旧ECC码完全一致说明数据无误。如果存在差异且差异模式表明是单比特错误硬件会自动翻转错误位将纠正后的数据返回给CPU并在后台将正确数据写回内存防止该位再次出错导致双比特错误。同时可纠正错误计数器加1。如果差异模式表明是双比特或多比特错误则错误无法纠正。硬件会触发一个NMI不可屏蔽中断通知系统发生了严重错误。地址参与ECC计算的意义这是一个关键设计。ECC不仅保护数据位也保护了地址偏移量。这可以防止地址线受到干扰导致访问到错误的内存位置而数据本身却“侥幸”通过了ECC检查的极端情况。手册中提到对于4KB的LSRAM块只使用地址的低11位参与计算因为11位足以寻址4KB空间2^11 2048个32位字2048*4字节8KB这里需要注意内存控制器可能以32位字为基本单元管理4KB RAM对应1K个32位字需10位地址手册的11位可能是包含对齐或预留。这优化了计算逻辑。3.2 奇偶校验在共享RAM中的应用对于共享RAMGSRAMF2837xD使用了相对简单的偶校验。它为每16位数据生成1位校验位并为地址也生成1位校验位。因此对于一个32位数据访问共有3位校验位低16位数据、高16位数据、地址。偶校验规则一组二进制位中“1”的个数为偶数则校验位置0为奇数则置1。这样整体数据校验位“1”的个数始终为偶数。能力限制奇偶校验只能检测奇数个比特的错误单比特、三比特等。如果发生偶数个比特错误奇偶校验会失效“1”的个数奇偶性不变。它没有任何纠错能力一旦检测到错误即视为不可纠正错误触发NMI。为什么共享RAM用奇偶校验主要是权衡了面积、功耗和可靠性需求。共享RAM通常容量较大使用完整的SECDED ECC会带来显著的存储开销每32位数据需要约7位ECC开销21%。而奇偶校验开销低每32位约3位开销~9%且对于多核间共享的数据检测到错误后通过NMI通知系统由软件进行错误恢复例如从备份中恢复数据或重启任务也是一种可行的安全策略。3.3 错误处理流程与软件职责ECC/奇偶校验的错误处理是分级的软件需要根据错误严重程度采取不同措施。1. 可纠正错误单比特ECC错误的处理硬件行为自动纠正数据写回内存递增“可纠正错误计数寄存器”。软件监控这是软件的主要职责。你需要初始化时设置一个“可纠正错误阈值寄存器”。当计数值达到该阈值时会触发一个可纠正错误中断。软件响应在中断中你应该读取“错误地址寄存器”定位频繁出错的地址。这可能指示某块内存区域因物理原因如工艺缺陷、强干扰变得脆弱。记录错误日志包括地址、计数和时间戳。评估系统状态。单比特错误率突然升高可能是系统即将失效的早期预警。决定是否采取预防性措施如将关键数据迁移到其他内存区域或通知上位机系统降级运行。清除中断标志复位计数器通常通过写特定值实现。2. 不可纠正错误双比特ECC错误、任何奇偶校验错误、地址ECC错误的处理硬件行为立即触发对应主控CPU或CLA的NMI。NMI是最高优先级的中断之一旨在让系统立即进入紧急处理流程。软件响应NMI ISRNMI服务程序必须极其精简和可靠。立即保存关键上下文如果可能且有时间。读取“不可纠正错误地址寄存器”和状态标志确定错误类型和位置。执行最紧急的安全操作在电机控制中这通常意味着立即封锁PWM输出将PWM引脚置为高阻或安全状态关闭功率器件防止硬件损坏。进行系统诊断与恢复尝试判断错误是否可恢复例如是否是偶发的瞬时干扰。有时可以尝试从备份数据区恢复但更多时候为了绝对安全需要发起系统软复位或进入安全状态等待看门狗复位。重要提示NMI ISR中应避免进行复杂的内存操作或调用可能不安全的库函数因为系统内存的完整性已遭破坏。一个容易忽略的细节手册中提到在CPU取指时发生不可纠正错误有可能在NMI发生前先触发一个ITRAP指令陷阱。这是因为错误的指令可能已经进入CPU流水线并被解码执行引发了非法操作。你的NMI处理程序需要考虑到这种可能性。4. 安全机制的应用测试与初始化安全机制本身也需要被测试以确保其在产品生命周期内始终有效。F2837xD提供了硬件测试钩子Test Hooks和必要的初始化功能。4.1 错误注入测试验证ECC/奇偶校验逻辑为了满足功能安全标准如ISO 26262必须能够定期或在启动时验证ECC/奇偶校验的检测与纠正逻辑是否正常工作。F2837xD通过RAMTEST模式实现了这一点。操作原理通过配置可以访问内存的“ECC/奇偶校验位映射区”。这个区域与数据区地址重叠但通过特殊模式访问。在此模式下你可以直接写入或修改ECC/Parity位而保持数据位不变或者修改数据位而保持ECC/Parity位不变。这样你就可以人为制造一个单比特或双比特错误。然后切换回正常模式读取该地址。硬件应检测到你注入的错误并触发相应的纠正对于单比特ECC或NMI对于双比特/奇偶错误。测试流程建议选择一块非关键性的测试内存区域。写入已知的数据模式如0xAA55AA55。进入RAMTEST模式读取该地址对应的ECC码根据表3-14位[6:0]是低16位数据的ECC位[14:8]是高16位数据的ECC位[22:16]是地址ECC。修改其中一个ECC位例如将位0翻转模拟单比特ECC错误。写回。退出RAMTEST模式以正常模式读取该地址。你应该观察到读取到的数据仍然是正确的0xAA55AA55错误被纠正。“可纠正错误计数寄存器”增加1。如果使能了中断会触发可纠正错误中断。重复步骤3-4但这次修改两个ECC位模拟双比特错误。此时正常读取应触发NMI。对奇偶校验内存GSRAM进行类似测试修改奇偶校验位应触发NMI。警告错误注入测试会真实地触发错误中断。务必在受控的测试环境中进行并确保你的中断服务程序能够妥善处理这些测试触发的中断避免影响正常的系统自检流程。4.2 RAM初始化避免“幽灵”ECC错误这是一个至关重要的启动步骤却常被忽视。芯片上电后RAM中的内容是随机的。如果ECC/奇偶校验功能已使能那么当你第一次读取一块未初始化的内存时随机的数据位和随机的ECC/奇偶位组合在一起极有可能不满足编码规则从而被硬件误判为一个内存错误硬件解决方案RAM_INIT功能F2837xD提供了硬件自动初始化功能。对每个内存块你可以通过设置对应的INIT寄存器位来启动初始化。硬件会将整块内存的数据区写0并计算写入0对应的正确ECC/奇偶校验位一并写入。软件操作流程与注意事项按顺序初始化在系统初始化早期在使能任何可能访问这些RAM的主控如CLA、DMA之前逐块初始化你需要使用的RAM。等待完成启动初始化后必须轮询对应内存块的INITDONE状态位直到该位被硬件置1。// 示例初始化LS0 RAM (假设寄存器地址已定义) MemCfgRegs.LS0_INIT.bit.INIT 1; // 启动初始化 while(MemCfgRegs.LS0_INITDONE.bit.INITDONE 0) { // 等待初始化完成 }绝对禁止在初始化完成前访问手册用加粗的“Note”强调在INITDONE置位前任何主控CPU、CLA、DMA都不得访问该内存块。否则访问行为和初始化过程都会出错。这是我开篇提到的那个坑的根本原因。共享内存的初始化对于GSRAM只有被配置为该内存主控的CPU才能发起初始化操作。这需要在多核系统中做好协调。一个最佳实践在你的启动代码Startup.c或SysInit()函数中在初始化任何外设或启动其他核心之前先完成所有要用到的RAM块的初始化。这能从根本上杜绝因未初始化内存导致的诡异ECC错误。5. Flash内存的ECC与访问性能优化F2837xD的Flash内存同样受ECCSECDED保护且其访问性能对整个系统的实时性有巨大影响。配置不当会导致CPU stalled影响中断响应。5.1 Flash ECC的特点与安全考量Flash ECC的原理与RAM ECC类似也是SECDED并包含地址校验。但其应用场景有些特殊写操作编程当使用Flash API如Fapi_issueProgrammingCommand编程Flash时ECC是自动计算并一并写入的。你无需手动计算ECC值。链接器ECC生成TI的链接器支持通过-ecc选项为Flash中的代码和数据生成ECC信息并写入特定的ECC存储区。但请注意手册明确指出CCS的Flash插件和UniFlash工具不支持编程由链接器生成的ECC。它们只支持“AutoEccGeneration”模式即工具在编程时自动计算ECC。如果你需要用到链接器生成的ECC例如为了满足特定的安全启动流程你需要自行实现Flash编程算法或寻找其他支持此功能的工具。测试模式与RAM类似Flash控制器也提供了测试模式用于注入ECC错误验证ECC逻辑的功能安全性。5.2 Flash等待状态与预取机制平衡性能与可靠性Flash的读取速度跟不上高速的CPU内核200MHz。为了弥补这个速度差F2837xD引入了等待状态和预取/缓存机制。等待状态RWAIT这是最基础的配置。CPU访问Flash时需要插入RWAIT1个系统时钟周期SYSCLK的等待。RWAIT值通过FRDCNTL寄存器配置。计算公式RWAIT ceil( (SYSCLK频率 / FCLK_max) - 1 )。其中FCLK_max是Flash支持的最大操作频率详见芯片数据手册。例如SYSCLK200MHzFCLK_max50MHz则RWAIT ceil(200/50 - 1) ceil(4 - 1) 3。你必须配置足够的等待状态否则会导致Flash读取不稳定引发数据错误或ECC错误。配置时机必须在从Flash中运行的代码里在初始化Flash相关设置之前就将这段初始化代码搬移到RAM中执行。因为修改RWAIT或预取设置时如果代码本身还在Flash中运行可能会导致访问冲突或不可预知的行为。预取机制Prefetch这是提升线性代码执行效率的关键。当使能预取后Flash控制器会基于当前指令地址提前将后面128位4条32位指令或8条16位指令的数据取到缓冲区中。CPU执行当前指令时预取逻辑已经在后台获取下一段指令了。对于顺序执行的代码这能极大减少因Flash等待状态带来的性能损失。使能与禁用通过FRD_INTF_CTRL寄存器的PREFETCH_EN位控制。边界注意事项手册特别警告如果使能了预取不要使用Flash Bank最后两行16个16位字的地址空间。因为预取逻辑会做“前瞻读取”如果当前指令位于Bank末尾预取可能会尝试读取Bank之外的不存在地址从而引发总线错误或ECC错误。数据缓存Data Cache对于Flash中的数据访问如查表可以使用数据缓存。将频繁访问的只读数据如正弦表、PID参数表放入Flash并启用对应区域的数据缓存能显著提升访问速度。配置流程总结编写一段Flash配置函数如InitFlash()其中包含设置RWAIT、使能预取/缓存等操作。在链接器命令文件.cmd中将InitFlash函数分配到RAM段例如.TI.ramfunc。在main()函数的最开始调用MemCopy函数将InitFlash的代码从Flash复制到RAMC2000的Boot ROM或启动代码有时会帮你做一部分但为了保险最好自己做。然后跳转到RAM中的InitFlash函数执行配置。配置完成后再返回继续执行主循环此时主循环代码仍在Flash中但预取已生效性能提升。6. 常见问题排查与实战经验分享理论最终要服务于调试。下面是一些我踩过的坑和总结的排查思路。6.1 问题排查速查表现象可能原因排查步骤与工具系统随机进入NMI1. 内存双比特ECC错误或奇偶错误。2. 访问保护违规特别是CLA取指违规触发MSTOP后可能关联NMI。3. Flash访问配置错误RWAIT不足。1. 在NMI ISR中读取ERR_STATUS和ERR_ADDR寄存器确定错误源和地址。2. 检查该地址对应的内存区域是否发生了未初始化的访问查RAMINIT状态。3. 检查该内存区域的保护配置MEMCFG寄存器是否与访问者匹配。4. 检查Flash等待状态RWAIT配置是否符合当前CPU频率。CLA莫名其妙停止工作1. CLA发生了取指保护违规触发MSTOP。2. CLA程序计数器跑飞访问了非法地址。1. 检查CLA对应的访问违规标志寄存器如CLA1_FETCH_VIOLATION。2. 检查CLA任务的内存配置LSRAM是程序RAM还是数据RAM。3. 使用CCS的CLA调试视图查看CLA的PC寄存器和状态寄存器。双核共享数据偶尔出错1. 未使用正确的同步机制如软件信号量、硬件IPC导致数据竞争。2. 共享内存GSRAM的ECC/奇偶错误。3. DMA传输覆盖了共享数据。1. 检查并强化数据访问的互斥保护关中断、使用原子操作等。2. 检查共享内存的ECC错误计数器。3. 检查DMA传输的目的地址和传输大小确认没有越界。检查DMAWRPROT位是否应被设置。程序在Flash中运行极慢Flash预取和缓存未使能且RWAIT配置可能过小导致实际访问不稳定。1. 确认InitFlash函数是否在RAM中正确运行并完成了配置。2. 检查FRD_INTF_CTRL寄存器确认PREFETCH_EN和DATA_CACHE_EN位已置位。3. 根据CPU时钟频率重新计算并设置FRDCNTL寄存器中的RWAIT值。在线调试时一切正常脱机运行就出问题1. 关键内存区域如中断向量表、代码段未正确初始化ECC。2. 依赖了调试时代码在RAM中运行的速度实际Flash运行速度慢导致时序问题。1. 确认所有已使能ECC的RAM在首次访问前都完成了RAM_INIT。2. 在main()开始时加入延时模拟Flash读取的等待时间测试时序逻辑。6.2 配置心得与避坑指南启动顺序是王道务必遵循复位 - 初始化时钟 - 初始化RAMECC/保护- 初始化Flash等待状态/预取- 初始化外设 - 启动其他核心CLA的顺序。任何错序都可能导致隐晦的硬件错误。保护配置宁严勿宽在项目初期可以先将所有内存区域的保护配置得严格一些。例如将不共享的LSRAM都设为CPU专属为所有GSRAM设置DMAWRPROT。然后在开发过程中根据实际需求逐步、谨慎地放开权限。这样能在早期暴露很多潜在的非法访问问题。善用中断和寄存器不要仅仅把保护机制当成“防火墙”。使能关键的访问违规中断和ECC错误中断并在中断服务程序中记录详细的错误信息地址、类型、时间戳。这些日志是线上问题定位的无价之宝。测试要覆盖边界和异常除了正常功能测试一定要设计测试用例去主动触发保护机制和ECC错误。例如写一段代码让CLA故意去读取配置为CPU专属的RAM验证违规中断是否触发进行错误注入测试验证ECC纠正和NMI响应是否正常。这不仅能验证硬件功能也能验证你的错误处理软件是否健壮。理解“调试特权”永远记住通过CCS调试器看到的内存世界和芯片真实运行时的世界可能不同。调试器可以绕过所有保护。判断一个配置是否生效一定要看芯片独立运行时或通过printf/串口输出的行为。深入理解并妥善运用F2837xD的内存保护与ECC机制是从“能让芯片跑起来”到“能让产品在复杂工业环境中稳定运行十年”的关键一步。它要求开发者具备硬件思维从系统的角度审视每一行代码对内存的访问。希望这篇详尽的解析能帮助你构建出更坚固、更可靠的嵌入式系统。