零基础国产GD32单片机编程入门(十二)FreeRTOS实时操作系统移植含源码

news2024/9/22 13:35:07

文章目录

    • 一.概要
    • 二.什么是实时操作系统
    • 三.FreeRTOS的特性
    • 四.FreeRTOS的任务详解
      • 1.任务函数定义
      • 2.任务的创建
      • 3.任务的调度原理
    • 五.FreeRTOS系统移植到GD32F103C8T6单片机
      • 1.硬件准备
      • 2.程序移植
      • 3.调试FreeRTOS任务调度
    • 六.工程源代码下载
    • 七.小结

一.概要

FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。
由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μC/OS-II、embOS、salvo、FreeRTOS等少数实时操作系统能在小RAM单片机上运行。相对μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行。

二.什么是实时操作系统

操作系统是一个控制程序,作为硬件和应用程序之间的桥梁,主要是和硬件打交道,负责协调分配计算资源和内存资源给不同的应用程序使用,并防止系统出现故障。面对来自不同应用程序的大量且互相竞争的资源请求,操作系统通过一个调度算法和内存管理算法尽可能把资源公平且有效率地分配给不同的程序。应用程序则通过调用操作系统提供的API接口获得相应资源完成指定的任务。

实时操作系统(RTOS-Real Time Operating System)中实时(Real Time)指的是任务(Task)或者说实现一个功能的线程(Thread)必须在给定的时间(Deadline)内完成。

三.FreeRTOS的特性

具有抢占式或者合作式的实时操作系统内核
功能可裁剪,最小占用10kB左右rom空间,0.5kB ram空间
灵活的任务优先级分配
具有低功耗模式
有互斥锁、信号量、消息队列等功能
运行过程可追踪
支持中断嵌套

四.FreeRTOS的任务详解

FreeRTOS的核心是任务调度器(Task Scheduler),它负责按照一定的调度策略将任务分配给处理器执行。每个任务都是一个独立的函数,可以有不同的优先级和堆栈大小。任务调度器根据任务的优先级和调度策略决定哪个任务被执行。

下图就是任务调度简单介绍
在这里插入图片描述

下面代码就是个简单的示例代码,通过调用osThreadCreate函数创建了两个任务vTaskLED(驱动LED灯灭)和vTaskLEDFlash(驱动LED灯亮)。在main函数中,通过调用vTaskStartScheduler函数启动了实时系统,使得任务可以被调度执行,由于两个任务都能不断运行,所以能驱动LED灯闪烁。

//LED熄灭
void vTaskLED(void *pvParameters)
{
    while (1)
    {
        /* LED OFF */
        gpio_bit_set(GPIOB, GPIO_PIN_4);
        vTaskDelay(150/ portTICK_RATE_MS);
    }
}
//LED点亮
void vTaskLEDFlash(void *pvParameters)
{
    while (1)
    {
         /* LED ON */
        gpio_bit_reset(GPIOB, GPIO_PIN_4);
        vTaskDelay(100/ portTICK_RATE_MS);
    }
}

1.任务函数定义

无论采用何种方法创建任务,均需要用到任务函数。FreeRTOS 规定任务函数的返回值必须为void,而且带有一个void型指针参数。

void vTaskLED(void *pvParameters)
{
    while (1)
    {
        /* LED OFF */
        gpio_bit_set(GPIOB, GPIO_PIN_4);
        vTaskDelay(150/ portTICK_RATE_MS);
    }
}

GD32F103C8T6单片机只有一个内核,那怎么让多个人同时干活呢?其实每个子任务虽然都是死循环,但并不是每个子任务一直都在执行,每个子任务在执行期间,可能需要延时,这边就通过 vTaskDelay(100/ portTICK_RATE_MS),等待100ms,单片机就可以停止此任务,然后切换到其它任务执行,这样看起来就是多个人在同时干活了。

2.任务的创建

xTaskCreate(vTaskLED, "Task LED", 10, NULL, 1, NULL);//创建一个任务,任务名,任务函数,优先级,堆栈大小

xTaskCreate函数中的第1个参数(vTaskLED)是任务函数:
任务函数是任务执行的代码,它应该是一个无返回值的函数,其参数是一个可选的指针,可以用来传递任何需要的数据,我们代码中的任务就是控制GPIO输出高或者低电平。

xTaskCreate函数中的第2个参数(“Task LED”)是任务名称:
这是一个字符串。

