一文看懂 AUTOSAR 中的 ECU 启动全流程

目录

  往期推荐

一、从复位开始:ECU 启动的第一步

二、OS 初始化:让系统“有中断可用”

Os_InitializeVectorTable 的一般情况:

三、 驱动初始化(Driver Initialization)

⏱ EcuM Startup Duration:

四、启动 OS

⚙️ 多核系统中的 OS 启动:

五、初始化任务(Init Task)

🧩 旧版 BSW 的特别说明:

六、BswM Start-up One:初始化记忆栈

七、BswM Start-up Two:启动 RTE 之前的最后一步

🔁 模块初始化顺序的变化:

八、RTE 启动:让 ECU 真正“跑起来”

九、调度表(Schedule Table)

调试技巧:OS 与死循环问题

总结:一条清晰的 ECU 启动主线

📘 思考


  往期推荐

  1. 2025汽车行业新宠:欧企都在用的工具软件
  2. 【AUTOSAR高效开发神器】Davinci AutomationInterface帮你!
  3. ETAS工具链自动化实战指南<一>
  4. ETAS工具链自动化实战指南<二>
  5. ETAS工具链自动化实战指南<三>
  6. AUTOSAR工程师必读:Artop的核心功能
  7. Vector工具链自动化实战指南<一>
  8. isolar高手秘籍| ECU Configuration三分钟速成!
  9. 掌握核心步骤:RTA-BSW以太网配置全解析
  10. 一文详解TC399 CAN MCAL 配置
  11. LSL常见应用场景及示例<一>
  12. LSL常见应用场景及示例<二>
  13. LSL常见应用场景及示例<三>
  14. 为什么Autosar钟情arxml而非json?大揭秘!
  15. 深入浅出:SOME/IP-SD的工作原理与应用
  16. 【技术进阶】|一文掌握Autosar ComStack的精髓!
  17. Autosar培训笔记整理<一>
  18. 【AutoSAR进阶】|实战详解ETAS工具链UDS 0x2f服务核心配置!
  19. 实战详解ETAS工具链CanTp模块自动化配置
  20. 一文掌握5种常见的AUTOSAR 错误类型
  21. 【AUTOSAR工程师必备知识】一文搞懂AUTOSAR架构9种通信方式
  22. 实战干货|详解ETAS工具链之 intra-ECU通信的数据转换

在调试 ECU 启动问题时,你是否遇到过这些疑问:

  • 为什么系统停在 EcuM_Init() 就不动了?

  • OS 启动后任务没跑起来是哪里没配置?

  • RTE 什么时候才真正开始调度?

  • BswM 的 Start-up One 和 Start-up Two 到底在干嘛?

本文带你完整梳理 AUTOSAR 中 ECU 的启动过程,从硬件复位到任务调度运行,逐步揭开 EcuM、OS、BswM、RTE 各阶段之间的调用逻辑。

一、从复位开始:ECU 启动的第一步

当 MCU 从复位向量(Reset Vector)跳转时,最先执行的是芯片特定的启动代码。这一步会初始化栈指针、准备内存空间,最终跳转到主应用入口点。

👉 ECU 应用层的第一个函数就是:

EcuM_Init();

它标志着 AUTOSAR 启动流程正式开始。

二、OS 初始化:让系统“有中断可用”

在 EcuM_Init() 中,系统会首先调用:

EcuM_AL_SetProgrammableInterrupts();

这一过程非常关键,因为内部会执行:

Os_InitializeVectorTable();

这是 OS 层的底层 API,用于准备中断向量表,让系统具备响应中断的能力。 但此时中断还未真正触发,只有在 StartOS() 调用之后,OS 才会开始接管中断。

📘 注意: 如果你的系统未正确调用 Os_InitializeVectorTable(),ISR 将无法运行,OS 任务调度也会异常。

Os_InitializeVectorTable 的一般情况:

如上所述,在 RH850 端口中 Os_InitializeVectorTable() 的调用方式如下:

通常有两种情况:

  • 在非 AUTOSAR 系统中,应在 Os_Main() 中调用;

  • 在 AUTOSAR 系统中,应通过 EcuM 调用。

若两处均被配置并连续调用两次,实际上只是覆盖初始化,不会造成严重影响(只要在 OS 启动前完成)。

三、 驱动初始化(Driver Initialization)

接下来是 Driver Init Zero 和 Driver Init One 调用,这是 BSW 中最早的初始化调用之一。这两个初始化列表用于启动 MCAL 层驱动 和最底层的 Complex Device Drivers

在 ISOLAR 中,这部分配置可在以下位置查看:

对应的生成代码位于:

通常每个模块会接收一个包含配置的结构体指针作为参数。某些目标平台上的非 AUTOSAR 兼容 MCAL 模块可能例外,具体请参考硬件厂商的生成代码或文档。

⏱ EcuM Startup Duration:

若想使用 EcuM_GetTicks() 函数,可通过设置相关配置参数为 true 启用。

当 EcuMRbStartupDuration = true,系统将在每个驱动初始化列表的起始与结束处自动生成该函数调用。

⚠️ 注意: 应确保 EcuM_GetTicks() 关联的计时器在调用前已启动。例如,若该函数返回的计时器值来自 MCU 初始化的计时器,而 MCU 尚未初始化,则结果将无效。 集成方需确保逻辑合理。

四、启动 OS

在 EcuM_Init() 的最后一步是启动 OS:

此时 MCU 进入一个 while 循环,执行 Os_Cbk_Idle(),该函数始终返回 TRUE,从而形成 while(1) 的空闲循环。

此时 OS 已启动,但调度表(Schedule Table)还没启动。只有当 RTE 启动后,任务调度才真正开始。

启动 OS 的调用也会触发所有配置为 Auto Start 的 OS 任务。在ETAS Starter Kit 中,唯一配置为自动启动的任务是InitTask,它不属于调度表,只在启动时执行一次。

⚙️ 多核系统中的 OS 启动:

在多核应用中,所有非主核最初均处于挂起状态。以 RH850 为例:

  • 只有主核主动启动;

  • 其他核通过 Os_AwaitStartup() 等待;

  • 主核通过 OS 内部函数 Os_Cbk_StartCore() 唤醒从核;

  • 所有核都会运行到 Os_Main(),并执行 EcuM_Init()

💬 换句话说:在多核系统中,EcuM_Init() 需要在每个核心上都执行一次。

五、初始化任务(Init Task)

Init Task 阶段的主要目标是初始化并启动 BswM Init 列表:

其核心任务是初始化 BswM 模块 并触发第一个 Action List。,为后续启动阶段做准备。

🧩 旧版 BSW 的特别说明:

在 BSW ≤ 6.1.2 的版本中,由于 SchM 在 BswM 之前初始化,需要重新启动一次 SchM。 原因是 AUTOSAR 4.2.2 的启动流程在 BSW 6.1.2 中沿用,而从 6.1.3 开始,系统已适配 AUTOSAR 4.3.1

旧版本的启动流程如下:

EcuM_StartupTwo() 会调用 BswM_Init(),当 BswM 初始化完成后,SchM_IModeInit 将触发 BswM Init List One

六、BswM Start-up One:初始化记忆栈

在 ISOLAR 中以下位置中查看 BswM 用户回调列表:

Start-up One 的目标是:

  1. 初始化内存栈(Mem Stack);

  2. 执行 NvM_ReadAll()

  3. 触发 Start-up Two

这两个操作是下一个动作列表(Action List)执行的触发条件。

七、BswM Start-up Two:启动 RTE 之前的最后一步

要激活 Start-up Two,必须满足以下两个条件:

  • NvM_ReadAll 完成;

  • Start-up One 完成。

在这一阶段,系统初始化剩余的 BSW 模块,其中最重要的是启动 RTE 的集成代码调用。

🔁 模块初始化顺序的变化:

RTA-BSW 版本

调用顺序

≤ 6.1.2

SchM_Init() → BswM_Init()

≥ 6.1.3

BswM_Init() → SchM_Init()

八、RTE 启动:让 ECU 真正“跑起来”

RTE 启动阶段是 ECU 启动序列中最关键的部分之一。调用 Rte_Start() 表示 ECU 几乎已完全启动。

当第一次调用 Rte_Start() 时,RTE 会:

  1. 启动 Schedule Table;此时 ECU 已接近完全运行状态

  2. 启动 Rte_TickCounter

  1. 启用 GPT 通知,每 1ms 触发一次计数器自增。

当 GPT 定时器稳定运行时,ECU 就正式进入“正常运行模式”。 此时 ECU 基本已启动完成,最后一个 BswM 动作列表用于启用 ComM 通道 和 PduGroup,从而使通信模块运行起来。

九、调度表(Schedule Table)

RTE 根据 runnable 的周期生成 osNeeds.arxml,其中定义了调度表(Schedule Table)。

例如在在 Starter Kit 中:

  • BSW 任务:每 1ms 执行;

  • ASW 任务:每 10ms 执行。

当任务被激活后,从 Suspended 状态进入 Ready 状态; OS 会根据优先级调度高优先级任务进入 Running 状态; 执行完成后任务重新进入 Suspended 状态。

由于调度表配置为循环,最后一个 Expiry Point 执行完会回到第一个。因此 ASW 每 10ms 激活一次。

每当 Rte_TickCounter 增加一次,OS 就进入下一个 Expiry Point。

调试技巧:OS 与死循环问题

若系统在启动中陷入死循环,可在 ErrorHook 中添加断点或日志输出,用于捕获 OS 报错:

void ErrorHook(void) {
    while(1); // 断点定位错误来源
}

如果代码进入了非预期的死循环,通常意味着启动过程中某个函数未获得期望的响应。例如,MCU 代码可能在等待 MCU_PLL_LOCKED 状态时无限阻塞。有些目标平台会在超时后进入错误钩子(ErrorHook),此时可通过错误信息进行调试。

总结:一条清晰的 ECU 启动主线

阶段

关键函数

说明

1

EcuM_Init()

启动入口

2

Os_InitializeVectorTable()

启动中断向量表

3

Driver Init Zero/One

初始化底层驱动

4

StartOS()

启动 OS 主循环

5

Init Task

初始化 BswM

6

BswM Start-up One

读 NvM,准备下一阶段

7

BswM Start-up Two

启动 RTE

8

Rte_Start()

启动调度表与任务调度

9

GPT TickCounter

驱动时间基准,系统稳定运行

📘 思考

EcuM 的启动过程其实就是“系统自举”过程的抽象: 从硬件 → OS → 驱动 → 服务 → 应用,每一层都为下一层提供运行条件。 理解启动顺序,能让我们更高效地排查启动异常、时序问题、乃至多核同步问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值