7.9 多核操作系统
本章规定了一些扩展功能,使得AUTOSAR系统能够在多核微处理器上使用。它描述了主要原理,以及针对多核场景对现有OS功能的额外扩展。下一章将详细说明OS内部一种名为IOC(核间应用通信器)的新机制,该机制支持位于同一核或不同核上的OS应用之间的通信。
7.9.1 背景与原理
现有的AUTOSAR操作系统基于OSEK/VDX操作系统,该系统在汽车行业应用广泛。AUTOSAR多核操作系统由现有的AUTOSAR OS衍生而来。
AUTOSAR中的多核OS并非虚拟ECU概念,而应理解为共享相同配置和大部分代码,但在每个核上操作不同数据结构的操作系统。
为减少内存占用,所有核应使用相同的代码库。有时,为了获得更快的ROM/Flash访问速度,可能需要消耗更多的ROM/Flash空间(例如使用本地ROM),并“复制”部分代码。
7.9.1.1 要求
[SWS_Os_00567] ⌈操作系统的生成部分源自单一配置,该配置包含所有核的相关信息。这意味着,ID(如TASKID、RESOURCEID等)在所有核中是唯一的。每个ID应精确指向一个实体,与访问该实体的核无关。这也适用于不能在核之间共享的对象。⌋(SRS_Os_80008)
7.9.2 调度
任务的优先级决定调度。由于多个核真正并行运行,多个任务可以同时执行。
| 优先级 | 核0 | 核1 | 核2 |
|---|---|---|---|
| 5 | T2 | - | - |
| 4 | - | T5 | - |
| 3 | T3 | T3 | T6 |
| 2 | T4 | - | T4 |
| 1 | - | T1 | - |
图2:优先级分配给任务。各核独立调度。任务T2、T3和T5真正并行执行。同一核上相同优先级的任务按激活顺序执行;不同核上相同优先级的任务可能不按激活顺序执行,因为各核调度相互独立。
每个核可并行进入操作系统。这优化了系统对多核的扩展性。各核独立调度,即一个核的调度不影响其他核的调度。一个核上的低优先级任务可能与另一个核上的高优先级任务并行运行。任务和中断不能通过调度算法动态切换核。
7.9.2.1 要求
[SWS_Os_00568] ⌈实现应能在每个已启动的AUTOSAR OS核上独立并行执行任务或中断服务程序(ISR)。⌋(SRS_Os_80001)
[SWS_Os_00569] ⌈在多核系统中,AUTOSAR OS中定义的调度策略应适用于每个核上分配的任务和中断服务程序。⌋(SRS_Os_80001、SRS_Os_80013)
7.9.3 可定位实体(LE)
可定位实体是必须完全位于一个核上的实体。可定位实体到核的分配在配置时定义(通过OsApplicationCoreRef)。
在本版AUTOSAR标准中,OS应用应作为可定位实体。因为每个任务必须在某个核上运行,所以在AUTOSAR R4.0的多核系统中,OS应用的使用成为必需。基础软件模块不得忽略OS应用,即使不使用任何保护机制也是如此。这与可伸缩性等级无关。
如《AUTOSAR操作系统规范》所述,如果使用OS应用,所有任务、中断服务程序等必须属于某个OS应用。这意味着,在多核系统中,不存在AUTOSAR软件位于OS应用之外的情况。
在单核系统中,OS应用仅在可伸缩性等级3和4中可用,因为该机制用于支持内存保护,且意味着使用扩展模式。在多核系统中,无论是否使用内存保护,OS应用始终可用,且在可伸缩性等级1的标准模式下也应可行。
7.9.3.1 要求
[SWS_Os_00570] ⌈分配给同一OS应用的所有任务应在同一核上执行。⌋(SRS_Os_80003、SRS_Os_80005)
[SWS_Os_00571] ⌈分配给同一OS应用的所有中断服务程序应在同一核上执行。⌋(SRS_Os_80003、SRS_Os_80005)
[SWS_Os_00572] ⌈启动时,操作系统应关闭中断均衡(如果硬件支持)。⌋(SRS_Os_80005、SRS_Os_80006)
[SWS_Os_00764] ⌈在多核情况下,OS模块应支持可伸缩性等级1和2中的OS应用。⌋()
[SWS_Os_00763] ⌈在可伸缩性等级1的系统中,应支持标准模式。⌋()
[SWS_Os_00573] ⌈OS应用到核的绑定应在OS应用容器中配置。⌋(SRS_Os_80003、SRS_Os_80005)
一个新的配置项:OS应用容器中的OsApplicationCoreRef,用于定义OS应用绑定到的核。OS生成器会将配置参数“CORE”映射到特定核,以便所有具有相同配置参数的OS应用位于同一核上。
7.9.4 多核启动概念
核的启动方式在很大程度上取决于硬件。通常,硬件仅启动一个核(称为主核),而其他核(从核)保持暂停状态,直到被软件激活。
与这种主从系统不同,还可以构想其他核独立启动的引导概念。然而,通过软件可以在这类系统上模拟主从行为。
AUTOSAR多核OS规范要求系统具备主从启动行为,这种行为可以由硬件直接支持,也可以通过软件模拟。主核定义为无需软件激活的核,而从核需要通过软件激活。
在多核配置中,每个受AUTOSAR使用的从核必须在该核上调用StartOS之前被激活。根据硬件情况,可能只能从主核激活部分可用核。从核在调用StartOS之前可能会激活其他核。所有属于AUTOSAR系统的核必须通过指定的AUTOSAR API函数激活。此外,必须在所有这些核上调用StartOS函数。
如果一个核被激活,它会执行一些硬件和编译器特定的操作,然后调用“main”函数。如果每个核执行相同的“main”函数,则在该函数中必须通过其特定的核ID来区分不同核。
示例:
void main ()
{
StatusType rv;
[…]
switch (GetCoreID())
{
case OS_CORE_ID_MASTER:
[…]
StartCore(OS_CORE_ID_0, &rv);
StartOS(OSDEFAULTAPPMODE);
break;
case OS_CORE_ID_0:
[…]
StartCore(OS_CORE_ID_1, &rv);
StartOS(DONOTCARE);
break;
default:
StartOS(DONOTCARE);
}
}
StartOS会对所有核进行两次同步。第一个同步点位于执行StartupHooks之前,第二个同步点位于OS应用特定的StartupHooks完成之后且调度程序启动之前。第二个同步点的确切位置取决于实现,但应在调度开始之前。本版AUTOSAR规范不支持同步阶段的超时。使用StartCore激活但未调用StartOS的核可能导致系统挂起。避免这种情况是集成者的责任。
如图3所示,每个核在第一次同步后立即调用StartupHook。然而,系统中只有一个StartupHook。例如,如果在StartupHook期间需要执行核特定的功能,可以使用GetCoreID函数来区分各个核。全局StartupHook完成后,每个核执行其OS应用的StartupHooks。由于OS应用绑定到核,因此OS应用特定的StartupHooks仅在相应OS应用绑定的核上执行。
| 核0 | 硬件特定初始化代码 | 激活核1 | 调用StartOS | OS执行操作系统初始化代码 | 同步所有核 | OS执行StartupHook | 应用StartupHook | 同步所有核 | OS内核运行 | 第一个用户任务运行 |
|---|---|---|---|---|---|---|---|---|---|---|
| 所有中断被禁用 | ||||||||||
| 核1 | 硬件特定初始化代码 | 激活核2和3 | 调用StartOS | OS执行操作系统初始化代码 | 同步所有核 | OS执行StartupHook | 应用StartupHook | |||
| 所有中断被禁用 | ||||||||||
| 核2 | 硬件特定初始化代码 | 调用StartOS | OS执行操作系统初始化代码 | 同步所有核 | OS执行StartupHook | |||||
| 所有中断被禁用 | ||||||||||
| 核3 | 硬件特定初始化代码 | 调用StartOS | OS执行操作系统初始化代码 | 同步所有核 | OS执行StartupHook |
图3:此图展示了一个4核初始化过程的示例。
7.9.4.1 要求
[SWS_Os_00574] ⌈主核应能激活其他核。⌋(SRS_Os_80006、SRS_Os_80026、SRS_Os_80027)
[SWS_Os_00575] ⌈任何从核应能激活其他核。⌋(SRS_Os_80006、SRS_Os_80026、SRS_Os_80027)
[SWS_Os_00576] ⌈允许仅将微控制器上可用核的一部分用于AUTOSAR系统。⌋(SRS_Os_80006、SRS_Os_80026、SRS_Os_80027)
[SWS_Os_00577] ⌈核应以主从模式启动。如果硬件不支持,核应并行启动并模拟主从系统的行为。⌋(SRS_Os_80006、SRS_Os_80026、SRS_Os_80027)
[SWS_Os_00578] ⌈在模拟情况下,受AUTOSAR OS控制的从核(CoreS)在另一个核通过StartCore(CoreS)激活它之前,不得进入main函数。⌋(SRS_Os_80006)
[SWS_Os_00579] ⌈所有属于AUTOSAR系统的核应在StartOS函数内、调度启动之前以及全局StartupHook调用之后进行同步。⌋(SRS_Os_80001、SRS_Os_80006)
[SWS_Os_00580] ⌈所有属于AUTOSAR系统的核应在StartOS内、全局StartupHook调用之前进行同步。⌋(SRS_Os_80006)
[SWS_Os_00581] ⌈全局StartupHook应在第一次同步点之后立即在所有核上调用。⌋(SRS_Os_80006)
[SWS_Os_00582] ⌈OS应用特定的StartupHooks应在全局StartupHook之后调用,但仅在OS应用绑定的核上调用。⌋(SRS_Os_80006、SRS_Os_80008)
7.9.5 受AUTOSAR OS控制的核
如上所述,AUTOSAR OS控制多个核。但它不必控制微控制器的所有核。可在配置的“OsOS”部分中配置可控制的最大核数。
AUTOSAR OS API提供StartCore函数来启动其控制下的核。StartCore函数接受一个CoreIdType类型的标量参数,指定要启动的核。可以在主核上多次调用StartCore,也可以在从核上调用。然而,每个核只能启动一次。例如:
StatusType rv1, rv2;
StartCore(OS_CORE_ID_1, &rv1);
StartCore(OS_CORE_ID_2, &rv2);
if ((rv1 != E_OK) || (rv2 != E_OK))
EnterPanicMode();
StartOS(OSDEFAULTAPPMODE);
必须在所有通过StartCore激活的核上调用StartOS函数。不允许从已调用StartOS的核调用StartCore。
属于AUTOSAR系统的核必须通过指定的AUTOSAR OS API服务StartCore启动。
7.9.5.1 要求
[SWS_Os_00583] ⌈可由AUTOSAR OS控制的核数应在离线时配置。
“OsOS”容器中的新配置项(OsNumberOfCores)用于指定AUTOSAR OS控制的最大核数。如果未指定(OsNumberOfCores)的值,则核数应为1。⌋(SRS_Os_80001、SRS_Os_80011)
7.9.6 不受AUTOSAR OS控制的核
StartNonAutosarCore函数可在调用StartOS之前和之后使用。它用于激活不受其他OS控制或根本不受任何OS控制的核。在这些核上不得调用AUTOSAR函数,否则行为未定义。
7.9.6.1 要求
[SWS_Os_00584] ⌈AUTOSAR OS应提供一个名为StartNonAutosarCore的函数,可用于启动不受AUTOSAR OS控制的核。⌋(SRS_Os_80006、SRS_Os_80026、SRS_Os_80027)
[SWS_Os_00585] ⌈应能在调用StartOS之前和之后激活不受AUTOSAR OS控制的核。⌋(SRS_Os_80006、SRS_Os_80026、SRS_Os_80027)
7.9.7 多核关闭概念
AUTOSAR支持两种关闭概念:同步关闭和单独关闭。同步关闭由新的API函数ShutdownAllCores()触发,而单独关闭由现有的API函数ShutdownOS()调用。
7.9.7.1 同步关闭概念
如果具有适当权限的任务调用“ShutdownAllCores”,会向所有其他核发送信号以启动关闭过程。一旦某个核上启动了关闭过程,就不再处理中断和任务,也不会进行调度,因此激活任何任务都没有意义,但不会产生错误。应用程序开发人员/系统集成者有责任确保在调用“ShutdownAllCores”之前,应用程序和基础软件级别的所有关闭准备工作都已完成(例如通过ECU状态管理器)。
在关闭过程中,每个核执行其OS应用特定的ShutdownHook函数,随后进入同步点。所有核都达到同步点后,所有核并行执行全局ShutdownHook函数。
| 任务3 | 任务3 | 任务3 | 关闭 | OS应用关闭钩子 | 等待 | 关闭钩子 |
|---|---|---|---|---|---|---|
| 任务2 | 任务2 | 任务2 | 关闭 | OS应用关闭钩子 | 等待 | 关闭钩子 |
| 任务1 | 任务1 | 关闭 | OS应用关闭钩子 | 等待 | 关闭钩子 | |
| 任务4 | 关闭 | OS应用关闭钩子 | 关闭钩子 |
图4:关闭过程示例。
[SWS_Os_00586] ⌈在关闭期间,OS应用特定的ShutdownHook应在相应OS应用绑定的核上调用。⌋(SRS_Os_80007)
[SWS_Os_00587] ⌈在调用全局ShutdownHook之前,所有核应进行同步。⌋(SRS_Os_80007)
[SWS_Os_00588] ⌈全局ShutdownHook应在所有核上调用。⌋(SRS_Os_80007)
7.9.7.2 单独关闭概念
如果任务调用ShutdownOS,将在调用ShutdownOS的核上关闭OS。每个核都应能调用ShutdownOS。与StartOS类似,此函数将关闭单个核。要关闭整个ECU,必须在每个核上调用ShutdownOS。该函数不会返回。AUTOSAR R4.x不支持单独关闭(AUTOSAR模式管理不会使用它)。
7.9.7.3 致命内部错误情况下的关闭
在多核系统中,可能仅在一个核上检测到致命的内部OS错误。在这种情况下,仅关闭该核是没有意义的。
[SWS_Os_00762] ⌈如果OS检测到致命的内部错误,所有核都应关闭。⌋()
7.9.8 OS服务功能(概述)
在本章中,我们描述了现有的单核AUTOSAR OS功能中有哪些已被扩展。下表概述了所有标准OS API函数。“多核支持”列包含以下值之一:
- 扩展:为支持特殊的多核功能,对函数进行了实质性扩展。
- 适配:函数需要一些小的更改,但基本保持不变。
- 未更改:函数的行为未改变。
- 新增:该函数是新的AUTOSAR OS API函数。
| 服务 | 多核支持 | 注释 |
|---|---|---|
| ActivateTask | 扩展 | 应支持跨核使用。 |
| ActivateTaskAsyn | 扩展 | 应支持跨核使用。 |
| AllowAccess | 未更改 | 仅在同一核上有效 |
| CallTrustedFunction | 适配 | 函数必须绑定到同一核 |
| CancelAlarm | 扩展 | 应支持跨核使用 |
| ChainTask | 扩展 | 应支持跨核使用。 |
| CheckISRMemoryAccess | 未更改 | |
| CheckObjectAccess | 未更改 | |
| CheckObjectOwnership | 未更改 | |
| CheckTASKMemoryAccess | 未更改 | |
| ClearEvent | 未更改 | |
| ControlIdle | 未更改 | 允许从任何核调用 |
| DisableAllInterrupts | 未更改 | 仅在同一核上有效 |
| EnableAllInterrupts | 未更改 | 仅在同一核上有效 |
| GetActiveApplicationMode | 未更改 | |
| GetAlarm | 扩展 | 应支持跨核使用 |
| GetAlarmBase | 扩展 | 应支持跨核使用 |
| GetApplicationID | 未更改 | |
| GetApplicationState | 扩展 | 应支持跨核使用 |
| GetCoreID | 新增 | 当前核的ID |
| GetCounterValue | 适配 | 不允许跨核。 |
| GetElapsedValue | 适配 | 不允许跨核。 |
| GetEvent | 未更改 | |
| GetISRID | 未更改 | |
| GetNumberOfActivatedCores | 新增 | 启动期间激活的核数。 |
| GetResource | 适配 | 可与自旋锁嵌套 |
| GetScheduleTableStatus | 扩展 | 应支持跨核使用。 |
| GetSpinlock | 新增 | 占用自旋锁 |
| GetTaskID | 未更改 | 仅在同一核上有效 |
| GetTaskState | 扩展 | 应支持跨核使用 |
| IncrementCounter | 适配 | 不允许跨核。 |
| NextScheduleTable | 未更改 | |
| ReleaseResource | 适配 | 可与自旋锁嵌套 |
| ReleaseSpinlock | 新增 | 释放自旋锁 |
| ResumeAllInterrupts | 未更改 | 仅在同一核上有效 |
| ResumeOSInterrupts | 未更改 | 仅在同一核上有效 |
| Schedule | 适配 | 检查未释放的自旋锁 |
| SetAbsAlarm | 扩展 | 应支持跨核使用 |
| SetEvent | 扩展 | 应支持跨核使用。 |
| SetRelAlarm | 扩展 | 应支持跨核使用 |
| SetScheduleTableAsync | 未更改 | |
| ShutdownAllCores | 新增 | 同步关闭。 |
| ShutdownOS | 扩展 | 支持多核系统 |
| StartCore | 新增 | 启动额外的核 |
| StartOS | 扩展 | 支持多核系统 |
| StartNonAutosarCore | 新增 | 启动额外的核 |
| StartScheduleTableAbs | 扩展 | 应支持跨核使用。 |
| StartScheduleTableRel | 扩展 | 应支持跨核使用。 |
| StartScheduleTableSynchron | 未更改 | |
| StopScheduleTable | 扩展 | 应支持跨核使用。 |
| SuspendAllInterrupts | 未更改 | 仅在同一核上有效 |
| SuspendOSInterrupts | 未更改 | 仅在同一核上有效 |
| SyncScheduleTable | 未更改 | |
| TerminateApplication | 扩展 | 检查未释放的自旋锁。应支持跨核使用。 |
| TerminateTask | 适配 | 检查未释放的自旋锁 |
| TryToGetSpinlock | 新增 | 尝试占用自旋锁 |
| WaitEvent | 适配 | 检查未释放的自旋锁 |
表2:OS服务调用的更改概述
| 服务 | 任务 | 类别1中断服务程序 | 类别2中断服务程序 | 错误钩子 | 任务前钩子 | 任务后钩子 | 启动钩子 | 关闭钩子 | 警报回调 | 保护钩子 |
|---|---|---|---|---|---|---|---|---|---|---|
| GetNumberOfActivatedCores | ✓ | ✓ | ||||||||
| GetCoreID | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| StartCore | ||||||||||
| StartNonAutosarCore | ✓ | |||||||||
| GetSpinlock | ✓ | ✓ | ||||||||
| ReleaseSpinlock | ✓ | ✓ | ||||||||
| TryToGetSpinlock | ✓ | ✓ |
表3:OS服务调用的允许调用上下文
[SWS_Os_00589] ⌈所有不允许跨核操作的函数,如果调用参数需要跨核操作,在扩展状态下应返回E_OS_CORE。⌋(SRS_Os_80013)
7.9.9 GetTaskID
GetTaskID可在任务和中断服务程序2级调用。在单核系统上,当从中断例程调用时,GetTaskID要么返回被中断的任务,要么指示没有任务在运行。在多核系统上,它:
- 指示该核上没有任务在运行,或者
- 返回该核上被中断的任务的ID。
7.9.10 中断禁用
注意:所有类型的中断只能在本地核上禁用。这意味着其他核上的中断标志保持其当前状态。其他核上的调度继续进行。其他核上运行的中断服务程序继续执行。
7.9.10.1 要求
[SWS_Os_00590] ⌈OS服务“DisableAllInterrupts”应仅影响调用它的核。⌋(SRS_Os_80013)
[SWS_Os_00591] ⌈OS服务“EnableAllInterrupts”应仅影响调用它的核。⌋(SRS_Os_80013)
[SWS_Os_00592] ⌈OS服务“SuspendAllInterrupts”应仅影响调用它的核。⌋(SRS_Os_80013)
[SWS_Os_00593] ⌈OS服务“ResumeAllInterrupts”应仅影响调用它的核。⌋(SRS_Os_80013)
[SWS_Os_00594] ⌈OS服务“SuspendOSInterrupts”应仅影响调用它的核。⌋(SRS_Os_80013)
[SWS_Os_00595] ⌈OS服务“ResumeOSInterrupts”应仅影响调用它的核。⌋(SRS_Os_80013)
7.9.11 任务激活
任务激活应扩展为支持跨核。本文档不指定任何实现细节。跨核操作时,此函数的时序行为可能更慢。如果需要在另一个核上激活任务,该核上需要进行调度决策。如果该核尚未启动,则会产生错误。
7.9.11.1 要求
[SWS_Os_00596] ⌈只要分配的访问权限允许,就应能激活属于位于另一个核上的OS应用的任务。⌋(SRS_Os_80001、SRS_Os_80015)
[SWS_Os_00598] ⌈跨核调用ActivateTask应同步执行,即调用在任务被激活或检测到错误后返回。在远程核上的ActivateTask完成之前,调用核上不得继续执行。⌋(SRS_Os_80015)
[SWS_Os_00599] ⌈如果跨核调用ActivateTask时发生错误,错误处理程序应在最初调用ActivateTask的核上调用。⌋(SRS_Os_80015)
[SWS_Os_00816] ⌈操作系统应提供ActivateTask的异步版本,该版本不向调用者返回错误,仅调用(全局)错误钩子(如果已配置)。函数名称应为ActivateTaskAsyn。⌋(SRS_Os_80015)
7.9.12 任务链接
任务链接应扩展为支持跨核。本文档不指定任何实现细节。跨核操作时,此函数的时序行为可能更慢。如果需要在另一个核上激活任务,该核上需要进行调度决策。如果该核尚未激活,则会产生错误。
7.9.12.1 要求
[SWS_Os_00600] ⌈只要分配的访问权限允许,就应能链接属于位于另一个核上的OS应用的任务。⌋(SRS_Os_80001、SRS_Os_80015)
7.9.13 事件设置
SetEvent应扩展为支持跨核。本文档不指定任何实现细节。跨核操作时,此函数的时序行为可能更慢。如果该核尚未激活,则会产生错误。
7.9.13.1 要求
[SWS_Os_00602] ⌈只要分配的访问权限允许,就应能设置属于位于另一个核上的OS应用的事件。⌋(SRS_Os_80016)
[SWS_Os_00604] ⌈跨核调用SetEvent应同步执行,即调用在事件被设置或检测到错误后返回。在远程核上的SetEvent完成之前,调用核上不得继续执行。⌋(SRS_Os_80016)
[SWS_Os_00605] ⌈如果跨核调用SetEvent时发生错误,错误处理程序应在最初调用SetEvent的核上调用。⌋(SRS_Os_80016)
[SWS_Os_00817] ⌈操作系统应提供SetEvent的异步版本,该版本不向调用者返回错误,仅调用(全局)错误钩子(如果已配置)。函数名称应为SetEventAsyn。⌋(SRS_Os_80016)
7.9.14 激活额外的核
如7.9.5节所述,激活额外核的机制
7.9.15 OS的启动
有必要扩展StartOS的功能。这是因为每个核上都会调用一次StartOS。用户通过StartOS(AppMode)的调用参数向操作系统提供所谓的应用模式。应用模式定义了OS自动启动哪些已配置的(启动)对象(任务、警报、调度表)。
在多核系统上,所有核应运行在相同的应用模式下。如果调用StartOS时使用的应用模式为DONOTCARE,则使用其他核的应用模式。至少有一个核必须定义非DONOTCARE的应用模式。
如果所有核上的应用模式相同,StartOS将继续其任务。更多细节见7.9.4章。
7.9.15.1 要求
[SWS_Os_00606] ⌈AUTOSAR规范不支持在某个核上调用StartOS后激活该AUTOSAR核。如果在StartOS之后调用StartCore,在扩展状态下应返回E_OS_ACCESS。⌋(SRS_Os_80001)
[SWS_Os_00607] ⌈StartOS应在调用它的核上启动OS。⌋(SRS_Os_80006、SRS_Os_80013)
[SWS_Os_00608] ⌈如果多个核调用StartOS时使用的应用模式非“DONOTCARE”,则应用模式应相同。StartOS应在第一个同步点检查这一点。如果违反,StartOS不应启动调度,不应调用任何StartupHooks,并在每个核上进入无限循环。⌋(SRS_Os_80006)
[SWS_Os_00609] ⌈如果调用StartOS时使用的应用模式为“DONOTCARE”,则应使用其他核(不同于“DONOTCARE”)的应用模式。⌋(SRS_Os_80006)
[SWS_Os_00610] ⌈至少有一个核应定义非“DONOTCARE”的应用模式。⌋(SRS_Os_80006)
[SWS_Os_00611] ⌈如果配置了IOC,StartOS应初始化IOC的数据结构。⌋(SRS_Os_80020)
7.9.16 任务终止
任务终止需要额外检查:不允许在占用自旋锁时终止任务。如果在占用自旋锁时调用TerminateTask/ChainTask,将返回错误。
7.9.16.1 要求
在标准状态下,如果在调用TerminateTask(或ChainTask)时调用任务持有自旋锁,行为未定义。
[SWS_Os_00612] ⌈在扩展状态下,TerminateTask/ChainTask应返回错误(E_OS_SPINLOCK),应用程序可对其进行评估。⌋(SRS_Os_80021)
[SWS_Os_00613] ⌈在响应保护钩子而终止的任务所占用的自旋锁应自动释放。这也适用于OS应用被终止的情况。⌋(SRS_Os_80021)
7.9.17 OS应用的终止
与任务类似,如果OS应用的任何任务占用自旋锁,则不能终止该OS应用。在这种情况下,锁将自动释放。为避免大量错误处理,不会调用ErrorHook。
可能会从不同核并行调用TerminateApplication(A)。实现必须支持这种调用模式,即执行第一个到达的TerminateApplication(A)调用,并忽略所有后续调用,直到终止完成。
7.9.17.1 要求
[SWS_Os_00614] ⌈TerminateApplication应检查OS应用中的任何任务是否占用了自旋锁。如果是,应释放自旋锁。⌋(SRS_Os_80021)
[SWS_Os_00615] ⌈如果从不同核并行调用TerminateApplication(A),则OsApplication“A”由第一个调用终止,所有后续调用在终止完成前将返回“E_OK”(在标准和扩展状态下),且不执行任何操作。⌋(SRS_Os_80021)
7.9.18 OS的关闭
每个核都应能通过调用ShutdownOS函数启动关闭。调用ShutdownOS只会使调用该函数的核进入关闭过程。如果用户希望(大致并行地)关闭所有核,应使用ShutdownAllCores。
ShutdownOS和ShutdownAllCores不会返回。
在AUTOSAR R4.0中,AUTOSAR模式管理不使用OS服务ShutdownOS。该函数提供给在没有RTE和模式管理的核上运行OS的用户。
7.9.18.1 要求
[SWS_Os_00616] ⌈ShutdownOS可从运行AUTOSAR OS的每个核调用。⌋(SRS_Os_80001、SRS_Os_80007)
[SWS_Os_00617] ⌈ShutdownOS应关闭调用它的核。⌋(SRS_Os_80007)
[SWS_Os_00618] ⌈一旦某个特定核进入关闭过程,OS不应启动该核上OS应用的任务。⌋(SRS_Os_80013)
[SWS_Os_00619] ⌈AUTOSAR OS函数ShutdownOS可在多个核上并行调用。⌋(SRS_Os_80013)
[SWS_Os_00620] ⌈ShutdownOS应释放调用核占用的所有自旋锁。⌋(SRS_Os_80021)
[SWS_Os_00621] ⌈ShutdownAllCores可从运行AUTOSAR OS的每个核调用。⌋(SRS_Os_80007)
7.9.19 等待事件
事件等待机制必须适应新的多核自旋锁功能:
调用WaitEvent时,任务可能会被解调度,在这种情况下,它将无法释放自旋锁。因此,WaitEvent必须检查调用任务是否持有自旋锁。与资源一样,处于等待状态的任务不能占用自旋锁。
7.9.19.1 要求
[SWS_Os_00622] ⌈AUTOSAR操作系统WaitEvent API服务应检查调用它时调用任务是否占用了自旋锁。在扩展状态下,应返回错误E_OS_SPINLOCK,且任务不应进入等待状态。⌋(SRS_Os_80021)
7.9.20 调用可信函数
函数可声明为某个OS应用的可信函数。然后,只能通过CallTrustedFunction API函数执行它们。假设配置了相应的访问权限,来自OS应用A的任务可以调用来自OS应用B的可信函数。
在多核系统上,从一个OS应用到另一个OS应用的这些可信函数调用仅限于同一核。
7.9.20.1 要求
[SWS_Os_00623] ⌈如果目标可信函数属于另一个核上的OS应用,OS API函数CallTrustedFunction在扩展状态下应返回E_OS_ACCESS。⌋(SRS_Os_80013)
7.9.21 调用重新调度
与WaitEvent类似,Schedule API服务必须适应新的多核自旋锁功能。
任务在占用自旋锁时不得主动强制解调度。
7.9.21.1 要求
[SWS_Os_00624] ⌈AUTOSAR操作系统Schedule API服务应检查调用它时调用任务是否占用了自旋锁。在扩展状态下,应返回错误E_OS_SPINLOCK,且不应调用调度程序。⌋(SRS_Os_80021)
7.9.22 资源占用
GetResource函数允许同一核上的任务之间互斥。OS生成器应离线检查任务不在不同核上(见7.9.30),并且GetResource函数将在线检查此要求。
(GetResource使用的)优先级上限协议临时更改任务的优先级。这种方法在多核系统上会失败,因为优先级是每个核本地的。因此,上限协议不足以保护关键段免受来自不同核的访问。
[SWS_Os_00801] ⌈如果任务/中断服务程序锁定了自旋锁和资源,则必须以严格的后进先出顺序解锁它们。如果违反解锁顺序,ReleaseResource()应返回E_OS_NOFUNC。不执行其他功能。⌋(SRS_Os_80021)
7.9.23 核ID
每个硬件为核分配唯一的物理ID。物理核ID是区分核的唯一方式。微控制器的物理核ID不一定是连续的,也不一定从0开始。
软件需要一种识别核的机制,例如使用核特定变量。由于物理核ID通常不能直接用作核特定变量的数组索引,因此需要逻辑CoreID将物理核ID映射到数组索引。在软件中,不必知道物理核ID,逻辑CoreID就足够了。
OS应用和其他软件对象到核的映射在配置文件中指定。所有此类映射应独立于硬件,因此不应基于物理核ID,而应基于逻辑CoreID。
函数GetCoreID在内部将物理核ID映射到逻辑CoreID。映射是实现特定的。GetCoreID可以是C函数或宏。
7.9.23.1 要求
[SWS_Os_00625] ⌈AUTOSAR操作系统API函数GetCoreID可在StartOS之前调用。⌋(SRS_Os_80006)
[SWS_Os_00626] ⌈实现应提供函数GetNumberOfActivatedCores,返回运行AUTOSAR OS的核数。⌋(SRS_Os_80001)
[SWS_Os_00627] ⌈实现应定义一组类型为CoreIdType的常量OS_CORE_ID_,其中的值从0到“OsNumberOfCores -1”。⌋(SRS_Os_80001)
[SWS_Os_00628] ⌈实现应提供类型为CoreIdType的常量OS_CORE_ID_MASTER,引用主核。⌋(SRS_Os_80001)
7.9.24 计数器,背景与原理
计数器由以“滴答”为单位的计数值和一些计数器特定的常量表示。
与单核情况类似,每个操作系统(在每个核上)提供至少一个源自计时器的计数器。因此,可以定义多个属于不同OS应用且位于同一核或不同核上的计数器。
| 任务 | 调度表 | 警报 | 调度表 | 警报 | 警报 | 计数器 | 计数器 | 计数器 | 计数器 |
|---|---|---|---|---|---|---|---|---|---|
| 计时器 | 计时器 | ||||||||
| 核内操作。 | 核间操作。 | 同步计数器 |
图5:计数器、警报、调度表和中断服务程序的允许配置示例。
7.9.25 多核对计数器的限制
AUTOSAR OS只能在计数器所在的核上递增计数器。分配给OS应用x的计数器不能由分配给不同核的OS应用Y递增。
7.9.25.1 要求
[SWS_Os_00629] ⌈属于OS应用的计数器应由该OS应用所在的核递增。该计数器不得由其他核递增。⌋(SRS_Os_80013)
[SWS_Os_00630] ⌈不允许从分配给不同核的计数器驱动调度表。⌋(SRS_Os_80013)
[SWS_Os_00631] ⌈不允许从分配给不同核的计数器驱动警报。⌋(SRS_Os_80013)
这些限制有两个不同的原因:
- 当允许跨核修改计数器时,可能会出现竞争条件(一个核等待另一个核修改计数器)。
- 递增计数器的核必须检查基于该计数器的警报是否已过期。当不同核操作相同的警报时,警报处理更加复杂,因为需要互斥。
| 警报 | 计数器 | 警报 | 警报 | 调度表 | 计数器 | 计数器 | 允许的配置/使用 | 禁止的配置/使用 |
|---|
图6:计数器、警报、调度表和回调的禁止配置示例。
7.9.26 计数器的同步
计数器用于驱动警报和调度表。要同步位于不同核上的警报和调度表,相应的计数器必须同步。
例如,如果硬件支持,不同核上相应的自由运行硬件计数器可以使用相同的计时器(由外设维护的相同计数值),因此在不同核上提供相同的时基。然后,软件计数器可以通过附加到这些核本地相应硬件计数器的警报来推进,例如驱动不同核上的同步调度表。
同步质量取决于硬件架构和系统配置。
7.9.27 警报
AUTOSAR操作系统的警报机制提供激活任务、设置事件、递增计数器或调用警报回调的服务。
如上所述,警报只能绑定到同一核上的计数器。无论任务绑定到哪个核,都可以通过警报操作激活任务和设置事件。但是,必须遵守OS应用定义的访问权限。此外,允许操作绑定到其他核的警报。API服务SetRelAlarm、SetAbsAlarm和CancelAlarm可用于操作其他核上的警报。
7.9.27.1 要求
[SWS_Os_00632] ⌈如果警报过期,应允许在不同核上激活任务。⌋(SRS_Os_80018)
[SWS_Os_00633] ⌈如果警报过期,应允许在不同核上设置事件。⌋(SRS_Os_80018)
[SWS_Os_00634] ⌈AUTOSAR操作系统应在其相应OS应用所在的核上处理警报。⌋(SRS_Os_80018)
[SWS_Os_00635] ⌈警报回调应在警报绑定的核上执行。这仅适用于可伸缩性等级1系统,因为否则不允许警报回调(SWS_Os_00242)。⌋(SRS_Os_80013)
[SWS_Os_00636] ⌈SetRelAlarm也应能作用于绑定到另一个核的警报。⌋(SRS_Os_80013)
[SWS_Os_00637] ⌈SetAbsAlarm也应能作用于绑定到另一个核的警报。⌋(SRS_Os_80013)
[SWS_Os_00638] ⌈CancelAlarm也应能作用于绑定到另一个核的警报。⌋(SRS_Os_80013)
[SWS_Os_00639] ⌈GetAlarmBase也应能作用于绑定到另一个核的警报。⌋(SRS_Os_80013)
[SWS_Os_00640] ⌈GetAlarm也应能作用于绑定到另一个核的警报。⌋(SRS_Os_80013)
7.9.28 调度表
与警报类似,调度表可用于激活任务和设置事件。与警报一样,调度表只能绑定到同一核上的计数器。
为简化系统启动,应能启动其他核上的调度表。系统设计人员负责调度表的正确处理。例如,可以从一个核控制调度表。
7.9.28.1 要求
[SWS_Os_00641] ⌈调度表应能激活绑定到与调度表所在核不同的核上的任务。⌋(SRS_Os_80018)
[SWS_Os_00642] ⌈调度表应能在与调度表所在核不同的核上设置事件⌋(SRS_Os_80018)
[SWS_Os_00643] ⌈AUTOSAR操作系统应在其相应OS应用所在的核上处理调度表。⌋(SRS_Os_80013)
[SWS_Os_00644] ⌈API调用“StartScheduleTableAbs”应能启动属于位于其他核上的OS应用的调度表。⌋(SRS_Os_80018)
[SWS_Os_00645] ⌈API调用“StartScheduleTableRel”应能启动属于位于其他核上的OS应用的调度表。⌋(SRS_Os_80013)
[SWS_Os_00646] ⌈API调用“StopScheduleTable”应能停止属于位于其他核上的OS应用的调度表。⌋(SRS_Os_80013)
[SWS_Os_00647] ⌈API服务“GetScheduleTableStatus”应能获取属于位于不同核上的OS应用的调度表的状态。⌋(SRS_Os_80013)
7.9.29 自旋锁机制
对于多核概念,需要一种新的机制来支持不同核上的任务之间的互斥。这种新机制不应在同一核上的任务之间使用,因为这没有意义。在这种情况下,AUTOSAR操作系统将返回错误。
“SpinlockType”类似于OSEK的“ResourceType”。自旋锁在离线时配置。
自旋锁是一种忙等待机制,它循环轮询(锁)变量,直到变量变为可用状态。通常,这需要原子“测试并设置”功能,其细节是实现特定的。
一旦某个任务/中断服务程序2占用了锁变量,其他核上的其他任务/中断服务程序2将无法占用该锁变量。自旋锁机制不会在这些其他任务轮询锁变量时将它们解调度。但是,在轮询锁变量时,可能会有更高优先级的任务/中断服务程序就绪。在这种情况下,自旋任务将被中断。如图7所示。
| 核0 | 高优先级任务 | 执行某些操作 | 获取自旋锁A | 自旋等待锁A | 抢占点 |
|---|---|---|---|---|---|
| 低优先级任务 | 获取自旋锁A | 执行某些操作 | 被抢占 |
图7:由干扰导致的死锁情况。高优先级任务无限自旋,因为低优先级任务已占用自旋锁。在这种情况下,第二次调用GetSpinlock将返回错误。
用户可以通过例如使用SuspendAllInterrupts包装自旋锁来保护任务免受这种情况的影响,以使其不会被其他任务干扰。OS可以根据配置参数OsSpinlockLockMethod自动为调用者执行此操作(见第104页)。
嵌套自旋锁调用可能导致第二种死锁情况,如图8所示。
| 核0 | 获取自旋锁A | 执行某些操作 | 获取自旋锁B | 自旋等待锁B |
|---|---|---|---|---|
| 核1 | 获取自旋锁B | 执行某些操作 | 获取自旋锁A | 自旋等待锁A |
图8:此图显示了两个核上的任务以不同顺序获取两个自旋锁导致的典型死锁。
为避免死锁,不允许嵌套不同的自旋锁。或者,如果允许嵌套自旋锁,则必须定义唯一的顺序。自旋锁只能按此顺序获取,而可以跳过个别自旋锁。在定义的顺序中不允许有循环。如图9所示。
| 任务1 | S1 | S2 | S3 | S4 | S5 | S6 | 配置的顺序 |
|---|---|---|---|---|---|---|---|
| 任务2 | 允许的有效顺序 | 禁止的有效顺序 |
图9:此图显示了两个任务访问一组自旋锁S1–S6的示例。允许按预定义顺序占用自旋锁,也允许跳过自旋锁。如果同时占用多个自旋锁,必须以严格的后进先出顺序锁定和解锁。
自旋锁机制本身并非无死锁。任务/中断服务程序请求自旋锁的顺序必须在配置描述中说明。如果任务占用自旋锁,调度应受到限制。
注意:AUTOSAR不规定用于实现自旋锁的算法。由于用户可能希望分析时序行为(例如锁定时间),实现应记录实际行为。
7.9.29.1 要求
[SWS_Os_00648] ⌈AUTOSAR操作系统应提供跨核工作的自旋锁机制。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00649] ⌈AUTOSAR操作系统应提供GetSpinlock函数,用于占用自旋锁。如果自旋锁已被占用,GetSpinlock应持续尝试占用自旋锁,直到成功。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00650] ⌈GetSpinlock可在任务级调用。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00651] ⌈GetSpinlock可在中断服务程序2级调用。⌋(SRS_Os_80021)
如果从类别1中断服务程序调用GetSpinlock,行为未定义。
[SWS_Os_00652] ⌈AUTOSAR操作系统应提供TryToGetSpinlock函数,用于占用自旋锁。如果自旋锁已被任务占用,TryToGetSpinlock应返回。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00653] ⌈TryToGetSpinlock可在任务级调用。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00654] ⌈TryToGetSpinlock可在中断服务程序2级调用。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00655] ⌈AUTOSAR操作系统应提供ReleaseSpinlock函数,用于释放已占用的自旋锁。如果自旋锁未被占用,应返回错误。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00656] ⌈ReleaseSpinlock可在任务级调用。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00657] ⌈ReleaseSpinlock可在中断服务程序2级调用。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00658] ⌈如果任务尝试占用分配给同一核上的任务/中断服务程序2(包括其自身)的自旋锁,AUTOSAR操作系统应产生错误。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00659] ⌈如果中断服务程序2尝试占用分配给同一核上的任务/中断服务程序2的自旋锁,AUTOSAR操作系统应产生错误。⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00660] ⌈应能在AUTOSAR操作系统中配置同一核上的任务/中断服务程序2占用多个自旋锁的唯一顺序。这可以通过配置项(OsSpinlockSuccessor{NEXT_SPINLOCK})实现,其中“NEXT_SPINLOCK”引用连续的自旋锁。(见第202页)⌋(SRS_Os_80018、SRS_Os_80021)
[SWS_Os_00661] ⌈如果某个核上的任务/中断服务程序2在同一核上的同一或不同任务/中断服务程序已持有自旋锁的情况下,尝试获取另一个未配置为最新获取的自旋锁的直接或间接后继(通过OsSpinlockSuccessor配置参数)的自旋锁,或者未配置后继,AUTOSAR操作系统应产生错误。⌋(SRS_Os_80018、SRS_Os_80021)
7.9.30 离线检查
AUTOSAR资源不能在不同核上的任务/中断服务程序之间共享。如果用户尝试将资源分配给不同核上的任务,OS生成器必须停止生成过程并产生错误。
计数器不能从不同核上的OS应用访问。OS生成器必须拒绝违反此规则的配置。
自旋锁的链表必须无循环,以允许自旋锁的正确嵌套,防止死锁。
OS生成器工具必须检查OS应用是否未分配给不存在的核。建议在配置时进行其他检查,例如通过AUTOSAR描述编辑器。
7.9.30.1 要求
[OS662] ⌈如果OS生成器工具检测到任何资源被分配给不同核上的任务或中断服务程序,应返回错误。⌋(SRS_Os_80021)
[SWS_Os_00663] ⌈如果警报分配给不同核上的计数器,OS生成器工具应返回错误。⌋(SRS_Os_80013)
[SWS_Os_00664] ⌈如果作为警报操作要递增不同核上的计数器,OS生成器工具应返回错误。⌋(SRS_Os_80013)
[SWS_Os_00665] ⌈如果调度表分配给不同核上的计数器,OS生成器工具应返回错误。⌋(SRS_Os_80013)
[SWS_Os_00666] ⌈如果自旋锁的链表有循环,OS生成器工具应返回错误。⌋(SRS_Os_80021)
[SWS_Os_00667] ⌈OS生成器工具应检查OS应用(包括分配给该OS应用的任务)到核的分配,如果任何这些核不存在,应返回错误。⌋(SRS_Os_80005)
7.9.31 自动启动对象
在调度开始之前,AUTOSAR操作系统会激活所有已配置的自动启动对象。这种机制在多核系统上的工作方式类似。在调度开始之前,多核OS应在相应的核上激活所有为当前应用模式配置的自动启动对象。由于OS应用被定义为可定位实体,因此不需要额外的配置容器。自动启动对象已配置为OS应用的一部分。
7.9.31.1 要求
[SWS_Os_00668] ⌈在调度初始启动之前,AUTOSAR操作系统应自动激活当前应用模式下配置的所有自动启动任务(相对于核)。⌋(SRS_Os_80006)
[SWS_Os_00669] ⌈在调度初始启动之前,AUTOSAR操作系统应自动激活当前应用模式下配置的所有自动启动警报(相对于核)。⌋(SRS_Os_80006)
[SWS_Os_00670] ⌈在调度初始启动之前,AUTOSAR操作系统应自动激活当前应用模式下配置的所有自动启动调度表(相对于核)。⌋(SRS_Os_80006)
7.10 操作系统间应用通信器(IOC)
7.10.1 背景与基本原理
IOC是“Inter OS-Application Communicator”(操作系统间应用通信器)的缩写。
“ IOC”负责OS应用之间的通信,尤其针对跨核心或内存保护边界的通信。其内部功能与操作系统紧密相关。
[SWS_Os_00671] ⌈IOC的实现应作为操作系统的一部分⌋(SRS_Os_80020)
IOC是除以下两种通信之外的第三种通信方式:
- OS应用内部通信:始终由RTE处理
- ECU间通信:已通过与通信栈(COM)的明确接口实现
内存保护边界是OS应用的特征,跨边界通信需要特殊机制。多核系统中,核心间通信也可能需要额外措施以确保安全。
所有AUTOSAR软件(包括基础软件和软件组件)都必须属于某个OS应用(见7.9.3),但不一定属于同一个OS应用。基础软件预计为可信代码,但应定义为一个或多个OS应用。
IOC提供OS应用之间的通信服务,尤其适用于多核系统中的跨核心通信。由于跨核心通信本质上也是跨OS应用通信,因此这两种机制被整合。不过,跨OS应用通信不一定需要跨核心通信。
OS应用间的通信频率可能高于ECU间通信。例如,当原本紧密关联的软件组件及其可运行实体被分布到多个核心以提升系统性能时,就会频繁发生OS应用间通信。将为单核心设计的可运行实体分布到多个核心后,满足时序约束的难度可能会增加。
在仅含一个核心的系统中,若只有一个OS应用,或没有OS应用使用内存保护机制,则可以完全省略IOC。
IOC不提供对IOC通道测量的标准化支持。
7.10.2 IOC的通用用途
IOC提供通信服务,供需要在同一ECU上跨OS应用边界通信的客户端使用。RTE使用IOC服务实现跨此类边界的通信。发送端(或客户端)和接收端(或服务端)的通信都必须通过RTE路由。
目前不支持除RTE之外的客户端直接访问IOC服务,但如果客户端(如CDD)提供符合规范的手写或生成的IOC配置描述,以及必要的回调函数,则可以例外。不过,IOC仅支持发送-接收通信。
位于同一OS应用(因此也在同一核心)中的软件组件和/或基础软件模块不应通过调用IOC服务进行通信,这比仅通过RTE通信效率更低。但在IOC支持的N:1通信中,若并非所有发送端和接收端都在同一OS应用,则必须使用IOC。
为使RTE尽可能独立于硬件,所有跨OS应用和跨核心通信机制及实现变体都封装在IOC中。IOC的内部功能依赖于硬件架构特性,尤其是内存架构。
IOC必须保证跨OS应用和跨核心(多核系统)通信的数据一致性,具体包括:
- 在队列式通信中,通信操作的顺序应保持不变。在N:1通信中,来自不同源的消息顺序由实现决定。
- 一次通信操作中发送的所有数据内容应保持不变,即每个通信操作都应视为原子操作。
IOC用于保证数据一致性的锁定机制(中断锁定、自旋锁、无锁实现等)未标准化。
7.10.3 IOC功能
7.10.3.1 通信
IOC仅提供发送-接收(信号传递)通信。RTE(或本规范未来版本中适配的基础软件模块)将客户端-服务端调用和响应传输转换为发送-接收通信。
IOC支持1:1、N:1和N:M(仅非队列)通信。
IOC允许在一次原子通信操作中传输一个数据项。数据项可以是原子基本数据类型的值,或复杂数据结构的引用。但数据结构必须实现为单个内存块,这样数据项才能整体传输。IOC无需了解内部数据结构,只需知道基本内存地址和长度(可根据数据项类型计算)。例如,IOC不支持核心间的字节序转换。
仅1:1通信支持在一次操作中传输多个数据项。这种情况下,IOC函数需使用多个类型和内存地址。与连续的IOC调用相比,其优势在于打开内存保护边界和通知接收端的机制只需执行一次,且所有数据项因在一次原子操作中传输而保证一致性。
IOC提供非队列(最新最优,数据语义)和队列(先进先出,事件语义)两种通信操作。若存在IOC内部队列,其长度可配置。
每个原子通信操作都在配置描述中通过独立的描述块指定,涉及发送端、接收端、数据类型、通知和队列等信息。
7.10.3.2 通知
IOC可选择在传输的数据在接收端可用时通知接收端,方式是调用用户提供的配置回调函数。
一种可能的实现是触发中断(第二类)机制,从接收端的中断服务程序(ISR)中调用回调函数,或使用微控制器提供的陷阱机制。回调函数应高效简洁,因为它在ISR中调用。
在某些情况下,可能无需触发ISR来通知接收端。此时,IOC生成器可根据硬件架构和其他约束选择合适的IOC内部通知方式,这可能比同一核心上OS应用间通信使用ISR更高效。
通知也可完全由IOC的客户端处理,例如当RTE调用IOC发送函数后,通知接收端RTE有新数据从IOC可用。这种情况下,IOC完全不涉及通知机制的细节。
若未来证明其他替代方案更高效,IOC内部通知可能会在AUTOSAR的后续版本中移除。
7.10.4 IOC接口
RTE与IOC之间的接口应类似于软件组件与RTE之间的接口,即针对每个通信操作生成特定接口,而非提供通用API。
与标准化接口相比,这种方式更有利于优化(如函数内联或将函数调用替换为宏)。大多数优化可在代码生成时离线执行,而非消耗宝贵的实时资源。
每个在IOC配置描述中指定的数据通信都有一组唯一的IOC服务API(至少包括发送和接收数据)。每个服务API都会被生成,且可通过每个数据通信的唯一ID识别。在N:1通信中,每个发送端必须使用自己的API。
同一1:1通信的IOC服务API可被发送端和接收端同一软件组件内的多个可运行实体使用。但IOC函数不可重入,否则在多核系统中,若IOC使用自旋锁,可能会导致自旋锁错误。因此,同一IOC API必须仅被顺序调用。如果所有可运行实体都在同一任务中调度,则不存在问题;否则,调用者需保证同一IOC API在不同调用返回前不会被再次调用。
软件组件只能通过RTE访问IOC。只有RTE可决定使用哪些通信服务来满足软件组件的通信需求。
不支持基础软件模块直接访问IOC服务,但对于CDD和其他模块,在不可避免的情况下允许访问。客户端必须提供符合规范的手写或生成的IOC配置描述。在需要通知接收端时,客户端需指定并提供特定的回调函数。但IOC仅支持发送-接收通信。
7.10.5 IOC内部结构
本节给出一些可能的IOC实现方案提示。
IOC可能进入特权模式以跨OS应用的保护边界。因此,IOC必须是OS的一部分。注意,位于内核上下文的功能可能不会被任务或第二类ISR中断,但可能会被第一类ISR中断。
IOC发送服务将数据写入与接收通信伙伴共享的内存区域中的缓冲区(这是一种使用共享内存的实现示例)。根据硬件架构和其他约束,IOC内部可能有不同的实现方案,但这些方案对客户端(RTE)应是透明的。
IOC确保数据一致性,即通过保护机制防止发送端和接收端对同一数据的并发访问,避免行为不一致和数据损坏。实现可依赖硬件。
在具有共享内存的系统中,每个数据项可在发送和接收OS应用共享的内存段中有特定的通信缓冲区。
若配置了具有事件语义(队列式)的IOC通信,则应定义队列长度。
7.10.6 IOC配置与生成
RTE与IOC之间的数据元素特定接口需要大量代码生成。为尽可能分离通用RTE代码生成和硬件相关的IOC代码生成,采用顺序代码生成流程,步骤如下:
- 在ECU配置描述文件中指定所有关于软件组件到OS应用和核心的分配信息。
- 生成RTE。RTE生成器创建数据元素特定的IOC服务调用,以及相应的IOC配置描述块(XML格式),用于指定每个数据元素的通信关系。
- 根据IOC配置描述(步骤2)并考虑硬件描述文件,生成IOC代码。此外,生成头文件(Ioc.h)供RTE.c包含,以提供定义、函数原型和宏。
每个原子通信都必须在IOC配置描述中以标准化的XML格式指定。每个通信操作有一个描述块,包含:
- 唯一标识符
- 数据类型
- 发送端属性
- 接收端属性
- 接收端回调函数名称(若有通知)
- 通信类型(队列式或非队列式(最新最优))
- 队列式通信的队列长度
详情见10.3章节。
对于每个跨OS应用通信,RTE生成器会创建一个或多个对IOC函数的调用(用于发送或接收数据),并将相应的描述块添加到IOC配置描述中。
可能有多个来源为IOC配置提供内容(如RTE、CDD)。主要输入来自RTE生成器。本规范版本不支持其他IOC配置描述来源(可能包括基础软件模块配置工具或允许使用基础软件服务的非AUTOSAR组件)。
在仅含一个OS应用的ECU中,可省略IOC配置描述。
7.10.7 IOC集成示例
本节描述两个典型用例,展示IOC如何支持OS应用之间的通信。两个示例中,OS应用都位于多核系统的不同核心上。
7.10.7.1 示例1:无通知的1:1发送端-接收端通信
一个软件组件以“事件”语义(队列式)向位于不同核心的另一个软件组件发送数据项。接收端的可运行实体定期(如通过警报)被调用,并通过RTE接收数据(见图10)。
由于通信跨核心边界,RTE调用IOC将数据从核心0传输到核心1。
在发送端,Rte_Send_<port>_<item>(..., <data>)调用被映射为IocSend_<Id>(<data>)调用。

