【ETAS CP AUTOSAR工具链】RTA-OS操作系统详解

RTA-OS基于早期ETAS操作系统的成熟技术,迄今为止,已在全球超过3.5亿个ECU中使用。RTA-OS是一个可静态配置的抢占式实时操作系统(RTOS),它常被用于资源受限但有着高性能要求的方案中。内核的实现不仅遵循了AUTOSAR R3.x、R4.0、R4.1、R4.2、R4.3的开放标准(包含了早期OSEK操作系统标准),还提供了许多RTA-OS所独有的附加功能。

文章首先介绍了RTA-OS诞生的整个过程,并粗略的介绍了不同阶段的系统特性,然后根据一个RTA-OS整体开发过程实例,介绍了RTA-OS基本的特性内容。因为整个RTA-OS是黑盒的,最终需要编译生成的静态链接库(不会像ISOLAR一样生成静态代码)。

目录

概述

开发过程

Counter配置

ISR配置 

Task配置 

Resources配置 

Schedule Table配置

Application Modes配置

RTA-OS编译

多核应用(Multicore Applications)

OS and Non-OS cores 

核心的启动

操作系统启动(StartOS behavior)

操作系统停止(Shutdown)

跨核操作


概述

RTA-OS诞生的过程如下图所示。

OSEK是一个欧洲汽车行业标准,致力于为汽车电子产品提供操作系统,定义相应的接口。该项目的全称是OS-EK/VDX。OSEK是由德语中的一个短语组成的首字母缩略词,其翻译过来为汽车电子系统的开放系统和相应接口。VDX脱胎于法国的一个标准(Vehicle Distributed eXecutive),现已与OSEK合并。如果您想了解更多关于OSEK标准,点击这里可以传送官网。

OSEK OS是OSEK标准中最成熟、应用最广泛的一种操作系统。OSEK OS曾应用于所有类型的汽车ECU,从动力总成、底盘和车身以及多媒体设备。OSEK OS提供了以下几种操作系统功能。

  • Tasks:任务是OSEKOS系统的主要组成部分。与其他一些操作系统不同,OSEK中的任务不需要自调度(也就是说,不需要将任务体放在无限循环中)。OSEK操作系统中有四种类型的任务:
    • BCC1:具有唯一优先级并且不可被多次激活的基本任务。这是最简单的任务形式,非常适合于硬实时系统。一旦任务被激活,它必须运行并终止,然后才能再次激活。这种类型的任务不能在执行过程中暂停自身以等待事件。
    • BCC2:基本任务之间可以共享同一个优先级,并且任务可以被多次激活,任务可以在运行的过程中被激活,激活被保留并等待运行终止之后来响应此次被保留的激活。这种类型的任务同样不能在执行过程中暂停自身以等待事件。
    • ECC1:具有唯一优先级的扩展任务。允许扩展任务在执行期间等待事件(即任务可以自我挂起)。但是,不可被多次被激活,任务必须具有唯一的优先级。
    • ECC2:具有共享优先级的扩展任务。扩展任务允许挂起等待事件,并且可以与系统中的其他任务共享优先级。在这方面,它们与BCC2任务类似。但是,与BCC2任务不同,扩展任务不能具有排队激活。
  • Scheduling:任务可以被抢占或者非抢占的调度,合作式的调度策略也可以被方便的构建。
  • Interrupts:中断允许操作系统与异步的外部传感器进行交互。OSEK操作系统中有两种类型的中断:
    • 第1类中断不由OS处理。
    • 第2类中断由操作系统处理,并且可以与操作系统交互。
  • Resources:资源是简单的二进制信号量,允许您在任务和中断之间共享的临界区上提供互斥。资源由操作系统使用优先级天花板协议(占有资源的任务优先级将高于所有有机会访问此资源的任务)管理,该协议保证免于死锁和优先级反转等问题。
  • Counters and Alarms:计数器和警报用于提供任务的周期性(和非周期性)调度。
  • Debugging Support:OS提供了两种编译方式,标准的编译方式提供了最小资源与错误为目标,扩展的编译方式提供了广泛的错误检测工具,调试提供了符合OSEK ORTI标准的符号,第三方调试器可以基于此实时显示任务状态。

