Freertos:

裸机编程通过中断实现不同任务的切换,实际上RTOS中通过不断更换CPU的使用权达到多任务运行的目的。FreeRTOS 中任务存在四种任务状态,分别为运行态、就绪态、阻塞态和挂起态。任务一般通过函数 vTaskSuspend()和函数 vTaskResums()进入和退出挂起态,处于挂起态的任务无法被运行;一般通过函数 vTaskDelay(),进行一段时间的延时,那么在延时超时之前,这个任务就处理阻塞态。任务也可以处于阻塞态以等待队列、信号量、事件组、通知或信号量等外部事件,但阻塞状态一定有延时时间。

FreeRTOS 的任务优先级高低与其对应的优先级数值,是成正比的,也就是说任务优先级数

值为 0 的任务优先级是最低的任务优先级,FreeRTOS 的任务优先级高低与其对应数值的逻辑关系正好与STM32 的中断优先级高低与其对应数值的逻辑关系相反。

FreeRTOS 的官方强烈建议 STM32 在使用 FreeRTOS 的时候,使用中断优先级分组 4(NVIC_PriorityGroup_4)即0-15级抢占优先级,0级子优先级。HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

 FreeRTOS 进出临界区:临界区是指那些必须完整运行的区域,在临界区中的代码必须完整运行,不能被打断。FreeRTOS 在进出临界区的时候,通过关闭和打开受 FreeRTOS 管理的中断但只是管理RTOS管理的优先级5之后的中断,以保护临界区中的代码。taskENTER_CRITICAL() 、 taskENTER_CRITICAL_FROM_ISR() 、 taskEXIT_CRITICAL() 、taskEXIT_CRITICAL_FROM_ISR(x),这四个宏定义分别用于在中断和非中断中进出临界区。在初始化任务时候使用。

FreeRTOS 任务调度方式为抢占式调度和时间片调度相结合。抢占式调度主要时针对优先级不同的任务,每个任务都有一个优先级,优先级高的任务可

以抢占优先级低的任务,只有当优先级高的任务发生阻塞或者被挂起,低优先级的任务才可以运行。时间片调度主要针对优先级相同的任务,当多个任务的优先级相同时,任务调度器会在每一次系统时钟节拍到的时候切换任务,也就是说 CPU 轮流运行优先级相同的任务,每个任务运行的时间就是一个系统时钟节拍。

静态创建任务需要自己设定栈等参数,一般都直接选着动态创建。

列表是 FreeRTOS 中最基本的一种数据结构,其在物理存储单元上是非连续、非顺序的。FreeRTOS 中的列表是一个双向链表,在list.h 文件中。列表项是列表中用于存放数据的地方,也在 list.h 文件中。

列表的意义:

跟踪任务: 列表被用来跟踪FreeRTOS中的任务。通过使用列表,FreeRTOS能够有效地管理任务的执行和调度。

数据结构: 列表是FreeRTOS中的一个数据结构,与链表类似。它提供了一种组织和管理任务的方式,使得任务的添加、删除和调度变得高效。

双向环形链表: FreeRTOS中的列表是一个双向环形链表,意味着列表的头和尾可以相互连接,形成一个闭环。这种设计有助于简化某些操作的实现,如任务的插入和删除。

列表项的意义:

任务信息存储: 列表项是存放在列表中的项目,它们包含了任务的相关信息。这些信息可能包括任务的优先级、状态、挂起条件等,对于FreeRTOS的任务管理和调度至关重要。

节点概念: 在数据结构中,列表项相当于链表中的节点。每个节点都包含有关任务的信息,并且可以通过指针与其他节点(任务)相互连接。

灵活性: 列表项的使用提供了灵活性,允许用户根据需要自定义任务的信息和属性。通过修改列表项的内容,用户可以实现对任务的精细控制和定制化操作。

函数 vTaskStartScheduler()用于启动任务调度器,任务调度器启动后,FreeRTOS 便会开始

进行任务调度,除非调用函数 xTaskEndScheduler()停止任务调度器,否则不会再返回。

调用函数 vTaskGetRunTimeStats()获取并通过串口打印系统任务运行时间信息,以此来合理进行每个任务资源的分配。

FreeRTOS 的系统时钟节拍计数器为全局变量 xTickCount,那么 FreeRTOS 又是何时操作这

