当前位置: 首页 > news >正文

【AUTOSAR】时间保护(Timing Protection)概念、应用与实现源代码解析(下篇)

在这里插入图片描述
本文主要接续上一文章的内容,通过一个开源的autosar cp的具体实现,来详细介绍一下实现的原理。感谢开源小满项目的共享,小满的开源代码可以在网上上获取到。具体的代码见代码文件:RTOS/kernel/Os_Tprot.c

首先摘录具体相关的代码函数实现,而后将具体的对每一个函数进行分析总结。

Part 1:相关函数实现源代码

Os_TmProtMainProc 工作过程详解

首先,观察Os_TmProtMainProc函数的代码结构:

FUNC(void, OS_CODE) Os_TmProtMainProc(void)
{VAR(uint16, OS_VAR) i;/* 1: Timing Protection for task. */Os_TmProtTaskProc();/* 2: Timing Protection for Resource lock. */
#if (CFG_STD_RESOURCE_MAX > 0)for (i = 0u; i < Os_CfgResourceMax; i++){Os_TmProtResCounter((ResourceType)i);}
#endif/* 3: Timing Protection for Isr2. */
#if (CFG_ISR2_MAX > 0)Os_TmProtIsrProc();
#endifreturn;
}

该函数分为三个主要部分:任务的时间保护、资源锁定的时间保护以及中断(ISR2)的时间保护。每个部分都通过条件编译控制是否启用。接下来需要深入每个子函数,分析它们的具体实现。

​**一:分析Os_TmProtTaskProc()**​

Os_TmProtTaskProc()负责处理所有任务的时间保护检查。其代码如下:

static FUNC(void, OS_CODE) Os_TmProtTaskProc(void)
{VAR(uint16, OS_VAR) i;VAR(Os_TaskStateType, OS_VAR) osTaskState;#if (CFG_TASK_MAX > 0)for (i = 0U; i < Os_SCB.sysTaskMax; i++){/* Implementation-dependent: IDLE task should not be protected. */if (OS_TASK_IDLE != (Os_TaskType)i){osTaskState = Os_TCB[i].taskState;if (TASK_STATE_RUNNING == osTaskState){/* Exe_budget only checked in running state. */Os_TmProtTaskCounter((Os_TaskType)i, TP_TASK_EXE);Os_TmProtTaskCounter((Os_TaskType)i, TP_TASK_ARRIVAL);Os_TmProtTaskCounter((Os_TaskType)i, TP_TASK_SUS_OS_INT);Os_TmProtTaskCounter((Os_TaskType)i, TP_TASK_SUS_ALL_INT);Os_TmProtTaskCounter((Os_TaskType)i, TP_TASK_DIS_ALL_INT);}else{/* Time-frame is checked in running and ready states. */Os_TmProtTaskCounter((Os_TaskType)i, TP_TASK_ARRIVAL);}}}
#endifreturn;
}

该函数遍历所有任务(除空闲任务外),根据任务状态执行不同的时间保护检查。对于正在运行的任务(TASK_STATE_RUNNING),会检查执行时间(TP_TASK_EXE)、到达间隔(TP_TASK_ARRIVAL)、中断锁定时间(如TP_TASK_SUS_OS_INT等)。对于非运行状态的任务(如就绪状态),仅检查到达间隔。

接下来需要理解Os_TmProtTaskCounter函数的具体实现,该函数是执行具体时间检查的核心。

二:分析Os_TmProtTaskCounter

该函数处理特定任务的某一类时间保护检查。例如,当osOptType为TP_TASK_EXE时,检查执行时间是否超限。关键代码如下:

