FreeRTOS 中断管理之延迟中断处理 -- 二值信号量同步

news2024/9/23 21:28:57

3.1 概览

3.1.1 事件:嵌入式实时操作系统需要对整个系统环境产生的事件作出反应,例如:按一下按键,灯闪一下

3.1.2 ISR 中断服务函数尽量越短越好,应快速执行完,然后退出中断服务函数

3.1.3 在中断服务函数中只能使用以 FromISR 或 FROM_ISR结尾的函数或宏

3.2 延迟中断处理

3.2.1 采用二值信号量同步

二值信号量可以在某个特殊的中断发生时,让任务解除阻塞,相当于让任务与中断同步。这样就可以让中断事件处理量大的工作在同步任务中完成,中断服务例程(ISR)中只是快速处理少部份工作。如此,中断处理可以说是被”推迟(deferred)”到一个”处理(handler)”任务。
如果某个中断处理要求特别紧急,可以将其延迟处理任务的优先级可以设为最高,以保证延迟处理任务随时都抢占系统中的其它任务。这样,延迟处理任务就成为其对应的 ISR退出后第一个执行的任务,在时间上紧接着 ISR 执行,相当于所有的处理都在 ISR 中完成一样。
在这里插入图片描述

延迟处理任务对一个信号量进行带阻塞性质的”take”调用,意思是进入阻塞态以等待事件发生。当事件发生后,ISR 对同一个信号量进行”give”操作,使得延迟处理任务解除阻塞,从而事件在延迟处理任务中得到相应的处理。

3.2.2 信号量的P、V 操作:take - P 操作,give - V操作

P 源自荷兰语 Parsseren,即英语的 Pass;V 源自荷兰语 Verhoog,即英语的 Increment。P(S)/V(S)操作是信号量的两个原子操作,S 为信号量 Semaphore,相当于一个标志,可以代表一个资源,一个事件等等,初始值视应用场合而定。
P(S) / V(S)原子操作有如下行为:
P(S) : IF (S <= 0) THEN 将本线程加入 S 的等待队列
S = S – 1
V(S) : S = S + 1
IF (S > 0) THEN 唤醒某个等待线程

在这种中断同步的情形下,信号量可以看作是一个深度为 1 的队列。这个队列由于最多只能保存一个数据单元,所以其不为空则为满(所谓”二值”)。延迟处理任务调用xSemaphoreTake()时,等效于带阻塞时间地读取队列,如果队列为空的话任务则进入阻塞态。当事件发生后,ISR 简单地通过调用 xSemaphoreGiveFromISR()放置一个令牌(信号量)到队列中,使得队列成为满状态。这也使得延迟处理任务切出阻塞态,并移除令牌,使得队列再次成为空。当任务完成处理后,再次读取队列,发现队列为空,又进入阻塞态,等待下一次事件发生。
中断给出信号量,甚至是在信号量第一次被获取之前就给出;而任务在获取信号量之后再也不给回来。在其它场合下,任务获得(Take)了信号量之后,必须得给(Give)回来。

3.3 创建信号量 vSemaphoreCreateBinary(xSemaphore)

FreeRTOS 中各种信号量的句柄都存储在 xSemaphoreHandle 类型的变量中。在使用信号量之前,必须先创建它

typedef void * QueueHandle_t;

typedef QueueHandle_t SemaphoreHandle_t;

#define xSemaphoreHandle    SemaphoreHandle_t

SemaphoreHandle_t xSemaphore = NULL;

#if (1 == configSUPPORT_DYNAMIC_ALLOCATION)
#define vSemaphoreCreateBinary(xSemaphore)    \
{ \
    (xSemaphore) = xQueueGenericCreate((UBaseType_t)1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE); \
    if ((xSemaphore) != NULL) \
    { \
        (void)xSemaphoreGive((xSemaphore)); \
    } \
}
#endif

3.3.1 参数1:xSemaphore,void * 类型的,创建的信号量

需要说明的是 vSemaphoreCreateBinary()在实现上是一个宏,所以信号量变量应当直接传入,而不是传址。信号量 API 实际上是由一组宏实现的,而不是函数。
在这里插入图片描述

3.4 获取信号量,P操作, xSemaphoreTake(xSemaphore, xBlockTime)

#define xSemaphoreTake(xSemaphore, xBlockTime)    xQueueGenericReceive((QueueHandle_t)(xSemaphore), NULL, (xBlockTime), pdFALSE)

“带走(Taking)”一个信号量意为”获取(Obtain)”或”接收(Receive)”信号量。只有当信号量有效的时候才可以被获取。在经典信号量术中,xSemaphoreTake()等同于一次 P()操作。
除互斥信号量外,所有类型的信号量都可以调用函数 xSemaphoreTake() 来获取。
xSemaphoreTake()不能在中断服务函数中调用

3.5 给出信号量,V操作, xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken)

除互斥信号量外, FreeRTOS 支持的其它类型的信号量都可以通过调用 xSemaphoreGiveFromISR() 给出
xSemaphoreGiveFromISR() 是 xSemaphoreGive() 的特殊形式,专门用于中断服务例程中。

3.6 在STM32系列单片机上,软件模拟产生一个中断

static void vPeriodicTask(void *pvParameters)
{
	for(;;)
	{
		/* 此任务通过每500毫秒产生一个软件中断来”模拟”中断事件 */
		vTaskDelay( 500 / portTICK_RATE_MS );

		/* 产生中断,并在产生之前和之后输出信息,以便在执行结果中直观直出执行流程 */

		printf("Periodic task - About to generate an interrupt.\r\n");

		NVIC_SetPendingIRQ(IRQn); // creat a interrupt by stm32fxx mcu

		printf("Periodic task - Interrupt generated.\r\n\r\n\r\n");
	}
}

3.7 中断延迟服务函数,在退出中断服务函数后会立马执行该中断延迟任务,P操作

static void vHandlerTask( void *pvParameters )
{
	for( ;; )
	{
		/* P operation, 使用信号量等待一个事件。任务被无超时阻塞, 该任务运行到这里会被挂起 vHandlerTask, 后面的不会执行了, 直到等到了信号量才会再次运行。此处也没有必要检测返回值 */
		xSemaphoreTake(xBinarySemaphore, portMAX_DELAY);

		/* 程序运行到这里时,事件必然已经发生。本例的事件处理只是简单地打印输出一个信息 */
		printf("Handler task - Processing event.\r\n");
	}
}

3.8 中断服务函数,软件触发中断,然后执行中断服务函数,给出信号量,V操作,然后跳转到中断延迟服务函数

static void IRQHandler(void)
{
	static portBASE_TYPE xHigherPriorityTaskWoken;

	xHigherPriorityTaskWoken = pdFALSE;

	/* 'Give' the semaphore to unblock the task. V operation*/
	xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);

	if (pdTRUE == xHigherPriorityTaskWoken)
	{
		portYIELD();
	}
}

3.9 在主函数中创建信号量 & 任务

int main(void)
{
	vSemaphoreCreateBinary(xBinarySemaphore); // create a semaphore

	NVIC_SetPriority(IRQn, priority); // set a soft interrupt for stm32fxx mcu

	// check wether the semaphore has been created success
	if(xBinarySemaphore != NULL)
	{
		/* 创建延迟处理任务。此任务将与中断同步。延迟处理任务在创建时使用了一个较高的优先级,以保证中断退出后会被立即执行。在本例中,为延迟处理任务赋予优先级3 */
		xTaskCreate(vHandlerTask, "Handler", 1000, NULL, 3, NULL);

		/* 创建一个任务用于周期性产生软件中断。此任务的优先级低于延迟处理任务。每当延迟处理任务切出阻塞态,就会抢占周期任务*/
		xTaskCreate(vPeriodicTask, "Periodic", 1000, NULL, 1, NULL);

		vTaskStartScheduler();
	}

	for(;;)
	{
	}
}

3.10 任务执行流程,任务切换过程

![[Pasted image 20230626190044.png]]

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web3在HTML中获取 MetaMask 启用的用户列表

当然 我们还是要先启动ganache环境 然后 通过MetaMask 导入一些用户 然后 我们需要在页面中引入 web3.min.js 如果您还没有这个文件 可以查看我的文章web3.js获取导入 然后我访问官网 https://learnblockchain.cn/docs/web3.js/web3-eth.html#getchainid 打开后 先来到 web3.…

OAuth2.0四种授权模式及实战

OAuth2.0四种授权模式以及Oauth2.0实战 首先我们得了解什么是Oauth2.0&#xff0c;简单来说Oauth2.0它是一个授权协议。我们可能会听说过&#xff0c;使用Oauth2.0来实现单点登录SSO&#xff0c;以及第三方登录。那个什么是授权&#xff1f; 举个通俗易懂的例子&#xff0c;就…

概率论与数理统计教程第六章节笔记

参考书籍&#xff1a;概率论与数理统计教程第三版 茆诗松 程依明 濮晓龙 编著 文章声明&#xff1a;如有错误还望批评指正 文章目录 ξ \xi ξ 6.1点估计的概念与无偏性 ξ 6.2 \xi6.2 ξ6.2矩估计及相和性 ξ 6.3 \xi6.3 ξ6.3最大似然估计与EM算法 ξ 6.6 \xi6.6 ξ6.6区间估…

Pandas 解决保存excel文件发生异常问题

代码&#xff1a; #保存excel my.to_excel(df.xlsx,#设置Excel1的工作表名sheet_name表1) 异常&#xff1a; 原因&#xff1a;没有导入这个库openpyxl 解决&#xff1a; 1) 使用 pip list 查看 2) 如果没有&#xff0c;则安装 pip install openpyxl 3) 再导入 import openpyx…

uniapp中引入uview教程

uview官网&#xff0c;本次教程中用不到&#xff0c;若需要查看官网教程&#xff0c;可点击前往 1、在插件市场中搜索uview&#xff0c;并导入项目&#xff0c;点击前往 2、如果没有安装scss&#xff0c;需要安装scss依赖&#xff0c;如已安装&#xff0c;请跳过 // 安装sass…

【刷题笔记】反转链表——头插法/栈实现

【刷题笔记】反转链表——头插法/栈实现 解法一&#xff1a;头插法 思路及代码&#xff1a; * 1、创建一个newheadnull&#xff0c;即最终反转后的链表的头结点* 2、循环遍历当前的链表的head&#xff0c;创建temp记录当前head的next&#xff0c;然后将head的next指向新的头ne…

Acer宏碁Swift笔记本电脑SF314-54原装Win10系统工厂模式恢复原厂OEM出厂系统镜像

Acer宏基&#xff0c;Acer宏碁Swift笔记本电脑&#xff0c;Swift SF314-54原装Windows10系统工厂模式恢复原厂OEM出厂状态镜像 系统自带所有驱动、Office办公软件、出厂主题壁纸LOGO、 Acer Care Center、Quick Access等预装程序 所需要工具&#xff1a;32G或以上的U盘&#…

springboot+vue高校科研队伍管理系统_2byeq-

1.登录和注册&#xff1a;创建用户密码后用户输入正确用户密码即可登录&#xff0c;超级管理员可查看平台内所有账号信息。 2.个人信息管理&#xff1a;支持修改个人信息以及保存。 3.科研队伍管理&#xff1a;支持创建科研队伍&#xff0c;个人可以创建队伍后自己成为组长&…

uniapp倒计时

uniapp实现根据传递的时间展示倒计时 需求说明&#xff1a;听书倒计时&#xff0c;设置完时间展示倒计时 countDownTime(showTime){ //showTime为传递的时间 默认在转化成分钟var that this;that.times showTime * 60that.timer setInterval(function() {that.times--;if(th…

教程 | Datavines 自定义数据质量检查规则(Metric)

Metric 是 Datavines 中一个核心概念&#xff0c;一个 Metric 表示一个数据质量检查规则&#xff0c;比如空值检查和表行数检查都是一个规则。Metric 采用插件化设计&#xff0c;用户可以根据自己的需求来实现一个 Metric。下面我们来详细讲解一下如何自定义Metric。 第一步 …