AUTOSAR(汽车开放系统架构)是一个开放的、标准化的汽车软件架构,由全球汽车制造商、供应商和工具开发商共同开发。AUTOSAR为基本软件模块(BSW)提供规范,例如操作系统、通信驱动程序、内存驱动程序和其他微控制器抽象。AUTOSAR标准还定义了一个基于组件的架构模型。该模型定义了一个虚拟功能总线(VFB),定义了一个抽象的应用软件组件(SW-Cs)之间的通信。VFB允许SW-Cs独立于底层硬件使其可在不同的ECU之间移植,并可在多个汽车项目中重复使用。VFB抽象由AUTOSAR运行时环境(RTE)封装。RTE提供了SW-Cs和BSW之间的“粘合剂”。对于AUTOSAR更多详细的内容点击这里跳转官网。

AUTOSAR OS是OSEK OS的扩展。AUTOSAR OS包含OSEK OS的所有功能,并添加了一些新功能,这些新功能分为四个可扩展性等级,如下所示:

  • Scalability Class 1:在OSEK OS的基础上增加:
    • Schedule Tables:在对多种相同与不同周期的任务和事件进行调度时,调度表提供了比OSEK Alarms的一种更简单的替代方法。每个调度表可以作为一个单独的表进行管理,并且可以在运行时在不同的表之间进行切换,使您可以轻松地构建模态系统。
    • Software Counter Interface:操作系统和计数器之间的交互已经标准化(在OSEK是供应商特定的)
    • Stack Monitoring:添加了额外的调试支持,以帮助处理堆栈故障。
  • Scalability Class 2:在SC1的基础上增加了:
    • Schedule Table Synchronization:调度表可以与全局的时钟进行同步。
    • Timing Protection:增加保护以防止任务和中断执行太长或太频繁。
  • Scalability Class 3:在SC1的基础上增加了Memory Protection与Service Protection。
  • Scalability Class 4:是SC1与SC2的集合。

RTA-OS 5.6.3支持Scalability Class1-4的所有AUTOSAR OS R3.x/4.x功能。它还支持AUTOSAR多核操作系统规范中描述的多核应用,包括iOC(操作系统间应用通信)机制。并且由于AUTOSAR OS基于OSEK OS,因此它向后兼容现有的基于OSEK操作系统的应用程序,即,为OSEK OS编写的应用程序将在很大程度上运行于AUTOSAR操作系统而无需修改。

RTA-OS增加了以下一些特性:

  • Time Monitoring:时间监控用于在运行时测量任务和Category2 lSR的执行时间,并根据预先配置的执行时间来检查是否符合要求。
  • Enhanced Stack Monitoring:增强的堆栈监视提供额外的可能性,以帮助您调试堆栈问题。
  • RTA-TRACE Integration:使用ETASRTA-TRACE实时操作系统分析和可视化工具,观察操作系统正在做什么。
  • User control of hardware:用户可以透过OS直接对硬件完成控制。
  • Predictable run-time overheads:可预测的运行时开销。
  • Graphical offline configuration editor:支持通过AUTOSAR XML来配置OS。
  • Easy integration into your build process:只需要一个命令行工具来生成OS代码。
  • Highly scalable kernel architecture:使用离线工具配置生成适合您的OS代码。

开发过程

本章简要概述了如何使用RTA-OS。该过程包括以下步骤:

  1. 使用rtaoscfg配置要使用的操作系统的功能。
  2. 使用rtaosgen生成自定义的RTA-OS内核库与相应符合AUTOSAR规范的头文件。
  3. 编写使用操作系统的程序代码,包括参照生成的Samples完成回调函数的实现。
  4. 编译程序代码并与RTA-OS库链接,生成可执行文件。
  5. 在你的目标板卡上运行你的应用程序。

