基于OSAL的嵌入式裸机事件驱动框架——整体架构调度机制


参考B站up主【架构分析】嵌入式祼机事件驱动框架
感谢大佬分享


  1. 任务ID : TASK_XXX
    TASK_XXX 在系统中每个任务的ID是唯一的,范围是 0 to 0xFFFE,0xFFFF保留为SYS_TSK_INIT。
    同时任务ID的大小也充当任务调度的优先级,ID越大,优先级越高,越排在任务链表的最前面

  2. 事件ID :EVE_XXX
    EVE_XXX和任务绑定,对于一个任务来说,一个任务的事件集有16位,最高位1<<15 保留为系统消息事件SYS_EVE_MSG,剩下的1<<0 到 1<<14由用户定义
    对于不同的任务,EVE_XXX可以相同,但是对于某一个任务,EVE_XXX应是唯一的

  3. 消息事件ID : EVE_MSG_XXX
    EVE_MSG_XXX被消息的bdy所携带,当将消息发送给任务时,会触发任务的系统消息事件SYS_EVE_MSG,然后在任务的事件处理函数handler中,取出消息事件EVE_MSG_XXX和数据data,根据EVE_MSG_XXX做不同的处理。
    EVE_MSG_XXX与EVE_XXX是不同的,EVE_MSG_XXX是消息事件中的消息所携带的事件,EVE_XXX是某个任务事件集中的某个事件。
    EVE_MSG_XXX的范围是 0 到 0xFFFF,尽可能使用不同的EVE_MSG_XXX

![[Pasted image 20250123183033.png]]
(注:此架构图来自B站up主的视频【架构分析】嵌入式祼机事件驱动框架)

创建任务,初始化(包括硬件方面,软件逻辑方面等)
也可以在初始化中创建软件定时器,软件定时器超时后会把对应任务的事件置位,即触发事件。

系统调度后在osal_system_start中会循环检查有没有触发事件的任务,有则通过task_handler处理

消息通过osal_send_msg发送消息到消息队列,因为消息其实是和任务task_id绑定起来的,消息发送到消息队列后会把对应的任务中的 SYS_MSG_EVE置位,即触发消息事件。然后在task_handler中通过osal_recv_msg读取 消息,把消息提取出来,然后释放消息内存

也可以直接通过调用osal_task_seteve触发指定任务的事件

核心就是任务task,应用层中 通过 task_id和event_id实现事件驱动的调度

中断中如何往OSAL中去集成

  1. 通过直接触发相应的事件osal_task_seteve
  2. 通过消息队列
    如果数据比较少,可以直接通过消息队列发送。
    或者使用数据缓冲层,在任务处理task_handler中取数据

在app.h中声明所有的任务id,事件id,以及处理接口ops

调度函数

osal_system_start
在主程序中调用osal_system_start

  1. 寻找触发事件的任务
  2. 执行任务事件处理函数
  3. 将执行完的事件在事件集中剔除掉

通过osal_task_active获取有效任务,即有事件触发的任务,将其事件集提取出来赋值给events变量。
将task_active->events给清理掉,最开始是一个多线程的考虑,在逻辑轮询中
调用任务的事件处理函数task_active->ops->handler,这个函数由用户提供,参数是任务id和事件集,在此函数中需要剔除掉对应的事件,然后将剔除事件 过后 的事件集 返回,然后将返回值 或上任务的事件集
![[Pasted image 20250125200955.png]]
(注:此架构图来自B站up主的视频【架构分析】嵌入式祼机事件驱动框架)

/*********************************************************************  
 * @fn      osal_system_start * * @brief * *   This function is the main loop function of the task system.  It *   will look through all task events and call the task_event_processor() *   function for the task with the event.  If there are no events (for *   all tasks), this function puts the processor into Sleep. *   This Function doesn't return. * * @param   void * * @return  none *//*可以考虑不加临界区,直接用原子操作,减少开销*/  
void osal_system_start(void)  
{  
    event_asb_t events,ret_events;  
    osal_task_t *task_active;  
  
    while(1)  
    {  
        task_active = osal_task_active();  
        if ( task_active != NULL )  
        {  
            OSAL_ENTER_CRITICAL();  
            events = task_active->events;  
            task_active->events = SYS_EVE_NONE;  
            OSAL_EXIT_CRITICAL();  
  
            if(events != SYS_EVE_NONE)  
            {  
                if(task_active->ops->handler != NULL)  
                {  
  
                    ret_events = task_active->ops->handler(task_active->task_id,events);  
                    OSAL_ENTER_CRITICAL();  
                    task_active->events |= ret_events;  
                    OSAL_EXIT_CRITICAL();  
                }  
            }  
        }  
    }  
}

osal.h

#ifndef OSAL_H  
#define OSAL_H  
  
//#include "heap.h"  
#include "stm32h7xx_hal.h"  
  
  
#define OSAL_ERROR                0  
#define OSAL_SUCCESS              1  
#define INVALID_TASK              2  
#define INVALID_MSG_POINTER       3  
#define INVALID_EVENT_ID          4  
#define INVALID_TIMER             5  
  
  
//芯片硬件字长  
typedef unsigned int        halDataAlign_t;  
  
// Unsigned numbers  
typedef unsigned char       osal_bool_t;  
typedef unsigned char       osal_byte_t;  
typedef unsigned char       osal_uint8_t;  
typedef unsigned short      osal_uint16_t;  
typedef unsigned int        osal_uint32_t;  
  
// Signed numbers  
typedef signed char         osal_int8_t;  
typedef signed short        osal_int16_t;  
typedef signed int          osal_int32_t;  
  
#define osal_container_of(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))  
  
/**进入临界区和退出临界区**/  
//#define CLI()         __set_PRIMASK(1)              // Disable Interrupts  
//#define SEI()         __set_PRIMASK(0)              // Enable Interrupts  
#define CLI()           __disable_irq()               // Disable Interrupts  
#define SEI()           __enable_irq()                // Enable Interrupts  
  
#define OSAL_ENABLE_INTERRUPTS()         SEI()       // Enable Interrupts  
#define OSAL_DISABLE_INTERRUPTS()        CLI()       // Disable Interrupts  
#define OSAL_ENTER_CRITICAL()            CLI()  
#define OSAL_EXIT_CRITICAL()             SEI()  
  
/**内存管理**/  
//#define osal_mem_alloc                  pvHeapMalloc  
//#define osal_mem_free                   vHeapFree  
  
#define osal_delay(ms)                  HAL_Delay(ms)  
  
  
osal_uint8_t osal_init_system(void);  
void osal_system_start(void);  
  
  
int osal_strlen( char *pString );  
void *osal_memcpy( void *dst, const void *src, unsigned int len );  
void *osal_revmemcpy( void *dst, const void *src, unsigned int len );  
void *osal_memdup( const void *src, unsigned int len );  
osal_uint8_t osal_memcmp( const void *src1, const void *src2, unsigned int len );  
void *osal_memset( void *dest, osal_uint8_t value, int len );  
  
#endif

osal.c

/*********************************************************************  
 * @fn      osal_init_system * * @brief * *   This function initializes the "task" system by creating the *   tasks defined in the task table (OSAL_Tasks.h). * * @param   void * * @return  ZSUCCESS */osal_uint8_t osal_init_system( void )  
{  
  // Initialize the Memory Allocation System  
#if OSALMEM_METRICS  
  osal_mem_init();  
#endif  
  
  return ( OSAL_SUCCESS );  
}  
  
/*********************************************************************  
 * @fn      osal_system_start * * @brief * *   This function is the main loop function of the task system.  It *   will look through all task events and call the task_event_processor() *   function for the task with the event.  If there are no events (for *   all tasks), this function puts the processor into Sleep. *   This Function doesn't return. * * @param   void * * @return  none *//*可以考虑不加临界区,直接用原子操作,减少开销*/  