个系统时钟节拍计数器的呢?本教程的配套例程而言,是在 SysTick 的中断服务函数中,一般也推荐使用 SysTick 作为 RTOS 的时钟节拍。

vTaskDelay() 任务延时函数,延时单位:系统时钟节拍。函数 vTaskDelay()传入的参数 xTicksToDelay 是任务被延时的具体延时时间,时间的单位为系统时钟节拍,这里要特别注意,很多 FreeRTOS 的初学者可能会一会此函数延时的时间单位为微妙、毫秒、秒等物理时间单位,当时 FreeRTOS 是以系统时钟节拍作为计量的时间单位 的 , 而 系 统 时 钟 节 拍 对 应 的 物 理 时 间 长 短 于 FreeRTOSConfig.h 文 件 中 的 配 置 项。

配置项 configTICK_RATE_HZ 是用于配置系统时钟节拍的频率的,本教程的所有配套例程,将此配置项配置成了 1000,即系统时钟节拍的频率为 1000,换算过来,一个系统时钟节拍就是 1 毫秒。

队列是一种任务到任务、任务到中断、中断到任务数据交流的一种机制。在队列中可以存

储数量有限、大小固定的多个数据,队列中的每一个数据叫做队列项目,队列能够存储队列项目的最大数量称为队列的长度,在创建队列的时候,就需要指定所创建队列的长度及队列项目的大小。因为队列是用来在任务与任务或任务于中断之间传递消息的一种机制,因此队列也叫做消息队列。队列通常采用 FIFO(先进先出)的存储缓冲机制,当有新的数据被写入队列中时,永远都是写入到队列的尾部,而从队列中读取数据时,永远都是读取队列的头部数据

队列不属于某个特定的任务,可以在任何的任务或中断中往队列中写入消息,或者从队列

中读取消息。

队列的结构体为 Queue_t,在 queue.c 文件中有定义

在使用队列进行任务之间的“沟通交流”时,一个队列只允许任务间传递的消息为同一种

数据类型,如果需要在任务间传递不同数据类型的消息时,那么就可以使用队列集。FreeRTOS

提供的队列集功能可以对多个队列进行“监听”,只要被监听的队列中有一个队列有有效的消息,那么队列集的读取任务都可以读取到消息,如果读取任务因读取队列集而被阻塞,那么队列集将解除读取任务的阻塞。

创建队列、队列集和其他任务,并添加队列到队列集中.

 /* 创建队列集 */

 xQueueSet = xQueueCreateSet(QUEUESET_LENGTH);

 /* 创建队列 */

 xQueue1 = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);

 xQueue2 = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);

 /* 创建二值信号量 */

 xSemaphore = xSemaphoreCreateBinary();

 /* 将队列和二值信号量添加到队列集 */

 xQueueAddToSet(xQueue1, xQueueSet);

 xQueueAddToSet(xQueue2, xQueueSet);

 xQueueAddToSet(xSemaphore, xQueueSet);

xQueueSend(xQueue1, &key, portMAX_DELAY);/* 队列 1 发送消息 */

xSemaphoreGive(xSemaphore);/* 释放二值信号量 */

activate_member = xQueueSelectFromSet(xQueueSet, portMAX_DELAY);

xQueueReceive(activate_member, &queue_recv, portMAX_DELAY);

 printf("接收到来自 xQueue1 的消息: %d\r\n", queue_recv);

xSemaphoreTake(activate_member, portMAX_DELAY);

 printf("获取到二值信号量: xSemaphore\r\n");

基于队列和队列集实现了不同任务之间的信息交流。

信号量可以用在多任务访问同一资源时的资源管理FreeRTOS 提供了多种信号量,按信号量的功能可分为二值信号量、计数型信号量、互斥信号量和递归互斥信号量。

解决同步问题的机制,可以实现对共享资源的有序访问。其中,“同步”指的是任务间的同步,即信号量可以使得一个任务等待另一个任务完成某件事情后,才继续执行;而“有序访问”指的是对被多任务或中断访问的共享资源(如全局变量)的管理,当一个任务在访问(读取或写入)一个共享资源时,信号量可以防止其他任务或中断在这期间访问(读取或写入)这个共享资源。

前面说过,信号量是基于队列实现的,二值信号量也不例外,二值信号量实际上就是一个

队列长度为 1 的队列,在这种情况下,队列就只有空和满两种情况,这不就是二值情况吗?二值信号量通常用于互斥访问或任务同步。

计数型信号量与二值信号量类似,二值信号量相当于队列长度为 1 的队列,因此二值信号

量只能容纳一个资源,这也是为什么命名为二值信号量,而计数型信号量相当于队列长度大于0 的队列,因此计数型信号量能够容纳多个资源,这是在计数型信号量被创建的时候确定的。

/* 创建计数型信号量 */

 CountSemaphore =

 xSemaphoreCreateCounting( (UBaseType_t)255, /* 计数型信号量最大值 */

 (UBaseType_t)0); /* 计数型信号量初始值 */

/* 释放计数型信号量 */

 xSemaphoreGive(CountSemaphore);

 /* 获取计数型信号量资源数 */

 semaphore_val = uxSemaphoreGetCount(CountSemaphore);

互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中(任务与任务或

中断与任务之间的同步)二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中。在互斥访问中互斥信号量相当于一把钥匙,当任务想要访问共享资源的时候就必须先获得这把钥匙,当访问完共享资源以后就必须归还这把钥匙,这样其他的任务就可以拿着这把钥匙去访问资源。

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

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

相关文章

为什么流不关闭会导致内存泄漏

引言 经常有人告诉你流用完要记得关,不然会导致内存泄漏,但你是否考虑过下面这些问题: 为什么流不关会导致内存泄漏?JVM不是有垃圾回收机制吗?这些引用我用完不就变垃圾了为什么不会被回收呢?流未关闭除了导致内存泄…

分布式(5)

目录 22.什么是Paxos算法?如何实现? 24.全局唯一ID有哪些实现方案? 25.数据库方式实现方案?有什么缺陷? 22.什么是Paxos算法?如何实现? Paxos算法是Lamport宗师提出的一种基于消息传递的分布…

【2024系统架构设计】 系统架构设计师第二版-通信系统架构设计理论与实践

目录 一 通信系统网络架构 二 网络构建的关键技术 三 网络构建和设计方法 四 案例分析 注:本节内容可作为知识储备,做一个基本的了解即可。

sonarqube配置本地扫描代码

一、本地maven设置setting文件&#xff1a; 1&#xff09;添加pluginGroup <pluginGroups><pluginGroup>org.sonarsource.scanner.maven</pluginGroup></pluginGroups> 2&#xff09;添加profile&#xff1a; <profile><id>sonar</i…

抓包神技--DPDK

DPDK&#xff0c;全称Data Plane Development Kit&#xff0c;是一个高性能的数据包处理工具集。估计有不少朋友使用过或者之前了解过&#xff0c;它通过绕过Linux内核协议栈&#xff0c;直接在用户空间进行数据包处理&#xff0c;大大提高了数据包处理的效率和吞吐量。 DPDK主…

Google Breakpad使用方法

源码下载地址&#xff1a;https://chromium.googlesource.com/breakpad/breakpad 依赖头文件下载地址&#xff1a; https://chromium.googlesource.com/linux-syscall-support Breakpad由三个主要组件&#xff1a; client 是一个库, 以library的形式内置在应用中&#xff0c…

可碧教你C++——位图

本章节是哈希的延申 可碧教你C——哈希http://t.csdnimg.cn/3R8TU 一文详解C——哈希 位图 位图是基于哈希表的原理产生的一种新的container——bitset 基于哈希映射的原理&#xff0c;我们在查找的时候&#xff0c;可以直接去定址到元素的具体位置&#xff0c;然后直接访问该…

池化层解析:简单易懂理解 PyTorch 中的核心组件

目录 torch.nn详解 nn.MaxPool1d nn.MaxPool2d nn.MaxPool3d nn.MaxUnpool1d nn.MaxUnpool2d nn.MaxUnpool3d nn.AvgPool1d nn.AvgPool2d nn.AvgPool3d nn.FractionalMaxPool2d nn.FractionalMaxPool3d nn.LPPool1d nn.LPPool2d nn.AdaptiveMaxPool1d nn.Adapt…

Springboot+RocketMQ通过事务消息优雅的实现订单支付功能

目录 1. 事务消息 1.1 RocketMQ事务消息的原理 1.2 RocketMQ订单支付功能设计 1. 事务消息 RocketMQ的事务消息&#xff0c;是指发送消息事件和其他事件需要同时成功或同时失败。比如银行转账&#xff0c; A银行的某账户要转一万元到B银行的某账户。A银行发送“B银行账户增加…

VirtualBox安装OpenEuler