RTA-OS是静态配置的,这意味着你需要的每一个任务和中断都必须在配置时声明,以及任何临界段、同步点、计数器等。RTA-OS包括rtaoscfg,这是一个图形化配置编辑器,用于配置RTA-OS应用程序。rtaoscfg接受任何AUTOSARXML文件作为输入,并允许您编辑配置的特定于操作系统的部分。rtaoscfg os配置工具如下图所示。

 要创建新的配置时,点击File-New Project即可以创建一个新的项目。

在下面的弹出窗口中依次填入AR Package Name、ECU Configuration Name、OS Configuration Name、Release信息,注意这块填入的内容要尽可能与导入的osNeeds.arxml保持一致,否则会在导入的过程中遇到问题。

此时,在RTA-OS主界面的OS Configuration界面中将会显示新工程的所有配置项,如下图所示。

我们先完成General中的配置,部分配置如下图所示。本书示例使用SC1等级的OS,并使能Startup、Shutdown与Error钩子(Hook)函数,便于OS的调试。 

其次,需要选择OS所运行的目标芯片,这边可以根据您具体板卡的情况选择。 

由于AUTOSAR中提出了运行时环境(RTE)的概念,先前也已经完成了运行实体RE向操作系统任务Task的映射,并完成了RTE Generation阶段的生成。其中,RTE生成的osNeeds.arxml描述文件包含了与操作系统相关的配置信息,将这个描述文件直接导入刚才创建的RTA-OS工程即可完成OS中与用户任务相关的大部分配置。下面介绍基于RTE的OS配置方法。 

首先,保存当前的.rtaos,保存名为CsdnTest。切换到Project Files菜单,并将刚才新建工程生成的arxml文件重名了为CsdnTest.arxml。

切换到Project Files菜单,右键点击OS工程文件CsdnTest.rtaos→Add Existing File,如下图所示。选择添加先前所述的OsNeeds.arxml文件即可。

添加完成之后如下图。

此时,再切换到OS Configuration界面,将看到大部分与用户任务相关的配置信息已导入进来,如下图所示。

下面我们针对几个重要的操作系统配置来详细说明。


Counter配置

如果您在ISOLAR-A中进行RTE配置时未定义OS Counter具体实现相关的属性,那么就需要进行添加。我们将Counter的计数基准配置为1ms,即将Rte_TickCounter中的Seconds Per Tick设置为0.001,并将Ticks Per Base设置为1,如图下图所示。

Counter分为Software Counters和Hardware Counters,Software Counters可以通过程序调用OS提供的API进行增加,硬件计数器则更加复杂,计数值保存在外部硬件设备中。RTA-OS使用特殊的回调函数来设置请求的Ticks数,取消请求,获取当前的计数值和计数器的状态,并通知已经超过了预设的Ticks数。本文中的Counter为Software的,它的计数器驱动模型如下。

我们可以选择一个周期的中断(GTM的回调函数)来增加Counter的Ticks,也可以在一个周期任务做这个事情。

//Using a periodic interrupt to tick a software counter
#include <Os.h>
ISR(HandleTimerInterrupt) {
DismissTimerInterrupt();
IncrementCounter(TimeCounter);
}

//Using a periodic Task to tick a software counter
#include <Os.h>
TASK(Critical){
...
if (Error) {
IncrementCounter(ErrorCounter);
}
...
TerminateTask();
}

在调度表启动之前,应确保Counter已经启动,这里以Gpt举例,使用Gpt_EnableNotification使能回调函数,然后Gpt_StartTimer启动定时器,这样定时器就会以我们设定的周期来回调一个函数,在这个函数里我们可以调用IncrementCounter来增加系统Counter的值。


ISR配置 