xTaskCreate函数中的第3个参数(10)是任务栈大小定义:
任务栈大小指定了任务可以使用多少RAM来存储局部变量和其他临时数据。这个大小应该足够大,能够容纳任务在执行期间可能出现的最大需求,一般代表多个字,如果是10,代表40字节,一般我们可以填100。

xTaskCreate函数中的第4个参数(NULL)是指向任务参数的指针:
这个参数可以是任何类型,它将传递给任务。

xTaskCreate函数中的第5个参数(1)是任务优先级:
任务优先级决定了任务在操作系统调度下的执行顺序。数值越大,优先级越高。

xTaskCreate函数的第6个参数(NULL)是任务句柄:
任务句柄是一个指针,可以用来引用已经创建的任务,以便可以在任务创建后对其进行操作,例如删除、挂起、恢复等。

3.任务的调度原理

FreeRTOS默认使用抢占式调度策略,对同等优先级的任务使用时间片轮询调度,时间片轮询就是可轮流享有相同的单片机时间(可设置),一个时间片等于SysTick中断周期。
抢占式调度是指调度器始终运行优先级最高且处于可运行状态的任务,无论任务何时可以运行。如在中断服务函数中更改了优先级最高且可运行的任务,调度器会停止当前执行的低优先级任务,并启动高优先级任务。
刚才程序中的vTaskDelay是通过将当前任务加入到延时列表中,并设置一个定时器来在指定的延时时间,延时时间过去之后将任务从延时列表中移除并将其设置为就绪状态。这样当定时器触发时,任务重新被加入到就绪列表中,等待被调度器再次调度执行。

下面代码截图就是操作系统底层寻找就绪任务的最高优先级,获取优先级最高的就绪任务的 TCB(任务控制块),然后更新到 pxCurrentTCB ,当前运行的任务只可能有一个,因此pxCurrentTCB只是单个TCB_t指针,它始终指向当前运行的任务。通过xPortPendSVHandler(PendSV_Handler)函数实现调度
在这里插入图片描述
PendSV_Handler 是 ARM Cortex-M 处理器中的一个特殊的中断处理函数,用于处理挂起 PendSV(Pending Supervisor Call)中断。PendSV 中断是 Cortex-M 架构中的一种特殊的软件中断,它可以用来实现任务切换或者其他与系统调度相关的操作。
PendSV_Handler 在中断向量表的位置
在这里插入图片描述

__asm void xPortPendSVHandler( void )

{

extern uxCriticalNesting;

extern pxCurrentTCB;

extern vTaskSwitchContext;

PRESERVE8

mrs r0, psp //(1)        读取进程栈指针,保存在寄存器 R0 里面。

isb

ldr r3, =pxCurrentTCB//(2)   获取当前任务的任务控制块,并将任务控制块的地址保存在寄存器 R2 里面。

ldr r2, [r3] //(3)

tst r14, #0x10 //(4)        判断任务是否使用了 FPU

it eq //(5)

vstmdbeq r0!, {s16-s31}// (6)

stmdb r0!, {r4-r11, r14} //(7)

str r0, [r2] //(8)

stmdb sp!, {r3} //(9)

mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY //(10)       

msr basepri, r0 //(11)           关闭中断,进入临界区

dsb

isb

bl vTaskSwitchContext //(12)    调用函数 vTaskSwitchContext(),此函数用来获取下一个要运行的任务,并将pxCurrentTCB 更新为这个要运行的任务。

mov r0, #0 //(13)

msr basepri, r0 //(14)        打开中断,退出临界区。

ldmia sp!, {r3} //(15)

ldr r1, [r3] //(16)

ldr r0, [r1] //(17)

ldmia r0!, {r4-r11, r14} //(18)

tst r14, #0x10 //(19)

it eq //(20)

vldmiaeq r0!, {s16-s31} //(21)

msr psp, r0 //(22)           更新进程栈指针 PSP 的值

isb

bx r14 //(23)     执行此行代码以后硬件自动恢复寄存器 R0~R3、 R12、 LR、 PC 和 xPSR 的值,确定异常返回以后应该进入处理器模式还是进程模式,使用主栈指针(MSP)还是进程栈指针(PSP)。很明显这里会进入进程模式,并且使用进程栈指针(PSP),寄存器 PC 值会被恢复为即将运行的任务的任务函数,新的任务开始运行!至此,任务切换成功。

}

五.FreeRTOS系统移植到GD32F103C8T6单片机

1.硬件准备

STLINK接GD32F103C8T6开发板,STLINK接电脑USB口。

在这里插入图片描述

2.程序移植

FreeRTOS主要文件介绍:

