电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
开源 | 嵌入式物联网应用开发 - 基于任务和事件的OSAL调度器
分 享
扫描二维码分享
开源 | 嵌入式物联网应用开发 - 基于任务和事件的OSAL调度器
嵌入式Linux
物联网应用开发
开源项目
微联智控工作室
关注
发布时间: 2020-07-23
丨
阅读: 639
在进行设备端硬件模块开发之前,先来分享一个单片机通用的软件调度器框架 --- 基于任务和事件的OSAL调度器。 OSAL的全称是Operating System Abstraction Layer,即操作系统抽象层。OSAL最初的概念是由德州仪器TI在ZigBee的协议栈Z-Stack上引入的,严格意义上来说,它并不是一个传统意义的操作系统,但可以实现部分类似操作系统的功能。 基于任务和事件的调度器,可以为MCU单片机编程提供一种通用意义上的框架,事件event是这个框架的最小单位,多个事件组成一个任务task。当一个事件发生时,OSAL负责将该事件分配给能够处理这个事件的任务,然后任务判断该事件的类型,再调用相应的事件处理函数进行处理。 本次开源项目设备端的MCU代码均采用OSAL调度器,OSAL调度器的框架如下图所示: ![](https://cf03.ickimg.com/bbsimages/202007/e85b39bf2e3199b01fce61d88c97a023.png) 这个OSAL调度器主要实现了以下两个功能:任务调度和时间管理。 **任务调度**:采用任务数组tasks_events来管理各层对应的任务事件,tasks_arr是任务事件的处理数组,使用osal_set_event()函数,可以为对应的任务设置事件,使用osal_clear_event()函数,可以清除对应的任务事件。 **时间管理**:OSAL使用STM32的滴答时钟systick作为时间基准,可以虚拟出多个软件定时器,使用这些软件定时器,可以设置延时任务事件,当延时时间到达后,会为对应的任务事件设置触发标志位,然后执行延时事件。 OSAL调度器主要涉及以下源文件: ![](https://cf03.ickimg.com/bbsimages/202007/b11bca8c781c9e51b85570234aa50648.png) osal.c和osal.h:主要是任务的注册和调度实现,以及提供任务事件函数设置函数和任务事件清除函数。 osal_clock.c和osal_clock.h:主要是OSAL调度器使用STM32的滴答时钟systick作为时基,更新系统的软件定时器计数值,以及查找定时任务是否到达定时时间。。 osal_timers.c和osal_timers.h:主要是通过链表的方式管理系统的软件定时器,对外提供软件定时任务的启动函数,软件定时任务的停止函数。 **如何使用OSAL调度器?** 先来看看OSAL调度器的调度流程图,如下图所示: ![](https://cf03.ickimg.com/bbsimages/202007/c1a640938d01c0dcac553751b423b54c.png) 以上流程图,板级初始化和OSAL任务初始化,在main函数中完成,具体的调用方式可以查看GitHub里面的源代码文件。run_system()函数主要在while(1)大循环中调用,不断更新软件定时器并查找是否有定时任务,如果有立即执行的任务或定时任务,则执行任务事件函数,事件处理函数执行完成后,清除事件标志位。 run_system()函数主要在osal.c文件中实现,函数的实现方式如下所示: ![](https://cf03.ickimg.com/bbsimages/202007/beffc10ecbf7acc82bf121c42fa099d6.png) 举个例子:例如我们需要添加一个看门狗的任务来监测系统是否正在运行,并定时进行喂狗操作。那么可以新建任务源文件iwdg_task.c和头文件iwdg_task.h,然后在osal.h文件中定义一个任务ID:IWDG_TASK_ID,这个ID就代表看门狗任务,看门狗任务的一系列事件,可以在头文件iwdg_task.h中进行定义。 源文件iwdg_task.c提供看门狗任务的初始化函数和任务执行函数,每个任务都需要提供任务的初始化函数和任务执行函数,格式如下图所示。 ![](https://cf03.ickimg.com/bbsimages/202007/9f8f6339b269e717a2d162e9b60d5b31.png) 在函数iwdg_task_init()中,先通过register_task_array()函数,绑定IWDG_TASK_ID任务ID和iwdg_task()任务处理函数,然后再初始化STM32的看门狗外设,最后通过osal_start_timer()函数启动一个定时器,不断定时进行喂狗操作。 喂狗事件IWDG_FEED_EVENT和喂狗周期IWDG_FEED_PERIOD是在头文件iwdg_task.h中进行定义的,这里需要注意的是,每个任务事件都是按位操作的,目前每个任务下面最多定义16个事件如下图所示。 ![](https://cf03.ickimg.com/bbsimages/202007/2e3e02bead6e4681a475d49edcd2b8fe.png) 对于OSAL调度器,以下函数接口使用得比较多: ![](https://cf03.ickimg.com/bbsimages/202007/693c4555fe0fc77085ec42ffe1ace407.png) ![](https://cf03.ickimg.com/bbsimages/202007/e8e7c233c83d9932d8b6b486dbce889b.png) 函数osal_set_event()和函数osal_clear_event()主要用来设置和清除立即执行的任务事件,当任务事件设置后,在run_system()函数中,该事件会立即执行。 函数osal_start_timer()和osal_stop_timer()主要用来设置和停止定时器任务事件,当定时时间到达后事件才会执行。osal_start_timer()的第三个参数timeout_value表示首次执行的超时时间,第四个参数reload_timeout_value表示下一次执行的重装载时间。如果要定时任务事件只触发一次,只需要把第四个参数reload_timeout_value置为0即可。 对于德州仪器TI提供的原生OSAL调度器,还有消息通信机制,不同的任务之间通过消息队列来进行数据传输,以实现任务间的数据访问。但这里为了使调度器简单易用,并没有把消息通信机制一并整合进来,使用这个调度器,多个任务间的数据仍然以共享内存的方式进行访问。 项目的开源地址: [https://github.com/embediot/Embedded-IoT-Project](https://github.com/embediot/Embedded-IoT-Project "https://github.com/embediot/Embedded-IoT-Project") [https://gitee.com/embediot/Embedded-IoT-Project](https://gitee.com/embediot/Embedded-IoT-Project "https://gitee.com/embediot/Embedded-IoT-Project") 感谢阅读! ![](https://cf03.ickimg.com/bbsimages/202007/124b259539d2a9f3176ca2128452411a.png)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
微联智控工作室
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交