由于ISR是与具体实现密切相关的部分,而且还与微控制器相关,所以也需要另行配置。可以右键点击ISRs→New新建一个中断服务函数,其名字必须对应MCAL中的中断服务函数名。这里以产生OS Tick的通用定时器(GPT)中断配置为例进行说明。这里新建一个名为GTMATOM0SR0_ISR的ISR,将其配置为二类中断(CATEGORY_2),定义一个优先级(Priority),并需要选择一个中
断向量号(Address/Vector),这里根据实际的工程代码实现,选择对应的中断源:GTM ATOM 0 Shared SR0 (SRC_GTMATOM00)。

中断的优先级IPL(Interrupt Priority Level)为0代表的是所有Task的优先级,中断的均为1或者更大,下图为第2类中断处理状态图。

每个中断的实现在MCAL中IRQ对应的不同外设中断静态代码中实现,比如CANSR0_ISR在Can_Irq.c中实现。 


Task配置 

Task的配置在导入OsNeeds.arxml的过程中已经包含了,如下图是ASW_OsTask_100ms任务的配置。任务的优先级为33,可激活的次数为1(不可重复激活),此任务的调度是完全抢占模式,任务使用了RTE_RESOURCE资源。

下图是任务的状态切换图,可以看出Task可以调用WaitEvent()等待一个事件从而进入到WAITING状态,所有任务一开始都是SUSPENDED状态,只有被激活之后才进入READY状态,根据优先级排队进入RUNNING状态。

下图是抢占式的任务调度,可以看出每次抢占都涉及到了上下文之间的切换,虽然这会消耗时间和空间上的资源,但为了保证操作系统整体的实时性这是值得的,但是不建议有大量相同优先级的任务,这不仅会增加资源的消耗,并且任务执行的顺序也是无法预测的。

程序需要实现Task的实体,下面的代码包含了BCC 和ECC TASK的实现例子。

//Example A Basic Task
#include <Os.h>
TASK(BCC_Task) 
{
    do_something();
    /* Task must finish with TerminateTask() or equivalent. */
    TerminateTask();
}

//Example Extended Task Waiting for Events
#include <Os.h>
TASK(ECC_Task) 
{
    InitializeTheTask();
    while (WaitEvent(SomeEvent)==E_OK)
    {
        do_something();
        ClearEvent(SomeEvent);
    }
    /* Task never terminates. */
}

每一个任务的实体在RTE生成代码的以任务名称命名的.c文件中定义。


Resources配置 

Resources的配置在导入OsNeeds.arxml的过程中已经包含了,资源用于提供对共享数据或硬件资源的访问的互斥。任务和ISR可以共享任意数量的资源。所有GetResource()和ReleaseResource()调用都必须正确嵌套。RTA-OS提供三种资源,Standard resources、Linked resources和Internal resources。我们使用的资源是Standard的,另外两种这里就不详述了,有兴趣的读者可以自行在《RTA-OS User Guide.pdf》中查找相关的说明。

下面是使用资源的例子。

#include <Os.h>
TASK(Task1) {
...
GetResource(Resource1);
/* Critical section. */
ReleaseResource(Resource1);
...
TerminateTask();
}

Schedule Table配置

我们可以利用Alarms来相对容易地构建需要周期性和非周期性行为的系统,但是Alarms的一个局限性是每个Alarm只能执行一个操作。如果您需要构建一个系统,在该系统中,任务激活具有阶段性序列,并保证每个序列在时间上有一定的Offset,那么您需要非常小心如何启动和停止警报。调度表能帮我们轻松的实现在这类系统中的任务调度,Schedule Table的配置在导入OsNeeds.arxml的过程中已经包含了,Schedule Table的驱动计数器为Rte_TickCounter,定义成了重复模式,且其持续时间为3000ms。如下图。

Schedule Table中每一个终结点的之间都相差1 tick,并且没有Initial Offset和Final Delay,所以一共产生了3000个终结点,在每个终结点定义了若干操作,下图中在第一个终结点激活了8个任务。