在该示例中,IocSend服务将数据写入共享内存区域中的缓冲区,接收端可通过IOC读取该缓冲区。
在接收端,接收可运行实体定期被调用。Rte_Receive_<port>_<item>(..., <data>)调用被映射为IocReceive_<Id>(<data>)调用,以从IOC内部队列读取数据。1:1通信无需RTE内部额外队列。
IOC生成器生成所有发送和接收函数。这些函数可能被定义为宏以优化性能。
这种无通知的端口到端口通信适用于:
- 发送端-接收端通信
- 队列式或非队列式通信
- 1:1通信
7.10.7.2 示例2:带RTE接收端通知的N:1客户端-服务端通信
一个软件组件调用位于不同核心的另一个软件组件提供的服务操作。接收端的可运行实体被激活以计算结果(见图11)。
RTE在客户端将客户端-服务端调用映射为发送-接收通信。由于通信跨核心边界,RTE使用IOC将数据从核心0传输到核心1。
在发送端,Rte_Call_<port>_<op>(..., <data>)调用被映射为IocSend_<Id>(<data>)调用,以通过IOC将参数传输到托管服务端可运行实体的核心。
将数据写入IOC内部队列缓冲区后,Rte_Call函数使用OS调用通过激活接收核心上的服务端任务来通知接收端。该任务由RTE提供。任务体负责通过调用IocReceive函数从IOC缓冲区读取数据,并将数据转发给服务端可运行实体。根据IOC函数的返回值,可能需要多次调用IocReceive和服务端可运行实体以清空IOC内部队列缓冲区(若已指定)。

