什么是 OSAL?

今天同学忽然问我有没有搞过OSAL,忽然间一头雾水,于是在搜索引擎上找到了答案,发现这是一个十分实用的东西。

OSAL(operating system abstraction layer),操作系统抽象层,是一种以实现多任务为核心的系统资源管理机制,实现了类似RTOS的某些功能,但并不能称之为真正意义上的RTOS,因为其本身还不支持任务的挂起,任务的抢占等等功能,但是这种机制,实现的代码十分精简,占用资源也非常少,对于资源十分紧张的嵌入式平台,也可以完成比较复杂的逻辑功能。

TI CC2530ZIGBEE协议栈Z-STACK中可以找到OSAL的身影,可以在官网上搜索z-stack下载相关的源码,其中就包含了OSAL机制实现的源码;移除掉一些无关功能的代码之后,剩下OSAL的源码总共约1100多行代码,全部由C语言实现,资源占用约为RAM:512Byte,ROM:2KB。理论上可以移植到绝大多数的芯片平台上。

源码安装

目前官网上最新的版本,下载安装到本地;

安装完成之后,可以到安装目录下,找到相应的源码,不过这里基本上是zigbee的协议栈,所以OSAL相关的部分在下图所示的路径中;



进入到osal路径下的文件结构如下图所示;



这个OSAL操作系统抽象层用于保护协议栈软件组件不受程序硬件细节的影响,减少程序的耦合性,提高可移植性和复用性。它可以独立于程序环境,并且提供了以下功能。

  1. 任务注册、初始化、启动;
  2. 任务间的消息交换;
  3. 任务同步;
  4. 中断处理;
  5. 计时器;
  6. 内存分配;

Linux 上OSAL的移植

可以尝试把OSAL的框架移植到单片机上,进行测试,这里是GitHubfork的一个仓库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工程目录下,然后对工程文件列表进行刷新,可以看到如下图所示;



下面是作者基于tiosal的移植说明:

  1. 完成OSAL\hal\timer.c文件,为系统提供时钟;
  2. 修改OSAL\include\type.h文件中的全局中断开关函数(可以为空),添加芯片对应的头文件,根据需要修改数据类型重定义,根据芯片字长修改halDataAlign_t类型;
  3. 根据需要修改OSAL\osal\osal_memory.h文件中的内存池大小定义,文件中osalMemHdr_t类型需要确保长度为16bit或以上,非8位单片机需要设定内存池的字节对齐;
  4. 添加任务函数中的任务优先级数值大的任务则优先级高;
  5. 根据需要修改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操作系统抽象层的移植的更多相关文章

  1. 2、CC2541芯片中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~

    本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...

  2. 4、CC2541芯片中级教程-OSAL操作系统(简单AT指令实现+IIC软件和硬件实现驱动MPU6050)

    本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...

  3. linux kernel的函数与抽象层

    在数学领域,函数是一种关系,这种关系使一个集合里的每一个元素对应到另一个(可能相同的)集合里的唯一元素. 在C语言中函数也有这种联系.自变量影响着因变量. 在linux内核驱动编程经常会有抽象层的概念 ...

  4. 5、CC2541芯片中级教程-OSAL操作系统(PWM+看门狗)

    本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...

  5. 3、CC2541芯片中级教程-OSAL操作系统(ADC光敏电阻和修改串口波特率)

    本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...

  6. PHP 数据库抽象层pdo

    PDO是PHP数据对象(PHP Data Object)的缩写. pdo就是一个"数据库访问抽象层",作用是统一各种数据库的访问接口,能够轻松地在不同数据库之间进行切换,使得数据库 ...

  7. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 2

    18.2  PDO所支持的数据库 使用PHP可以处理各种数据库系统,包括MySQL.PostgreSQL.Oracle.MsSQL等.但访问不同的数据库系统时,其所使用的PHP扩展函数也是不同的.例如 ...

  8. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 1

    现在,如果你已经能熟练地使用MySQL客户端软件来操作数据库中的数据,就可以开始学习如何使用PHP来显示和修改数据库中的数据了.PHP提供了标准的函数来操作数据库.在PHP 5以上的版本中可以使用My ...

  9. 网络编程之网络架构及其演变过程、互联网与互联网的组成、OSI七层协议、socket抽象层

    目录 网络架构及其演变过程 单机架构 CS架构 BS架构 BS架构和CS架构的区别 C/S架构的优缺点: B/S架构的优缺点: 互联网与互联网的组成 互联网的组成(教科书版) 互联网的组成(科普版) ...

随机推荐

  1. Cobalt Strike系列教程第七章:提权与横向移动

    Cobalt Strike系列教程分享如约而至,新关注的小伙伴可以先回顾一下前面的内容: Cobalt Strike系列教程第一章:简介与安装 Cobalt Strike系列教程第二章:Beacon详 ...

  2. Android | 教你如何在安卓上实现通用卡证识别,一键各种卡绑定

    目录 前言 通用卡证识别的应用场景 如何使用通用卡证识别服务 集成通用卡证识别服务的关键流程 开发实战 1 开发准备 1.1 在项目级gradle里添加华为maven仓 1.2 在应用级的build. ...

  3. 你自学半年也搞不懂的go底层,看这篇。这篇讲 go的数组、切片、Maps

    目录 数组 1.定义数组 2.使用数组 3.定义并赋值 4.数组的大小是类型的一部分 5.数组是值类型(当参数传递到函数中,修改不会改变原来的值) 6.数组长度 7.循环数组 8.多维数组 切片 1. ...

  4. [PHP] 文件创建、写入、读取

    创建$p = fopen('text.txt','a+b'); 写入第一种方式//var_export方式存储数组到文件中 //这中方式存浮点型数据,存储后会多很多数字!只适合简单的存储吧!我感觉! ...

  5. leetcode-0101 对称二叉树

    题目地址 https://leetcode-cn.com/problems/symmetric-tree/ 1.递归 本题最简单的思路是递归,可以假设两棵一模一样的树在进行镜像对比.他们之间的关系满足 ...

  6. 如何用TensorFlow实现线性回归

    环境Anaconda 废话不多说,关键看代码 import tensorflow as tf import os os.environ['TF_CPP_MIN_LOG_LEVEL']='2' tf.a ...

  7. Java 多线程 -- lambda 表达式推导

    jdk 8 开始 java 引入了lambda 表达式. lambda适用场景: 1.接口或父类 2.接口或父类只有一个方法 我们从多线程写法来推导一下: 1.外部类写法: package com.x ...

  8. SpringBoot项目集成Redis

    一.在pom文件中添加依赖 <!-- 集成redis --> <dependency> <groupId>org.springframework.boot</ ...

  9. 0day笔记(1)PE文件格式与虚拟文件内存的映射

    PE文件格式 PE 文件格式把可执行文件分成若干个数据节(section),不同的资源被存放在不同的节中. 一个典型的 PE 文件中包含的节如下: .text 存放着二进制的机器代码 .data 初始 ...

  10. [转]Git详解之四 服务器上的Git

    服务器上的 Git 到目前为止,你应该已经学会了使用 Git 来完成日常工作.然而,如果想与他人合作,还需要一个远程的 Git 仓库.尽管技术上可以从个人的仓库里推送和拉取修改内容,但我们不鼓励这样做 ...