下图是两个不同起点的调度表执行情况,调度表的Initial Offset为4,Final Delay是10。

调度表支持三种同步策略,分别是None、Implicit、Explicit。其中前两种RTA-OS不做任何事情来确保同步,Implicit这种同步是通过将调度表的Duration配置成与定时器MaxAllowedValue一致且使用StartScheduleTableAbs()绝对起点来启动调度表保证的同步。而Explicit则需要两个计数器,首先需要的是驱动器计数器,用于驱动调度表判断终结点位置的。其次需要操作系统外部的同步计数器,RTA-OS被告知同步计数器的值,并使用它来同步调度表。

启动一个调度表有三种不同的方法,第一种使用如下接口在绝对点启动调度表。

/* Start Schedule Table Tbl when the counter reaches tick 6 */
StartScheduleTableAbs(Tbl, 6);

下图为对应调度表的执行情况。

第二种启动方法是以相对当下的Counter计数值的偏移来作为起点,接口如下。

/* Start Schedule Table Tbl 6 ticks from now */
StartScheduleTableRel(Tbl, 6);
Example 10.3: Using StartScheduleTableRel()

下图为对应的调度表执行情况。

最后一种为同步启动,同步启动分为两个步骤,第一是使用StartScheduleTableSynchron函数告知调度表进入WAITING状态,第二个使用SyncScheduleTable告知外部的定时器当前的值。

/* Start Schedule Table when the synchronization count is
provided */
StartScheduleTableSynchron(ExplicitlySynchronizedTable);
/* Table now waits */
...
SyncScheduleTable(ExplicitlySynchronizedTable,42);
/* Table processes first expiry point Duration-42+InitialOffset
ticks from now */

下图为同步启动调度表的执行情况。

调度表的停止调用StopScheduleTable停止调度表。

调度表的启动和停止在RTE生成的Rte_Lib.c中Rte_Start与Rte_Stop进行调用。


Application Modes配置

RTA-OS可以在不同的Application Modes下启动。模式是与应用程序的特定功能模式相对应的完整应用程序功能的集合或子集。Application Modes与一组任务、警报和调度表相关联,当操作系统启动时,这些任务、警报和调度表会自动启动。这样就可以实现我们可以在一个版本程序中实现不同类型功能(也可以匹配不同的硬件设计,高低边输出,高低有效输入等)。这里我们配置成OSDEFAULTAPPMODE。下图为将ASW_OsTask_100ms任务添加到以OSDEFAULTAPPMODE启动的OS自启动项。

在启动系统之前,需要先初始化目标硬件,然后才能运行RTA-OS,除非所有内容都位于内存中正确的位置,否则RTA-OS将无法正常工作。可以使用Shutdown0S()调用随时停止RTA-OS。下面是一个启动OS的例子。

OS_MAIN(){
InitializeTarget();
/* Use RTA-OS to initialize interrupts */
Os_InitializeVectorTable();
StartOS(OSDEFAULTAPPMODE);
/* Never reach here */
}

实际会在EcuM中的静态代码EcuM_Prv.c中的EcuM_Prv_StartOS函数根据配置的应用模式来启动OS。


RTA-OS编译

RTA-OS工具可以直接调用编译器对OS相关代码进行编译,生成静态链接库供程序使用。在完成
了OS所有配置后,可以切换到Builder→Setup界面,对生成文件的路径、包含的头文件等进行设置后,工具会自动生成Build脚本。

我们首先选择基本的配置项如下。

然后我们配置项目输出的,这里默认的是工程文件的相对路径,一般不需要改动。

下面我们可以选择生成一些Samples。ErrorHook提供了ErrorHook函数的模板,我们在使能了错误回调之后,就可以在函数中相应的一些错误处写一些错误处理逻辑。

