OSAL

一、概述 OSAL(Operating System Abstraction Layer),翻译为“操作系统抽象层”,OSAL就是以实现多任务为核心的系统资源管理机制。所以OSAL与标准的操作系统还是有很大的区别的。简单而言,OSAL实现了类似操作系统的某些功能,但并不能称之为真正意义上的操作系统。二、OSAL系统的初始化首先在main()中调用OSAL初始化函数Init_Osal(),在Init_Osal()中通过调用osal_init_system()来进行初始化OSAL,在调用osal_init_system()过程中关闭所有中断。在osal_init_system()中包括了内存、定时器、任务初始化、添加任务和初始化添加的任务等。(分别为函数osal_mem_init();osalTimerInit();osalTaskInit(); osalAddTasks();osalInitTasks();osal_mem_kick();)现在我们先进行OSAL系统任务是如何运行的进行分析。关于任务初始化中主要用到 osalTaskInit(); osalAddTasks();osalInitTasks();这三个函数。osalTaskInit()函数的功能是将任务头指针tasksHead置零,有效任务指针activeTask置零,并且初始化任务ID变量taskIDs 为零。 osalAddTasks()函数的功能是添加所有的任务,所谓的添加任务就是在系统内存空间(此部分关于内存的操作将放到最后进行说明)中申请一段空间用于存储任务的结构变量osalTaskRec,按照链表的形式存储所有的任务结构变量,此结构变量中将存储所有任务所需要的信息。通过调用osalTaskAdd()依次添加每个任务。添加任务有三个作用的参数,他们分别是:pfnInit、pfnEventProcessor和taskPriority(任务初始化函数地址、任务处理函数地址和任务的优先级)而taskID参数则是系统通过osalAddTasks()函数随机给分配的。因此编写初始化任务之前必须先编写任务的相关函数(初始化和处理函数)备注:任务处理函数是负责处理传递给此任务的事件,比较重要,具体将在本文的后面进行分析。osalInitTasks()函数的功能是依次调用所有任务的初始化函数,进行初始化。一般都在任务初始化函数中将系统分配的taskID赋值给任务ID全局变量这样在设置任务时方便使用这个任务ID全局变量来传递参数和识别。三、OSAL系统的运行还是先从mian()函数中来寻找OSAL系统运行的蛛丝马迹,轻易的就能找到osal_start_system();这个函数。分析此函数就能大概明白OSAL系统是如何运行的了,首先是定义一个定时器中断,每隔一定的时间产生一次中断,这里使用的是看门狗定时器中断。(这个定时器中断是很重要的,它相当于OSAL系统的时钟,每隔一定的时间进行一次系统的刷新,而后判断任务和时间是否激活,激活的话转入相应的函数进行处理。)紧接着会看到一个for(;;){},这是一个死循环,可以得出程序将一直在这个循环中运行,这段代码的主要功能是:调用osalNextActiveTask()函数判断是否有事件产生,如果有的话返回系统内存空间中相应任务地址,而后读取事件标识并清该事件标识,最后调用相应任务的处理函数,并传递事件标识号,处理相应的事件。那么系统是如何设置事件标识的呢?一、熟悉单片机的都应该知道中断,既然程序将始终在for(;;){}中循环,唯一的方式就是通过中断,在中断程序中调用函数进行事件标识的设置。上文中已经提到过定时器中断(看门狗定时器)在此中断中调用osal_set_event()传递参数:TaskID和EVENT标识,这样将设置相应任务并且设置任务中的事件标识,在for(;;){}中就能读取到有事件产生。二、上面这种方式比较直接,另一种也是通过中断,但是不是直接调用osal_set_event()来设置任务事件,而是通过定时器这样经过一定的延时后才设置任务事件的。这里涉及到OSAL系统中的定时器,这是软件级的定时器,并非单片机上硬件定时器的概念。但是这个软件定时器也是通过上文提到的定时器中断(看门狗定时器)提供的基本时间来进行定时的。白话点就是:当定时器中断(看门狗定时器)产生时,调用一次软件定时器。即调用osal_update_timers();->osalTimerUpdate( tmr_decr_time )。osalTimerUpdate()函数的主要功能是:通过传递的参数更新OSAL系统时间即osal_systemClock += updateTime;而后判断定时器链表中是否有定时器,有的话按链表的顺序依次判断是否达到定时时间(timeout),达到的话则设置该定时器对应的taskID和event_flag,在for(;;){}中就能读取到有事件产生。达到定时时间的定时器将被从链表中清除,未达到的继续等待。此处还有一个问题没有解释,那就是这些对应于不同的taskID的定时器是在哪里初始化和设定的。现在再分析一下定时器的初始化,在OSAL系统初始化的时候就调用过osalTimerInit();函数对定时器进行初始化了,主要的功能是对几个定时器相关变量进行赋值tmr_count = TICK_TIME; //TICK_TIME=250000 tmr_decr_time = TIMER_DECR_TIME;//TIMER_DECR_TIME=250ms osal_timer_activate( false ); timerActive = false;而后就可以在需要的地方进行定时器的添加了,一般都在中断中调用osal_start_timerEx( );进行添加操作的。例如本人使用的程序中在按键中断中调用osal_start_timerEx( Hal_TaskID, HAL_KEY_XIAODOU_EVENT, 10);函数进行添加定时器的,对于定时器的添加操作过程中关闭所有中断,其中调用了osalAddTimer( );函数进行定时器的添加(添加定时器的代码和添加任务的代码很相似)。也是在系统内存空间中申请一段空间用于存储定时器的结构变量osalTimerRec_t并且按照链表的形式存储所有的定时器结构变量。
### 使用OSAL(Operating System Abstraction Layer)的方法 #### 什么是OSALOSAL是一种操作系统抽象层,其主要目的是提供一个多任务环境的支持机制。尽管它不是一个传统意义上的操作系统,但它实现了部分类似于操作系统的功能[^1]。 #### OSAL的主要特性 - **多任务支持**:允许多个任务并行执行。 - **事件驱动架构**:当特定事件发生时,OSAL能够调用对应的事件处理函数进行响应[^3]。 - **跨平台兼容性**:由于设计上采用了硬件抽象的概念,因此可以轻松移植到不同的硬件平台上[^2]。 #### 如何使用OSAL? 以下是关于如何使用OSAL的一些基本指导: ##### 初始化OSAL 在任何应用程序中使用OSAL之前,都需要对其进行初始化。通常情况下,这一步骤涉及设置必要的参数以及启动任务调度器。 ```c #include "osal.h" void main(void) { // 初始化OSAL Osal_InitSys(); // 启动任务调度器 Osal_StartScheduler(); } ``` 上述代码展示了如何通过`Osal_InitSys()`函数完成OSAL的初始化工作,并随后调用`Osal_StartScheduler()`来激活任务调度器。 ##### 创建任务 为了使OSAL能够在系统中管理不同任务,开发者需要定义这些任务及其优先级。下面是一个简单的例子展示如何创建一个新的任务。 ```c // 定义任务入口点 uint8 MyTask(uint8 task_id) { while (TRUE) { // 执行任务逻辑... // 等待下一个事件触发 Osal_Sleep(task_id); } } // 注册新任务 void RegisterMyTask() { Task_t my_task; my_task.pfnTask = &MyTask; // 设置任务回调函数指针 my_task.priority = TASK_PRIORITY_NORMAL; // 设定任务优先级 Osal_RegisterTask(&my_task); // 注册该任务至OSAL框架 } ``` 这里的关键在于理解每一个任务都有自己的ID和优先级级别,在注册过程中需指定它们以便于后续管理和调度。 ##### 处理事件 OSAL的一个重要特点是基于事件驱动模型运作。这意味着每当某个预设条件满足或者外部中断到来时,都会通知相应任务去处理相关事务。 ```c #define EVENT_ID_MY_EVENT 0x01 bool HandleEvent(uint8 event_id, uint8 param[]) { switch(event_id){ case EVENT_ID_MY_EVENT: // 对应事件的具体业务逻辑实现 break; default: return FALSE; // 如果未识别则返回失败状态 } return TRUE; // 成功处理完毕 } ``` 此片段说明了怎样编写一个通用型事件处理器以应对各种可能发生的状况。值得注意的是,每个事件都应当被赋予独一无二的身份标识符用于区分。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值