WPF 零基础入门笔记(3):数据绑定详解(更新中)

文章目录 文章合集数据绑定数据绑定实战事件通知型数据驱动&#xff0c;双向绑定资源绑定数据源绑定全局数据源后端和前端绑定问题 文章合集 WPF基础知识博客专栏 WPF微软文档 WPF控件文档 B站对应WPF数据绑定视频教程 数据绑定 我们在之前的文章中&#xff0c;详细解释了数…

windows配置jmeter定时任务

场景&#xff1a; 需要让脚本在指定的执行 步骤&#xff1a; 准备jmeter脚本&#xff0c;保证在命令行中可以调用脚本且脚本运行正常&#xff1a;"C:\Apache\jmeter\bin\jmeter.bat" -n -t C:\tests\test_plan.jmx -l C:\tests\results.jtl -t : 指定执行jmeter脚…

chatgpt赋能python:Python计算CCI指标的介绍

Python计算CCI指标的介绍 CCI&#xff08;Commodity Channel Index&#xff09;是一种技术指标&#xff0c;是推断价格高低位和趋势变化的一种工具。通过计算股票、期货、外汇和其他市场的典型价格、最高价和最低价以及CCI的值&#xff0c;可以预测未来价格趋势并进行交易。 …

Solidity第二次作业

目录 第一题 第二题 第三题 第四题 第五题 第六题 第一题 // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; contract math { //1.根据所属类型值域&#xff0c;修改变量numa与numb值 uint8 numa 256; int8 numb 128; int numc 255; fun…

安科瑞无线测温系统在高压开关柜中的应用

摘要&#xff1a;高压开关柜是配电系统中重要的组成部分&#xff0c;其主要作用是控制电荷、分配电能和开断电流等&#xff0c;对维持系统的稳定性有一定的保障作用。将无线测温技术应用于高压开关柜&#xff0c;可以实现对其进行实时的动态监测&#xff0c;有助于相关工作人员…

使用CSS的polygon属性画各个方向的半圆环

CSS的polygon属性 CSS polygon()函数是一个图形函数&#xff0c;用于指定某种基本图形类型。polygon()函数用于定义一个多边形 .container{width: 50px;height: 50px;border: 13px solid #0c73fe;border-radius: 50px;/* 上半圆环 */clip-path: polygon(100% 50%, 0 50%, 0 0, …

Redis cluster集群搭建集群增删集群节点

1.Redis cluster集群架构&#xff08;本机ip:192.168.2.100&#xff09; 建立三台linux服务器&#xff0c;分别是192.168.2.61、192.168.2.62、192.168.2.63 1.1.建立192.168.2.61Linux服务器 1.配置Linux服务器 # 在 /etc/sysconfig/network-scripts/ifcfg-eno16777736文件…

C# 读写ABPLC( Allen Bradley)

1.安装 libplctag.net库 GitHub - libplctag/libplctag.NET: This is a .NET wrapper for libplctag. 2.PLC IP和tag 3.写入值 var myTag new TagReal(){//Name is the full path to tag. Name "HMI_F26[0]",//Gateway is the IP Address of the PLC or communicat…

7-WebApis-3

Web APIs - 3 目标&#xff1a;学习事件流&#xff0c;事件委托&#xff0c;其他事件等知识&#xff0c;优化多个事件绑定和实现常见网页交互 事件流移除事件监听其他事件元素尺寸与位置综合案例 事件流 为什么要学习事件流&#xff1f; 可以帮我们解决一些疑惑&#xff0c;比…

npm全局安装的包在cmd能找到,在powershell中找不到

背景 使用npm i g 全局安装的包&#xff0c;比如&#xff1a;eslint&#xff1b;安装完成后&#xff0c;执行eslint相关命令&#xff0c;显示命令不存在&#xff1b;以为是node没配置全局环境变量&#xff0c;检查发现配置了&#xff1b;后来试了一下在cmd是可以使用的&#x…