Includes提供了符合AUTOSAR规范的头文件,当我们在将OS集成到符合AUTOSAR规范的程序时可以使用其提供的头文件,其中介绍以下几个。下面是提供的头文件与AUTOSAR头文件之间的关系。

我们在这里简要介绍几个头文件包含的内容。

  • Compiler.h:Os_Compiler_Cfg.h文件包含了一组标记数据与代码大类的宏定义,用于声明符合AUTOSAR规范的函数,Compiler_Cfg.h包含了具体需要系统集成商集成的代码标记宏定义,于声明符合AUTOSAR规范的函数,例如FUNC(void, OS_ERRORHOOK_CODE) ErrorHook(StatusType Error),OS_ERRORHOOK_CODE就在此文件中定义。Compiler.h文件包含上述两个文件,同样包含AUTOSAR规范必要的宏定义,包括#define FUNC(rettype, memclass) rettype memclass等。
  • MemMap.h:Os_MemMap.h按功能提供了系统集成商集成代码的Section开始和结束的宏定义,系统集成商可以在这个基础上增加#Param指令与链接文件配合将代码或数据放置到指定的存储位置。

Applications\HelloWorld例程包含了一些空的错误回调函数我们在集成的过程中参考使用,例如以下。

/* ------------------------------------------------------------------------- */
/* This is called during StartOS() and before RTA-OS starts the scheduler.
 * It is the safest place to enable interrupt sources that have been initialized
 * before StartOS() was called. */
FUNC(void, OS_APPL_CODE) StartupHook(void) {
 TargetEnableInterrupts();
}

/* ------------------------------------------------------------------------- */
FUNC(void, OS_APPL_CODE) ShutdownHook(StatusType Error) {
  /* End of example */
}

/* ------------------------------------------------------------------------- */

FUNC(Os_StopwatchTickType, OS_APPL_CODE) Os_Cbk_GetStopwatch(void) {
    return (Os_StopwatchTickType)STM_TIM0.U;
}

具体的配置如下。 

然后为了编译能够正常通过,我们需要包含一些头文件,包括Std_Types.h与Compiler.h,前者包含一些标准类型的定义,后者包含代码数据存储位置信息。

配置完成后,切换到Builder→Build界面,点击Build Now按钮即可开始OS工程的编译,如下图所示。过程中RTA-OS将调用编译器完成OS相关代码的编译。

多核应用(Multicore Applications)

AUTOSAR在R4.0版本中引入了对多核处理器的支持,RTA-OS5.0及更高版本的用户可以使用具有2个或更多核的目标设备。

多核AUTOSAR应用程序的基本概念如下:

  • 基本配置与单核项目中相同,不同之处在于您必须指定要使用的内核数和对应的Applications配置。Applications配置包括通用配置以及属于其的任务和ISR以及调度表等(只在此核心应用)。

  • 任务和ISR的调度在核之间是独立的。一个内核上的低优先级任务不会受到另一个内核上的高优先级任务或ISR的影响。在内核上禁用中断不会影响任何其他内核。资源被限制在单个内核中,锁定资源不能影响不同内核上的任务。
  • 任务可以从任何核心激活。如果任务配置为在不同的内核上运行,那么操作系统将确保正确执行此操作。
  • 如果您为另一个内核上调用任务激活APl(ActivateTask),则会在ActivateTask调用期间检查可能出现的所有错误(如E_OS_LIMIT),并将其返回给调用者。但是,如果任务成功激活,则任务将在另一个核上运行,运行的时间点适合于那里发生的调度。即使调用任务的优先级高于激活任务的优先级,它也将正常运行(如果任务在同一个内核上,这是不会发生的)。
  • 引入自旋锁来保护不同内核对共享内存的读/写访问。如前所述,您不能依赖任务优先级、中断锁或资源来帮助您在不同内核上的任务之间安全地共享数据。自旋锁用于确保一次只有一个内核可以访问共享数据。内核必须在进入关键代码段之前““获取”自旋锁,然后必须释放它。如果一个核心已经获得了锁,那么任何试图获得锁的其他核心将被阻塞(busy-wait),直到锁被释放。较高优先级的任务或ISR仍然可以抢占等待自旋锁的被阻塞的任务。

