OSEK定时器(Alarms)

1 前言

       对于反复出现的事件的处理,例如周期事件,或处理在特定时间点触发的事件,需要OS提供一种定时机制。对此,OSEK提供了一个两阶段的概念来实现,周期性事件被同步注册到一个计数器(counter),在此基础上OS向应用提供定时器机制(alarm mechanisms)。

2 计数器(Counters)

        OSEK会提供至少一个计数器,该计数器可以由硬件计时器或软件计时器触发。计数器的分辨率通常称为tick,表示计数器单位变化对应的时间;OSEK并没有位计数器提供标准的API接口,但OSEK需要负责相关alarm的处理机制。

3 alarm管理

        系统生成时,会为定时器(alarm)预定义一个溢出值,该值可以是关于某一真实计数值的一个相对值(相对定时器,relative alarm),也可以直接取一个绝对值(绝对定时器,absolute alarm)。举例来说,可以设置定时器相对于当前时间四个后溢出(闹钟铃响),这就是相对定时器;也可以设置定时器到每天早上七点溢出,这就是绝对定时器。

        具体来说,在系统生成时,会对定时器进行静态配置:

• 将定时器与一个计数器绑定,即将alarm与counter关联起来;
• 将定时器与一个任务或定时器回调函数绑定起来,这主要取决于该定时器的作用。

       也就是说,计数器和定时器(Counters and alarms)都是静态配置绑定的(如图1所示),且定时器溢出后所需的处理也是通过静态配置来定义的。

图1  计数器和定时器静态配置关联示意图

        OSEK需要提供一种服务,即当定时器(alarm)溢出时,可以设置去激活一个任务,或设置发起一个时间,亦或者调用执行定时器回调函数(alarm callback routine)。其中,定时器回调函数是由应用层软件注册的一个较短(执行快)的函数,在该回调函数中可以调用的系统接口如图2所示,即只可以调用SuspendAllInterruptsResumeAllInterrupts且当其执行时,需要关闭二类中断。此外,OS还应提供接口以取消定时器或获取某一定时器的当前状态。

图2 系统接口调用限制规范 

        根据定时器溢出后是否复位重复运行,可以将定时器分为单次定时器(single alarms)和周期定时器(cyclic alarms)。

4 定时器回调函数(Alarm-callback routines)

        定时器回调函数有点类似ISR,既不可以有入参,也不可以有返回值。

/* Declare the callback function. */
#define ALARMCALLBACK(name)                    void name(void)

/* Example for an alarm-callback routine: */
ALARMCALLBACK(BrakePedalStroke)
{
/* do application processing */
}

        关于定时器回调函数的处理级别(processing level),一般主要为调度器或ISR所用,这取决于具体的实现方式。 

5 定时器相关系统API

/*
Parameter (In): AlarmID Reference to alarm
Parameter (Out): Info Reference to structure with constants of the alarm base
*/
StatusType GetAlarmBase ( AlarmType <AlarmID>, AlarmBaseRefType <Info> )

/*
Parameter (In): AlarmID Reference to an alarm
Parameter (Out): Tick Relative value in ticks before the alarm <AlarmID> expires.
It is up to the application to decide whether for example a CancelAlarm may still be useful
*/
StatusType GetAlarm ( AlarmType <AlarmID>, TickRefType <Tick>)

/*
Parameter (In): AlarmID:  Reference to the alarm element 
                increment:Relative value in ticks
                cycle:    Cycle value in case of cyclic alarm. In case of single alarms, cycle shall be zero.
Parameter (Out): none

The system service occupies the alarm <AlarmID> element. After <increment> ticks have elapsed, the task assigned to the alarm <AlarmID> is activated or the assigned event (only for extended tasks) is set or the alarm-callback routine is called.

The behaviour of <increment> equal to 0 is up to the implementation.
If the relative value <increment> is very small, the alarm may expire, and the task may become ready or the alarm-callback may be called before the system service returns to the user.
If <cycle> is unequal zero, the alarm element is logged on again immediately after expiry with the relative value <cycle>.
The alarm <AlarmID> must not already be in use.
To change values of alarms already in use the alarm shall be cancelled first.
If the alarm is already in use, this call will be ignored and the error E_OS_STATE is returned
*/
StatusType SetRelAlarm ( AlarmType <AlarmID>, TickType <increment>, TickType <cycle> )

5.1 相对定时器设置 

        显然,alarm的使用与freeRTOS中的软件定时器的使用极为相似,甚至可以说是如出一辙。其中,SetRelAlarm 用于设置并启动相对定时器,主要有以下几个注意点

        • 当<AlarmID>对应的定时器启动后,为系统服务所占有;这也就意味着,在调用SetRelAlarm时,必须保证该定时器并未在使用中;此外,如果想要更改正在使用中的定时器,则必须先取消该定时器,然后再更改;否则,此次更改会被忽略,同时返回错误E_OS_STATE;
        • 若入参<increment>为0,其行为取决于具体的系统实现;

        • 若入参<increment>为一个很小的值,则可能会使得在SetRelAlarm返回应用层,就发生了定时器溢出,或者导致一个任务被唤醒进入就绪态,亦或者对应的定时器回调函数会直接被调用;

        • 如果<cycle>为非零值,则当定时器溢出后,会即刻以同样的<increment>重载该定时器。

5.2 绝对定时器设置

/*
Parameter (In): AlarmID Reference to the alarm element start Absolute value in ticks
  cycle Cycle value in case of cyclic alarm. In case of single alarms, cycle shall be zero.
Parameter (Out): none
*/
StatusType SetAbsAlarm ( AlarmType <AlarmID>, TickType <start>, TickType <cycle> )

       关于绝对定时器的设置,主要有以下几点需要注意:

        • 当<AlarmID>对应的定时器启动后,为系统服务所占有;这也就意味着,在调用SetAbsAlarm时,必须保证该定时器并未在使用中;此外,如果想要更改正在使用中的定时器,则必须先取消该定时器,然后再更改;否则,此次更改会被忽略,同时返回错误E_OS_STATE,这一点与相对定时器相同;
        • 入参<start>是一个绝对值,如果在调用SetRelAlarm,前就已经溢出了,则应等待counter计数到下一个循环,并在此到达<start>时,才可以触发定时器溢出,这一点与freeRTOS的处理完全不同;举例来说,14点钟设置13点半的闹钟,则只能等到第二天下午两点,闹钟才会响了;

        • 若入参<start>非常接近当前的计数值(counter value),则可能会使得在SetRelAlarm返回应用层,就发生了定时器溢出,或者导致一个任务被唤醒进入就绪态,亦或者对应的定时器回调函数会直接被调用;

        • 如果<cycle>为非零值,则当定时器溢出后,会即刻以同样的<increment>重载该定时器。

5.3 其余API

/*
Parameter (In): AlarmID Reference to alarm
Parameter (Out): Info Reference to structure with constants of the alarm base
*/
StatusType GetAlarmBase ( AlarmType <AlarmID>, AlarmBaseRefType <Info> )

/*
Parameter (In): AlarmID Reference to an alarm
Parameter (Out): Tick Relative value in ticks before the alarm <AlarmID> expires.
It is up to the application to decide whether for example a CancelAlarm may still be useful
*/
StatusType GetAlarm ( AlarmType <AlarmID>, TickRefType <Tick>)

/*
Parameter (In): AlarmID Reference to an alarm
Parameter (Out): none
*/
StatusType CancelAlarm ( AlarmType <AlarmID> )

FYI.

  • 30
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值