void osal_system_start(void)  
{  
    event_asb_t events,ret_events;  
    osal_task_t *task_active;  
  
    while(1)  
    {  
        task_active = osal_task_active();  
        if ( task_active != NULL )  
        {  
            OSAL_ENTER_CRITICAL();  
            events = task_active->events;  
            task_active->events = SYS_EVE_NONE;  
            OSAL_EXIT_CRITICAL();  
  
            if(events != SYS_EVE_NONE)  
            {  
                if(task_active->ops->handler != NULL)  
                {  
  
                    ret_events = task_active->ops->handler(task_active->task_id,events);  
                    OSAL_ENTER_CRITICAL();  
                    task_active->events |= ret_events;  
                    OSAL_EXIT_CRITICAL();  
                }  
            }  
        }  
    }  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959940.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

理解C++中的右值引用

右值引用&#xff0c;顾名思义&#xff0c;就是对一个右值进行引用&#xff0c;或者说给右值一个别名。右值引用的规则和左值一用一模一样&#xff0c;都是对一个值或者对象起个别名。 1. 右值引用和左值引用一样&#xff0c;在定义的同时必须立即赋值&#xff0c;如果不立即赋…

寒假1.23

题解 web&#xff1a;[极客大挑战 2019]Secret File&#xff08;文件包含漏洞&#xff09; 打开链接是一个普通的文字界面 查看一下源代码 发现一个链接&#xff0c;点进去看看 再点一次看看&#xff0c;没什么用 仔细看&#xff0c;有一个问题&#xff0c;当点击./action.ph…

分布式版本控制系统:Git

1 Git概述 Git官网&#xff1a;https://git-scm.com/ Git是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目Git易于学习&#xff0c;占地面积小&#xff0c;性能极快。它具有廉价的本地库、方便的暂存区域和多个工作流分支等特性…

< OS 有关 > 阿里云:轻量应用服务器 的使用 :轻量化 阿里云 vpm 主机

原因&#xff1a; &#xff1c; OS 有关 &#xff1e; 阿里云&#xff1a;轻量应用服务器 的使用 &#xff1a;从新开始 配置 SSH 主机名 DNS Tailscale 更新OS安装包 最主要是 清除阿里云客户端这个性能杀手-CSDN博客 防止 I/O 祸害系统 操作&#xff1a; 查看进程&#x…

工业相机 SDK 二次开发-Sherlock插件

本文介绍了 sherlock 连接相机时的插件使用。通过本套插件可连接海康的工业相机。 一&#xff0e;环境配置 1. 拷贝动态库 在用户安装 MVS 目录下按照如下路径 Development\ThirdPartyPlatformAdapter 找到目 录为 DalsaSherlock 的文件夹&#xff0c;根据 Sherlock 版本找到…

为什么机器学习中梯度下降是减去斜率,而不是按照其数学意义减去斜率的倒数

做个简单假设&#xff0c;Loss函数的某一个参数的函数曲线是二次方程&#xff0c;其导数函数为 r 2 ∗ w r 2*w r2∗w 按照斜率意义来看&#xff0c;要减去斜率倒数 降低LOSS需要将w1更新为w2&#xff0c;所以更新公式为 w w − Δ L Δ w w w - \frac{\Delta L}{\Delta w…

Linux高级--3.3.2 自定义协议设计--ProtoBuf

一、自定义协议设计的必要性 自定义通信协议通常有以下几个原因&#xff0c;尤其在IM即时通信、节点服务器、HTTP协议、Nginx、Redis协议、SOME/IP协议和DoIP协议等场景中&#xff0c;设计和使用自定义协议能带来特定的优势&#xff1a; 1. 性能优化 更高效的资源利用&#…

技术总结:FPGA基于GTX+RIFFA架构实现多功能SDI视频转PCIE采集卡设计方案

目录 1、前言工程概述免责声明 3、详细设计方案设计框图SDI 输入设备Gv8601a 均衡器GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGBFDMA图像缓存RIFFA用户数据控制RIFFA架构详解Xilinx 7 Series Integrated Block for PCI ExpressRIFFA驱动及其安装QT上位机HDMI输出RGB转BT…

docker 部署 java 项目详解

在平常的开发工作中&#xff0c;我们经常需要部署项目&#xff0c;开发测试完成后&#xff0c;最关键的一步就是部署。今天我们以若依项目为例&#xff0c;总结下部署项目的整体流程。简单来说&#xff0c;第一步&#xff1a;安装项目所需的中间件&#xff1b;第二步&#xff1…

动手学图神经网络(2):跆拳道俱乐部案例实战

动手学图神经网络&#xff08;2&#xff09;&#xff1a;跆拳道俱乐部案例实战 在深度学习领域&#xff0c;图神经网络&#xff08;GNNs&#xff09;能将传统深度学习概念推广到不规则的图结构数据&#xff0c;使神经网络能够处理对象及其关系。将基于 PyTorch Geometric 库&a…

Elastic Agent 对 Kafka 的新输出:数据收集和流式传输的无限可能性

作者&#xff1a;来 Elastic Valerio Arvizzigno, Geetha Anne 及 Jeremy Hogan 介绍 Elastic Agent 的新功能&#xff1a;原生输出到 Kafka。借助这一最新功能&#xff0c;Elastic 用户现在可以轻松地将数据路由到 Kafka 集群&#xff0c;从而实现数据流和处理中无与伦比的可扩…

1.25学习

web bugku-源代码 打开环境后看到了一个提交的界面&#xff0c;我们根据题目查看源代码&#xff0c;看到了js代码&#xff0c;其中有几处是url编码&#xff0c;我们对其进行解码&#xff0c;后面的unescape&#xff08;&#xff09;函数就是将p1解码以及%35%34%61%61%32p2解码…

Hive详细讲解-基础语法快速入门

文章目录 1.DDL数据库相关操作1.1创建数据库1.2指定路径下创建数据库1.3添加额外信息创建with dbproperties1.4查看数据库 结合like模糊查询 2.查看某一个数据库的相关信息2.1.如何查看数据库信息&#xff0c;extended可选2.2修改数据库 3.Hive基本数据类型4.复杂数据类型5.类型…

深度解析:基于Vue 3与Element Plus的学校管理系统技术实现

一、项目架构分析 1.1 技术栈全景 核心框架&#xff1a;Vue 3 TypeScript UI组件库&#xff1a;Element Plus&#xff08;含图标动态注册&#xff09; 状态管理&#xff1a;Pinia&#xff08;用户状态持久化&#xff09; 路由方案&#xff1a;Vue Router&#xff08;动态路…

基于Django的个人博客系统的设计与实现

【Django】基于Django的个人博客系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 系统采用Python作为主要开发语言&#xff0c;结合Django框架构建后端逻辑&#xff0c;并运用J…

【架构面试】一、架构设计认知

涉及分布式锁、中间件、数据库、分布式缓存、系统高可用等多个技术领域&#xff0c;旨在考查候选人的技术深度、架构设计能力与解决实际问题的能力。 1. 以 Redis 是否可以作为分布式锁为例&#xff1a; 用 Redis 实现分布式锁会存在哪些问题&#xff1f; 死锁&#xff1a;如果…

DrawDB:超好用的,免费数据库设计工具

DrawDB&#xff1a;超好用的&#xff0c;免费数据库设计工具 引言 在软件开发过程中&#xff0c;数据库设计是一个至关重要的环节。 无论是关系型数据库还是非关系型数据库&#xff0c;良好的数据库设计都能显著提升系统的性能和可维护性。 然而&#xff0c;数据库设计往往…

如何将xps文件转换为txt文件?xps转为pdf,pdf转为txt,提取pdf表格并转为txt

文章目录 xps转txt方法一方法二 pdf转txt整页转txt提取pdf表格&#xff0c;并转为txt 总结另外参考XPS文件转换为TXT文件XPS文件转换为PDF文件PDF文件转换为TXT文件提取PDF表格并转为TXT示例代码&#xff08;部分&#xff09; 本文测试代码已上传&#xff0c;路径如下&#xff…

【Linux】线程、线程控制、地址空间布局

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 1、Linux线程1.1 线程的优缺点1.2 线程异常和用途1.3 线程等待1.3 线程终止1.4 线程分离1.5 线程ID和地址空间布局1.6 线程栈 1、…

c语言操作符(详细讲解)

目录 前言 一、算术操作符 一元操作符&#xff1a; 二元操作符&#xff1a; 二、赋值操作符 代码例子&#xff1a; 三、比较操作符 相等与不相等比较操作符&#xff1a; 大于和小于比较操作符&#xff1a; 大于等于和小于等于比较操作符&#xff1a; 四、逻辑操作符 逻辑与&…