【Mode Management】EcuM模块详细介绍
目录
8.5 WakeupRestart Sequence执行的动作
9.4 WakeupValidation Sequence执行的动作
9.4.1 通信通道唤醒Wakeup of Communication Channels
9.4 唤醒验证的需求Requirements for Wakeup Validation
9.6 集成电源控制唤醒源 Wakeup Sources with Integrated Power Control
13.4 主从和通信-Master Core and Slave Core Signalling
13.5 示例-关机同步 Shutdown Synchronization
1.功能概述
ECU管理模块是一个基本的软件模块,用于管理ECU状态的公共方面。具体如下:
????. 初始化和反初始化OS,SchM,BswM以及一些基础软件的驱动模块
????. 在请求时将ECU配置为休眠(Sleep)和关机(Shutdown)
????. 管理ECU所有的唤醒事件
ECU管理器模块提供了唤醒验证协议来区分'真实的''唤醒事件'和'不稳定的'唤醒事件。
ECU management有两种:flexible and fixed
相比于Fixed management,Flexible management 使得ECU状态的固定模式和它们之间的转换被消除,以允许以下附加场景:
. 部分或快速启动,其中 ECU 以有限的能力启动,然后由应用程序决定,继续逐步启。
. 交错启动,其中 ECU 启动最少,然后启动 RTE 以尽快执行 SW-C 中的功能。 然后它继续启动更多的 BSW 和 SW-C,从而将 BSW 和应用程序功能交织在一起。
. ECU 具有多个运行状态的多种操作状态。
. 多核Ecu:STARTUP、SHUTDOWN、SLEEP 和 WAKEUP 是在ECU的所有核上协调工作。
Flexible management采用以下模块提供的通用模式管理工具:
. RTE 和 BSW SchM模块合并为一个模块:该模块支持可自由配置的 BSW 和应用程序模式及其模式切换设施。
. BswM模块:该模块实现可配置的规则和操作列表,以评估切换 ECU 模式的条件并实施必要的操作。
因此,通过Flexible management,大多数 ECU 状态不再在 EcuM模块本身中实现。 通常,当通用模式管理工具在以下情况下不可用时,ECU 管理器模块会接管控制:
. STARTUP的第一阶段
. SHUTDOWN的最后阶段
. 设施被调度程序锁定的SLEEP阶段
在 ECU 管理器模块的 UP 阶段,BSW 模式管理器负责进一步的操作。 而 ECU 管理器模块仲裁来自 SW-C 的 RUN 和 POST_RUN 请求,并通知 BswM 有关模式的状态。
RUN 请求协议是 ECU State Manager Fixed 中已建立的方法,用于确定 ECU 应保持活动状态还是准备关闭。
固定 ECU 管理以先前 AUTOSAR 版本的形式继续 ECU 管理。 它有一组固定的 ECU 状态和它们之间的转换,对于没有特殊要求的传统 ECU 来说已经足够了,例如部分或快速启动、交错启动和多个操作状态(多个 RUN 状态)。 固定 ECU 管理不支持多核 ECU,等等。
小结:Flexible?EcuM和Fixed?EcuM的区别与联系
EcuM | Fixed | Flexible |
区别 | . Fixed EcuM状态机固定,状态跳转唯一 . 仅适用于单核启动,不支持多核启动 .不支持局部、快速、交叉启动 | . 根据实际续期设计EcuM状态机,EcuM状态不固定。 . 支持多核启动 . 支持局部、快速、交叉启动 |
联系 | Fixed EcuM可以理解为Flexible EcuM的一个具体实例 | Flexible EcuM是EcuM模块的高度抽线,可根据实际需求实例化设计。 |
图1:映射:固定 EcuM 到灵活 EcuM 的阶段
2.关键概念理解
Callout: Callout函数是系统设计人员可以实现特定功能的打桩函数,通常在配置时,以向 EcuM模块添加功能。Callout分为两类, 一类提供强制性 EcuM模块功能并用作硬件抽象层。 另一个类提供可选功能。
Mode:模式是车辆中运行的、与特定实体、应用程序或整个车辆相关的各种状态机(不仅仅是ECU管理器)的一组特定状态。
Passive Wakeup:由连接的总线而不是内部事件(如计时器或传感器活动)引起的唤醒。
Phase: ?ECU管理器的动作和事件(例如启动,关机,休眠...)在逻辑上或者时间上的集合。
Shutdown Target:ECU 在进入休眠状态、断电或复位前必须关闭。 因此,SLEEP、OFF 和 RESET 是有效的关机目标。 通过选择关闭目标,应用程序可以在下一次关闭后将其对 ECU 行为的期望状态传达给 ECU 管理器模块。
State: 状态在它们各自的BSW组件内部,因此对应用程序不可见。所以它们只被BSW的内部状态机使用。ECU管理器内部的状态组成阶段(Phase),并被用于模式处理。
Wakeup Event:导致唤醒的物理事件。 CAN 消息或切换 IO 线可以是唤醒事件。
Wakeup Reason:唤醒原因是唤醒事件,即上次唤醒的实际原因。
Wakeup Source:处理唤醒事件的外设或 ECU 组件称为唤醒源。
3.EcuM模块对其他模块的依赖
3.1Mcu模块
MCU 驱动程序是由 ECU 管理器模块初始化的第一个基本软件模块。 然而,当 MCU_Init 返回时,MCU 模块和 MCU 驱动模块不一定完全初始化。 可能需要额外的 MCU 模块特定步骤来完成初始化。 ECU 管理器模块提供了两个可放置此附加代码的Callout函数。
3.2具有唤醒能力外设模块
唤醒源必须由驱动程序处理和封装。这些驱动程序必须遵循EcuM详细设计文档中提供的协议和要求,以确保无缝集成到 AUTOSAR BSW。 基本上,协议如下:
1)驱动程序必须调用 EcuM_SetWakeupEvent 来通知 ECU 管理器模块已检测到挂起的唤醒事件。 驱动程序不仅必须在 ECU 在睡眠阶段等待唤醒事件时调用 EcuM_SetWakeupEvent,而且在驱动程序初始化阶段和 EcuM_MainFunction 运行时的正常操作期间也必须调用
2)驱动程序必须提供一个显式函数来使唤醒源进入睡眠状态。 该函数将使唤醒源进入低功耗模式并重新装备唤醒通知机制。
3)如果唤醒源能够生成虚假事件,则驱动程序或使用驱动程序的软件或其他适当的 BSW 模块必须为唤醒事件提供验证时间有效性的Callout函数或调用 ECU 管理器模块的验证功能。 如果不需要验证,则此要求不适用于相应的唤醒源。
3.3操作系统OS
ECU 管理器模块启动 AUTOSAR 操作系统并关闭它。 ECU 管理器模块定义了在操作系统启动之前如何处理控制以及在操作系统关闭之后如何处理控制的协议。
3.4BSW调度器
ECU 管理器模块初始化BSW调度器,ECU 管理器模块还包含 EcuM_MainFunction,它被BSW Scheduler周期调度,评估唤醒请求并更新Alarm Clock。
3.5BswM模块
ECU 状态一般实现为 AUTOSAR 模式,BSW 模式管理器负责监控 ECU 中的变化并影响 ECU 状态机的相应变化。
BSW 模式管理器只能在模式管理运行后管理 ECU 状态机 - 即在 SchM 初始化之后,直到 SchM 被取消初始化或停止。 当 BSW 模式管理器无法运行时,ECU 管理器模块会控制 ECU。
因此,ECU 管理器模块在 ECU 启动后立即取得控制权,并在初始化 SchM 和 BswM 后将控制权交给 BSW 模式管理器。
BswM 将 ECU 的控制权传递回 ECU 管理器模块以锁定操作系统并处理唤醒事件。BswM 还会在 OS 在关机时停止之前立即将控制权传递回 ECU 管理器。当唤醒源被验证时,ECU 管理器模块通过模式切换请求向 BswM 指示唤醒源状态变化。
3.6应用软件组件SWC
ECU 管理器模块处理以下 ECU 范围的属性: Shutdown target。SWC可通过AUTOSAR端口可以设置Shutdown target。
3.7小结
上文中我们提到Fixed EcuM是Flexible?EcuM的具体实现。所以我们在使用Flexible EcuM的时候可以设计一个软件组件SWC来监控ECU的状态,通过配置BswM进行模块管理,三个模块(SWC,BswM,EcuM)协同工作,最终也会Fixed一个EcuM。
图2:SWC、EcuM及BswM三方交互
4.EcuM模块的各个阶段介绍
未特殊说明,以下描述都只针对Flexible?EcuM。
Flexible EcuM没有固定的状态或者模式,EcuM的设计者必须决定需要哪些状态并配置它们。
当使用 ECU 模式处理时,标准状态 RUN 和 POST_RUN 由 RUN 请求协议仲裁并传播到 BswM。 系统设计者在通过 BswM 操作设置 EcuM 模式时必须确保满足各个状态的前提条件。
4.1 STARTUP阶段
STARTUP 阶段的目的是将基础软件模块初始化到通用模式管理工具可操作的点。
4.2 UP Phase阶段
本质上,当 BSW 调度程序启动并调用BswM_Init时,UP 阶段开始。那时,内存管理没有初始化,没有通信栈,没有 SW-C 支持 (RTE) 并且 SW-C 还没有启动。以特定模式(Startup后配置的下一个模式)开始,并具有相应的可运行对象,即 BSW MainFunctions。BswM模式仲裁开始工作,然后BswM的模式控制的Actions能够触发和禁用SWC。
然而,从 ECU 管理器模块的角度来看,ECU 处于“UP”状态。然后 BSW 模式管理器模块启动模式仲裁,所有进一步的 BSW 初始化、启动 RTE 和(隐式)启动 SW-C 成为在 BswM 的动作列表中执行的代码或由依赖于模式的调度驱动,这些都是可以在BswM的设计阶段又集成者(integrator设计控制的)。
因此,初始化 NvM 并调用 NvM_Readall 也成为集成代码。 这意味着继承者(integrator)负责在 NvM_ReadAll 结束时触发 Com、DEM 和 FIM 的初始化。 当 NvM_ReadAll 完成时,NvM 将通知 BswM。
注意 RTE 可以在 NvM 和 COM 初始化后启动。 另请注意,在初始化 COM 之前不需要完全初始化通信堆栈。
这些更改会以任意顺序初始化 BSW 模块以及启动 SW-C,直到 ECU 达到满负荷为止,并且此后这些更改还将继续确定 ECU 的功能。
最终模式开关会停止 SW-C 并取消初始化 BSW,以便当 ECU 达到可以关闭电源的状态时,Up 阶段结束。
因此,就 ECU 管理器模块而言,BSW 和 SW-C 会一直运行,直到它们准备好让 ECU 关闭或进入睡眠状态。
4.3 SHUTDOWN阶段
SHUTDOWN 阶段处理基础软件模块的受控关闭,最终导致选定的关闭目标 OFF 或 RESET。
4.4 SLEEP阶段
ECU在SLEEP阶段进入低功耗阶段。通常情况下,不执行任何代码,但电源仍然提供,如果进行相应的配置,ECU在这种状态下是可唤醒的。ECU管理器模块提供了一组可配置的(硬件)睡眠模式,通常是在功耗和重启ECU的时间之间进行权衡。
ECU 管理器模块唤醒 ECU,以响应有意或无意的唤醒事件。 由于意外唤醒事件应该被忽略,ECU 管理器模块提供了一个协议来验证唤醒事件。 该协议指定了处理唤醒源的驱动程序和 ECU 管理器之间的协作过程。
4.5 OFF阶段
ECU 在断电时进入OFF 状态。 在这种状态下,ECU 可能是可唤醒的,但仅适用于具有SBC(System Base Chip)电源控制的唤醒源。 在任何情况下,ECU 都必须是可启动的(例如通过重置事件)。
图4:EcuM的各个阶段
5.ECU Manager的结构描述
图4说明了ECU Manager模块与其他BSW模块接口的关系。在大多数情况下,ECU管理器模块只负责初始化。然而,有一些模块与ECU管理器模块有功能关系,这将在以下段落中解释。
图5:EcuM模块需要使用的其他模块的接口
一些基本的软件驱动模块在EcuM模块唤醒时被初始化、关闭和重新初始化。操作系统由EcuM初始化并关闭。在操作系统初始化之后,EcuM模块再将控制权传递给BswM之前执行额外的初始化步骤。在操作系统关闭之前,BswM立即将执行控制交还给EcuM模块。SW-C 使用 AUTOSAR 端口与 ECU 管理器模块交互。
6.STARTUP阶段详解
图5展示了 ECU 的启动行为。 当通过 EcuM_Init 调用时,EcuM模块控制 ECU 启动程序。 通过调用 StartOS,EcuM模块暂时放弃对ECU的控制。要重新获得控制权,集成器(Integrator)必须执行一个自动启动的操作系统任务,并将调用 EcuM_StartupTwo 作为其第一个操作。
图5:STARTUP序列
6.1EcuM_Init之前的动作
EcuM模块假定在调用EcuM_Init之前已经进行了 MCU 的最小初始化,以便设置堆栈并可以执行代码,并且已经执行了变量的 C 初始化。
EcuM_Init一般就是进入Main函数之后的第一行代码,也就是说EcuM_Init之前主要时MCU的启动代码阶段,一般完成堆栈的初始化,RAM的初始化,然后跳转到Main函数开始执行EcuM_Init。
6.2StartPreOS Sequence执行的动作
StartPreOS Sequence | ||
初始化活动 | 说明 | 是否是可选项 |
Callout EcuM_AL_SetProgrammableI nterrupts | 在具有可编程中断优先级的ecu上,必须在操作系统启动之前设置这些优先级。 | 是 |
Callout EcuM_AL_DriverInitZero | 初始化不使用配置参数的BSW模块。callout不仅可以包含驱动程序初始化,还可以包含任何类型的os之前的低级初始化代码 | 是 |
Callout EcuM_DeterminePbConfigura tion | 调用将返回一个指向完全初始化的EcuM_ConfigType结构体的指针,该结构体包含 ECU管理器模块和所有其他BSW模块的构建后配置数据 | 否 |
检查配置数据的一致性 | 数据一致性检查失败后调用 EcuM_ErrorHook | 否 |
Callout EcuM_AL_DriverInitOne | 不仅可以包含驱动程序初始化,还可以包含任何类型的os之前的低级初始化代码。 | 是 |
Get reset reason | 调用MCU模块提供的AUTOSAR标准接口Mcu_GetResetReason获取复位原因,同时调用EcuM_SetWakeupEvent设置唤醒事件 | 否 |
选择默认的shutdown目标 | 否 | |
Callout EcuM_LoopDetection | 如果启用了循环检测,则每次启动时都会调用该调用。如果检测到复位回路,则返回true。否则返回false。 | 是 |
Start OS | 启动AUTOSAR OS | 否 |
StartPreOS序列的目的是准备ECU初始化操作系统,应该尽可能短。如果可能的话,驱动程序应该在UP阶段初始化,并且调用也应该保持简短。在这个序列中不应该使用中断。如果必须使用中断,在StartPreOS序列中只允许I类中断。
驱动程序和硬件抽象模块的初始化不是由ECU管理器严格定义的。两个callout EcuM_AL_DriverInitZero和EcuM_AL_DriverInitOne被提供来定义init块0和1。这些块包含了与StartPreOS序列相关的初始化活动。
MCU_Init不提供完整的MCU初始化。此外,与硬件相关的步骤必须在系统设计时执行并定义。这些步骤应该在EcuM_AL_DriverInitZero或EcuM_AL_DriverInitOne callout中采取。详细信息可以在MCU驱动程序规范中找到。
ECU管理器模块应该调用 EcuM_GetValidatedWakeupEvents与配置的默认关机目标EcuMDefaultShutdownTarget.
StartPreOS序列将初始化启动操作系统所需的所有基本软件模块。
图6-StartPreOS Sequence
6.3StartPostOS Sequence执行的动作
StartPostOS Sequence | ||
初始化活动 | 说明 | 是否是可选项 |
初始化 BSW调度器(Init BSW Scheduler) | 为BSW模块使用的临界区初始化信号量 | 否 |
初始化BSW管理模块(Init BSW Mode Manager) | 否 |
当通过EcuM_StartupTwo函数激活时,ECU Manager模块将执行startposto序列中的动作。
图7-StartPostOS序列
6.4驱动初始化
一个驱动程序在初始化过程中的位置很大程度上取决于它的实现和目标硬件设计。
驱动可以在STARTUP阶段的Init Block 0或Init Block 1中由ECU Manager模块初始化,也可以在WakeupRestart序列的EcuM_AL_DriverRestart callout中重新初始化。驱动程序也可以在UP阶段由BswM初始化或重新初始化。
6.5DET初始化
默认错误跟踪模块是一个BSW模块,它包含用于调试的软件。在操作之前,DET必须被初始化(通过调用Det_Init)和启动(通过调用Det_Start)。
如果至少有一个模块被配置为跟踪开发错误,ECU Manager模块应该在StartPreOS序列中,在所有其他驱动程序之前初始化DET。
7.SHUTDOWN阶段详解
BswMMode状态机切换到SHUTDOWN状态后调用EcuMSelectShutdownTarget_OFF_MCU和EcuMGoDown使得EcuM接管程序走SHUTDOWN?Sequence。
当关机阶段发生唤醒事件时,ECU Manager模块应立即完成关机并重启。
图8-Shutdown阶段
7.1OffPreOS Sequence执行的动作
OffPreOS?Sequence | ||
Shudown活动 | 说明 | 是否是可选项 |
反初始化BswM模块 | 否 | |
反初始化BswM调度器模块 | 否 | |
检查挂起的唤醒事件 | 目的是检测关机期间发生的唤醒事件 | |
如果唤醒事件挂起,将RESET设置为关机目标(将使用EcuMDefaultResetModeRef的默认重置模式) | 只有检测到挂起的唤醒事件时,才会执行此操作,以允许立即启动 | |
ShutdownOs | 该操作系统任务的最后一次操作 |
作为它的最后一个活动,ECU管理器模块应该调用shutdownnos函数。操作系统在关机结束时调用关机钩子。
关机钩子函数应该调用EcuM_Shutdown来终止关机进程。EcuM_Shutdown不应返回,最后要么关闭ECU或复位MCU。
图9-OffPreOS序列
7.2OffPostOS Sequence执行的动作
OffPostOS序列执行最后的步骤,在操作系统关闭后到达关机目标。EcuM_Shutdown启动该序列。
关机目标可以是ECUM_STATE_RESET或ECUM_STATE_OFF,其中特定的复位模式由复位模式决定。
OffPostOS?Sequence | ||
Shudown活动 | 说明 | 是否是可选项 |
Callout EcuM_OnGoOffTwo | 否 | |
Callout EcuM_AL_Reset or Callout EcuM_AL_SwitchOff | 取决于Shutdown的目标(Off或者Reset) | 否 |
图11-OffPostOS序列
当关机目标为RESET时,ECU Manager模块将调用EcuM_AL_Reset callout。当关机目标为OFF时,ECU Manager模块应调用EcuM_AL_SwitchOff callout。
8.SLEEP阶段详解
BswMMode状态机切换到SLEEP状态后调用EcuMSelectShutdownTarget_SLEEP_MCU和EcuMGoHalt或者EcuMGoPoll使得EcuM接管程序走SLEEP Sequence。
EcuM_GoHalt和EcuM_GoPoll启动两个不同的控制流,它们在实现睡眠的机制上不同。然而,它们在准备睡觉和从睡眠中恢复时的顺序是相同的。
图12-Sleep阶段
另一个模块,可能是BswM,也可以是一个SW-C,必须确保在调用EcuM_GoHalt或EcuM_GoPoll之前选择了适当的ECUM_STATE_SLEEP关机目标。
8.1GoSleep Sequence执行的动作
在GoSleep序列中,ECU管理器模块为即将到来的睡眠阶段配置硬件,并为下一次唤醒事件设置ECU。
为了在接下来的睡眠模式中设置唤醒源,ECU Manager模块应该对每个在目标睡眠模式的EcuMWakeupSourceMask中配置的唤醒源执行EcuM_EnableWakeupSources调用。
Note: Callout函数EcuM_EnableWakeupSources中的实现需要根据具体的芯片来实现。如果芯片厂商的提供的MCAL代码中提供了标准接口(例如RH850_F1KM提供了Mcu_WakeUpFactor_Preparation接口)则直接调用,如果没有提供,则需要去Callout函数中设置唤醒中断。
相对于SHUTDOWN阶段,ECU Manager模块在进入SLEEP阶段时不会关闭操作系统。睡眠模式,即EcuM睡眠阶段和Mcu模式的结合,应该对操作系统透明。
图13-GoSleep序列
当在多核ECU上运行时,ECUM应该为每个核预留一个专用的资源(RES_AUTOSAR_ECUM),在GoSleep期间分配。
8.2 Halt Sequence执行的动作
ECU管理器模块应在休眠模式下执行Halt序列,使微控制器停止运行。在这些睡眠模式下,ECU管理器模块不执行任何代码。
ECU管理器模块应该在MCU进入深度休眠前调用EcuM_GenerateRamHash callout,处理器从halt返回后将会调用EcuM_CheckRamHash?callout。
如果应用多核和存在“slave”EcuM(s),这个检查应该只在“master”EcuM上执行。“主”EcuM从其可触及的所有数据中生成散列。“slave”EcuMs的私有数据不在检查范围内。
当ECU长时间处于休眠状态时,Ram内存可能会损坏。因此,应该检查RAM内存的完整性,以防止不可预见的行为。系统设计者可以选择一个适当的校验和算法来执行校验。
图14-Halt Sequence
ECU管理器模块应该调用EcuM_GenerateRamHash,系统设计者可以放置一个RAM完整性检查。
8.3 Poll Sequence执行的动作
ECU Manager模块应在睡眠模式下执行Poll序列,以降低微控制器的功耗,但仍执行代码。在Poll序列中,EcuM将在阻塞循环中调用调用EcuM_SleepActivity()和EcuM_CheckWakeup(),直到报告了一个挂起的唤醒事件。
图15-Poll Sequence
8.4 Leave Halt or Poll后执行的动作
如果ECU处于Halt或Poll状态时发生了唤醒事件(例如切换唤醒线电平状态、CAN总线上的通信等),那么ECU状态管理器模块的ECU管理器规范将通过执行WakeupRestart序列重新获得控制并退出SLEEP阶段。
可以调用ISR来处理唤醒事件,但这取决于硬件和驱动程序实现。
当ECU处于Halt或Poll状态时,如果出现不规则事件(硬件复位或电源循环),ECU Manager模块将在STARTUP阶段重新启动ECU。
8.5 WakeupRestart Sequence执行的动作
WakeupRestart?Sequence | ||
Wakeup活动 | 说明 | 是否是可选项 |
控制MCU从Sleep模式恢复到Normal模式 | 所选MCU模式在配置参数EcuMNormalMcuModeRef中进行配置 | |
获取挂起的唤醒源事件 | 禁用当前等待的唤醒源,但让其他唤醒源武装起来,以便以后可以唤醒。 | |
Callout EcuM_DisableWakeupSources | 目的是检测关机期间发生的唤醒事件 | |
Callout EcuM_AL_DriverRestart | 初始化需要重启的驱动 | |
Unlock Scheduler | 从此时起,所有其他任务都可以再次运行。 |
ECU管理器模块调用EcuM_AL_DriverRestart callout,用于重新初始化驱动程序。其中,具有唤醒源的驱动程序通常需要重新初始化。
在重新初始化期间,驱动程序必须检查它所分配的唤醒源中是否有一个是上次唤醒的原因。如果这个测试为true,驱动程序必须调用它的' wakeup detected '回调,它必须调用EcuM_SetWakeupEvent。
驱动程序实现应该只调用wakeup回调一次。此后,在通过显式函数调用重新武装之前,它不应该再次调用wakeup回调。因此,驱动程序必须重新武装以再次触发回调。
当WakeupRestart序列结束时,如果ECU Manager模块有一个唤醒源候选列表,ECU Manager模块应该在EcuM_MainFunction中验证这些唤醒源候选列表。
图16-WakeupRestart Sequence
9.UP阶段详解
在UP阶段,EcuM_MainFunction定期执行,它有三个主要功能:
- 要检查唤醒源是否已被唤醒,并启动唤醒验证,如果需要的话
- 更新Alarm计时器
- 仲裁RUN和POST_RUN请求和释放
9.1 Alarm时钟处理
如果EcuMAlarmClockPresent参数配置使用了Alarm时钟服务,则 EcuM_MainFunction中需要更新Alarm时钟。
9.2 唤醒源状态处理
唤醒源不仅在唤醒期间被处理,而且持续地与所有其他EcuM活动并行处理。这个功能运行在EcuM_MainFunction中,完全与ECU通过模式请求进行管理的其余部分解耦。
唤醒源状态表:
状态 | 描述 |
ENABLED | 唤醒源被使能 |
NONE | 没有检测到唤醒事件或者唤醒事件被清除 |
PENDING | 检测到唤醒事件,但尚未验证 |
VALIDATED | 检测到唤醒事件并成功验证 |
EXPIRED | 检测到唤醒事件,但验证失败 |
下图说明了唤醒源状态与引起状态更改的条件函数之间的关系。
图17-唤醒源状态
当ECU Manager操作导致唤醒源状态改变时,ECU Manager模块应向BswM发出模式请求,将唤醒源的模式改变为新的唤醒源状态。
当ECU Manager模块处于UP阶段时,唤醒事件通常不会触发状态变化。然而,它们触发了Halt和Poll阶段的结束。ECU管理器模块然后自动执行WakeupRestart序列,然后返回到UP阶段。
由集成商在BswM中配置规则,以便ECU正确地对唤醒事件作出反应,因为该反应完全依赖于当前ECU(而不是ECU Management)状态。
如果唤醒源有效,BswM将返回ECU的RUN状态。如果所有唤醒事件都返回NONE或EXPIRED, BswM将再次为SLEEP或OFF准备BSW,并根据上一个关机目标调用EcuM_GoPoll或EcuM_GoHalt或EcuM_GoDown。
总结:每个未决事件都被独立地验证(如果配置了),EcuM将结果作为模式请求发布给BswM,而BswM反过来可以触发EcuM中的状态更改。
9.3 唤醒状态的内部表现
EcuM管理器模块提供以下接口来确定这些唤醒源的状态:
·?EcuM_GetPendingWakeupEvents
·?EcuM_GetValidatedWakeupEvents
·?EcuM_GetExpiredWakeupEvents
并通过以下接口操作唤醒源的状态:
· EcuM_ClearWakeupEvent
· EcuM_SetWakeupEvent
· EcuM_ValidateWakeupEvent
· EcuM_CheckWakeup
· EcuM_DisableWakeupSources
· EcuM_EnableWakeupSources
· EcuM_StartWakeupSources
· EcuM_StopWakeupSources
ECU Manager模块最多可管理32个唤醒源。唤醒源的状态通常在上面命名的EcuM接口中通过EcuM_WakeupSourceType位掩码表示,其中单个唤醒源对应于一个固定的位位置。有5个预定义的位位置,其余的可以通过配置分配。
ECU Manager模块一方面管理各个唤醒源的模式。另一方面,ECU Manager模块假设有“内部变量”(即EcuM_WakeupSourceType实例)来跟踪哪些唤醒源处于特定的状态(特别是NONE(即清除)、PENDING、VALIDATED和EXPIRED)。ECU Manager模块在各自的接口定义中使用这些“内部变量”来定义接口的语义。
因此,这些“内部变量”是否确实被执行是次要的。它们只是用来解释接口的语义。
9.4 WakeupValidation Sequence执行的动作
由于唤醒事件可能在无意中产生(例如can线上的EVM峰值),因此有必要在ECU完全恢复运行之前验证唤醒。
所有唤醒源的验证机制都是相同的。当一个唤醒事件发生时,ECU从它的SLEEP状态被唤醒,并在MCU驱动的MCU_SetMode服务中继续执行。当WakeupRestart序列完成时,ECU管理器模块将有一个等待验证的唤醒事件列表(参见SWS_EcuM_02539)。ECU管理模块然后释放BSW调度器和所有BSW MainFunctions;在这种情况下,最明显的是,EcuM MainFunction可以恢复处理。
实现提示:由于SchM将在StartPostOS和WakeupRestart序列的末尾运行,所以有可能EcuM_MainFunction会对一个堆栈还没有初始化的源启动验证。集成开发者应该配置适当的模式,表明堆栈不可用,并相应地禁用EcuM_MainFunction。
图18-WakeupValidation Sequence
ECU管理器模块只能在配置要求的唤醒源上调用唤醒验证。如果没有配置验证协议,那么调用EcuM_SetWakeupEvent也意味着调用EcuM_ValidateWakeupEvent。
ECU管理器模块应该为每个有待验证的唤醒事件启动验证超时。超时时间应该是每个唤醒事件具体设置的。
实现提示:实现只提供一个计时器就足够了,当报告新的唤醒事件时,该计时器将被延长到最大超时。
当一个挂起的唤醒事件的验证超时时,EcuM_MainFunction(OR-operation)在内部过期唤醒事件变量中设置超时位。
当一个挂起的唤醒事件的验证超时过期时,EcuM_MainFunction应该调用BswM_EcuM_CurrentWakeup,使用EcuM_WakeupSourceType位掩码参数,该位对应于唤醒事件设置,状态值参数设置为ECUM_WKSTATUS_EXPIRED
在验证唤醒源或计时器过期时,BswM将被配置为通过来自EcuM的模式切换请求来监视唤醒验证。如果最后一次验证超时过期没有进行验证,则BswM将认为唤醒验证失败。如果至少有一个挂起的事件被验证,那么整个验证应该已经通过。
挂起的事件通过调用EcuM_ValidateWakeupEvent来验证。这个调用必须放在驱动程序中,或者中断处理函数中。放置它的最佳位置取决于硬件和软件设计。
9.4.1 通信通道唤醒Wakeup of Communication Channels
如果在通信通道上发生了唤醒,相应的总线收发驱动必须通过调用EcuM_SetWakeupEvent函数通知ECU管理器模块。
9.4.2 唤醒源和ECU管理器的交互
ECU管理器模块应以相同的方式处理所有唤醒源。程序如下:
当发生唤醒事件时,对应的驱动器应通知ECU Manager模块唤醒。这种通知最可能的方式是:
-- 退出Halt或Poll序列后。在这个场景中,ECU管理器模块调用EcuM_AL_DriverRestart来重新初始化相关的驱动程序,这些驱动程序反过来有机会扫描他们的硬件,例如等待唤醒中断。
--如果唤醒源实际上处于睡眠模式,驱动程序必须自动扫描唤醒事件;通过轮询或等待中断。
如果一个唤醒事件需要验证,那么ECU管理器模块应该调用验证协议。
如果唤醒事件不需要验证,ECU管理器模块应该发出模式切换请求,将事件的模式设置为ECUM_WKSTATUS_VALIDATED。
如果唤醒事件被验证了(要么是立即验证,要么是通过唤醒验证协议验证),ECU Manager模块应该通过EcuM_GetValidatedWakeupEvents来显示它是当前ECU唤醒的一个源。
9.4.3 唤醒验证超时
ECU管理模块应提供单个唤醒验证超时计时器,或每个唤醒源提供一个计时器。
需要满足以下的需求:
ECU Manager模块在EcuM_SetWakeupEvent时启动唤醒验证超时定时器。
EcuM_ValidateWakeupEvent将停止唤醒验证超时定时器。
如果后续同一个唤醒源调用了EcuM_SetWakeupEvent, ECU Manager模块将不会重启唤醒验证超时。
如果只使用一个定时器,建议采用以下方法:
EcuM_SetWakeupEvent被调用时,如果一个唤醒源在同一个唤醒周期中还没有被触发,那么ECU Manager模块应该延长该唤醒源的验证超时时间。
9.4.4 唤醒源对驱动程序的需求
当检测到唤醒事件时,驱动程序必须调用EcuM_SetWakeupEvent,并提供一个EcuM_WakeupSourceType参数来标识唤醒的来源。
从Halt或者Poll或者Off状态退出时,EcuM模块将检测驱动程序初始化之前发生的唤醒。驱动程序必须提供一个API为Sleep状态提供唤醒功能,提供启用或禁用唤醒源的功能,提供设置相关外设进入休眠状态的功能。这些要求仅适用于硬件提供这些功能的情况。
驱动程序应该在其初始化函数中启用回调调用。
9.4 唤醒验证的需求Requirements for Wakeup Validation
如果唤醒源需要验证,这可以由基本软件的任何一个(但只有一个)适当的模块来完成。这可能是一个驱动程序、一个接口、一个处理程序或一个管理器。
验证通过调用EcuM_ValidateWakeupEvent函数来完成。
如果EcuM不能确定Mcu驱动返回的复位原因,那么EcuM会为默认的唤醒源ECUM_WKSOURCE_RESET设置一个唤醒事件。
9.5 唤醒源和服务原因
ECU Manager模块API只提供了一种类型,可以描述ECU启动或唤醒的所有原因。
ECU管理器模块不能对以下唤醒源进行验证:
· ECUM_WKSOURCE_POWER
· ECUM_WKSOURCE_RESET
· ECUM_WKSOURCE_INTERNAL_RESET
· ECUM_WKSOURCE_INTERNAL_WDG
· ECUM_WKSOURCE_EXTERNAL_WDG
9.6 集成电源控制唤醒源 Wakeup Sources with Integrated Power Control
通过系统芯片(SBC)控制单片机的电源来实现睡眠。典型的例子是带有集成电源的CAN收发器,它可以在应用请求时关闭电源,在CAN活动时打开电源。其结果是,对于这种类型的硬件上的ECU管理器模块来说,SLEEP看起来像是OFF。
实际的影响是,CAN上的被动唤醒看起来就像ECU复位时的电源。因此,在一个唤醒事件之后,ECU将继续执行STARTUP序列。尽管如此,唤醒验证仍然是必需的,系统设计师必须考虑以下主题:
-- CAN收发器在一个驱动初始化块中被初始化(默认情况下在BswM控制下)。这是配置或生成的代码,即在系统设计人员控制下的代码。
-- CAN收发器驱动程序API提供了一些功能,用来发现是否是CAN收发器在被动唤醒时启动了ECU。系统设计师的职责是检查CAN收发器的唤醒原因,并通过使用EcuM_SetWakeupEvent和EcuM_ClearWakeupEvent函数将该信息传递给ECU管理器模块。
这些原理适用于所有具有综合功率控制的唤醒源。此处仅以CAN收发器为例。
10.关机目标Shutdown Target
“关机目标”是一个描述性术语,用于描述没有执行代码的所有ECU状态。它们被称为关闭目标,因为它们是状态机在离开UP阶段时将驱动到的目标状态。以下状态为关机目标:
· Off
· Sleep
· Reset
确定关闭目标的时间并不一定是关闭的开始时间。由于BswM现在控制了大部分ECU资源,它将决定何时应该设置关机目标,并将其直接或间接地进行设置。因此,BswM必须确保,例如,在调用EcuM_GoHalt或EcuM_GoPoll之前,必须将关机目标从其默认值更改为ECUM_STATE_SLEEP。
在ECU Manager模块的早期版本中,睡眠目标被特殊处理,因为在ECU中实现的睡眠模式取决于ECU的功能。这些睡眠模式取决于硬件,通常在时钟设置或硬件提供的其他低功耗特性上有所不同。这些不同的特性可以通过MCU驱动程序作为所谓的MCU模式进行访问。
还有不同的复位方式,由不同的模块控制或触发:
· Mcu_PerformReset
· WdgM_PerformReset
· Toggle I/O Pin via DIO / SP
ECU管理器模块提供了一个工具,通过跟踪时间和前一次复位的原因来管理这些复位模式。这些复位模式,使用与睡眠相同的模式设施。
10.1 Sleep
在SLEEP阶段不能错过任何唤醒事件。如果GoSleep序列中发生了唤醒事件,则不能输入Halt或Poll序列。
ECU管理器模块可以定义一组可配置的睡眠模式,其中每个模式本身是关机目标。
ECU管理器模块应允许将MCU的睡眠模式映射到ECU的睡眠模式,从而允许它们作为关机目标。
ShutdownTarget睡眠将使所有核进入睡眠状态。
10.2 Reset
ECU管理器模块应定义一组可配置的复位模式,其中每个模式本身是关机目标。该集合最少包括以下复位方式:
· Mcu_PerformReset
· WdgM_PerformReset
· Toggle I/O Pin via DIO / SPI
ECU管理器模块应定义一组可配置的复位原因。该集合应最少包括以下复位原因:
??EcuM状态机进入shutdown状态
??WdgM检测到错误
??Dcm模块请求shutdwon
ECU管理模块应为BSW模块和SW-C提供以下服务:
·记录关机原因
·获取一组最近关机原因
11.定时唤醒--Alarm Clock
ECU管理器模块提供了一个可选的持久时钟服务,即使在睡眠期间也保持“活跃”。因此,它保证了ECU将在未来的某个时间被唤醒(假设硬件没有故障),并为长期活动提供时钟服务(例如,以小时、天、甚至年计算)。
通常,该服务将通过ECU中的计时器来实现,该计时器可以诱导唤醒。然而,在某些情况下,外部设备也可以使用常规中断线来周期性唤醒ECU。无论使用何种机制,服务都会私下使用一个唤醒源。
EcuM模块维护一个主报警时钟(master alarm clock),主报警时钟的设置决定了ECU被唤醒的时间。此外,EcuM管理一个内部时钟,EcuM时钟,它是用来和主报警时钟进行比较校准。
定时唤醒机制只与SLEEP阶段相关。SWC和BSW模块可以在UP阶段设置和检索报警值(仅在UP阶段),设置的值在SLEEP阶段被体现。
与其他可以使用通用ECU管理器模块实现的定时/唤醒机制相比,Alarm Clock服务在计时器过期之前不会启动WakeupRestart序列。当ECU模块检测到它的计时器引起了一个唤醒事件,它增加它的计时器并立即返回睡眠,除非时钟时间超过了闹钟时间。
12.EcuM模式处理
ECU模式处理为sw - c引入了一个公共接口,即固定状态机(EcuMFixed)的ECU状态管理器。带有灵活状态机(EcuMFlex)的ECU状态管理器为sw - c提供了请求和释放模式RUN和POST_RUN(可选)的接口.
EcuMFixed使用特定的接口来决定ECU是否必须保持活动或准备关闭。与EcuMFixed相比,EcuMFlex只仲裁sw - c发出的请求和释放,并将结果传播到BswM。EcuM和BswM之间的合作是必要的,因为只有BswM可以决定何时可以过渡到不同的模式。由于EcuM没有自己的状态机,EcuM依赖于BswM进行的状态转换。因此,EcuM不请求状态。此外,它将所有请求的当前仲裁通知BswM。当RTE执行了属于某个模式的所有Runnables时,BswM会得到通知。
图19-ECU模式处理架构图
当BswM通过EcuM_SetState()设置EcuM的状态时,EcuM应将对应的模式更新到RTE。
当最后一个RUN请求被释放时,ECU State Manager模块应该使用API BswM_EcuM_RequestedState(POST_RUN, ECUM_RUNSTATUS_RELEASED .)向BswM请求状态POST_RUN。
如果SW-C在POST_RUN期间需要post运行活动(例如,shutdown准备),那么它必须在释放run请求之前请求POST_RUN。否则,不能保证这个SW-C将有机会运行它的POST_RUN代码。
当ECU状态管理器不处于SWC所请求的状态时,它应该使用BswM_EcuM_RequestedState() API通知BswM所请求的状态。
POST_RUN状态为SW-C提供了一个运行后阶段,并允许它们保存重要数据或关闭外设。
当最后一个POST_RUN请求被释放时,ECU State Manager模块应该使用API BswM_EcuM_RequestedState(SHUTDOWN,ECUM_RUNSTATUS_RELEASED)向BswM请求状态SHUTDOWN。
提示:为了防止ECU mode的模式机实例滞后,以及EcuM和RTE的状态脱离相位,EcuM可以使用确认反馈进行模式切换通知.
请注意,EcuM只向RUN和POST_RUN请求模式,SLEEP Mode必须由BswM设置,因为EcuM没有关于何时可以进入该模式的信息.
状态机(State) | 描述 |
STARTUP | 初始值。当Rte_Start()被调用时,由Rte设置。 |
RUN | 当所有必要的BSW模块初始化后,BswM将切换到此模式。 |
POST_RUN | 当没有可用的RUN请求时,EcuM请求POST_RUN。 |
SLEEP | 当没有RUN和POST_RUN请求时,EcuM请求SLEEP模式,Shutdown Target设置为SLEEP。 |
SHUTDOWN | 当没有RUN和POST_RUN请求时,EcuM请求SHUTDOWN模式,SHUTDOWN Target设置为SHUTDOWN。 |
13. 多核--Multicore
13.1 多核功能简介
本节介绍BSW模块在不同分区上的分布。
一个分区可以被看作是映射到一个核上的一个独立的部分。因此,每个核(包括单核和多核架构)至少包含一个分区,但也可以包含任意数量的分区。但是没有一个分区可以跨越多个核。
BSW模块可以分布在不同的分区上,因此也可以分布在不同的内核上。一些BSW模块(如BswM)必须包含到每个分区中。其他模块(如OS或EcuM)被包含到每个核心的一个分区中。
图20-ECU内部的分区Partitions
在多核架构中,EcuM必须以每个核存在一个实例的方式分布。
有一个指定的主内核,其中引导加载程序通过EcuM_init启动主EcuM。主EcuM启动一些驱动程序,决定Post-Build配置,并启动所有剩余的核心与所有卫星EcuM。然后,每个EcuM启动本地Core操作系统和所有本地BswM(在每个分区中恰好驻留一个BswM)。
如果相同的EcuM映像在ECU的每个核心上执行,ECU Manager的行为必须在不同的核心上有所不同。这可以由ECU管理器完成,首先测试它是在主核还是在从核上,并采取适当的行动。
ECU管理器模块支持与传统ECU相同的阶段(即STARTUP, UP, SHUTDOWN和SLEEP)。
如果使用了安全机制,ECU状态管理器必须以完全信任级别运行。
13.2 主核-Master core
多核系统有一个主核。主核由引导加载程序决定。主核的EcuM模块作为第一个BSW模块启动,并执行初始化操作。然后开始初始化其他核的EcuM模块。EcuM完成初始化后,对应核的OS和BswM也完成了初始化。
13.3 从核-Slave core
在每个从核上,必须运行一个EcuM模块。一个核上可以包含多个分区,每个核必须包括一个EcuM。
13.4 主从和通信-Master Core and Slave Core Signalling
操作系统为同步主核和从核上操作系统的启动提供了基本机制。Scheduler Manager为跨分区边界的BSW模块通信提供了基本机制。每个核心有一个BSW模式管理器负责启动和停止RTE。
13.5 示例-关机同步 Shutdown Synchronization
在调用ShutdownAllCores之前,“主”ECU管理模块必须启动所有“从”ECU管理模块的关闭,并且必须等待所有模块对它们负责的BSW模块进行反初始化并成功关闭。
因此,主ECU管理模块设置了一个关机标志,所有从模块都可以读取该标志。EcuM为每个配置的从核激活后续任务。从模块读取主例程中的标志,并在被请求时关闭。任务名称为“EcuM_SlaveCore<X>_Task”,其中X为数字。该任务需要由系统集成-er配置。需要激活的任务数可以通过计算EcuMPartitionRef的实例减1来计算,因为主服务器使用一个EcuMFlexPartionRef。
示例:配置三个EcuMPartitionRef实例。然后在调用EcuM_GoDown()时,“EcuM_SlaveCore1_Task”和“EcuM_SlaveCore2_Task”会被启动。从模块读取主例程中的标志,并在被请求时关闭。
操作系统扩展了OSEK SetEvent函数。一个核上的任务可以等待另一个核上设置的事件。下图说明了如何在调用ShutdownAllCores之前同步内核的问题(省略了反初始化的细节)。Set/WaitEvent函数接受一个位掩码,该位掩码可以用来指示各个从核上的shutdown就绪状态。每一个来自“从”ECU管理模块的SetEvent调用将停止“主”ECU管理模块的等待。因此,“主”ECU管理器模块必须跟踪各个从核的状态,并设置等待,直到所有核都已就绪。
图21-关机同步
13.6 UP Phase
从硬件的角度来看,唤醒中断可能发生在所有的核上。然后整个ECU被唤醒,运行在上面的EcuM处理唤醒事件。
与单核情况一样,BswM(由集成者配置)负责控制ECU资源,确定本地核心可下电或深度休眠,以及在将其核心的控制移交给EcuM之前,去初始化适当的应用程序和BSW。
13.7 STARTUP Phase
ECU管理器模块在所有核心上的功能几乎相同。也就是说,对于单核的情况,ECU Manager模块执行Startup指定的步骤;最重要的是启动操作系统、初始化SchM和启动核心本地bswm。
主EcuM在调用InitBlock 1并进行reset/wakeup验证后激活所有从核。在被激活之后,从核执行它们的启动例程,在它们的核心上调用EcuM_Init。
在每个EcuM调用其核上的StartOs之后,操作系统在每个核启动钩子函数之前同步这些核,并在每个核上执行第一个任务之前再次同步这些核心。
每个分区上的一个BswM必须为该核心启动RTE。
图22-Master Core StartPreOS Sequence
图23-Master Core StartPostOS Sequence
图24-- Slave Core StartPreOS Sequence
图25-Slave Core StartPostOS Sequence
13.8 SHUTDOWN Phase
不支持个别核心关闭(即当ECU的其余部分继续运行时)。所有核心同时关闭。
当ECU应该关闭时,主ECU管理模块调用ShutdownAllCores而不是通过某种方式调用各个核上的ShutdownOs。ShutdownAllCores停止所有核上的操作系统,同时也停止所有核。
因为主核可以在所有从核完成处理之前发出ShutdownAllCores,所以在进入SHUTDOWN之前必须同步内核.
BswM(分布在所有分区上)确定ECU应该关闭并与ECU中的每个BwsM同步。所有BswM反初始化所有分区的Bsw、Swc和Cdd,并向其他BswM发送适当的信号,表明它们准备关闭。
对于ECU的关闭,BswM(位于主EcuM的同一个分区中)最终调用主核上的GoOff,该GoOff将请求分发给所有的从核。“主”EcuM对BswM和SchM进行反初始化。从内核上的EcuMs取消了它们的SchM和BswM的初始化,然后发送一个信号,表明内核已经为ShutdownOs做好了准备。
主EcuM等待来自每个从核EcuM的信号,然后像往常一样在主核上启动关机(主EcuM调用ShutdownAllCores,并且ECU与全局关机挂钩放在bed上)。
图26- Master Core OffPreOS Sequence
图27-Master Core OffPostOS Sequence
图28-- Slave Core OffPreOS Sequence
图29-Slave Core OffPostOS Sequence
13.9 SLEEP Phase
当Shutdown目标Sleep]被请求时,所有内核将同时休眠。MCU必须为每个核心发出一个Halt指令。由于任务的定时和优先级是能在本地核的OS中完成,因此调度程序和RTE都不需要在MCU进入Halt状态后进行同步。因为主核可以在所有从核完成处理之前让MCU停止,所以内核必须在进入GoHalt之前进行同步。
BswM确定应该启动睡眠,并为每个核心分配适当的ECU模式。从核上的bsw、swc和cdd必须被它们的分区本地BswM通知,适当地去初始化并向BswM发送适当的模式请求,以表明它们的准备就绪。
如果ECU被置于睡眠状态,“halt”必须被同步,以便在主核计算校验和之前所有的从核都被停止(Halted)。主核上的ECU管理器模块使用了与GoOff上同步核相同的“信号”机制。
类似地,主核上的ECU管理器模块必须在从核从“停止”状态释放之前验证校验和.
图30- Master Core GoSleep Sequence
图31-Master Core Halt Sequence
图32- Master Core Poll Sequence
图33- Master Core WakeupRestart Sequence
图34-Slave Core GoSleep Sequence
图35-Slave Core Halt Sequence
图36-Slave Core Poll Sequence
图37-Slave Core WakeupRestart Sequence
14.EcuM在使用经验
多数情况下MCU在使用的时候一般都会使用相关的SBC芯片,因此在EcuM的Shutdown Target中直接选择对应的OFF模式就可以。在使用了外部的SBC控制相关的MCU的下电的时候,在OFF阶段最后调用SBC进入到Sleep的指令。
在MCU走最后的下电,让外部的SBC休眠流程的时候一定要确保SBC唤醒相关的引脚没有高电平,否则操作SBC进入休眠会导致SBC相关的错误。
在APP层可以添加相关的模块单独做ECU的唤醒检测,并不需要使用EcuM内部的唤醒功能做,也可以基于两者设计唤醒相关的检测机制。
APP中也可以定义模式管理模块来协调BSW的模式管理,同时管理APP层的各个模块状态切换和运行。
在多核下电的时候,一定要让从核进行GetCoreID的判断,保证主核进入到最终的下电操作。
EcuM_OnGoOffTwo和EcuM_AL_SwitchOff可以直接使用一个实现,并不一定完全使用CP AUTOSAR定义的这两个下电流程。
对于RESET的Shutdown Target可以不要做,直接做成OFF,然后根据相关的功能(DCM请求、程序流监控出错、内存相关的权限监控出错等)使用直接调用Mcu_PerformReset相关的函数执行RESET操作。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!