下面为一个标准双核启动的过程代码。

OS_MAIN(){
StatusType status;
if (GetCoreID() == OS_CORE_ID_MASTER) {
StartCore(OS_CORE_ID_0, &status);
StartCore(OS_CORE_ID_1, &status);
}
StartOS(OSDEFAULTAPPMODE);
/* StartOS does not return */
}

OS and Non-OS cores 

在多核应用程序中,每个内核可以是OS或Non-OS内核。

  • OS:OS内核是指为其分配了OS Applications的内核。操作系统负责管理在其上运行的代码。属于OS应用程序的所有OS对象都在内核上运行。这包括它的任务,ISR,资源,计数器,警报和调度表。
  • Non-OS:Non-OS(或NonAutosar)内核是指没有为它们分配任何OS Applications的内核,即内核上没有操作系统。

核心的启动

英飞凌3系列芯片会通过Ifx_Ssw_Tcx.c提供的软件启动流程来依次拉起需要启动的核心。


操作系统启动(StartOS behavior)

每个操作系统内核都必须调用Start0s(),并且每次都应该传递相同的AppMode值。

StartOS()API将阻塞等待,直到所有配置了操作系统的内核都将控制权交给OS之后,然后OS将以同步的方式进行启动。它执行所有数据初始化,然后调用StartupHook()(如果配置好的话)。您可以在StartupHook()中调用GetCorelD()来执行特定于核心的代码。

所有OS内核从StartupHook()返回后,将正式启动OS。因为每个操作系统应用程序都属于一个内核,所以这些应用程序只能在一个内核上运行。当所有的启动钩子都完成后,OS会调度所有自动启动的任务,并在空闲时将核心交给ldle机制(0s_Cbk_ldle)。所有操作系统内核都运行相同的全局0s_Cbk_ldle(),与StartupHook()一致,所以其中都需要使用GetCoreID来区别不同核心执行代码。


操作系统停止(Shutdown)

标准的ShutdownOS()调用可用于关闭单个内核的OS,被关闭的核心OS是调用方的核心OS。关闭单个内核OS不会影响其他内核,只是它们将无法再激活已关闭的内核上的任务。OSRestart()机制不能用于重新启动单个内核,因为在StartOS()等待其他内核重新启动期间它会被阻塞。

ShutdownAllCores()可以从任何操作系统核心调用,并将迫使每个核心以有序的方式关闭。OS_Restart()机制可用于重新启动所有核心,前提是它们都在Shutdown_Hook()中调用OS_Restart()。ShutdownHook的行为与StartupHook相同,全局ShutdownHook()在每个内核上运行。


跨核操作

下面的API可以跨内核运行。这意味着,例如,您可以在一个核心上设置事件,而ECC任务实际上将在另一个核心上运行。同样,您可以在一个内核上启动调度表,但它运行在另一个内核上。

  • ActivateTask
  • ChainTask
  • GetTaskState
  • SetEvent
  • GetAlarmBase
  • GetAlarm
  • SetRelAlarm
  • SetAbsAlarm
  • CancelAlarm
  • StartScheduleTableRel
  • StartScheduleTableAbs
  • StopScheduleTable
  • GetScheduleTableStatus
  • GetCounterValue
  • GetElapsedCounterValue

下面的API只在它们被调用的核心的上下文中运行。

  • GetTaskID
  • DisableAllInterrupts
  • EnableAllInterrupts
  • SuspendAllInterrupts
  • ResumeAllInterrupts
  • SuspendOSInterrupts
  • ResumeOSInterrupts
  • CallTrustedFunction
  • IncrementCounter

 十六宿舍 原创作品,转载必须标注原文链接。

©2023 Yang Li. All rights reserved.

欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值