核心1上的服务结果以类似方式传输回核心0上的客户端。结果的通信路径未在图11中显示。
这种带RTE通知的端口到端口通信适用于:
- 带通知的发送端-接收端通信
- 客户端-服务端通信(此时RTE需提供服务,将服务端调用映射为1:1发送端-接收端通信(用于服务端调用)和另一个发送端-接收端通信(用于将结果返回客户端))
- 队列式或非队列式通信
- 1:1通信(若接收端不定期轮询数据,此时示例1的方案可能更合适)
- N:1通信
7.10.8 未来扩展
本规范的第一个版本不支持某些功能,但可能在后续版本中添加:
- 未来,IOC将支持基础软件模块之间的直接高效通信,或基础软件模块与位于不同OS应用的软件组件(通过RTE)之间的通信。将添加对基础软件模块直接访问IOC服务的支持。
- 可能会向IOC添加其他通知选项(如激活接收端的指定任务)。
7.11 系统可扩展性
7.11.1 背景与基本原理
为了根据用户需求定制操作系统,并充分利用处理器特性,操作系统可按照以下可扩展性等级进行分级:
| 功能 | 描述章节 | 可扩展性等级1 | 可扩展性等级2 | 可扩展性等级3 | 可扩展性等级4 | 硬件要求 |
|---|---|---|---|---|---|---|
| OSEK OS(所有一致性等级) | 7.1 | ✓ | ✓ | ✓ | ✓ | - |
| 计数器接口 | 8.4.17 | ✓ | ✓ | ✓ | ✓ | - |
| 软件自由运行定时器接口 | 8.4.18、8.4.19 | ✓ | ✓ | ✓ | ✓ | - |
| 调度表 | 7.3 | ✓ | ✓ | ✓ | ✓ | - |
| 堆栈监控 | 7.5 | ✓ | ✓ | ✓ | ✓ | - |
| 保护钩子 | 7.8 | - | ✓ | ✓ | ✓ | - |
| 定时保护 | 7.7.2 | - | ✓ | - | ✓ | 具有高优先级中断的定时器 |
| 全局时间/同步支持 | 7.4 | - | ✓ | - | ✓ | 全局时间源 |
| 内存保护 | 7.7.1、7.7.4 | - | - | ✓ | ✓ | 内存保护单元(MPU) |
| 操作系统应用 | 7.6、7.12 | - | - | ✓ | ✓ | - |
| 服务保护 | 7.7.3 | - | - | ✓ | ✓ | - |
| 调用可信函数 | 7.7.5 | - | - | ✓ | ✓ | (非)特权模式 |
表4:可扩展性等级
| 功能 | 可扩展性等级1 | 可扩展性等级2 | 可扩展性等级3 | 可扩展性等级4 |
|---|---|---|---|---|
| 支持的最小调度表数量 | 2 | 8 | 2 | 8 |
| 支持的最小操作系统应用数量 | 0 | 0 | 2 | 2 |
| 支持的最小软件计数器数量 | 8 | 8 | 8 | 8 |
表5:可扩展性等级的最低要求
7.11.2 要求
[SWS_Os_00240] ⌈如果低可扩展性等级的实现支持高等级的功能,那么这些功能的接口必须符合本操作系统软件规范。⌋(SRS_Os_11012、SRS_Os_11016)
[SWS_Os_00241] ⌈操作系统模块应根据配置的可扩展性等级支持相应的功能(参见表4)。⌋(SRS_Os_11012、SRS_Os_11016)
[SWS_Os_00327] ⌈在可扩展性等级3和4中,操作系统模块应始终使用扩展状态。⌋()
7.12 钩子函数
7.12.1 背景与基本原理
OSEK OS中定义的钩子程序运行在操作系统模块层面,因此只能属于可信环境。此外,这些钩子程序是系统全局的(特定于系统),很可能由ECU集成商提供。
然而,在AUTOSAR中,每个操作系统应用可能需要执行特定于应用的代码,例如在其自己额外的(特定于应用的)启动钩子中初始化某些硬件。这些被称为特定于应用的钩子程序。一般来说,特定于应用的钩子具有与OSEK OS规范中描述的钩子程序相同的属性。以下将描述其差异。
7.12.2 要求
[SWS_Os_00439] ⌈操作系统模块应向所有配置的错误钩子提供OSEK错误宏(OSError…()),并且应有两个(如在OIL中)全局配置参数来开启或关闭这些宏。⌋()
启动钩子(StartupHook)
[SWS_Os_00060] ⌈如果为操作系统应用配置了特定于应用的启动钩子,操作系统模块应在操作系统模块启动时调用StartupHook_。⌋()
[SWS_Os_00226] ⌈操作系统模块应使用相关操作系统应用的访问权限执行特定于应用的启动钩子。⌋()
[SWS_Os_00236] ⌈如果同时配置了系统特定的启动钩子和一个(或多个)特定于应用的启动钩子,操作系统模块应在特定于应用的启动钩子之前调用系统特定的启动钩子。⌋()
关闭钩子(ShutdownHook)
[SWS_Os_00112] ⌈如果为操作系统应用配置了特定于应用的关闭钩子,操作系统模块应在操作系统关闭时调用ShutdownHook_。⌋()
[SWS_Os_00225] ⌈操作系统模块应使用相关操作系统应用的访问权限执行特定于应用的关闭钩子。⌋()
[SWS_Os_00237] ⌈如果同时配置了系统特定的关闭钩子和一个(或多个)特定于应用的关闭钩子,操作系统模块应在特定于应用的关闭钩子之后调用系统特定的关闭钩子。⌋()
错误钩子(Error Hook)
[SWS_Os_00246] ⌈当发生错误且为故障操作系统应用配置了特定于应用的错误钩子时,操作系统模块应在调用系统特定的错误钩子(如果已配置)之后调用该特定于应用的错误钩子ErrorHook_。⌋(SRS_Os_11013)
[SWS_Os_00085] ⌈操作系统模块应使用相关操作系统应用的访问权限执行特定于应用的错误钩子。⌋()
[SWS_Os_00367] ⌈不返回StatusType的操作系统模块服务(ActivateTaskAsyn和SetEventAsyn除外)不应触发错误钩子。⌋()
7.13 硬件外设访问
7.13.1 背景与原理
在一些微控制器(MCU)架构中,存在内存映射的硬件寄存器(外设区域),这些寄存器仅能在特定模式(例如特权模式)下访问。只要任务/中断服务程序(ISR)在具有完整硬件访问权限的情况下运行,它们就可以直接访问这些寄存器。如果操作系统使用内存保护,非可信OS应用的任务/中断服务程序则不能直接访问这些寄存器,否则会被操作系统识别为内存违规。
为了允许即使是非可信应用也能访问这些寄存器,操作系统提供了以下用于读写和修改寄存器的API:
StatusType ReadPeripheral8 (AreaIdType Area, const uint8 * Address, uint8 * ReadValue)StatusType ReadPeripheral16(AreaIdType Area, const uint16 * Address, uint16 * ReadValue)StatusType ReadPeripheral32(AreaIdType Area, const uint32 * Address, uint32 * ReadValue)StatusType WritePeripheral8 (AreaIdType Area, uint8 * Address, uint8 WriteValue)StatusType WritePeripheral16(AreaIdType Area, uint16 * Address, uint16 WriteValue)StatusType WritePeripheral32(AreaIdType Area, uint32 * Address, uint32 WriteValue)StatusType ModifyPeripheral8 (AreaIdType Area, uint8 * Address, uint8 Clearmask, uint8 Setmask)StatusType ModifyPeripheral16(AreaIdType Area, uint16 * Address, uint16 Clearmask, uint16 Setmask)StatusType ModifyPeripheral32(AreaIdType Area, uint32 * Address, uint32 Clearmask, uint32 Setmask)
为了控制对寄存器的访问,必须为每个OS应用配置访问权限。这样,操作系统就能在运行时检查调用者是否拥有足够的权限。
7.13.2 要求
[SWS_Os_00806] ⌈ 外设寄存器访问检查
操作系统仅当满足以下条件时,才应通过API ReadPeripheralX、WritePeripheralX 和 ModifyPeripheralX 执行对外设寄存器的访问:
- 参数
Address在OsPeripheralAreaStartAddress和OsPeripheralAreaEndAddress的范围内 - 参数
Area有效 - 调用者被配置为拥有足够的权限(
OsPeripheralAreaAccessingApplication)。⌋(SRS_Os_11005)
[SWS_Os_00807] ⌈ 外设访问API的错误处理
如果操作系统在执行 ReadPeripheralX、WritePeripheralX 和 ModifyPeripheralX 时检测到错误(见[SWS_Os_00806]),则应返回相应的 StatusType 并调用 ErrorHook()。否则,应返回 E_OK。⌋(SRS_Os_11005)
7.14 中断源API
7.14.1 背景与原理
操作系统需要保证调度功能,因此它必须是唯一能访问中断控制器的组件。为此,它向其他基础软件(BSW)/复杂驱动(CDD)组件提供了 DisableInterruptSource、EnableInterruptSource 和 ClearPendingInterrupt 接口,以允许访问第二类中断服务程序的中断控制寄存器。
DisableInterruptSource/EnableInterruptSource 这对接口可用于两种不同场景:
- 特定中断应在短时间内被屏蔽(可能是为了避免数据一致性问题)。被屏蔽的请求在中断源再次启用后应得到处理。
- 特定源的中断请求应在特定时间内被忽略(可能是较长时间,例如当CAN驱动处于休眠状态时)。启用该源后,仅应处理新的请求。
7.14.2 要求
[SWS_Os_00808] ⌈ 操作系统应为每个第二类中断源(OsIsrCategory == CATEGORY_2)提供API DisableInterruptSource、EnableInterruptSource 和 ClearPendingInterrupt。⌋(SRS_Os_11011)
中断源控制API不支持嵌套调用。
[SWS_Os_00809] ⌈ 中断源控制API的嵌套调用
如果对已禁用的中断源调用 DisableInterruptSource,或者对已启用的中断源调用 EnableInterruptSource,操作系统应在扩展状态下返回 E_OS_NOFUNC。⌋(SRS_Os_11011)
[SWS_Os_00810] ⌈ 中断源控制API的错误处理
如果操作系统在执行 DisableInterruptSource、EnableInterruptSource 和 ClearPendingInterrupt 时检测到错误,应返回相应的 StatusType 并调用 ErrorHook()。否则,应返回 E_OK。⌋(SRS_Os_11011)
[SWS_Os_00811] ⌈ 调用 EnableInterruptSource 应通过修改中断控制器寄存器来启用请求的中断源。此外,它还应清除中断挂起标志。⌋(SRS_Os_11011)
[SWS_Os_00812] ⌈ 调用 DisableInterruptSource 应通过修改中断控制器寄存器来禁用请求的中断源。⌋(SRS_Os_11011)
[SWS_Os_00813] ⌈ 调用 ClearPendingInterrupt 应通过修改相应的中断控制器寄存器来清除中断挂起标志。⌋(SRS_Os_11011)
[SWS_Os_00814] ⌈ 清除挂起中断应仅限于清除中断控制器中的挂起标志。⌋(SRS_Os_11011)
注:这并不一定能保证中断请求被成功清除,即中断服务程序(ISR)之后仍可能被执行。(这可能由于竞争条件发生,或者因为需要在请求的硬件单元中也清除该请求。)
7.15 错误分类
AUTOSAR基础软件模块通常向Det(开发错误)或Dem(生产错误)报告其错误。操作系统处理错误的方式不同(另见[15]),不向Dem/Det报告其错误。如果需要向Dem/Det报告错误,用户可以在 ErrorHook() 中执行此操作。
下表包含了操作系统可能报告的所有错误代码(除了[15]中已定义的那些)
| 错误类型 | 相关错误代码 | 值 |
|---|---|---|
| 服务不能被调用。 | E_OS_SERVICEID | 由实现分配 |
| 向服务传递了无效地址作为参数。 | E_OS_ILLEGAL_ADDRESS | 由实现分配 |
任务未调用 TerminateTask() 或 ChainTask() 就终止。 | E_OS_MISSINGEND | 由实现分配 |
| 在中断禁用/启用对中调用了OS服务。 | E_OS_DISABLEDINT | 由实现分配 |
| 操作系统通过堆栈监控检测到堆栈故障 | E_OS_STACKFAULT | 由实现分配 |
| 发生内存访问违规 | E_OS_PROTECTION_MEMORY | 由实现分配 |
| 第二类中断服务程序超过其执行时间预算 | E_OS_PROTECTION_TIME | 由实现分配 |
| 任务/第二类中断服务程序在其时间帧到期前到达 | E_OS_PROTECTION_ARRIVAL | 由实现分配 |
| 任务超过其执行时间预算 | E_OS_PROTECTION_TIME | 由实现分配 |
| 任务/第二类中断服务程序阻塞时间过长 | E_OS_PROTECTION_LOCKED | 由实现分配 |
| 发生陷阱 | E_OS_PROTECTION_EXCEPTION | 由实现分配 |
| 内核不可用 | E_OS_CORE | 由实现分配 |
| 持有自旋锁时进行调度 | E_OS_SPINLOCK | 由实现分配 |
| 由于干扰导致死锁情况 | E_OS_INTERFERENCE_DEADLOCK | 由实现分配 |
| 由于错误嵌套导致潜在死锁 | E_OS_NESTING_DEADLOCK | 由实现分配 |
| 传入空指针作为参数 | E_OS_PARAM_POINTER | 由实现分配 |
7.16 ARTI钩子宏(草案)
操作系统应包含特殊宏,这些宏可被ARTI跟踪工具用于插入任何类型的跟踪功能。
AUTOSAR CP操作系统的钩子遵循ARTI宏的一般结构:
ARTI_TRACE(_contextName, _className, _instanceName, instanceParameter, _eventName, eventParameter);
某些参数使用文本字面量(标记)而非符号标识符。这允许宏定义将这些参数连接成更具体的宏。在运行时传递和评估所有参数的成本很高,尤其是在运行时消耗方面。
以下是通用 ARTI_TRACE 宏的一种可能实现方式,ARTI跟踪工具供应商可据此定义以匹配其跟踪工具的接口:
#define ARTI_TRACE(_contextName, _className, _instanceName, instanceParameter, _eventName, eventParameter) \
ARTI_TRACE ## _ ## _className ## _ ## _eventName ## _ ## _instanceName ## _ ## _contextName ( (instanceParameter), (eventParameter) )
这种实现将为 _className、_eventName 和 _contextName 的所有可能组合生成一个钩子,并仅在运行时传递 instance_id 和 event_value 参数。
下面描述各参数的含义。
_contextName:标记,文本字面量,上下文名称。可为以下之一:NOSUSP:表示钩子在中断被禁用的上下文中调用SPRVSR:表示被调用的钩子可能禁用中断USER:表示被调用的钩子不能禁用中断
_className:标记,文本字面量,宏的类名。AUTOSAR OS的预定义类如下:AR_CP_OS_APPLICATION:应用程序的启动和停止AR_CP_OS_TASKSCHEDULER:任务调度AR_CP_OS_CAT2DISPATCHER:第二类中断调度AR_CP_OS_SERVICECALLS:服务程序调用AR_CP_OS_SPINLOCK:自旋锁调用
_instanceName:ARXML中定义的OS实例的短名称。instanceParameter:索引[uint32] 0…4294967295,OS所看到的CPU内核索引()。该索引应始终从0开始并连续计数。它可能与物理内核的索引相同,也可能不同。_eventName:标记,文本字面量,特定类定义的事件名称。eventParameter:[uint32] 0…4294967295值,作为事件的参数。
因此,AUTOSAR OS的所有ARTI宏都遵循以下模板:
ARTI_TRACE(_contextName, <AR OS Class Name>, <OS Short Name>, <Core Index>, <Event Name>, <Event Parameter>)
OS中的钩子调用示例:
ARTI_TRACE( NOSUSP, AR_CP_OS_TASKSCHEDULER, OS1, (uint32)GetCoreID(), OsTask_Activation, (uint32)GetTaskID() );
预处理输出示例:
ARTI_TRACE_NOSUSP_AR_CP_OS_TASKSCHEDULER_OS1_OsTask_Activation( (uint32)GetCoreID(), (uint32)GetTaskID() );
7.16.1 类 AR_CP_OS_APPLICATION
| 事件描述 | 应用程序状态转换 | _eventName | eventParameter |
|---|---|---|---|
| 启动 | StartOS → ACCESSIBLE | OsApplication_Start | OS应用程序索引 |
| 终止 | ACCESSIBLE → TERMINATED | OsApplication_Terminate | OS应用程序索引 |
| 重启 | ACCESSIBLE → RESTARTING | OsApplication_Restart | OS应用程序索引 |
| 允许访问 | RESTARTING → ACCESSIBLE | OsApplication_AllowAccess | OS应用程序索引 |
7.16.2 类 AR_CP_OS_TASKSCHEDULER
类 AR_CP_OS_TASKSCHEDULER 包含允许跟踪AUTOSAR经典平台中定义的OS任务的事件。
类 AR_CP_OS_TASKSCHEDULER 的ARTI宏遵循以下模板:
ARTI_TRACE(_contextName, AR_CP_OS_TASKSCHEDULER, <OS Short Name>, <Core Index>, <Event Name>, <Task Index>)
下表中任何事件的 <Core Index> 应表示相应任务被调度所在的内核ID。
以下事件属于类 AR_CP_OS_TASKSCHEDULER:
| 事件描述 | 任务状态转换 | _eventName | eventParameter |
|---|---|---|---|
| 任务终止 | 运行中 → 挂起 | OsTask_Stop | 任务索引 |
| 任务激活成功 | 挂起 → 激活(就绪) | OsTask_Activation | 任务索引 |
| 任务启动 | 激活(就绪) → 运行中 | OsTask_Start | 任务索引 |
| 先前处于等待状态的终止任务继续执行 | 释放(就绪) → 运行中 | OsTask_Resuming | 任务索引 |
| 终止任务挂起 | 运行中 → 等待 | OsTask_Waiting | 任务索引 |
| 终止任务释放 | 等待 → 释放(就绪) | OsTask_Release | 任务索引 |
7.16.3 类 AR_CP_OS_CAT2DISPATCHER
类 AR_CP_OS_CAT2DISPATCHER 包含允许跟踪AUTOSAR经典平台中定义的第二类中断的事件。类 AR_CP_OS_CAT2DISPATCHER 的ARTI宏遵循以下模板:
ARTI_TRACE(_contextName, AR_CP_OS_CAT2DISPATCHER, <OS Short Name>, <Core Index>, <Event Name>, <Isr Index>)
下表中任何事件的 <Core Index> 应表示相应第二类中断被调度所在的内核ID。
以下事件属于类 AR_CP_OS_CAT2DISPATCHER:
(原文此处内容不完整,暂缺具体事件表)
7.16.4 类 AR_CP_OS_SERVICECALLS
类 AR_CP_OS_SERVICECALLS 包含允许跟踪与调度事件和中断相关的服务调用的事件。
_eventName | eventParameter |
|---|---|
OsServiceCall_DisableAllInterrupts | 0 |
OsServiceCall_SuspendAllInterrupts | 嵌套深度 |
7.16.5 类 AR_CP_OS_SPINLOCK
| 描述 | _eventName | eventParameter |
|---|---|---|
| AUTOSAR自旋锁锁定尝试 | OsSpinlock_Try | SpinlockIdType |
| AUTOSAR自旋锁开始 | OsSpinlock_Start | SpinlockIdType |
| AUTOSAR自旋锁完成 | OsSpinlock_Stop | SpinlockIdType |
8 API规范
本章包含操作系统提供的API。请注意,并非所有服务在所有可扩展性级别中都可用,某些服务的行为会针对特定可扩展性级别进行扩展。例如,相对启动调度表的API会额外检查该调度表是否允许隐式同步。此检查仅在支持调度表同步的SC2和SC4中执行。
8.1 常量
8.1.1 状态类型(StatusType)的错误代码
在多核环境中,以下常量可用。
[SWS_Os_91007] ⌈
| 名称 | 类型 | 范围 |
|---|---|---|
| AppModeType | 枚举 | – |
| DONOTCARE | – | – |
| 描述 | 内核的应用模式应从另一个内核继承。 | |
| 通过以下方式可用 | Os.h |
[SWS_Os_91002] ⌈
| 名称 | 类型 | 范围 |
|---|---|---|
| TotalNumberOfCores | 标量 | 1…65535 |
| 描述 | 内核的总数 | |
| 通过以下方式可用 | Os.h |
其他常量见7.15节和[15]。
8.2 宏
OSMEMORY_IS_READABLE()
OSMEMORY_IS_WRITEABLE()
OSMEMORY_IS_EXECUTABLE()
OSMEMORY_IS_STACKSPACE()
如果内存是可读/可写/可执行的或为栈空间,这些宏返回一个非零值。宏的参数必须是AccessType类型。通常,Check[Task|ISR]MemoryAccess()服务的返回值用作这些宏的参数。
8.3 类型定义
8.3.1 应用类型(用于OS-应用)
[SWS_Os_00772] ⌈
| 名称 | ApplicationType |
|---|---|
| 类型 | uint32 |
| 范围 | INVALID_OSAPPLICATION – |
| 描述 | 此数据类型标识OS-应用。 |
| 通过以下方式可用 | Os.h |
8.3.2 应用状态类型
[SWS_Os_00773] ⌈
| 名称 | ApplicationStateType |
|---|---|
| 类型 | 标量 |
| 范围 | APPLICATION_ACCESSIBLE – APPLICATION_RESTARTING – APPLICATION_TERMINATED – |
| 描述 | 此数据类型标识OS-应用的状态。 |
| 通过以下方式可用 | Os.h |
8.3.3 应用状态引用类型
[SWS_Os_00774] ⌈
| 名称 | ApplicationStateRefType |
|---|---|
| 类型 | 指针 |
| 描述 | 此数据类型指向可存储ApplicationStateType的位置。 |
| 通过以下方式可用 | Os.h |
8.3.4 可信函数索引类型
[SWS_Os_00775] ⌈
| 名称 | TrustedFunctionIndexType |
|---|---|
| 类型 | 标量 |
| 描述 | 此数据类型标识可信函数。 |
| 通过以下方式可用 | Os.h |
8.3.5 可信函数参数引用类型
[SWS_Os_00776] ⌈
| 名称 | TrustedFunctionParameterRefType |
|---|---|
| 类型 | 指针 |
| 描述 | 此数据类型指向一个结构,该结构包含调用可信函数的参数。 |
| 通过以下方式可用 | Os.h |
8.3.6 访问类型
[SWS_Os_00777] ⌈
| 名称 | AccessType |
|---|---|
| 类型 | 整数 |
| 描述 | 此类型包含有关特定内存区域访问方式的信息。 |
| 通过以下方式可用 | Os.h |
8.3.7 对象访问类型
[SWS_Os_00778] ⌈
| 名称 | ObjectAccessType |
|---|---|
| 类型 | – |
| 范围 | ACCESS – NO_ACCESS – |
| 描述 | 此数据类型标识OS-应用是否有权访问对象。 |
| 通过以下方式可用 | Os.h |
8.3.8 对象类型类型
[SWS_Os_00779] ⌈
| 名称 | ObjectTypeType |
|---|---|
| 类型 | – |
| 范围 | OBJECT_TASK – OBJECT_ISR – OBJECT_ALARM – OBJECT_RESOURCE – OBJECT_COUNTER – OBJECT_SCHEDULETABLE – |
| 描述 | 此数据类型标识对象。 |
| 通过以下方式可用 | Os.h |
8.3.9 内存起始地址类型
[SWS_Os_00780] ⌈
| 名称 | MemoryStartAddressType |
|---|---|
| 类型 | – |
| 描述 | 此数据类型是一个指针,能够指向MCU地址空间中的任何位置。 |
| 通过以下方式可用 | Os.h |
8.3.10 内存大小类型
[SWS_Os_00781] ⌈
| 名称 | MemorySizeType |
|---|---|
| 类型 | – |
| 描述 | 此数据类型包含内存区域的大小(以字节为单位)。 |
| 通过以下方式可用 | Os.h |
8.3.11 中断服务程序类型
[SWS_Os_00782] ⌈
| 名称 | ISRType |
|---|---|
| 类型 | – |
| 范围 | INVALID_ISR |
| 描述 | 此数据类型标识中断服务程序(ISR)。 |
| 通过以下方式可用 | Os.h |
8.3.12 调度表类型
[SWS_Os_00783] ⌈
| 名称 | ScheduleTableType |
|---|---|
| 类型 | – |
| 描述 | 此数据类型标识调度表。 |
| 通过以下方式可用 | Os.h |
8.3.13 调度表状态类型
[SWS_Os_00784] ⌈
| 名称 | ScheduleTableStatusType |
|---|---|
| 类型 | – |
| 范围 | SCHEDULETABLE_STOPPED – SCHEDULETABLE_NEXT – SCHEDULETABLE_WAITING – SCHEDULETABLE_RUNNING – SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS – |
| 描述 | 此类型描述调度的状态。状态可以是以下之一: o 调度表未启动(SCHEDULETABLE_STOPPED) o 调度表将在当前运行的调度表结束后启动(调度表在NextScheduleTable()服务中使用)(SCHEDULETABLE_NEXT) o 调度表使用显式同步,已启动且正在等待全局时间。(SCHEDULETABLE_WAITING) o 调度表正在运行,但当前不同步于全局时间源(SCHEDULETABLE_RUNNING) o 调度表正在运行且同步于全局时间源(SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS) |
| 通过以下方式可用 | Os.h |
8.3.14 调度表状态引用类型
[SWS_Os_00785] ⌈
| 名称 | ScheduleTableStatusRefType |
|---|---|
| 类型 | – |
| 描述 | 此数据类型指向ScheduleTableStatusType类型的变量。 |
| 通过以下方式可用 | Os.h |
8.3.15 保护返回类型
[SWS_Os_00787] ⌈
| 名称 | ProtectionReturnType |
|---|---|
| 类型 | – |
| 范围 | PRO_IGNORE – PRO_TERMINATETASKISR – PRO_TERMINATEAPPL – PRO_TERMINATEAPPL_RESTART – PRO_SHUTDOWN – |
| 描述 | 此数据类型标识一个值,该值控制从保护钩子返回时OS的进一步操作。 |
| 通过以下方式可用 | Os.h |
8.3.16 重启类型
[SWS_Os_00788] ⌈
| 名称 | RestartType |
|---|---|
| 类型 | – |
| 范围 | RESTART – NO_RESTART – |
| 描述 | 此数据类型定义终止OS-应用后重启任务的使用。 |
| 通过以下方式可用 | Os.h |
8.3.17 物理时间类型
[SWS_Os_00789] ⌈
| 名称 | PhysicalTimeType |
|---|---|
| 类型 | – |
| 描述 | 此数据类型用于转换宏(参见OS393() OS_TICKS2_())返回的值。 |
| 通过以下方式可用 | Os.h |
8.3.18 内核ID类型
[SWS_Os_00790] ⌈
| 名称 | CoreIdType |
|---|---|
| 类型 | 标量 |
| 范围 | OS_CORE_ID_MASTER – 指主内核,可能是OS_CORE_ID_的别名 OS_CORE_ID_0…OS_CORE_ID_65533 – 指逻辑内核0、内核1等 |
| 描述 | CoreIdType是一个标量,允许标识单个内核。CoreIdType应表示逻辑CoreID |
| 通过以下方式可用 | Os.h |
8.3.19 自旋锁ID类型
[SWS_Os_00791] ⌈
| 名称 | SpinlockIdType |
|---|---|
| 类型 | 标量 |
| 范围 | 1…65535 – 0x01、0x02、…:标识自旋锁实例 INVALID_SPINLOCK – 表示无效的自旋锁实例 |
| 描述 | SpinlockIdType标识自旋锁实例,并由API函数使用:GetSpinlock、ReleaseSpinlock和TryToGetSpinlock。 |
| 通过以下方式可用 | Os.h |
8.3.20 尝试获取自旋锁类型
[SWS_Os_00792] ⌈
| 名称 | TryToGetSpinlockType |
|---|---|
| 类型 | 枚举 |
| 范围 | TRYTOGETSPINLOCK_SUCCESS – 自旋锁成功占用 TRYTOGETSPINLOCK_NOSUCCESS – 无法占用自旋锁 |
| 描述 | TryToGetSpinlockType指示自旋锁是否已被占用。 |
| 通过以下方式可用 | Os.h |
8.3.21 空闲模式类型
[SWS_Os_00793] ⌈
| 名称 | IdleModeType |
|---|---|
| 类型 | 标量 |
| 范围 | IDLE_NO_HALT – 内核在空闲时间不执行任何特定操作 |
| 描述 | 此数据类型标识空闲模式行为。 |
| 通过以下方式可用 | Os.h |
8.3.22 区域ID类型
[SWS_Os_91000] ⌈
| 名称 | AreaIdType |
|---|---|
| 类型 | 标量 |
| 范围 | 0…65534 – 标识外围设备区域 |
| 描述 | AreaIdType标识外围设备区域,并由API函数使用:ReadPeripheralX、WritePeripheralX和ModifyPeripheralX |
| 通过以下方式可用 | Os.h |
8.4 函数定义
以下服务的可用性在表4中定义。这些服务的使用可能会根据调用它们的上下文受到限制。详见表1。
8.4.1 获取应用ID
[SWS_Os_00016] ⌈
| 服务名称 | GetApplicationID |
|---|---|
| 语法 | ApplicationType GetApplicationID( void ) |
| 服务ID[十六进制] | 0x00 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | 无 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | ApplicationType – <运行的OS-应用的标识符> 或 INVALID_OSAPPLICATION |
| 描述 | 此服务确定调用者最初所属(被配置为属于)的OS-应用(必须为每个应用分配唯一标识符)。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00261] ⌈ GetApplicationID()应返回执行中的任务/中断服务程序/钩子被配置所属的应用标识符。⌋ ( )
[SWS_Os_00262] ⌈如果没有OS-应用在运行,GetApplicationID()应返回INVALID_OSAPPLICATION。⌋ ( )
[SWS_Os_00514] ⌈GetApplicationID()的可用性:在可扩展性级别3和4以及多核系统中可用。⌋ ( )
8.4.2 获取当前应用ID
[SWS_Os_00797] ⌈
| 服务名称 | GetCurrentApplicationID |
|---|---|
| 语法 | ApplicationType GetCurrentApplicationID( void ) |
| 服务ID[十六进制] | 0x27 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | 无 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | ApplicationType – <OS-应用的标识符> 或 INVALID_OSAPPLICATION |
| 描述 | 此服务确定调用服务的调用者当前正在执行的OS-应用。请注意,如果调用者不在CallTrustedFunction()调用中,则该值等于GetApplicationID()的结果。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00798]⌈GetCurrentApplicationID()应返回当前任务/中断服务程序/钩子执行所在的应用标识符。⌋ ( )
[SWS_Os_00799] ⌈如果没有OS-应用在运行,GetCurrentApplicationID()应返回INVALID_OSAPPLICATION。⌋ ( )
[SWS_Os_00800] ⌈GetCurrentApplicationID()的可用性:在可扩展性级别3和4中可用。⌋ ( )
8.4.3 获取中断服务程序ID
[SWS_Os_00511] ⌈
| 服务名称 | GetISRID |
|---|---|
| 语法 | ISRType GetISRID( void ) |
| 服务ID[十六进制] | 0x01 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | 无 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | ISRType – <运行中的中断服务程序的标识符> 或 INVALID_ISR |
| 描述 | 此服务返回当前执行的中断服务程序的标识符。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00263] ⌈如果从2类中断服务程序(或在2类中断服务程序内部调用的钩子程序)调用,GetISRID()应返回当前执行的中断服务程序的标识符。⌋ ( )
[SWS_Os_00264] ⌈如果其调用者不是2类中断服务程序(或在2类中断服务程序内部调用的钩子程序),GetISRID()应返回INVALID_ISR。⌋ ( )
[SWS_Os_00515] ⌈GetISRID()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.4 调用可信函数
[SWS_Os_00097] ⌈
| 服务名称 | CallTrustedFunction |
|---|---|
| 语法 | StatusType CallTrustedFunction( TrustedFunctionIndexType FunctionIndex, TrustedFunctionParameterRefType FunctionParams ) |
| 服务ID[十六进制] | 0x02 |
| 同步/异步 | 同步。可能导致重新调度。 |
| 可重入性 | 可重入 |
| 输入参数 | FunctionIndex – 要调用的函数的索引。 FunctionParams – 指向要调用的函数(由FunctionIndex指定)的参数的指针。如果未提供参数,则必须传递空指针。 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_SERVICEID:此索引没有定义函数 |
| 描述 | (可信或非可信)OS-应用使用此服务调用可信函数。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00265] ⌈如果是定义的函数索引,CallTrustedFunction()应从实现特定的可信函数列表中调用函数,并使用提供该可信函数的OS-应用的保护设置,完成后返回E_OK。⌋ ( )
[SWS_Os_00312] ⌈CallTrustedFunction()的注意事项:
被调用的可信函数必须符合以下C原型:void TRUSTED_<trusted_service_name>(TrustedFunctionIndexType, TrustedFunctionParameterRefType);(参数与CallTrustedFunction()的参数相同)。
通常,用户不会直接调用此服务,而是它会成为某些标准接口的一部分,例如标准I/O接口。
被调用的可信函数有责任检查传递参数的权限,特别是当参数被解释为输出参数时。
需要注意的是,CallTrustedFunction()不会为调用该服务的任务禁用定时保护。这甚至可能在可信OS-应用内部导致定时故障(ProtectionHook()的调用)。因此,建议仅将CallTrustedFunction()用于无状态函数(例如不写入或没有内部状态的函数)⌋ ( )
[SWS_Os_00266] ⌈当CallTrustedFunction()调用函数时,该函数应在所属OS-应用的相同处理器模式、内存保护边界和服务保护限制下执行。“当前应用”的概念应保持为调用任务或2类中断服务程序的概念。⌋ ( )
对定时保护的反应可以定义为终止OS-应用。如果任务在CallTrustedFunction()内部,并且在同一OS-应用内发生任务重新调度,新运行的更高优先级任务可能导致定时保护并终止OS-应用,从而间接中止可信函数。为避免这种情况,需要限制属于调用者同一OS-应用的其他任务的调度,以及同一OS-应用的中断的可用性。
[SWS_Os_00565] ⌈当调用CallTrustedFunction()且CallTrustedFunction()的调用者受到定时保护的监控时,操作系统应将任何定时保护错误延迟到CallTrustedFunction()返回到OsTrustedApplicationDelayTimingViolationCall == FALSE的OsApplication为止。⌋ ( )
[SWS_Os_00564] ⌈如果在任务的CallTrustedFunction()嵌套调用序列中检测到此类违规,则延迟应持续到CallTrustedFunction()返回到OsTrustedApplicationDelayTimingViolationCall == FALSE的OsApplication为止。⌋ ( )
[SWS_Os_00563] ⌈操作系统不应调度属于非可信调用者所属OS-应用的任何其他任务。这应通过优先级上限来实现。在服务执行期间,属于同一OS-应用的2类中断也应被禁用。⌋ ( )
[SWS_Os_00364] ⌈如果CallTrustedFunction()从2类中断服务程序上下文调用可信函数,则该函数应继续在相同的中断优先级上运行,并被允许调用为2类中断服务程序定义的所有系统服务(参见7.7.3.2中的表)。⌋ ( )
[SWS_Os_00365] ⌈如果CallTrustedFunction()从任务上下文调用可信函数,则该函数应继续在相同的优先级上运行,并被允许调用为任务定义的所有系统服务(参见7.7.3.2中的表)。⌋ ( )
[SWS_Os_00292] ⌈如果在CallTrustedFunction()的调用中函数索引未定义,CallTrustedFunction()应返回E_OS_SERVICEID。⌋ ( )
[SWS_Os_00516] ⌈CallTrustedFunction()的可用性:在可扩展性级别3和4中可用。⌋ ( )
8.4.5 检查中断服务程序内存访问
[SWS_Os_00512] ⌈
| 服务名称 | CheckISRMemoryAccess |
|---|---|
| 语法 | AccessType CheckISRMemoryAccess( ISRType ISRID, MemoryStartAddressType Address, MemorySizeType Size ) |
| 服务ID[十六进制] | 0x03 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ISRID – 中断服务程序引用 Address – 内存区域的起始地址 Size – 内存区域的大小 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | AccessType – 包含对内存区域的访问权限的值。 |
| 描述 | 此服务检查内存区域是否可写/可读/可执行,并返回该内存区域是否为栈空间的信息。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00267] ⌈如果CheckISRMemoryAccess()调用中的中断服务程序引用有效,CheckISRMemoryAccess()应返回中断服务程序对指定内存区域的访问权限。⌋ ( )
[SWS_Os_00313] ⌈如果在CheckISRMemoryAccess()的调用中指定的整个内存区域的访问权限(例如“读”)无效,CheckISRMemoryAccess()不应产生与此权限相关的访问。⌋ ( )
[SWS_Os_00268] ⌈如果中断服务程序引用无效,CheckISRMemoryAccess()不应产生访问权限。⌋ ( )
[SWS_Os_00517] ⌈CheckISRMemoryAccess()的可用性:在可扩展性级别3和4中可用。⌋ ( )
8.4.6 检查任务内存访问
[SWS_Os_00513] ⌈
| 服务名称 | CheckTaskMemoryAccess |
|---|---|
| 语法 | AccessType CheckTaskMemoryAccess( TaskType TaskID, MemoryStartAddressType Address, MemorySizeType Size ) |
| 服务ID[十六进制] | 0x04 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | TaskID – 任务引用 Address – 内存区域的起始地址 Size – 内存区域的大小 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | AccessType – 包含对内存区域的访问权限的值。 |
| 描述 | 此服务检查内存区域是否可写/可读/可执行,并返回该内存区域是否为栈空间的信息。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00269] ⌈如果CheckTaskMemoryAccess()调用中的任务引用有效,CheckTaskMemoryAccess()应返回任务对指定内存区域的访问权限。⌋ ( )
[SWS_Os_00314] ⌈如果在CheckTaskMemoryAccess()的调用中指定的整个内存区域的访问权限(例如“读”)无效,CheckTaskMemoryAccess()不应产生与此权限相关的访问。⌋ ( )
[SWS_Os_00270] ⌈如果CheckTaskMemoryAccess()调用中的任务引用无效,CheckTaskMemoryAccess()不应产生访问权限。⌋ ( )
[SWS_Os_00518] ⌈CheckTaskMemoryAccess()的可用性:在可扩展性级别3和4中可用⌋ ( )
8.4.7 检查对象访问
[SWS_Os_00256] ⌈
| 服务名称 | CheckObjectAccess |
|---|---|
| 语法 | ObjectAccessType CheckObjectAccess( ApplicationType ApplID, ObjectTypeType ObjectType, void … ) |
| 服务ID[十六进制] | 0x05 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ApplID – OS-应用标识符 ObjectType – 后续参数的类型 … – 要检查的对象 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | ObjectAccessType – 如果ApplID有权访问对象,则为ACCESS;否则为NO_ACCESS |
| 描述 | 此服务确定由ApplID给出的OS-应用是否被允许在API调用中使用任务、资源、计数器、警报或调度表的ID。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00271] ⌈如果CheckObjectAccess()调用中的OS-应用有权访问被查询的对象,CheckObjectAccess()应返回ACCESS。⌋ ( )
[SWS_Os_00272] ⌈如果CheckObjectAccess()调用中的OS-应用无权访问被查询的对象,CheckObjectAccess()应返回NO_ACCESS。⌋ ( )
[SWS_Os_00423] ⌈如果在CheckObjectAccess()的调用中,要检查的对象不是有效对象,或者无效,或者无效,那么CheckObjectAccess()应返回NO_ACCESS。⌋ ( )
[SWS_Os_00519] ⌈CheckObjectAccess()的可用性:在可扩展性级别3和4中可用。⌋ ( )
8.4.8 检查对象所属关系
[SWS_Os_00017] ⌈
| 服务名称 | CheckObjectOwnership |
|---|---|
| 语法 | ApplicationType CheckObjectOwnership( ObjectTypeType ObjectType, void … ) |
| 服务ID[十六进制] | 0x06 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ObjectType – 后续参数的类型 … – 要检查的对象 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | ApplicationType – <OS-应用>:对象ObjectType所属的OS-应用,或者如果对象不存在则为INVALID_OSAPPLICATION |
| 描述 | 此服务确定给定的任务、中断服务程序、计数器、警报或调度表所属的OS-应用。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00273] ⌈如果在CheckObjectOwnership()的调用中指定的对象ObjectType存在,CheckObjectOwnership()应返回该对象所属的OS-应用的标识符。⌋ ( )
[SWS_Os_00274] ⌈如果在CheckObjectOwnership()的调用中,指定的对象ObjectType无效,或者类型的参数(“…”)无效,或者该对象不属于任何OS-应用,CheckObjectOwnership()应返回INVALID_OSAPPLICATION。⌋ ( )
[SWS_Os_00520] ⌈CheckObjectOwnership()的可用性:在可扩展性级别3和4以及多核系统中可用。⌋ ( )
8.4.9 相对启动调度表
[SWS_Os_00347] ⌈
| 服务名称 | StartScheduleTableRel |
|---|---|
| 语法 | StatusType StartScheduleTableRel( ScheduleTableType ScheduleTableID, TickType Offset ) |
| 服务ID[十六进制] | 0x07 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ScheduleTableID – 要启动的调度表 Offset – 相对于基础计数器“当前”值的偏移量(以 ticks 为单位) |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):ScheduleTableID无效 E_OS_VALUE(仅在扩展状态下):Offset大于(OsCounterMaxAllowedValue - InitialOffset)或等于0 E_OS_STATE:调度表已启动 |
| 描述 | 此服务相对于基础计数器的“当前”值在“Offset”处开始调度表的处理。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00275] ⌈如果StartScheduleTableRel()调用中的调度表无效,StartScheduleTableRel()应返回E_OS_ID。⌋ ( )
[SWS_Os_00452] ⌈如果StartScheduleTableRel()调用中的调度表是隐式同步的(OsScheduleTblSyncStrategy = IMPLICIT),StartScheduleTableRel()应返回E_OS_ID。⌋ ( )
[SWS_Os_00332] ⌈如果StartScheduleTableRel()调用中的为零,StartScheduleTableRel()应返回E_OS_VALUE。⌋ ( )
[SWS_Os_00276] ⌈如果偏移量大于基础计数器的OsCounterMaxAllowedValue减去初始偏移量,StartScheduleTableRel()应返回E_OS_VALUE。⌋ ( )
[SWS_Os_00277] ⌈如果StartScheduleTableRel()调用中的调度表不在SCHEDULETABLE_STOPPED状态,StartScheduleTableRel()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00278] ⌈如果StartScheduleTableRel()的输入参数有效且调度表的状态为SCHEDULETABLE_STOPPED,则StartScheduleTableRel()应开始调度表的处理。初始到期点应在基础计数器上经过 + 初始偏移量ticks后处理。在服务返回给调用者之前,的状态设置为SCHEDULETABLE_RUNNING。⌋ ( )
[SWS_Os_00521] ⌈StartScheduleTableRel()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.10 绝对启动调度表
[SWS_Os_00358] ⌈
| 服务名称 | StartScheduleTableAbs |
|---|---|
| 语法 | StatusType StartScheduleTableAbs( ScheduleTableType ScheduleTableID, TickType Start ) |
| 服务ID[十六进制] | 0x08 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ScheduleTableID – 要启动的调度表 Start – 启动调度表的绝对计数器tick值 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):ScheduleTableID无效 E_OS_VALUE(仅在扩展状态下):Start大于OsCounterMaxAllowedValue E_OS_STATE:调度表已启动 |
| 描述 | 此服务在基础计数器上的绝对值“Start”处开始调度表的处理。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00348] ⌈如果StartScheduleTableAbs()调用中的调度表无效,StartScheduleTableAbs()应返回E_OS_ID。⌋ ( )
[SWS_Os_00349] ⌈如果StartScheduleTableAbs()调用中的大于基础计数器的OsCounterMaxAllowedValue,StartScheduleTableAbs()应返回E_OS_VALUE。⌋ ( )
[SWS_Os_00350] ⌈如果StartScheduleTableAbs()调用中的调度表不在SCHEDULETABLE_STOPPED状态,StartScheduleTableAbs()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00351] ⌈如果StartScheduleTableAbs()的输入参数有效且处于SCHEDULETABLE_STOPPED状态,StartScheduleTableAbs()应在基础计数器下次等于时开始调度表的处理,并在返回给用户之前将的状态设置为——对于非同步/显式同步调度表为SCHEDULETABLE_RUNNING,或者对于隐式同步调度表为SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS。(初始到期点将在基础计数器下次等于 + 初始偏移量时处理。)⌋ ( )
[SWS_Os_00522] ⌈StartScheduleTableAbs()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.11 停止调度表
[SWS_Os_00006] ⌈
| 服务名称 | StopScheduleTable |
|---|---|
| 语法 | StatusType StopScheduleTable( ScheduleTableType ScheduleTableID ) |
| 服务ID[十六进制] | 0x09 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ScheduleTableID – 要停止的调度表 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):ScheduleTableID无效 E_OS_NOFUNC:调度表已停止 |
| 描述 | 此服务在调度表运行时的任何时候立即取消其处理。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00279] ⌈如果StopScheduleTable()调用中的调度表标识符无效,StopScheduleTable()应返回E_OS_ID。⌋ ( )
[SWS_Os_00280] ⌈如果调用StopScheduleTable()时,标识符为的调度表处于SCHEDULETABLE_STOPPED状态,StopScheduleTable()应返回E_OS_NOFUNC。⌋ ( )
[SWS_Os_00281] ⌈如果StopScheduleTable()的输入参数有效,StopScheduleTable()应将的状态设置为SCHEDULETABLE_STOPPED,并(停止调度表处理任何进一步的到期点)并返回E_OK。⌋ ( )
[SWS_Os_00523] ⌈StopScheduleTable()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.12 下一个调度表
[SWS_Os_00191] ⌈
| 服务名称 | NextScheduleTable |
|---|---|
| 语法 | StatusType NextScheduleTable( ScheduleTableType ScheduleTableID_From, ScheduleTableType ScheduleTableID_To ) |
| 服务ID[十六进制] | 0x0a |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ScheduleTableID_From – 当前处理的调度表 ScheduleTableID_To – 提供其到期点系列的调度表 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):ScheduleTableID_From或ScheduleTableID_To无效 E_OS_NOFUNC:ScheduleTableID_From未启动 E_OS_STATE:ScheduleTableID_To已启动或为下一个 |
| 描述 | 此服务将处理从一个调度表切换到另一个调度表。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00282] ⌈如果NextScheduleTable()调用中的输入参数<ScheduleTableID_From>或<ScheduleTableID_To>无效,NextScheduleTable()应返回E_OS_ID。⌋ ( )
[SWS_Os_00330] ⌈如果在NextScheduleTable()的调用中,调度表<ScheduleTableID_To>由与调度表<ScheduleTableID_From>不同的计数器驱动,则NextScheduleTable()应返回错误E_OS_ID。⌋ ( )
[SWS_Os_00283] ⌈如果NextScheduleTable()调用中的调度表<ScheduleTableID_From>处于SCHEDULETABLE_STOPPED状态或SCHEDULETABLE_NEXT状态,NextScheduleTable()应保持<ScheduleTable_From>和<ScheduleTable_To>的状态不变,并返回E_OS_NOFUNC。⌋ ( )
[SWS_Os_00309] ⌈如果NextScheduleTable()调用中的调度表<ScheduleTableID_To>不处于SCHEDULETABLE_STOPPED状态,NextScheduleTable()应保持<ScheduleTable_From>和<ScheduleTable_To>的状态不变,并返回E_OS_STATE。⌋ ( )
[SWS_Os_00484] ⌈如果NextScheduleTable()调用中<ScheduleTableID_To>的OsScheduleTblSyncStrategy不等于<ScheduleTableID_From>的OsScheduleTblSyncStrategy,则NextScheduleTable()应返回E_OS_ID。⌋ ( )
[SWS_Os_00284] ⌈如果NextScheduleTable()的输入参数有效,则NextScheduleTable()应在<ScheduleTableID_From>的最终到期点处理后<ScheduleTableID_From>.FinalDelay ticks开始调度表<ScheduleTableID_To>的处理,并返回E_OK。NextScheduleTable()应在<ScheduleTableID_From>的最终到期点处理后<ScheduleTableID_From>.FinalDelay + <ScheduleTable_To>.InitialOffset ticks处理<ScheduleTableID_To>的初始到期点。⌋ ( )
[SWS_Os_00324] ⌈如果NextScheduleTable()的输入参数有效,并且<ScheduleTableID_From>已经有一个“下一个”调度表,则NextScheduleTable()应将先前的“下一个”调度表替换为<ScheduleTableID_To>,并将旧的“下一个”调度表状态更改为SCHEDULETABLE_STOPPED。⌋ ( )
[SWS_Os_00505] ⌈如果NextScheduleTable()调用中的调度表<ScheduleTableID_From>和<ScheduleTableID_To>的OsScheduleTblSyncStrategy为EXPLICIT,并且操作系统模块已经同步<ScheduleTableID_From>,则NextScheduleTable()应在开始处理<ScheduleTableID_To>后继续同步。⌋ ( )
[SWS_Os_00453] ⌈如果NextScheduleTable()中的<ScheduleTableID_From>被停止,NextScheduleTable()不应启动“下一个”调度表,并将其状态更改为SCHEDULETABLE_STOPPED。⌋ ( )
[SWS_Os_00524] ⌈NextScheduleTable()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.13 同步启动调度表
[SWS_Os_00201] ⌈
| 服务名称 | StartScheduleTableSynchron |
|---|---|
| 语法 | StatusType StartScheduleTableSynchron( ScheduleTableType ScheduleTableID ) |
| 服务ID[十六进制] | 0x0b |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ScheduleTableID – 要启动的调度表 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):ScheduleTableID无效 E_OS_STATE:调度表已启动 |
| 描述 | 此服务同步启动显式同步的调度表。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00387] ⌈如果在StartScheduleTableSynchron()的调用中,调度表无效,或者调度表不是显式同步的(OsScheduleTblSyncStrategy != EXPLICIT),StartScheduleTableSynchron()应返回E_OS_ID。⌋ ( )
[SWS_Os_00388] ⌈如果StartScheduleTableSynchron()调用中的调度表不处于SCHEDULETABLE_STOPPED状态,StartScheduleTableSynchron()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00389] ⌈如果StartScheduleTableSynchron()调用中的有效,StartScheduleTableSynchron()应将的状态设置为SCHEDULETABLE_WAITING,并在通过SyncScheduleTable()设置调度表的同步计数后开始调度表的处理。当初始偏移量为调度表中最短的到期点偏移量,且(Duration - SyncValue)+ InitialOffset ticks在同步计数器上经过时,应处理初始到期点。⌋ ( )
[SWS_Os_00525] ⌈StartScheduleTableSynchron()的可用性:在可扩展性级别2和4中可用。⌋ ( )
8.4.14 同步调度表
[SWS_Os_00199] ⌈
| 服务名称 | SyncScheduleTable |
|---|---|
| 语法 | StatusType SyncScheduleTable( ScheduleTableType ScheduleTableID, TickType Value ) |
| 服务ID[十六进制] | 0x0c |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ScheduleTableID – 要同步的调度表 Value – 同步计数器的当前值 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):ScheduleTableID无效或调度表不能显式同步(OsScheduleTblSyncStrategy = IMPLICIT) E_OS_VALUE(仅在扩展状态下):超出范围 E_OS_STATE:调度表的状态等于SCHEDULETABLE_STOPPED |
| 描述 | 此服务为调度表提供同步计数并启动同步。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00454] ⌈如果SyncScheduleTable()调用中的无效,或者调度表不能显式同步(OsScheduleTblSyncStrategy不等于EXPLICIT),SyncScheduleTable()应返回E_OS_ID。⌋ ( )
[SWS_Os_00455] ⌈如果SyncScheduleTable()调用中的大于或等于OsScheduleTableDuration,SyncScheduleTable()应返回E_OS_VALUE。⌋ ( )
[SWS_Os_00456] ⌈如果SyncScheduleTable()调用中的调度表的状态等于SCHEDULETABLE_STOPPED或SCHEDULETABLE_NEXT,SyncScheduleTable()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00457] ⌈如果SyncScheduleTable()调用中的参数有效,SyncScheduleTable()应为给定的调度表向操作系统模块提供当前同步计数。(用于将调度表的处理与同步计数器同步。)⌋ ( )
[SWS_Os_00526] ⌈SyncScheduleTable()的可用性:在可扩展性级别2和4中可用。⌋ ( )
8.4.15 设置异步调度表
[SWS_Os_00422] ⌈
| 服务名称 | SetScheduleTableAsync |
|---|---|
| 语法 | StatusType SetScheduleTableAsync( ScheduleTableType ScheduleTableID ) |
| 服务ID[十六进制] | 0x0d |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ScheduleTableID – 要查询状态的调度表 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):无效的ScheduleTableID |
| 描述 | 此服务停止调度表的同步。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00362] ⌈如果对运行中的调度表调用SetScheduleTableAsync(),操作系统模块应停止进一步的同步,直到调用SyncScheduleTable()。⌋ ( )
[SWS_Os_00323] ⌈如果对运行中的调度表调用SetScheduleTableAsync(),操作系统模块应继续处理调度表上的到期点。⌋ ( )
[SWS_Os_00458] ⌈如果SetScheduleTableAsync()调用中的OsScheduleTblSyncStrategy不等于EXPLICIT,或者无效,则SetScheduleTableAsync()应返回E_OS_ID。⌋ ( )
[SWS_Os_00483] ⌈如果SetScheduleTableAsync()调用中的当前状态等于SCHEDULETABLE_STOPPED、SCHEDULETABLE_NEXT或SCHEDULETABLE_WAITING,则SetScheduleTableAsync()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00300] ⌈如果SetScheduleTableAsync()调用中的当前状态等于SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS(或SCHEDULETABLE_RUNNING),则SetScheduleTableAsync()应将的状态设置为(或在SCHEDULETABLE_RUNNING的情况下保持为)SCHEDULETABLE_RUNNING。⌋ ( )
[SWS_Os_00527] ⌈SetScheduleTableAsync()的可用性:在可扩展性级别2和4中可用。⌋ ( )
8.4.16 获取调度表状态
[SWS_Os_00227] ⌈
| 服务名称 | GetScheduleTableStatus |
|---|---|
| 语法 | StatusType GetScheduleTableStatus( ScheduleTableType ScheduleTableID, ScheduleTableStatusRefType ScheduleStatus ) |
| 服务ID[十六进制] | 0x0e |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ScheduleTableID – 要查询状态的调度表 |
| 输入/输出参数 | 无 |
| 输出参数 | ScheduleStatus – 指向ScheduleTableStatusType的引用 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):无效的ScheduleTableID |
| 描述 | 此服务查询调度表的状态(也与同步相关)。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00289] ⌈如果GetScheduleTableStatus()调用中的调度表未启动,GetScheduleTableStatus()应通过引用参数传回SCHEDULETABLE_STOPPED,并返回E_OK。⌋ ( )
[SWS_Os_00353] ⌈如果GetScheduleTableStatus()调用中的调度表在NextScheduleTable()调用中使用,并且等待当前调度表结束,GetScheduleTableStatus()应通过引用参数返回SCHEDULETABLE_NEXT,并返回E_OK。⌋ ( )
[SWS_Os_00354] ⌈如果GetScheduleTableStatus()调用中的调度表配置为显式同步,并且已通过StartScheduleTableSynchron()启动,且未向操作系统提供同步计数,GetScheduleTableStatus()应通过引用参数返回SCHEDULETABLE_WAITING,并返回E_OK。⌋ ( )
[SWS_Os_00290] ⌈如果GetScheduleTableStatus()调用中的调度表已启动且同步,GetScheduleTableStatus()应通过引用参数传回SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS,并返回E_OK。⌋ ( )
[SWS_Os_00291] ⌈如果GetScheduleTableStatus()调用中的调度表已启动且不同步(偏差不在精度区间内或调度表已设置为异步),GetScheduleTableStatus()应通过引用参数ScheduleStatus传回SCHEDULETABLE_RUNNING,并返回E_OK。⌋ ( )
[SWS_Os_00293] ⌈如果GetScheduleTableStatus()调用中的标识符无效,GetScheduleTableStatus()应返回E_OS_ID。⌋ ( )
[SWS_Os_00528] ⌈GetScheduleTableStatus()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.17 递增计数器
[SWS_Os_00399] ⌈
| 服务名称 | IncrementCounter |
|---|---|
| 语法 | StatusType IncrementCounter( CounterType CounterID ) |
| 服务ID[十六进制] | 0x0f |
| 同步/异步 | 同步,可能导致重新调度 |
| 可重入性 | 可重入 |
| 输入参数 | CounterID – 要递增的计数器 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):CounterID无效或计数器是硬件实现的且不能由软件递增 |
| 描述 | 此服务递增软件计数器。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00285] ⌈如果IncrementCounter()调用中的输入参数无效,或者该计数器是硬件计数器,IncrementCounter()应返回E_OS_ID。⌋ ( )
[SWS_Os_00286] ⌈如果IncrementCounter()的输入参数有效,IncrementCounter()应将计数器递增1(如果与此计数器相连的任何警报到期,则执行给定的操作,例如任务激活),并返回E_OK。⌋ (SRS_Os_11020)
[SWS_Os_00321] ⌈如果在IncrementCounter()的调用中,在警报操作执行期间发生错误(例如,因任务激活导致的E_OS_LIMIT),IncrementCounter()应调用错误钩子,但IncrementCounter()服务本身应返回E_OK。⌋ ( )
[SWS_Os_00529] ⌈IncrementCounter()的注意事项:如果从任务调用,可能会发生重新调度。⌋ ( )
[SWS_Os_00530] ⌈IncrementCounter()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.18 获取计数器值
[SWS_Os_00383] ⌈
| 服务名称 | GetCounterValue |
|---|---|
| 语法 | StatusType GetCounterValue( CounterType CounterID, TickRefType Value ) |
| 服务ID[十六进制] | 0x10 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | CounterID – 要读取tick值的计数器 |
| 输入/输出参数 | 无 |
| 输出参数 | Value – 包含计数器的当前tick值 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):无效 |
| 描述 | 此服务读取计数器的当前计数值(如果计数器由硬件驱动,则返回硬件计时器ticks;如果由用户驱动,则返回软件ticks)。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00376] ⌈如果GetCounterValue()调用中的输入参数无效,GetCounterValue()应返回E_OS_ID。⌋ ( )
[SWS_Os_00377] ⌈如果GetCounterValue()调用中的输入参数有效,GetCounterValue()应通过返回计数器的当前tick值,并返回E_OK。⌋ (SRS_Frt_00033)
[SWS_Os_00531] ⌈GetCounterValue()的注意事项:请注意,对于OsCounterType = HARDWARE的计数器,返回的是真实的计时器值(可能经过调整的硬件值,参见SWS_Os_00384),而对于OsCounterType = SOFTWARE的计数器,返回的是当前的“软件”tick值。⌋ ( )
[SWS_Os_00532] ⌈GetCounterValue()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.19 获取经过的值
[SWS_Os_00392] ⌈
| 服务名称 | GetElapsedValue |
|---|---|
| 语法 | StatusType GetElapsedValue( CounterType CounterID, TickRefType Value, TickRefType ElapsedValue ) |
| 服务ID[十六进制] | 0x11 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | CounterID – 要读取的计数器 |
| 输入/输出参数 | Value – 输入:计数器先前读取的tick值;输出:计数器当前的tick值 |
| 输出参数 | ElapsedValue – 与先前读取值的差值 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID(仅在扩展状态下):CounterID无效 E_OS_VALUE(仅在扩展状态下):给定的Value无效 |
| 描述 | 此服务获取当前tick值与先前读取的tick值之间的ticks数。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00381] ⌈如果GetElapsedValue()调用中的输入参数无效,GetElapsedValue()应返回E_OS_ID。⌋ ( )
[SWS_Os_00391] ⌈如果GetElapsedValue()调用中的大于的最大允许值,GetElapsedValue()应返回E_OS_VALUE。⌋ ( )
[SWS_Os_00382] ⌈如果GetElapsedValue()调用中的输入参数有效,GetElapsedValue()应通过返回自给定值以来经过的ticks数,并返回E_OK。⌋ (SRS_Frt_00034)
[SWS_Os_00460] ⌈GetElapsedValue()应在参数中返回计数器的当前tick值。⌋ ( )
[SWS_Os_00533] ⌈GetElapsedValue()的注意事项:如果计时器已经再次超过值(或多次超过),返回的结果将是错误的。原因是该服务无法检测到这种相对溢出。⌋ ( )
[SWS_Os_00534] ⌈GetElapsedValue()的可用性:在所有可扩展性级别中可用。⌋ ( )
8.4.20 终止应用
[SWS_Os_00258] ⌈
| 服务名称 | TerminateApplication |
|---|---|
| 语法 | StatusType TerminateApplication( ApplicationType Application, RestartType RestartOption ) |
| 服务ID[十六进制] | 0x12 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Application – 要终止的OS-应用的标识符。如果调用者属于,则调用导致自终止。 RestartOption – 要么是RESTART(用于重启OS-应用),要么是NO_RESTART(如果OS-应用不应重启)。 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID:无效(仅在扩展状态下) E_OS_ACCESS:调用者没有权限终止(仅在扩展状态下) E_OS_STATE:的状态不允许终止 |
| 描述 | 此服务终止调用任务/2类中断服务程序/应用特定错误钩子所属的OS-应用。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00493] ⌈如果TerminateApplication()调用中的输入参数无效,TerminateApplication()应返回E_OS_ID。⌋ ( )
[SWS_Os_00459] ⌈如果TerminateApplication()调用中的无效,TerminateApplication()应返回E_OS_VALUE。⌋ ( )
[SWS_Os_00494] ⌈如果TerminateApplication()调用中的输入参数有效,且调用者属于非可信OS-应用,且调用者不属于,TerminateApplication()应返回E_OS_ACCESS。⌋ ( )
[SWS_Os_00507] ⌈如果TerminateApplication()调用中的状态为APPLICATION_TERMINATED,TerminateApplication()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00508] ⌈如果TerminateApplication()调用中的状态为APPLICATION_RESTARTING,且调用者不属于,则TerminateApplication()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00548] ⌈如果TerminateApplication()调用中的状态为APPLICATION_RESTARTING,且调用者属于,且等于RESTART,则TerminateApplication()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00287] ⌈如果TerminateApplication()的参数有效且满足上述条件,TerminateApplication()应终止(即终止所有任务,禁用属于该OS-应用的那些中断服务程序的中断源,并释放与该应用相关联的所有其他OS资源),并且如果等于RESTART,则激活的配置OsRestartTask。如果未配置OsRestartTask,则不发生重启。如果被重启,其状态设置为APPLICATION_RESTARTING,否则设置为APPLICATION_TERMINATED。如果调用者属于,TerminateApplication()不应返回,否则应返回E_OK。⌋ ( )
[SWS_Os_00535] ⌈TerminateApplication()的注意事项:
如果未配置应用,实现应确保此服务不可用。
属于可信应用的任务和中断可以终止任何OS-应用。属于非可信应用的任务和中断只能终止其所属的OS-应用。⌋ ( )
注意:尽管可信OS-应用可以被其他可信OS-应用的任务/中断强制终止,但不建议这样做。这可能会产生进一步的影响,例如,对于当前通过CallTrustedFunction()调用参与此类OS-应用的用户。
[SWS_Os_00536] ⌈TerminateApplication()的可用性:在可扩展性级别3和4中可用。⌋ ( )
8.4.21 允许访问
[SWS_Os_00501] ⌈
| 服务名称 | AllowAccess |
|---|---|
| 语法 | StatusType AllowAccess( void ) |
| 服务ID[十六进制] | 0x13 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | 无 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType – E_OK:无错误 E_OS_STATE:调用者的OS-应用处于错误状态 |
| 描述 | 此服务将OS-应用自身的状态从APPLICATION_RESTARTING设置为APPLICATION_ACCESSIBLE。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00497] ⌈如果AllowAccess()调用者的OS-应用的状态不是APPLICATION_RESTARTING,AllowAccess()应返回E_OS_STATE。⌋ ( )
[SWS_Os_00498] ⌈如果AllowAccess()调用者的OS-应用的状态为APPLICATION_RESTARTING,AllowAccess()应将状态设置为APPLICATION_ACCESSIBLE,并允许其他OS-应用访问调用者OS-应用的配置对象。⌋ ( )
[SWS_Os_00547] ⌈AllowAccess()的可用性:在可扩展性级别3和4中可用。⌋ ( )
8.4.22 获取应用状态
[SWS_Os_00499] ⌈
| 服务名称 | GetApplicationState |
|---|---|
| 语法 | StatusType GetApplicationState( ApplicationType Application, ApplicationStateRefType Value ) |
| 服务ID[十六进制] | 0x14 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Application – 要请求状态的OS-应用 |
| 输入/输出参数 | 无 |
| 输出参数 | Value – 应用的当前状态 |
| 返回值 | StatusType – E_OK:无错误 E_OS_ID:无效(仅在扩展状态下) |
| 描述 | 此服务返回OS-应用的当前状态。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00495] ⌈如果GetApplicationState()调用中的无效,GetApplicationState()应返回E_OS_ID。⌋ ( )
[SWS_Os_00496] ⌈如果GetApplicationState()调用中的参数有效,GetApplicationState()应在中返回OS-应用的状态。⌋ ( )
[SWS_Os_00537] ⌈GetApplicationState()的可用性:在可扩展性级别3和4中可用。⌋ ( )
8.4.23 获取已激活内核数量
[SWS_Os_00672] ⌈
| 服务名称 | GetNumberOfActivatedCores |
|---|---|
| 语法 | uint32 GetNumberOfActivatedCores( void ) |
| 服务ID[十六进制] | 0x15 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | 无 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | uint32 – 通过StartCore函数激活的内核数量(见下文) |
| 描述 | 该函数返回通过StartCore函数激活的内核数量。此函数可能是一个宏。 |
| 通过以下方式可用 | Os.h |
该函数GetNumberOfActivatedCores应可从任务和2类中断服务程序中调用。否则,行为未指定。
[SWS_Os_00673] ⌈GetNumberOfActivatedCores的返回值应小于或等于“OsNumberOfCores”的配置值。⌋ (SRS_Os_80001)
8.4.24 获取内核ID
[SWS_Os_00674] ⌈
| 服务名称 | GetCoreID |
|---|---|
| 语法 | CoreIdType GetCoreID( void ) |
| 服务ID[十六进制] | 0x16 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | 无 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | CoreIdType – 返回值是内核的唯一ID。 |
| 描述 | 该函数返回唯一的内核标识符。 |
| 通过以下方式可用 | Os.h |
[SWS_Os_00675] ⌈函数GetCoreID应返回调用该函数的内核的唯一逻辑CoreID。物理内核到逻辑CoreID的映射是实现特定的。⌋ (SRS_Os_80001)
8.4.25 StartCore
[SWS_Os_00676] ⌈
| 服务名称: | StartCore |
|---|---|
| 语法: | void StartCore( CoreIdType CoreID, StatusType* Status ) |
| 服务ID[十六进制]: | 0x17 |
| 同步/异步: | 同步 |
| 可重入性: | 不可重入 |
| 输入参数: | CoreID:核心标识符 |
| 输入输出参数: | 无 |
| 输出参数: | Status:函数在扩展状态下的返回值:E_OK:无错误;E_OS_ID:核心ID无效;E_OS_ACCESS:在启动OS后调用该函数;E_OS_STATE:核心已激活。函数在标准状态下的返回值:E_OK:无错误 |
| 返回值: | 无 |
| 描述: | 不支持在调用StartOS之后调用此函数。该函数启动由参数CoreID指定的核心。输出参数允许调用者检查操作是否成功。如果通过此函数启动一个核心,则必须在该核心上调用StartOS。 |
| 可通过以下方式获取: | Os.h |
⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
[SWS_Os_00677] ⌈函数StartCore应启动一个将在AUTOSAR OS控制下运行的核心。⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
[SWS_Os_00678] ⌈在StartOS()之后调用StartCore函数应返回E_OS_ACCESS,且核心不会被启动。⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
[SWS_Os_00679] ⌈如果参数CoreID指向已通过StartCore函数启动的核心,则相关核心会被忽略,且应返回E_OS_STATE。⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
[SWS_Os_00680] ⌈如果参数CoreID指向已通过StartNonAutosarCore函数启动的核心,则相关核心会被忽略,且应返回E_OS_STATE。⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
[SWS_Os_00681] ⌈如果在StartCore执行过程中发生错误,不会调用ErrorHook();⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
8.4.26 StartNonAutosarCore
[SWS_Os_00682] ⌈
| 服务名称: | StartNonAutosarCore |
|---|---|
| 语法: | void StartNonAutosarCore( CoreIdType CoreID, StatusType* Status ) |
| 服务ID[十六进制]: | 0x18 |
| 同步/异步: | 同步 |
| 可重入性: | 不可重入 |
| 输入参数: | CoreID:核心标识符 |
| 输入输出参数: | 无 |
| 输出参数: | Status:函数在标准状态下的返回值:E_OK:无错误;E_OS_ID:核心ID无效;E_OS_STATE:核心已激活。函数在扩展状态下的返回值:E_OK:无错误 |
| 返回值: | 无 |
| 描述: | 该函数启动由参数CoreID指定的核心。允许在调用StartOS之后调用此函数。输出参数允许调用者检查操作是否成功。不允许在通过StartNonAutosarCore激活的核心上调用StartOS,否则行为未定义。 |
| 可通过以下方式获取: | Os.h |
⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
[SWS_Os_00683] ⌈函数StartNonAutosarCore应启动一个不受AUTOSAR OS控制的核心。⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
[SWS_Os_00684] ⌈如果参数CoreID指向已通过StartNonAutosarCore函数启动的核心,则该函数无效果,并将“Status”设置为E_OS_STATE。⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
[SWS_Os_00685] ⌈如果参数CoreID指向未知核心,则函数StartNonAutosarCore无效果,并将“Status”设置为E_OS_ID。⌋ (SRS_Os_80006, SRS_Os_80026, SRS_Os_80027)
8.4.27 GetSpinlock
[SWS_Os_00686] ⌈
| 服务名称: | GetSpinlock |
|---|---|
| 语法: | StatusType GetSpinlock( SpinlockIdType SpinlockId ) |
| 服务ID[十六进制]: | 0x19 |
| 同步/异步: | 同步 |
| 可重入性: | 可重入 |
| 输入参数: | SpinlockId:指向要锁定的自旋锁实例的值 |
| 输入输出参数: | 无 |
| 输出参数: | 无 |
| 返回值: | StatusType(状态类型):E_OK——在标准和扩展状态下:无错误;E_OS_ID——在扩展状态下:SpinlockId无效;E_OS_INTERFERENCE_DEADLOCK——在扩展状态下:任务尝试占用自旋锁,而该锁已被同一核心上的任务占用,这将导致死锁;E_OS_NESTING_DEADLOCK——在扩展状态下:任务尝试占用自旋锁,而同一核心上的任务正以可能导致死锁的方式持有另一个自旋锁;E_OS_ACCESS——在扩展状态下:无法访问自旋锁 |
| 描述: | GetSpinlock尝试占用自旋锁变量。如果函数返回,则要么成功获取锁,要么发生错误。自旋锁机制是一种主动轮询机制。该函数不会导致调度切换。 |
| 可通过以下方式获取: | Os.h |
⌋ (SRS_Os_80021)
[SWS_Os_00687] ⌈函数GetSpinlock应占用一个自旋锁。如果该自旋锁已被占用,函数应忙等直到自旋锁可用。⌋ (SRS_Os_80021)
[SWS_Os_00688] ⌈如果未检测到错误,函数GetSpinlock应返回E_OK。此时,调用核心上的调用任务/ISR2占用该自旋锁。⌋ (SRS_Os_80021)
[SWS_Os_00689] ⌈如果参数SpinlockID指向不存在的自旋锁,函数GetSpinlock应返回E_OS_ID。⌋ (SRS_Os_80021)
[SWS_Os_00690] ⌈如果参数SpinlockID指向的自旋锁已被同一核心上的任务/ISR2占用,函数GetSpinlock应返回E_OS_INTERFERENCE_DEADLOCK。⌋ (SRS_Os_80021)
[SWS_Os_00691] ⌈如果同一核心上的任务同时占用多个自旋锁的顺序不符合配置的顺序,函数GetSpinlock应返回E_OS_NESTING_DEADLOCK。⌋ (SRS_Os_80021)
[SWS_Os_00692] ⌈如果访问的OS应用程序未在配置(OsSpinlock)中列出,函数GetSpinlock应返回E_OS_ACCESS。⌋ (SRS_Os_80021)
[SWS_Os_00693] ⌈允许在中断被禁用时调用函数GetSpinlock。⌋ (SRS_Os_80021)
[SWS_Os_00694] ⌈允许在资源被占用时调用函数GetSpinlock。⌋ (SRS_Os_80021)
8.4.28 ReleaseSpinlock
[SWS_Os_00695] ⌈
| 服务名称: | ReleaseSpinlock |
|---|---|
| 语法: | StatusType ReleaseSpinlock( SpinlockIdType SpinlockId ) |
| 服务ID[十六进制]: | 0x1a |
| 同步/异步: | 同步 |
| 可重入性: | 可重入 |
| 输入参数: | SpinlockId:指向要锁定的自旋锁实例的值 |
| 输入输出参数: | 无 |
| 输出参数: | 无 |
| 返回值: | StatusType(状态类型):E_OK——在标准和扩展状态下:无错误;E_OS_STATE——在扩展状态下:自旋锁未被任务占用;E_OS_ACCESS——在扩展状态下:无法访问自旋锁;E_OS_ID——在扩展状态下:SpinlockId无效;E_OS_NOFUNC——在扩展状态下:尝试释放自旋锁,但需先释放另一个自旋锁(或资源) |
| 描述: | ReleaseSpinlock释放之前被占用的自旋锁变量。在终止任务之前,所有通过GetSpinlock()占用的自旋锁变量都应被释放。在调用WaitEVENT之前,所有自旋锁都应被释放。 |
| 可通过以下方式获取: | Os.h |
⌋ (SRS_Os_80021)
[SWS_Os_00696] ⌈函数ReleaseSpinlock应释放已被同一(调用)任务占用的自旋锁。如果相关的GetSpinlock调用使用了配置的锁(ECUC_Os_01038),则该函数还应执行所用锁的撤销操作。⌋ (SRS_Os_80021)
[SWS_Os_00697] ⌈如果未检测到错误,函数ReleaseSpinlock应返回E_OK。此时,自旋锁处于空闲状态,可被同一任务或其他任务占用。⌋ (SRS_Os_80021)
[SWS_Os_00698] ⌈如果参数SpinlockID指向不存在的自旋锁,函数ReleaseSpinlock应返回E_OS_ID。⌋ (SRS_Os_80021)
[SWS_Os_00699] ⌈如果参数SpinlockID指向的自旋锁未被调用任务占用,函数ReleaseSpinlock应返回E_OS_STATE。⌋ (SRS_Os_80021)
[SWS_Os_00700] ⌈如果任务无法访问参数SpinlockID指向的自旋锁,函数ReleaseSpinlock应返回E_OS_ACCESS。⌋ (SRS_Os_80021)
[SWS_Os_00701] ⌈如果任务尝试释放自旋锁,但需先释放另一个自旋锁(或资源),函数ReleaseSpinlock应返回E_OS_NOFUNC,且不执行任何功能。⌋ (SRS_Os_80021)
8.4.29 TryToGetSpinlock
[SWS_Os_00703] ⌈
| 服务名称: | TryToGetSpinlock |
|---|---|
| 语法: | StatusType TryToGetSpinlock( SpinlockIdType SpinlockId, TryToGetSpinlockType* Success ) |
| 服务ID[十六进制]: | 0x1b |
| 同步/异步: | 同步 |
| 可重入性: | 可重入 |
| 输入参数: | SpinlockId:指向要锁定的自旋锁实例的值 |
| 输入输出参数: | 无 |
| 输出参数: | Success:返回锁是否被占用 |
| 返回值: | StatusType(状态类型):E_OK——在标准和扩展状态下:无错误;E_OS_ID——在扩展状态下:SpinlockId无效;E_OS_INTERFERENCE_DEADLOCK——在扩展状态下:任务尝试占用自旋锁,而该锁已被同一核心上的任务占用,这将导致死锁;E_OS_NESTING_DEADLOCK——在扩展状态下:任务尝试占用自旋锁,而持有另一个自旋锁的方式可能导致死锁;E_OS_ACCESS——在扩展状态下:无法访问自旋锁 |
| 描述: | TryToGetSpinlock与GetSpinlock具有相同的功能,不同之处在于,如果自旋锁已被不同核心上的任务占用,该函数会设置输出参数“Success”并返回E_OK。 |
| 可通过以下方式获取: | Os.h |
⌋ (SRS_Os_80021)
[SWS_Os_00704] ⌈函数TryToGetSpinlock应原子性地测试自旋锁的可用性,如果可用则占用它。返回成功的结果。⌋ (SRS_Os_80021)
[SWS_Os_00705] ⌈如果自旋锁成功被占用,函数TryToGetSpinlock应将输出参数“Success”设置为TRYTOGETSPINLOCK_SUCCESS;如果未被占用,则设置为TRYTOGETSPINLOCK_NOSUCCESS。在这两种情况下,都应返回E_OK。⌋ (SRS_Os_80021)
[SWS_Os_00706] ⌈如果函数TryToGetSpinlock未返回E_OK,则输出参数“Success”的值未定义。⌋ (SRS_Os_80021)
[SWS_Os_00707] ⌈如果参数SpinlockID指向不存在的自旋锁,函数TryToGetSpinlock应返回E_OS_ID。⌋ (SRS_Os_80021)
[SWS_Os_00708] ⌈如果参数SpinlockID指向的自旋锁已被同一核心上的任务占用,函数TryToGetSpinlock应返回E_OS_INTERFERENCE_DEADLOCK。⌋ (SRS_Os_80021)
[SWS_Os_00709] ⌈如果任务尝试占用自旋锁,而持有另一个自旋锁的方式可能导致死锁,函数TryToGetSpinlock应返回E_OS_NESTING_DEADLOCK。⌋ (SRS_Os_80021)
[SWS_Os_00710] ⌈如果任务无法访问参数SpinlockID指向的自旋锁,函数TryToGetSpinlock应返回E_OS_ACCESS。⌋ (SRS_Os_80021)
[SWS_Os_00711] ⌈允许在中断被禁用时调用函数TryToGetSpinlock。⌋ (SRS_Os_80021)
[SWS_Os_00712] ⌈允许在资源被占用时调用函数TryToGetSpinlock。⌋ (SRS_Os_80021)
8.4.29 TryToGetSpinlock
[SWS_Os_00703] ⌈
| 服务名称 | TryToGetSpinlock |
|---|---|
| 语法 | StatusType TryToGetSpinlock(SpinlockIdType SpinlockId, TryToGetSpinlockType* Success) |
| 服务ID[十六进制] | 0x1b |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | SpinlockId:指向要锁定的自旋锁实例的值 |
| 输入/输出参数 | 无 |
| 输出参数 | Success:返回自旋锁是否被成功获取 |
| 返回值 | StatusType - E_OK:在标准状态和扩展状态下均表示无错误 - E_OS_ID:在扩展状态下,表示SpinlockId无效 - E_OS_INTERFERENCE_DEADLOCK:在扩展状态下,当任务尝试获取自旋锁,而该锁已被同一内核上的任务占用时,可能导致死锁 - E_OS_NESTING_DEADLOCK:在扩展状态下,当任务在持有另一个自旋锁的情况下尝试获取自旋锁,可能导致死锁 - E_OS_ACCESS:在扩展状态下,表示无法访问自旋锁 |
| 描述 | TryToGetSpinlock与GetSpinlock功能相同,不同之处在于如果自旋锁已被其他内核上的任务占用,该函数会设置输出参数“Success”并返回E_OK。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_80021)
[SWS_Os_00704] ⌈TryToGetSpinlock函数应原子性地检查自旋锁的可用性,若可用则获取它。成功与否的结果会返回。⌋ (SRS_Os_80021)
[SWS_Os_00705] ⌈若自旋锁成功获取,TryToGetSpinlock函数应将输出参数“Success”设为TRYTOGETSPINLOCK_SUCCESS;若未获取,则设为TRYTOGETSPINLOCK_NOSUCCESS。两种情况下均返回E_OK。⌋ (SRS_Os_80021)
[SWS_Os_00706] ⌈若TryToGetSpinlock函数未返回E_OK,则输出参数“Success”的值未定义。⌋ (SRS_Os_80021)
[SWS_Os_00707] ⌈若参数SpinlockID指向不存在的自旋锁,TryToGetSpinlock函数应返回E_OS_ID。⌋ (SRS_Os_80021)
[SWS_Os_00708] ⌈若参数SpinlockID指向的自旋锁已被同一内核上的任务占用,TryToGetSpinlock函数应返回E_OS_INTERFERENCE_DEADLOCK。⌋ (SRS_Os_80021)
[SWS_Os_00709] ⌈若任务在持有另一个自旋锁的情况下尝试获取自旋锁,可能导致死锁,TryToGetSpinlock函数应返回E_OS_NESTING_DEADLOCK。⌋ (SRS_Os_80021)
[SWS_Os_00710] ⌈若任务无法访问参数SpinlockID指向的自旋锁,TryToGetSpinlock函数应返回E_OS_ACCESS。⌋ (SRS_Os_80021)
[SWS_Os_00711] ⌈允许在中断禁用时调用TryToGetSpinlock函数。⌋ (SRS_Os_80021)
[SWS_Os_00712] ⌈允许在资源被占用时调用TryToGetSpinlock函数。⌋ (SRS_Os_80021)
8.4.30 ShutdownAllCores
[SWS_Os_00713] ⌈
| 服务名称 | ShutdownAllCores |
|---|---|
| 语法 | void ShutdownAllCores(StatusType Error) |
| 服务ID[十六进制] | 0x1c |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Error:需要是AUTOSAR OS支持的有效错误代码 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | 无 |
| 描述 | 调用此服务后,所有AUTOSAR内核上的操作系统都会关闭。允许在任务级、中断级调用,也可由操作系统内部调用。该函数永不返回,会强制其他内核进入关闭状态。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_80007)
[SWS_Os_00714] ⌈应通过API函数ShutdownAllCores触发同步关闭。⌋ (SRS_Os_80007)
[SWS_Os_00715] ⌈ShutdownAllCores函数永不返回。⌋ (SRS_Os_80007)
[SWS_Os_00716] ⌈若从非可信代码调用ShutdownAllCores,该调用会被忽略。⌋ (SRS_Os_80007)
8.4.31 ControlIdle
[SWS_Os_00769] ⌈
| 服务名称 | ControlIdle |
|---|---|
| 语法 | StatusType ControlIdle(CoreIdType CoreID, IdleModeType IdleMode) |
| 服务ID[十六进制] | 0x1d |
| 同步/异步 | 同步 |
| 可重入性 | 不可重入 |
| 输入参数 | CoreID:选择要设置空闲模式的内核 IdleMode:内核空闲时要执行的模式 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID(仅扩展状态):无效的内核和/或无效的空闲模式 |
| 描述 | 此API允许调用者选择操作系统空闲时(如无任务/中断活动时)执行的空闲模式操作。它可用于实现节能。实际的空闲模式取决于硬件,未进行标准化。每个内核的默认空闲模式为IDLE_NO_HALT。 |
| 可通过以下方式获取 | Os.h |
⌋ ()
[SWS_Os_00770] ⌈若未检测到错误且参数有效,ControlIdle函数应返回E_OK。⌋ (SRS_Os_80023)
[SWS_Os_00771] ⌈若参数CoreID或IdleMode无效(例如,所指内核不存在、空闲模式未知),ControlIdle函数应返回E_OS_ID。在单核系统中,不检查CoreID。⌋ (SRS_Os_80023)
[SWS_Os_00802] ⌈若内核(由CoreID指定)已处于与给定IdleMode不同的另一种空闲模式,则新的IdleMode应在该内核下次进入空闲模式时生效。⌋ (SRS_Os_80023)
8.4.32 ReadPeripheralX
[SWS_Os_91013] ⌈
| 服务名称 | ReadPeripheral8 |
|---|---|
| 语法 | StatusType ReadPeripheral8(AreaIdType Area, const uint8* Address, uint8* ReadValue) |
| 服务ID[十六进制] | 0x28 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 |
| 输入/输出参数 | 无 |
| 输出参数 | ReadValue:给定内存位置()的内容 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务返回给定内存位置()的内容。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
[SWS_Os_91015] ⌈
| 服务名称 | ReadPeripheral16 |
|---|---|
| 语法 | StatusType ReadPeripheral16(AreaIdType Area, const uint16* Address, uint16* ReadValue) |
| 服务ID[十六进制] | 0x29 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 |
| 输入/输出参数 | 无 |
| 输出参数 | ReadValue:给定内存位置()的内容 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务返回给定内存位置()的内容。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
[SWS_Os_91014] ⌈
| 服务名称 | ReadPeripheral32 |
|---|---|
| 语法 | StatusType ReadPeripheral32(AreaIdType Area, const uint32* Address, uint32* ReadValue) |
| 服务ID[十六进制] | 0x2b |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 |
| 输入/输出参数 | 无 |
| 输出参数 | ReadValue:给定内存位置()的内容 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务返回给定内存位置()的内容。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
8.4.33 WritePeripheralX
[SWS_Os_91010] ⌈
| 服务名称 | WritePeripheral8 |
|---|---|
| 语法 | StatusType WritePeripheral8(AreaIdType Area, uint8* Address, uint8 WriteValue) |
| 服务ID[十六进制] | 0x2b |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 WriteValue:要写入内存地址的值 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务将写入给定的内存位置()。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
[SWS_Os_91012] ⌈
| 服务名称 | WritePeripheral16 |
|---|---|
| 语法 | StatusType WritePeripheral16(AreaIdType Area, uint16* Address, uint16 WriteValue) |
| 服务ID[十六进制] | 0x2c |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 WriteValue:要写入内存地址的值 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务将写入给定的内存位置()。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
[SWS_Os_91011] ⌈
| 服务名称 | WritePeripheral32 |
|---|---|
| 语法 | StatusType WritePeripheral32(AreaIdType Area, uint32* Address, uint32 WriteValue) |
| 服务ID[十六进制] | 0x2d |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 WriteValue:要写入内存地址的值 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务将写入给定的内存位置()。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
8.4.34 ModifyPeripheralX
[SWS_Os_91016] ⌈
| 服务名称 | ModifyPeripheral8 |
|---|---|
| 语法 | StatusType ModifyPeripheral8(AreaIdType Area, uint8* Address, uint8 Clearmask, uint8 Setmask) |
| 服务ID[十六进制] | 0x2e |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 Clearmask:通过按位与操作修改内存地址 Setmask:通过按位或操作修改内存地址 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务使用公式修改给定的内存位置(): = (( & ) |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
[SWS_Os_91018] ⌈
| 服务名称 | ModifyPeripheral16 |
|---|---|
| 语法 | StatusType ModifyPeripheral16(AreaIdType Area, uint16* Address, uint16 Clearmask, uint16 Setmask) |
| 服务ID[十六进制] | 0x2d |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 Clearmask:通过按位与操作修改内存地址 Setmask:通过按位或操作修改内存地址 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务使用公式修改给定的内存位置(): = (( & ) |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
[SWS_Os_91017] ⌈
| 服务名称 | ModifyPeripheral32 |
|---|---|
| 语法 | StatusType ModifyPeripheral32(AreaIdType Area, uint32* Address, uint32 Clearmask, uint32 Setmask) |
| 服务ID[十六进制] | 0x2f |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | Area:硬件外设区域引用 Address:内存地址 Clearmask:通过按位与操作修改内存地址 Setmask:通过按位或操作修改内存地址 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:区域ID超出范围(扩展状态) - E_OS_VALUE:地址不属于给定区域(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用任务或中断服务程序不允许访问给定区域 |
| 描述 | 此服务使用公式修改给定的内存位置(): = (( & ) |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11005)
8.4.35 EnableInterruptSource
[SWS_Os_91020] ⌈
| 服务名称 | EnableInterruptSource |
|---|---|
| 语法 | StatusType EnableInterruptSource(ISRType ISRID, boolean ClearPending) |
| 服务ID[十六进制] | 0x31 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ISRID:2类中断服务程序的ID ClearPending:定义是否清除挂起标志(TRUE表示清除,FALSE表示不清除) |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:ISRID不是有效的2类中断服务程序标识符(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用应用程序不是该中断服务程序的所有者(服务保护) |
| 描述 | 通过修改中断控制器寄存器启用中断源。此外,它可能会清除中断挂起标志。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11011)
8.4.36 DisableInterruptSource
[SWS_Os_91019] ⌈
| 服务名称 | DisableInterruptSource |
|---|---|
| 语法 | StatusType DisableInterruptSource(ISRType ISRID) |
| 服务ID[十六进制] | 0x30 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ISRID:2类中断服务程序的ID |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:ISRID不是有效的2类中断服务程序标识符(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用应用程序不是该中断服务程序的所有者(服务保护) |
| 描述 | 通过修改中断控制器寄存器禁用中断源。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11011)
8.4.37 ClearPendingInterrupt
[SWS_Os_91021] ⌈
| 服务名称 | ClearPendingInterrupt |
|---|---|
| 语法 | StatusType ClearPendingInterrupt(ISRType ISRID) |
| 服务ID[十六进制] | 0x32 |
| 同步/异步 | 同步 |
| 可重入性 | 可重入 |
| 输入参数 | ISRID:2类中断服务程序的ID |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | StatusType - E_OK:无错误 - E_OS_ID:ISRID不是有效的2类中断服务程序标识符(扩展状态) - E_OS_CALLEVEL:API函数的调用上下文错误(扩展状态) - E_OS_ACCESS:调用应用程序不是该中断服务程序的所有者(服务保护) |
| 描述 | 通过修改中断控制器寄存器清除中断挂起标志。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_11011)
8.4.38 ActivateTaskAsyn
[SWS_Os_91022] ⌈
| 服务名称 | ActivateTaskAsyn |
|---|---|
| 语法 | void ActivateTaskAsyn(TaskType id) |
| 服务ID[十六进制] | 0x33 |
| 同步/异步 | 异步 |
| 可重入性 | 可重入 |
| 输入参数 | id:要激活的任务的ID |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | 无 |
| 描述 | ActivateTask()函数的异步版本。用于跨内核任务激活。可能的错误不会返回给调用者,但可能通过错误钩子报告。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_80015)
[SWS_Os_00818] ⌈ActivateTaskAsyn的可用性:在支持OS-Applications的系统中可用。⌋ (SRS_Os_80015)
注意:如果在任务激活过程中发生错误,且调用者已不存在(例如,调用者的OS-Application已终止、调用者的内核正在关闭等),则对错误钩子的调用会被放弃,不进行报告。
8.4.39 SetEventAsyn
[SWS_Os_91023] ⌈
| 服务名称 | SetEventAsyn |
|---|---|
| 语法 | void SetEventAsyn(TaskType TaskId, EventMaskType Mask) |
| 服务ID[十六进制] | 0x34 |
| 同步/异步 | 异步 |
| 可重入性 | 可重入 |
| 输入参数 | TaskId:要设置事件的任务的ID Mask:要设置的事件掩码 |
| 输入/输出参数 | 无 |
| 输出参数 | 无 |
| 返回值 | 无 |
| 描述 | SetEvent()函数的异步版本。用于跨内核事件设置。可能的错误不会返回给调用者,但可能通过错误钩子报告。 |
| 可通过以下方式获取 | Os.h |
⌋ (SRS_Os_80015)
[SWS_Os_00819] ⌈SetEventAsyn的可用性:在支持OS-Applications的系统中可用。⌋ (SRS_Os_80015)
注意:如果在事件设置过程中发生错误,且调用者已不存在(例如,调用者的OS-Application已终止、调用者的内核正在关闭等),则对错误钩子的调用会被放弃,不进行报告。
5525

被折叠的 条评论
为什么被折叠?



