STM32 OSAL操作系统抽象层的移植
什么是 OSAL?
今天同学忽然问我有没有搞过OSAL
,忽然间一头雾水,于是在搜索引擎上找到了答案,发现这是一个十分实用的东西。
OSAL(operating system abstraction layer
),操作系统抽象层,是一种以实现多任务为核心的系统资源管理机制,实现了类似RTOS
的某些功能,但并不能称之为真正意义上的RTOS
,因为其本身还不支持任务的挂起,任务的抢占等等功能,但是这种机制,实现的代码十分精简,占用资源也非常少,对于资源十分紧张的嵌入式平台,也可以完成比较复杂的逻辑功能。
在TI CC2530
的ZIGBEE
协议栈Z-STACK
中可以找到OSAL的身影,可以在官网上搜索z-stack
下载相关的源码,其中就包含了OSAL
机制实现的源码;移除掉一些无关功能的代码之后,剩下OSAL的源码总共约1100多行代码,全部由C语言实现,资源占用约为RAM:512Byte,ROM:2KB。理论上可以移植到绝大多数的芯片平台上。
源码安装
目前官网上最新的版本,下载安装到本地;
安装完成之后,可以到安装目录下,找到相应的源码,不过这里基本上是zigbee
的协议栈,所以OSAL
相关的部分在下图所示的路径中;
进入到osal
路径下的文件结构如下图所示;
这个OSAL
操作系统抽象层用于保护协议栈软件组件不受程序硬件细节的影响,减少程序的耦合性,提高可移植性和复用性。它可以独立于程序环境,并且提供了以下功能。
- 任务注册、初始化、启动;
- 任务间的消息交换;
- 任务同步;
- 中断处理;
- 计时器;
- 内存分配;
Linux 上OSAL的移植
可以尝试把OSAL
的框架移植到单片机上,进行测试,这里是GitHub
上fork
的一个仓库OSAL ,已经具体的移植方法,可以在Linux
平台上进行测试,
void osal_main(void)
{
//系统硬件、外设等初始化
//禁止中断
HAL_DISABLE_INTERRUPTS();
//osal操作系统初始化
osal_init_system();
//添加任务
osal_add_Task(print_task_init, print_task_event_process, 1);
osal_add_Task(statistics_task_init, statistics_task_event_process, 2);
//添加的任务统一进行初始化
osal_Task_init();
osal_mem_kick();
//允许中断
HAL_ENABLE_INTERRUPTS();
//设置初始任务事件,上电就需要自动轮询的任务事件可在此添加
//启动osal系统,不会再返回
osal_start_system();
}
STM32上OSAL的移植
如果直接使用ti
官方的代码改动会相对比较大,这里直接在github
上找到一份移植到stm32
的工程,直接fork了一份改成HAL
库,可以参考一下stm32-osal,
克隆代码之后,直接复制osal
文件夹到CubeIDE
工程目录下,然后对工程文件列表进行刷新,可以看到如下图所示;
下面是作者基于ti
的osal
的移植说明:
- 完成
OSAL\hal\timer.c
文件,为系统提供时钟; - 修改
OSAL\include\type.h
文件中的全局中断开关函数(可以为空),添加芯片对应的头文件,根据需要修改数据类型重定义,根据芯片字长修改halDataAlign_t类型; - 根据需要修改
OSAL\osal\osal_memory.h
文件中的内存池大小定义,文件中osalMemHdr_t类型需要确保长度为16bit或以上,非8位单片机需要设定内存池的字节对齐; - 添加任务函数中的任务优先级数值大的任务则优先级高;
- 根据需要修改
OSAL\include\osal_memory.h
文件中的OSALMEM_METRICS定义,有效则开启内存统计功能;
关键点
总体来说,因为站在举人的肩膀上,或者纯粹是拿来主义,所以总体代码需要修改的量已经很少了。首先这个机制是根据时间片轮询调度的,所以会对每个任务分配一个ID以及一个任务专属的定时器,同时,使用一个链表管理每个任务的定时器,同样的,每个定时器会更加任务ID来进行匹配,所以,需要在hal增加对定时器更新的函数;如下所示;
因为使用CubeMX修改配置,重新生成代码后会覆盖原文件stm32f1xx_it.c
,所以,重新生成的时候,注意添加osal_update_timers()
,如果对其他内容感兴趣的话,可以参考一下源码;
测试代码
使用串口3进行任务测试,定义了两个任务,先贴出其中的一部分,详细的可以全部的工程代码;
int osal_main(void)
{
HAL_DISABLE_INTERRUPTS();
osal_init_system();
osal_add_Task(Serial_Task_Init,Serial_Task_EventProcess, 1);
osal_add_Task(Serial_Task_02_Init,Serial_Task_02_EventProcess, 2);
osal_Task_init();
osal_mem_kick();
HAL_ENABLE_INTERRUPTS();
//"hello task 01\r\n";
osal_start_reload_timer( Serial_TaskID, PRINTF_STR, 100);
//"hello task 02\r\n";
osal_start_reload_timer( Serial_Task_02_ID, PRINTF_STR_TASK_02, 500);
osal_start_system();
}
下面是运行结果:
结语
有条件的话还是用RTOS吧,支持的功能也比较多,如果不用rtos的话,osal的话感觉也是不错的选择,不过还需要对其源码需要进一步的理解,这样在出现问题的时候,才可以对症下药。
附件
该工程基于CubeIDE 1.3
:
链接
提取码:ncry
STM32 OSAL操作系统抽象层的移植的更多相关文章
- 2、CC2541芯片中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- 4、CC2541芯片中级教程-OSAL操作系统(简单AT指令实现+IIC软件和硬件实现驱动MPU6050)
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- linux kernel的函数与抽象层
在数学领域,函数是一种关系,这种关系使一个集合里的每一个元素对应到另一个(可能相同的)集合里的唯一元素. 在C语言中函数也有这种联系.自变量影响着因变量. 在linux内核驱动编程经常会有抽象层的概念 ...
- 5、CC2541芯片中级教程-OSAL操作系统(PWM+看门狗)
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- 3、CC2541芯片中级教程-OSAL操作系统(ADC光敏电阻和修改串口波特率)
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- PHP 数据库抽象层pdo
PDO是PHP数据对象(PHP Data Object)的缩写. pdo就是一个"数据库访问抽象层",作用是统一各种数据库的访问接口,能够轻松地在不同数据库之间进行切换,使得数据库 ...
- 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 2
18.2 PDO所支持的数据库 使用PHP可以处理各种数据库系统,包括MySQL.PostgreSQL.Oracle.MsSQL等.但访问不同的数据库系统时,其所使用的PHP扩展函数也是不同的.例如 ...
- 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 1
现在,如果你已经能熟练地使用MySQL客户端软件来操作数据库中的数据,就可以开始学习如何使用PHP来显示和修改数据库中的数据了.PHP提供了标准的函数来操作数据库.在PHP 5以上的版本中可以使用My ...
- 网络编程之网络架构及其演变过程、互联网与互联网的组成、OSI七层协议、socket抽象层
目录 网络架构及其演变过程 单机架构 CS架构 BS架构 BS架构和CS架构的区别 C/S架构的优缺点: B/S架构的优缺点: 互联网与互联网的组成 互联网的组成(教科书版) 互联网的组成(科普版) ...
随机推荐
- L15卷积神经网络基础
卷积神经网络基础 本节我们介绍卷积神经网络的基础概念,主要是卷积层和池化层,并解释填充.步幅.输入通道和输出通道的含义. 二维卷积层 本节介绍的是最常见的二维卷积层,常用于处理图像数据. 二维互相关运 ...
- 不同目录有同名proto文件情况下,protoc生成.cc/.h
首先先参考一下别人的博客,看完了,看懂了,再回过头来看我下面说的情况. 链接 https://blog.csdn.net/CAir2/article/details/78201572 但是这个也就是基 ...
- 关于Python+selenium 定位浏览器弹窗元素
首先要确定弹窗的类型: (1)div弹窗 (2)新标签页弹窗 (3)alert弹窗 一,div弹窗div弹窗是浏览器中比较好定位的弹窗,定位的方法与普通的元素一样.不过这里会有一个坑,明明可以找到这个 ...
- JavaScript函数作用域和声明提前(3.10.1 page.57)
<h4>3.函数作用域和声明提前</h4> <p> <!--<script type="text/javascript">-- ...
- 网站假死 重启NGINX无效 必须重启PHP 原因分析
一.错误提示说明: Nginx 502 Bad Gateway:请求的PHP-CGI已经执行,但是由于某种原因(一般是读取资源的问题)没有执行完毕而导致PHP-CGI进程终止. Nginx 504 G ...
- webpack之Loader
我们知道webpack的优点之一就是专注于处理模块化的项目,能做到开箱即用,但同时这也是webpack的缺点,只能用于模块化开发的项目,例如:Vue,React,Angular.Webpack在进行打 ...
- vue原生表格怎样实现动态列及表格数据下载
最近项目经常用到带有合并效果以及动态列的表格,而翻阅iview和element-ui官网没有找到合适的(也有可能自己的水平有限,不会改写),所以只好自己用原生表格写了一个,具体效果如下: 这个表格右侧 ...
- Openstack Swift 如何查找 slave node 挂载的 VD 的 IP
1. 在 /etc/swift/container-server.conf 或者 object-server.conf 中的 devices= 一行 可以找到 /srv/node. 在 /srv/no ...
- [Windows] DiskPart commands
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/diskpart
- [Windows] 如何用编程的方式格式化硬盘
If memory serves, you're looking for SHFormatDrive(). Use the Format method of the Win32_Volume clas ...