port.c:这是一个示例端口文件,用于 Cortex-M3 微控制器。你需要根据你的处理器架构修改这个文件。
portmacro.h:这个文件包含硬件抽象层代码,也需要根据你的处理器架构修改。
FreeRTOSConfig.h:这个文件包含了 FreeRTOS 的配置选项,你可能需要修改这个文件来满足你的项目需求。
tasks.c, queue.c, list.c:这些是(kernel核心)文件,它们包含了FreeRTOS核心的任务管理和同步机制实现。
heap_2.c:这个是内存管理方法,它是一个小型的内存分配器,用于分配和释放固定大小的块内存。
timers.c:实现了定时器的所有功能,包括定时器的创建、删除、启动和停止等。
routine.c:这个文件包含了FreeRTOS的协程(或者称为微任务)的实现。

解压GD32F103C8T6的第一个例程:
1.GPIO输出实验
在这里插入图片描述

添加Freertos相关文件

添加FreeRTOS文件夹下面的所有文件到工程文件目录下
在这里插入图片描述
FreeRTOS文件夹下面的所有文件可以官网下载,也可以从我们例程上拷贝
在这里插入图片描述

添加FreeRTOSConfig.h文件
在这里插入图片描述

打开Keil5工程,创建FreeRTOS文件夹,添加下述文件到工程
在这里插入图片描述

添加头文件路径
在这里插入图片描述

删除中断文件中的三个中断服务程序,操作系统中已经对这三个文件重新定义了
在这里插入图片描述

main.c中添加包含头文件,并定义两个任务
在这里插入图片描述

main函数中创建这两个任务,并执行启动系统,完成系统移植
在这里插入图片描述

3.调试FreeRTOS任务调度

调试代码,能更好理解任务调度。

打断点,能跑进任务1
在这里插入图片描述

打断点,能跑进任务2
在这里插入图片描述

当前运行任务
在这里插入图片描述
任务切换后将要运行的任务
在这里插入图片描述

六.工程源代码下载

通过网盘分享的文件:13.FREERTOS实验.zip
链接: https://pan.baidu.com/s/1jR-GL6W_IbUX6Y7UKkdrMA 提取码: rrnb
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

CSDN下载

七.小结

FreeRTOS实时操作系统能使在GD32单片机软件开发中,程序结构清晰,单片机执行效率提升许多,在多个任务模块的代码中,可以考虑使用FreeRTOS。

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

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

相关文章

海外直播对网速、带宽、安全的要求

要满足海外直播的要求,需要拥有合适的网络配置。在全球化的浪潮下,海外直播正逐渐成为企业、个人和各类组织的重要工具。不论是用于市场推广、品牌宣传,还是与观众互动,海外直播都为参与者带来了丰富的机会。然而,确保…

KTH2502 系列车规数字锁存霍尔效应传感器

KTH2502 采用了先进的斩波技术,集成了温度补偿电路和过流、负压保护电路,具有卓越的灵敏度和温度稳定 性。磁场通过数字双极锁存器输出指示。该芯片具有开漏输出级以及 30mA 的灌电流能力。 2.7~32 V 的宽电压工 作范围,反极性保护高达 -22…

渗透测试靶机--- DC系列 DC-9

渗透测试靶机— DC系列 DC-9 开启靶机,依旧登录窗,平平无奇 扫描信息 访问页面看看 页面中存在查询接口,这里页面输入的内容是get请求,可以尝试sql注入,如果是post请求,那么抓包。将请求体放入sqlmap跑一下…

太速科技-基于Kintex-7 XC7K160T 的CameraLink转四路光纤数据转发卡(Full Camera Link图像转万兆以太网适配器 )

基于Kintex-7 XC7K160T 的CameraLink转四路光纤数据转发卡(Full Camera Link图像转万兆以太网适配器 ) 一、板卡概述 该板卡是一款CameraLink(Full)转4路光纤接口板,可以实现1路CamerLink Full模式的图像信号转换成…

Druid未授权访问解决

Druid未授权访问原因分析 漏洞说明:Druid由阿里巴巴数据库出品,为监控而生的数据库连接池,并且Druid可以提供监控,监控SQL的执行时间、监控Web URI的请求、Session监控等功能,使用广泛。 需要明确: Druid…

物联网(IoT)支持的小型水处理厂实时硬件在环(HIL)仿真

这篇论文的标题是《Real-Time Hardware-In-The-Loop Simulation of IoT-Enabled Mini Water Treatment Plant》,作者是 Mohamad Taib Miskon 等人,发表在 2024 年 IEEE 自动控制与智能系统国际会议(I2CACIS)上。以下是该论文的主要…