static FUNC(void, OS_CODE) Os_TmProtTaskCounter(Os_TaskType osTaskId, Os_TmProtOptTaskType osOptType)
{VAR(StatusType, OS_VAR) osErrType;P2VAR(Os_TCBType, AUTOMATIC, OS_VAR) pTcb;P2VAR(Os_TmProtCbDataDef, AUTOMATIC, OS_VAR) pCbData;if (TP_TASK_ARRIVAL == osOptType){Os_TmProtTaskFrameCounter(osTaskId, osOptType);}else{pTcb = &Os_TCB[osTaskId];pCbData = &(pTcb->osTpTask[osOptType]);if (TRUE == pCbData->osIsTpStart){if (OS_TMPROT_TARGET_ISR_OFFSET <= Os_IntNestISR2){/* 中断嵌套时不处理 */}else{pCbData->osTpTime += 1U;
#if ((OS_SC4 == CFG_SC) && (CFG_TRUSTED_SYSTEM_SERVICE_MAX > 0U))if (FALSE == Os_TrustedFuncTportDelayCall)
#endif{if (pCbData->osTpTime >= pCbData->osTpBudget){pCbData->osTpTime = 0u;pCbData->osIsTpStart = FALSE;if (TP_TASK_EXE == osOptType){osErrType = E_OS_PROTECTION_TIME;}else{osErrType = E_OS_PROTECTION_LOCKED;}(void)Os_CallProtectionHook(osErrType, OS_TMPROT_HOOK_TASK);}}}}}
}

该函数首先判断是否是到达间隔检查(TP_TASK_ARRIVAL),如果是,调用Os_TmProtTaskFrameCounter处理时间帧检查。否则,针对其他类型的时间保护(如执行时间、中断锁定时间),检查计时器是否已启动(osIsTpStart),并在非中断嵌套的情况下累加时间。如果时间超过预算(osTpBudget),则调用保护钩子函数报告错误。

三:分析Os_TmProtResCounter

资源锁定的时间保护在Os_TmProtResCounter中处理:

static FUNC(void, OS_CODE) Os_TmProtResCounter(ResourceType osResId)
{P2VAR(Os_RCBType, AUTOMATIC, OS_VAR) pRcb;P2VAR(Os_TCBType const, AUTOMATIC, OS_VAR) pTcb;P2VAR(Os_TmProtCbDataDef, AUTOMATIC, OS_VAR) pCbData;P2VAR(Os_SCBType const, AUTOMATIC, OS_VAR) pScb;VAR(boolean, OS_VAR) Status = TRUE;pRcb = &Os_RCB[osResId];pCbData = &(pRcb->osResTpData);pScb = &Os_SCB;/* 检查资源是否被任务或中断有效占用 */if (pRcb->osWhichTaskOccupy < Os_SCB.sysTaskMax){pTcb = &Os_TCB[pRcb->osWhichTaskOccupy];if (TASK_STATE_RUNNING != pTcb->taskState){Status = FALSE;}}else if (Os_IntNestISR2 >= OS_TMPROT_TARGET_ISR_OFFSET){if (pScb->sysIsrNestQueue[Os_IntNestISR2 - OS_TMPROT_TARGET_ISR_OFFSET] != pRcb->osWhichIsrOccupy){Status = FALSE;}}else{Status = FALSE;}if (Status){if (pCbData->osIsTpStart){pCbData->osTpTime += 1U;if (pCbData->osTpTime >= pCbData->osTpBudget){pCbData->osTpTime = 0u;pCbData->osTpBudget = 0u;pCbData->osIsTpStart = FALSE;(void)Os_CallProtectionHook(E_OS_PROTECTION_LOCKED, (uint32)pCbData->osWhoHook);}}}
}

该函数检查资源是否被有效占用(任务在运行或中断在嵌套队列中),如果计时器已启动,则累加时间并检查是否超限。超限时报告E_OS_PROTECTION_LOCKED错误。

四:分析Os_TmProtIsrProc

中断的时间保护由Os_TmProtIsrProc处理:

static FUNC(void, OS_CODE) Os_TmProtIsrProc(void)
{VAR(uint16, OS_VAR) i;VAR(Os_IsrType, OS_VAR) osIsrC2Id;P2CONST(Os_IsrCfgType, AUTOMATIC, OS_VAR) pIsrCfg;P2VAR(Os_SCBType const, AUTOMATIC, OS_VAR) pScb;pScb = &Os_SCB;if (Os_IntNestISR2 >= OS_TMPROT_TARGET_ISR_OFFSET){osIsrC2Id = pScb->sysIsrNestQueue[Os_IntNestISR2 - OS_TMPROT_TARGET_ISR_OFFSET];if (osIsrC2Id < CFG_ISR_MAX){pIsrCfg = &Os_IsrCfg[osIsrC2Id];if (OS_ISR_CATEGORY2 == pIsrCfg->OsIsrCatType){Os_TmProtIsrCounter(osIsrC2Id, TP_ISR_CAT2_EXE);Os_TmProtIsrCounter(osIsrC2Id, TP_ISR_CAT2_SUS_OS_INT);Os_TmProtIsrCounter(osIsrC2Id, TP_ISR_CAT2_SUS_ALL_INT);Os_TmProtIsrCounter(osIsrC2Id, TP_ISR_CAT2_DIS_ALL_INT);}}}#if (CFG_ISR2_MAX > 0U)for (i = (Os_CfgIsrMax - Os_CfgIsr2Max); i < Os_CfgIsr2Max; i++){if (i != pScb->sysRunningIsrCat2Id){Os_TmProtIsrCounter(i, TP_ISR_CAT2_ARRIVAL);}}
#endifreturn;
}

该函数首先处理当前嵌套中断的执行时间,然后遍历所有ISR2检查其到达间隔。Os_TmProtIsrCounter与任务的计数器类似,处理中断的执行时间和锁定时间。

Part 2:相关函数实现总结

1. 任务时间保护(Os_TmProtTaskProc)
  • 遍历所有任务(除空闲任务):

    • 运行状态任务
      • 执行时间检查(TP_TASK_EXE):累加osTpTime,若超过osTpBudget,触发E_OS_PROTECTION_TIME错误。
      • 到达间隔检查(TP_TASK_ARRIVAL):验证任务激活间隔是否符合时间帧(OsTaskTimeFrame)。
      • 中断锁定检查(如TP_TASK_SUS_OS_INT):监控任务禁用中断的时间。
    • 非运行状态任务(如就绪状态):
      • 仅检查到达间隔,防止频繁激活。
  • 示例
    任务A配置执行预算为100 ticks(10ms)。每次系统节拍中断(1ms)时,osTpTime递增。若任务A连续运行超过10ms,第10次中断时触发超限错误。

2. 资源锁定时间保护(Os_TmProtResCounter)
  • 遍历所有资源

    • 检查资源占用者状态
      • 任务占用:验证任务是否仍在运行。
      • 中断占用:确认中断位于当前嵌套队列中。
    • 计时器处理
      • 若资源被有效占用,累加osTpTime
      • 超限时触发E_OS_PROTECTION_LOCKED错误,标识占用者类型(任务/中断)。
  • 示例
    资源R的锁定预算为50 ticks(5ms)。任务B获取R后执行耗时操作,若6ms未释放,触发锁定超限错误。

3. 中断时间保护(Os_TmProtIsrProc)
  • 处理当前嵌套中断

    • 执行时间检查(TP_ISR_CAT2_EXE):累加中断执行时间,超限时上报错误。
    • 中断锁定检查(如TP_ISR_CAT2_SUS_OS_INT):监控中断禁用其他中断的时间。
  • 检查所有ISR2的到达间隔

    • 排除当前运行中断:避免自检干扰。
    • 验证中断激活间隔,防止高频触发。
  • 示例
    中断ISR1配置时间帧为200 ticks(20ms)。若ISR1在15ms内被触发两次,第二次激活时触发到达间隔错误。

4. 错误处理与钩子调用
  • 统一错误上报
    • 通过Os_CallProtectionHook传递错误类型(如E_OS_PROTECTION_TIME)和触发实体(任务/中断)。
    • 应用层可自定义钩子函数,执行恢复策略(如终止任务、系统复位)。
5. 条件编译与配置适配
  • 资源保护:通过CFG_STD_RESOURCE_MAX控制是否启用。
  • 中断保护:由CFG_ISR2_MAX决定是否包含ISR2检查。
  • 安全扩展:如CFG_TRUSTED_SYSTEM_SERVICE_MAX支持可信功能延迟处理。

时序与硬件依赖

  • 触发周期:由系统节拍中断驱动,通常在1-10ms之间。
  • 硬件支持:依赖高精度定时器(如TPT)实现精确计时,确保计数器独立于软件延迟。
  • 中断嵌套处理:通过Os_IntNestISR2跟踪嵌套深度,避免在深层中断中误判时间。

总结

Os_TmProtMainProc作为时间保护的总控函数,通过周期性检查任务、资源和中断的时间属性,确保系统行为符合AUTOSAR OS的安全约束。其设计紧密结合硬件特性与实时性要求,是功能安全(如ISO 26262 ASIL-D)的关键实现。

相关文章:

  • 华为HCIP-Cloud-Service认证H13-821V2.0-002
  • 大模型应用开发第三讲:大模型是Agent的“大脑”,提供通用推理能力(如GPT-4、Claude 3)
  • 记录一ubuntu22.04做开机启动mysql、nginx、redis
  • ceph recovery 相关参数
  • 本地jar包发布到maven远端
  • [特殊字符]使用 Hyperlane 实现 WebSocket广播
  • 第三十三天打卡
  • 芝麻糊SSVIP2.0.5.7 | 自动收取能量 小游戏任务
  • 微服务难题?Nacos服务发现来救场
  • python调用langchain实现RAG
  • 安全接口设计:筑牢对外接口的安全防线
  • 【Web应用】若依:基础篇03-入门案例,若依代码生成器生成前后端代码
  • 互联网大厂Java面试:从Spring到微服务的挑战
  • Java提取markdown中的表格
  • Mysql全局优化
  • 学习路之PHP--easyswoole入门及文件热加载
  • 基于 Node.js 的 Express 服务是什么?
  • 【Elasticsearch】scripted_upsert
  • 使用Mathematica绘制随机多项式的根
  • 【elasticsearch 7 或8 的安装及配置SSL 操作指引】
  • 简单大气的网站模板/品牌营销策略案例
  • wordpress js失效/seo岗位
  • 广东深圳疫情严重吗/seo网站推广怎么做
  • 北京市建设和城乡住房委员会/深圳网站设计实力乐云seo
  • 建设大型网站建设/长沙建站优化
  • 一个空间如何做2个网站/搜索引擎是软件还是网站