初学OSEK/VDX
OSEK/VDX:静态定义的实时操作系统?
任务篇:
任务是完成特定功能的一段程序,为实现具有不同实时性要求的系统子功能提供了框架,任务可以异步方式“并行”运行,任务具有不同的优先级。
基本任务和扩展任务都有一个静态的优先级。高优先级任务运行时,低优先级任务会禁止,相同优先级别的任务也会被禁止。
基本任务:
基本任务特征
1.可以被高优先级任务和高优先级中断抢占。
2.可以通过API服务设置不允许被抢占。
基本任务状态:
1.阻塞、就绪、运行 。
StartOS()时,基本任务通过对OIL文件的配置,来达到操作启动后基本任务的状态。如定义为自启动状态则 操作系统启动后该任务处于就绪状态,反之为阻塞状态。
状态迁移图:
扩展任务:
扩展任务特征
与基本任务类似,多了一个附件状态--等待状态和2个附加事件--wait、trigger。
扩展任务进入等待状态后会等待一个事件,等待到事件后进入就绪状态。等待状态期间仍然暂用消耗资源,如堆 栈和内存空间。
时序图:
两种任务比较:
基本任务 | 扩展任务 | |
**事件 | 一个 | 多个 |
释放处理器方式 | 被抢断、终止、中断 | 被抢断、终止、中断 |
数据流控制 | 全局变量 | 局部变量 |
典型应用 | 周期轮训 | 事件驱动 |
任务优先级:
决定了任务执行的顺序和访问处理器的优先权。优先级是创建任务时静态分配的,某些条件下,OS可动态改变任务优先级(针对资源管理的优先级天花板协议)。数值越大,优先级越高,一致性类定义了是否允许不同的任务具有相同的优先级,具有相同优先级的任务:根据FIFO原则顺序执行。
任务调度:
调度程序使用任务的优先级决定哪个单个任务的进入运行状态,每个任务使用静态优先级,运行过程中不能被改变,最低优先级是0.
Full Preemptive:
应用程序中所有任务都被OIL配置成抢占式任务,则该应用白用抢占式调度策略。
抢占式调度程序启用条件:
- 任务被TerminateTask()成功终止
- 任务被成功终止,且另一个任务被ChainTask()**
- 任务被来自 API服务ActivityTask()**
- 一个扩展任务被移进等待状态
- 引起扩展任务进入就绪状态的事件被设置
- 一个任务级的资源被释放
- 从中断返回到任务级
Non Preemptive:
与抢占式调度策略相反,当应用程序中所有任务都被OIL配置成非抢占式任务,则该应用白用非抢占式调度策略。
非抢占式调度程序启用条件:
- 任务被TerminateTask()成功终止
- 任务被成功终止,且另一个任务被ChainTask()**
- API服务被Schedule()被任务调度
- 一个扩展任务被移进等待状态
混合强制式任务调度:
应用程序中部分任务被OIL配置成抢占式另一些为非抢占式任务,则采用混合调度策略。系统根据当前运行任务的抢占类型来决定是否启用调度程序。
优先级天花板协议:
OIL中定义资源,在应用程序中为任务集定义这个资源。
API介绍:
StatusType ActivateTask(TaskType<TaskID>)
使任务由挂起态转为就绪态, OS确保任务代码从第一条语句开始执行
@parameter TaskID ,为传入的要**的任务名,该函数也可以在OIL中被调用
返回的错误值
- E_OK 无错误
- E_OS_ID 非法的任务ID
- E_OS_LIMIT 太多次**调用。
StatusType TerminateTask(void)
终止被调用任务的运行, 任务由运行态进入挂起态
返回的错误值
- E_OK 无错误
- E_OS_RESOURCE 资源仍被占用
- E_OS_CALLEVEL 服务函数是从中断级被调用的
StatusType Schedule(void)
引起任务的重新调度: 如果有更高优先级的任务处于就绪状态,并且任务的内部资源被释放, 那么当前任务转入就绪态, 其上下文会被保存, 更高优先级的任务被执行
返回的错误值
- E_OK 无错误
- E_OS_RESOURCE 资源仍被占用
- E_OS_CALLEVEL 服务函数是从中断级被调用的
StatusType ChainTask (TaskType<TaskID>)
终止当前任务的运行, 并**后继任务
返回的错误值
- E_OK 无错误
- E_OS_ID 非法任务ID
- E_OS_LIMIT 太多**请求
- E_OS_RESOURCE 资源仍被占用
- E_OS_CALLEVEL 服务函数是从中断级被调用的
StatusType GetTaskID (TaskRefType<TaskID>)
获取当前正在运行的任务的ID信息
返回的错误值
- E_OK 无错误
StatusType GetTaskState(TaskType<TaskID>Z, TaskStateRefType<State>)
获取当前正在运行的任务的状态信息
返回的错误值
- E_OK 无错误
- E_OS_ID 非法的任务ID
中断:
分类:
按照功能将中断处理程序分为两类
- 第1类ISR: 不使用系统服务函数
- 第2类ISR: 使用系统服务函数
V2.1规范中规定了第3类ISR,V2.2规范中已将其删除
在第2类ISR中,允许使用除下列之外的所有系统服务函数
- 引起等待状态(WaitEvent)
- 仅对任务起作用的,如:
-
- TerminateTask()
- ChainTask()
- Schedule()
- ClearEvent()
事件:
事件描述:
事件的主要目的是任务同步,事件被任务一对一的拥有,一个任务拥有一个事件时,这个事件即为扩展事件。设置了某事件后, 接收它的任务会切换到就绪状态,当任务表明在“等待某事件”时, 会切换到等待状态。一个任务可接收多个事件,一个事件只能分配给一个任务, 不存在广播事件。
- 等待(Wait) : 只有扩展任务才能等待事件
- 设置(Set): 所有任务都可设置事件以及警报、消息和ISR
- 清除(Clear): 任务只能等待并复位自己的事件
- 获取(Get): 可以检查其它任务的事件状态
事件和中断比较:
中断 | 事件 | |
**方式 | 由外部事件** | 由外部事件** |
处理方式 | 由等待的CPU/中断控制器处理 | 由等待的任务处理 |
优先级 | 取代低优先级的程序 | 取代低优先级的任务 |
资源:
资源描述:
任何为任务/ISR所占用的实体都可称为资源,如:
- I/O硬件设备
- 内存区(RAM)
- 应用程序: 变量, 结构体, 程序段, 等
- 操作系统实体(调度器)
资源管理:
- 两个任务不能同时占用同一资源
- 不会发生优先级反转(priority inversion)
- 使用资源不会引起死锁(deadlock)
- 不会在waiting状态产生资源访问
标准资源:
默认资源,操作系统调度器,被作为应用的资源。在任何一个希望在临界区不被另一个任务抢占的应用中,预先定义的资源,当调度器被加锁时,仍然可以接收并处理中断,中断任务作为非抢占式任务。
特殊资源管理:
- 禁止对相同资源的嵌套访问
- 一个任务对多个资源加锁,资源的释放按照LIFO顺序释放。
- 若确实需嵌套访问,推荐使用一个具有相同行为的资源
- OIL支持定义具有相同行为的资源: Linked Resource
资源管理API:
- DeclareResource(ResourceType<ResID>);
- StatusType GetResource(ResourceType<ResID>);
E_OK no error
E_OS_ID invalid resource ID
E_OS_ACCESS inadmissible access
- StatusType ReleaseResource(ResourceType<ResID>);
E_OK no error
E_OS_ID invalid resource ID
E_OS_NOFUNC not occupied or wrong order
E_OS_ACCESS inadmissible access
Alarm:
警报主要用于处理循环发生的事件。
动态行为:
- 可在运行时刻设定或更改参考值
- 单次超时
- 循环反应
alarm动作:
- **任务
- 设置一个事件
- 调用回调函数
alarm实现:
- 使用与具体实现相关的软件计数器
- 警报的精度取决于实现和配置
alarm原理: