1、Hook routines
OSEK操作系统提供了特定于系统的钩子例程,允许在操作系统内部处理中执行用户定义的操作。
钩子例程特性如下:
- 由OS在特定上下文中调用,具体取决于OS的实现
- 比所有tasks的优先级高
- 不被2类中断程序中断
- OS的一部分
- 由用户使用用户定义的功能实现
- 接口是标准化的,但功能(钩子例程本身的环境和行为)不是标准化的,因此通常钩子例程是不可移植的
- 仅允许使用API函数的子集
- 强制的,但是可以通过OIL进行配置
在OSEK操作系统中,钩子例程可以用在:
- 系统启动:相应的钩子例程(StartupHook)在操作系统启动后和调度器运行之前被调用。
- 系统关闭:对应的钩子例程(ShutdownHook)在应用程序请求关闭系统时调用,或者在发生严重错误时由操作系统请求关闭系统。
- 追踪或是基于用户定义的外部切换的调试应用
- 出错管理
每个OSEK实现都必须描述钩子例程的约定。
如果应用程序在钩子例程中调用了一个不允许的API服务,则行为没有定义。如果引发错误,则实现应返回特定于实现的错误代码。
大多数操作系统服务都不允许使用钩子例程。此限制对于降低系统复杂性是必要的。
2、Error handing
处理OSEK操作系统中临时和永久发生的错误,其基本框架是预定义的,由用户完成。这让用户可以选择高效的集中或分散错误处理。
错误分为两种类型:
- 应用错误:操作系统无法正确执行请求的服务,但假定其内部数据是正确的。在这种情况下,调用集中错误处理。此外,操作系统通过状态信息返回错误,用于分散错误处理。根据发生的错误,由用户来决定要做什么。
- 严重错误:操作系统不能再修订其内部数据。在这种情况下,操作系统调用集中系统关闭。
所有这些错误服务都分配了一个指定错误的参数。
OSEK操作系统提供了两个级别的错误检查,标准状态和扩展状态。如果task在标准状态的版本中被激活,会返回“E OK”或“Too many task activation”。此外,在有扩展状态的版本中,还可以返回附加的返回值“Task is invalid”或“Task still occupy resources”等。
在目标应用程序中这些扩展的返回值不会出现,即相应的错误不会在运行的操作系统中被截获。
OSEK API-services的返回值优先于输出参数。如果API服务返回错误,输出参数的值是未定义的。
错误钩子程序
如果系统服务返回的StatusType值不等于E_OK,则调用错误钩子例程(ErrorHook)。如果从ErrorHook本身调用系统服务,则不会调用该钩子例程ErrorHook(也就是说,永远不会递归调用错误钩子)。从ErrorHook调用系统服务时可能发生的错误只能通过计算返回值来检测。如果在任务激活或事件设置期间检测到错误,例如在alarm超时或消息抵达时,ErrorHook也会被调用。
错误管理
为了在ErrorHook中实现有效的错误管理,用户可以访问附加信息。
宏OSErrorGetServiceId()提供了出现错误的服务标识符。服务标识符的类型是OSServiceldType。取值为“OSServiceld xxxx”,其中xxxx为系统服务名称。OSErrorGetServiceld的实现是强制性的。
如果提供了调用ErrorHook的系统服务的参数,则使用以下访问宏名称构建方案:
OSError_Name1_Name2即: Name1: 系统服务的名称;Name2: 是OSEK操作系统规范中参数的正式名称
例如,访问SetRelAlarm参数的宏如下:
OSError_SetRelAlarm_AlarmID()
OSError_SetRelAlarm_increment ()
OSError_SetRelAlarm_cycle()
如果参数是对象标识符,则访问系统服务的第一个参数的宏是必须的。
3、系统启动
处理器重置后初始化将实现,但OSEK OS提供了对标准化初始化方式的支持。硬件、操作系统和应用程序的初始化接口必须由实现明确定义。
OSEK OS不强制应用程序定义操作系统初始化后需要启动的特殊任务,但允许用户在生成系统时指定自动启动任务和自动启动alarms。
复位CPU后,会执行与硬件相关的应用软件(无操作系统上下文)。不可移植部分以检测应用程序模式结束。出于安全考虑,这种检测不应该依赖于系统历史记录。
在OSEK OS和OSEKtime OS共存的系统中(图11-2中没有体现),OSEKtime初始化总是先运行,OSEKtime初始化的剩余部分将在OSEKtime进入Idle loop后执行,这将导致OSEKtime自动调用StartOS,该应用程序模式已经作为参数传递给OSEKtime。
否则,应用程序的可移植部分从调用一个启动操作系统的函数开始,即以应用程序模式为参数的StartOS。在操作系统初始化后(scheduler没有运行),StartOS调用钩子例程StartupHook,在那里用户可以放置所有与操作系统相关的初始化代码。为了根据启动的应用模式来构造StartupHook中的初始化代码,提供了GetActiveApplicationMode服务。从钩子例程返回后,操作系统启用中断并启动调度器。之后,系统将运行并执行用户任务。
(1) 重置后,用户可以自由地执行(不可移植的)特定于硬件的代码。2类中断在第5阶段之前不允许运行。不可移植部分通过检测应用程序模式结束。
(2)以应用模式为参数调用StartoS。这个调用启动操作系统(如果存在OSEKtime,这是自动完成的)。
(3)操作系统执行内部启动功能和调用钩子例程StartupHook,用户可以在其中放置初始化过程。
(4)在执行钩子程序期间,所有用户中断被disable
(5)操作系统允许用户中断并启动调度活动。操作系统启动为当前应用程序模式声明的自启动tasks和alarms(计数器-如果可能-在alarms自启动前,由系统初始化设置为零。例外:日历计时器等。对于自启动的alarms,所有值均为相对值。)。没有定义同等优先级的自启动tasks的激活顺序。在alarms自启动之前,需要先执行tasks的自启动。
4、系统关闭
OSEK操作系统规范定义了一个关闭操作系统的服务,ShutdownOS。被应用程序或OS检测到严重错误而被请求该服务。
当调用ShutdownnOS时,操作系统将调用钩子例程ShutdownHook并随后关闭。
在ShutdownHook中,用户通常可以自由定义任何系统行为,例如不从例程返回。(参见章节,ShutdownOS)。然而,在OSEK OS与OSEKtime OS共存的情况下,在ShutdownHook中可能会执行一些功能方面的限制。可能只有OSEK OS被关闭,而OSEKtime OS保持不变。因此,在OSEKtime内处理的I/O设备在ShutdownHook中不会复位,ShutdownHook将返回。
5、调试(debugging)
两个钩子例程(PreTaskHook和PostTaskHook)在任务上下文切换时被调用。
这两个钩子例程可以用于调试或时间测量(包括上下文切换时间)。因此,每次在旧任务离开RUNNING状态之前,都会直接调用PostTaskHook;每次有新任务进入RUNNING状态后,PreTaskHook都会被直接调用。因为任务仍然/已经处于RUNNING状态,所以GetTaskId不返回INVALID task。
如果PostTaskHook调用没被定义在ShutdownHook之前或之后。当task运行时调用ShutdownOS,可能调用也可能不调用PostTaskHook。