VirtualBox安装OpenEuler 下载地址 virtualbox下载地址&#xff1a;https://www.virtualbox.org/wiki/Downloads openEuler下载地址&#xff1a;https://www.openeuler.org/zh/download/?versionopenEuler%2022.03%20LTS%20SP3安装virtualbox virtualbox安装penEuler点击新建 …

1-04C语言执行过程

一、概述 本小节主要讲解一个C程序从源代码到最终执行的过程&#xff0c;这个过程又可以细分为两部分&#xff1a; 源代码到可执行文件的过程可执行文件在内存中执行 本小节是C语言基础当中&#xff0c;比较容易被初学者忽视的知识点。而实际上&#xff1a; 熟悉C程序从源文…

高光谱分类论文解读分享之基于生成对抗性少数过采样的高光谱图像分类

IEEE TGRS 2022&#xff1a;基于生成对抗性少数过采样的高光谱图像分类 题目 Generative Adversarial Minority Oversampling for Spectral–Spatial Hyperspectral Image Classification 作者 Swalpa Kumar Roy , Student Member, IEEE, Juan M. Haut , Senior Member, IE…

kubernetes RBAC Authentication 详解

开头语 写在前面&#xff1a;如有问题&#xff0c;以你为准&#xff0c; 目前24年应届生&#xff0c;各位大佬轻喷&#xff0c;部分资料与图片来自网络 内容较长&#xff0c;页面右上角目录方便跳转 Kubernetes 安全架构 K8S安全控制框架主要由下面3个阶段进行控制&#xf…

React 类组件和函数组件

组件component 一.概念 Element VS Component (元素与组件) //不成文的约定:元素小写&#xff0c;组件大写 const divReact.createElement(div,...) 这是一个React元素(小写) const Div()>React.createElement(div,...) 这是一个React组件(大写) 什么是组件? 能跟其他…

重磅!大模型框架 LangChain 首个稳定版本终于来了!

著名的大模型智能体工具&#xff0c;现在有大版本更新了。 不知不觉&#xff0c;LangChain 已经问世一年了。作为一个开源框架&#xff0c;LangChain 提供了构建基于大模型的 AI 应用所需的模块和工具&#xff0c;大大降低了 AI 应用开发的门槛&#xff0c;使得任何人都可以基于…

报错解决:RuntimeError: Error building extension ‘bias_act_plugin‘

系统&#xff1a; Ubuntu22.04&#xff0c; nvcc -V&#xff1a;11.8 &#xff0c; torch&#xff1a;2.0.0cu118 一&#xff1a;BUG内容 运行stylegan项目的train.py时遇到报错&#x1f447; Setting up PyTorch plugin "bias_act_plugin"... Failed! /home/m…

认知能力测验,⑦如何破解类比推理类测试题?

关于认知能力测评&#xff0c;今天这稿算是最后一篇&#xff0c;一共写了7篇&#xff0c;分别是数字推理、逻辑思维、语言常识、数量关系、图形推理、逻辑判断、和类比推理。 不论是校招、社招、网申、还是行测&#xff0c;在线人才测评已经是普遍普及的想象&#xff0c;而认知…

从源码角度来谈谈 HashMap

HashMap的知识点可以说在面试中经常被问到&#xff0c;是Java中比较常见的一种数据结构。所以这一篇就通过源码来深入理解下HashMap。 1 HashMap的底层是如何实现的&#xff1f;(基于JDK8) 1.1 HashMap的类结构和成员 /** HashMap继承AbstractMap,而AbstractMap又实现了Map的…

深入了解网络流量清洗--使用免费的雷池社区版进行防护

​ 随着网络攻击日益复杂&#xff0c;企业面临的网络安全挑战也在不断增加。在这个背景下&#xff0c;网络流量清洗成为了确保企业网络安全的关键技术。本文将探讨雷池社区版如何通过网络流量清洗技术&#xff0c;帮助企业有效应对网络威胁。 ![] 网络流量清洗的重要性&#x…

一个简单的MIPS-常见MIPS指令

ALU操作 这些指令用于执行算术和逻辑操作&#xff1a; ADDU&#xff08;无符号加法&#xff09;&#xff1a;将寄存器 rs 和 rt 的内容相加&#xff0c;结果存储在 rd 寄存器中。SUBU&#xff08;无符号减法&#xff09;&#xff1a;从寄存器 rs 减去寄存器 rt 的内容&#x…