搭建 xxl-job 调度中心

文章目录 1、初始化“调度数据库”2、修改“调度中心”配置3、打包运行”调度中心“ 1、初始化“调度数据库” 请下载项目源码并解压,获取 “调度数据库初始化SQL脚本” 并执行即可。 “调度数据库初始化SQL脚本” 位置为:/xxl-job/doc/db/tables_xxl_j…

微服务日常总结

1.当我们在开发中,需要连接多个库时,可以在yml中进行配置。 当在查询的时候,跨库时,需要通过DS 注解来指定,需要yml配置需要保持一致。 2. 当我们想把数据存入到clob类型中,需要再字段 的占位符后面加上j…

鸢尾花书实践和知识记录[数学要素3-1万物皆数]

章节框图 文章目录 本章用到的函数使用math库来打印出一些常用的值判断奇数偶数两数加减产生序列矩阵向量的表示:取数组矩阵元素的方法streamlit的绘图矩阵的一般类型构造二维矩阵矩阵的加和运算 本章用到的函数 复数和自然数 使用math库来打印出一些常用的值 i…

多表查询_关联查询

inner join:通常关联项on后面的是主外键,两个表都有的才显示 left join:左连,select * from S left join B on s.字段 B.字段,一定会将左边表的数据全部查询出来 right join:select * from S right join B on s.字段 B.字段一定会将右边表的…

Unity面向对象补全计划 之 List<T>与class(非基础)

C# & Unity 面向对象补全计划 泛型-CSDN博客 关于List,其本质就是C#封装好的一个数组,是一个很好用的轮子,所以并不需要什么特别说明 问题描述 假设我们有一个表示学生的类 Student,每个学生有姓名和年龄两个属性。我们需要创…

Git学习尚硅谷(002 git常用命令)

尚硅谷Git入门到精通全套教程(涵盖GitHub\Gitee码云\GitLab) 总时长 4:52:00 共45P 此文章包含第8p-第p15的内容 文章目录 git常用命令设置用户签名初始化本地库查看本地库状态添加暂存区提交本地库日志查看修改文件版本穿梭 git常用命令 设置用户签名…

视频集中存储智能边缘计算网关软硬一体机智能边缘计算网关应用场景

在信息化飞速发展的今天,数据处理的速度和效率直接影响到各行各业的运作和发展。传统的云计算模式虽然强大,但在面对实时性和带宽要求越来越高的应用场景时,往往显得力不从心。此时,智能边缘计算网关的出现,为我们带来…

源代码怎么加密防泄漏?9种方法教会你

想做源代码加密防止泄漏,首先要了解程序员可以通过哪些方式将源代码传输出去! 程序员泄密的常见方式 物理方法: — 网线直连,即把网线从墙上插头拔下来,然后和一个非受控电脑直连; — winPE启动,通过光盘…

pikachu文件包含漏洞靶场攻略

1.File inclusion(local)(本地文件包含) 步骤一:选择一个球员提交 步骤二:filename后面输入../../../../shw.php访问php文件 2.File Inclusion(remote)(远程文件包含) 步骤一:修改配置 远程包…

网吧业务安全对抗(有源码)

网吧业务竞争激烈,网吧都会有以下系统软件。 无盘: 无盘是指没有硬盘。好处是统一维护管理和节约成本。本人研究无盘好几年,后面会专门发帖介绍。 计费: 是指收费系统。 营销软件: 包括销售饮品、‌零食和向客户发送电子邮件营销和短信营销等。产品如…

银行资本种类

一、账面资本(会计资本) 账面资本又称为会计资本,是指商业银行持股人的永久性资本投入,即出资人在商业银行资产中享有的经济利益,其金额等于资产减去负债后的余额,包括实收资本或普通股、资本公积、盈余公…

【C++第十六章】多态

【C第十六章】多态 定义🧐 多态通俗来说,就是多种形态,我们去完成某个行为时,不同对象完成时会产生出不同的状态。比如游乐园中,1.2米以上买票就需要买成人票,1.2米以下就可以买儿童票。 多态是在不同继承…

Spring之整合Mybatis底层源码解析

整合核心思路 由很多框架都需要和Spring进行整合,而整合的核心思想就是把其他框架所产生的对象放到Spring容器中,让其成为Bean。 ​ 比如Mybatis,Mybatis框架可以单独使用,而单独使用Mybatis框架就需要用到Mybatis所提供的一些类…