FreeRTOS学习笔记-基于stm32(6)时间片调度实验

news2024/9/20 10:35:23

1、什么是时间片调度

        在任务优先级相同的时候,CPU会轮流使用相同的时间去执行它,即时间片调度。这个相同的时间就是时间片。而时间片的大小就是SysTick的中断周期(SysTick的中断周期可以修改)

        比如有三个相同优先级的任务在运行,时间片大小为10ms。那么CPU前10ms执行task1,然后用10ms执行task2,再花10ms执行task3,再回到task1执行10ms,这样的轮流执行被称之为时间片流转。如果期间有一个任务执行到一半被挂载了,那么CPU就会立马抛弃这个任务执行下一个任务。

2、时间片调度实验

        代码内容为:将时间片设置为50ms,然后创建task1和task2来不断在串口打印他们的运行次数。

步骤1:

        要想使用时间片必须先将这两个宏置1,这两个宏在 FreeRTOSConfig.h 中;

#define configUSE_PREEMPTION		1           //1使用抢占式内核,0使用协程
#define configUSE_TIME_SLICING		1			//1使能时间片调度(默认式使能的)

步骤2:

        在 FreeRTOSConfig.h 中找到此宏,修改1000为20;因为1000hz对应的 SysTick 中断周期即时间片大小是1ms。我们要改为50ms,就应该将1000hz / 50 = 20hz;

#define configTICK_RATE_HZ	   	(20)      //时钟节拍频率,这里设置为1000,周期就是1ms

步骤3:

        创建任务:

        需要注意的是:

        1、我们使用的是delay_ms(10)而不是vTaskDelay(10),因为后者会挂载当前任务转而执行另一个任务,这样就起不到50ms流转的效果了。而10ms的延时会让CPU停止工作。所以我们每50ms进行一次任务切换,然后每执行一次任务会延时10ms,所以每次任务中按理应该执行5遍while循环。又因为 printf 比较耗时,再加上其他代码的执行,实际每次任务while循环会执行4~5次

        2、因为实际每次任务while循环会执行4~5次,所以有时候在串口打印数据打印一半就可能会产生任务切换执行另一个任务,然后导致串口打印出现问题。所以我们在每次串口打印的时候加上临界段保护

/*START_TASK任务配置*/
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128     //128字=128*4字节
TaskHandle_t start_task_handler;
void start_task( void * pvParameters );

/*TASK1任务配置*/
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128     //128字=128*4字节
TaskHandle_t task1_handler;
void task1( void * pvParameters );

/*TASK2任务配置*/
#define TASK2_PRIO         2
#define TASK2_STACK_SIZE   128     //128字=128*4字节
TaskHandle_t task2_handler;
void task2( void * pvParameters );

/*入口函数*/
void freertos_demo(void)
{
    xTaskCreate(	(TaskFunction_t )    start_task,                //任务函数
                    (char *         )    "start_task",              //任务名称
                    (uint16_t       )    START_TASK_STACK_SIZE,     //任务堆栈大小
                    (void *         )    NULL,                      //传递给任务函数的参数
                    (UBaseType_t    )    START_TASK_PRIO,           //任务优先级
                    (TaskHandle_t * )    &start_task_handler );     //任务句柄 
    vTaskStartScheduler();         //开启任务调度器
}

void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();       //进入临界区
    printf("start_task正在运行\r\n");
    xTaskCreate(	(TaskFunction_t )    task1,                //任务函数
                    (char *         )    "task1",              //任务名称
                    (uint16_t       )    TASK1_STACK_SIZE,     //任务堆栈大小
                    (void *         )    NULL,                 //传递给任务函数的参数
                    (UBaseType_t    )    TASK1_PRIO,           //任务优先级
                    (TaskHandle_t * )    &task1_handler );     //任务句柄
                    
    xTaskCreate(	(TaskFunction_t )    task2,                //任务函数
                    (char *         )    "task2",              //任务名称
                    (uint16_t       )    TASK2_STACK_SIZE,     //任务堆栈大小
                    (void *         )    NULL,                 //传递给任务函数的参数
                    (UBaseType_t    )    TASK2_PRIO,           //任务优先级
                    (TaskHandle_t * )    &task2_handler );     //任务句柄
    vTaskDelete(NULL);      //vTaskDelete(start_task_handler);
    taskEXIT_CRITICAL();        //退出临界区
}

void task1( void * pvParameters )
{
	uint32_t task1_num=0;
    while(1)
    {
		taskENTER_CRITICAL();       //进入临界区
		printf("task1的运行次数 = %d\r\n",++task1_num);
		taskEXIT_CRITICAL();        //退出临界区
        delay_ms(10);
    }
}

void task2( void * pvParameters )
{
	uint32_t task2_num=0;
    while(1)
    {
		taskENTER_CRITICAL();       //进入临界区
		printf("task2的运行次数 = %d\r\n",++task2_num);
		taskEXIT_CRITICAL();        //退出临界区
        delay_ms(10);
    }
}

3、运行结果

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

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

相关文章

基于C++基础知识的指针

一、变量与指针 在C中,变量是用来存储数据的一个标识符,而指针是一个变量,该变量存储的是另一个变量的地址。 变量可以是不同的数据类型,包括整数、浮点数、字符、布尔值等。在声明变量时,需要指定变量的数据类型和标…

差分约束 C++ 算法例题

差分约束 差分约束 是一种特殊的 n 元一次不等式组,m 个约束条件,可以组成形如下的格式: { x 1 − x 1 ′ ≤ y 1 x 2 − x 2 ′ ≤ y 2 ⋯ x m − x m ′ ≤ y m \begin{cases} x_1-x_1^{} \le y_1 \\ x_2-x_2^{} \le y_2 \\ \cdots \\ x_…

TCP的四次挥手过程

TCP连接是双向传输的对等的模式(全双工模式),就是说双方都可以同时向对方发送或接收数据。 而断开的时候,也是双方都可以主动断开,此时需要经过四次挥手的过程,流程如下图所示: 主动方发送FIN包…

HTTP1.1的优化措施

3.2 HTTP/1.1 如何优化? 可以从以下三个方面来优化http/1.1协议: 尽量避免发送 HTTP 请求; 在需要发送 HTTP 请求时,考虑如何减少请求次数; 减少服务器的 HTTP 响应的数据大小; 避免发送HTTP请求 对于…

智能文件夹改名助手:一键秒级恢复原始名称,轻松告别繁琐操作,提升文件管理效率

文件夹管理成为了我们日常工作和生活中不可或缺的一部分。然而,随着文件数量的不断增加和文件夹命名的复杂性,我们经常面临着重命名文件夹的繁琐操作。你是否曾经因为误改文件夹名称而头疼不已?是否曾经为了找回原始名称而耗费大量时间&#…

将CentOS 7安装在U盘上,这时你将体验到......

文章目录 前言一、Linux 是什么?二、使用步骤1.下载安装 VMware Workstation Pro2.下载 CentOS 镜像3.准备一个U盘(最好是32G以上的)4.VMware 里安装 CentOS 总结 前言 随着 Linux 在服务器、嵌入式系统、移动设备等领域的广泛应用&#xff…

【jitsi】jitsi 布署及docker打包

目录 单独的布署 最后总结的成果 旧的架构 单独的布署 最后总结的成果 http://10.30.40.10/dualvenDoc/installjitsi/ 旧的架构 wvp视频调度平台架构布署图_wvp 架构-CSDN博客

Word应用:一键提取手写签名

1、将带有签名的图片插入到word文档中,裁剪出签名部分; 2、点击“格式-颜色”,选择“重新着色”中的“黑白50%”; 3、“格式-颜色”,设置透明色; 4、选择“文件”选项卡,选择打开“选项”,点击“…

【Unity Shader入门精要 第6章】基础光照(二)

1. 获取环境光 unity shader中可以通过 UNITY_LIGHTMODEL_AMBIENT获取当前环境光颜色信息。 fixed4 frag(v2f i) : SV_Target {return UNITY_LIGHTMODEL_AMBIENT; }2. 漫反射 2.1 兰伯特模型 创建Chapter_6_Diffuse_Lambert作为测试材质创建Chapter_6_Diffuse_Lambert作为测…

AI智能写作网站推荐:好用的工具看这几款就够了!

在近年来的科技发展浪潮中,人工智能写作工具以其独特的优势和魅力,引起了行业内外的广泛关注。从技术层面来看,这种工具的应用和发展已经取得了重要的突破,而从应用层面来看,它们对内容创作领域的深远影响更是不可忽视…

关于Speech processing Universal PERformance Benchmark (SUPERB)基准测试及衍生版本

Speech processing Universal PERformance Benchmark (SUPERB)是由台湾大学、麻省理工大学,卡耐基梅隆大学和 Meta 公司联合提出的评测数据集,其中包含了13项语音理解任务,旨在全面评估模型在语音处理领域的表现。这些…

EasyExcel简单使用

EasyExcel简单使用 ​ 之前一直用的Apache POI来做数据的导入导出&#xff0c;但听说阿里的EasyExcel也拥有POI的功能的同时&#xff0c;在处理大数据量的导入导出的时候性能上比POI更好&#xff0c;所以就来尝试使用一下 导入Maven依赖&#xff1a; <dependency><…

图和网络笔记

文章目录 1. 图(节点边) 1. 图(节点边) 一个图可以由节点和边组成&#xff0c;假设我们有一个节点notes &#xff1a;n4,边edges&#xff1a;m5的有向图&#xff0c;表示如下 通过以上电路图可以得到关联矩阵(incident matrix),我们定义边&#xff0c;开始端用-1表示&#x…

Elasticsearch查看集群信息,设置ES密码,Kibana部署

Elasticsearch查看集群信息&#xff0c;设置ES密码&#xff0c;Kibana部署 查看集群信息查看节点信息查看集群健康状态查看分片信息查看其他集群信息 Kibana部署安装设置ES密码 查看集群信息 查看节点信息 curl http://127.0.0.1:9200/_cat/nodes?v 参数说明&#xff1a; ip…

基于大模型的idea提炼:围绕论文和引用提炼idea之ResearchAgent

前言 对本博客比较熟悉的朋友知道&#xff0c;我司论文项目组正在基于大模型做论文的审稿(含CS英文论文审稿、和金融中文论文审稿)、翻译&#xff0c;且除了审稿翻译之外&#xff0c;我们还将继续做润色/修订、idea提炼(包含论文检索)&#xff0c;是一个大的系统&#xff0c;包…

星辰考古:TiDB v1.0 再回首

“ 1.0 版本只是个开始&#xff0c;是新的起点&#xff0c;愿我们一路相扶&#xff0c;不负远途。 前言 TiDB 是 PingCAP 公司自主设计、研发的开源分布式关系型数据库。 近日&#xff0c;TiDB v8.0.0 DMR 发布&#xff0c;详细发版说明戳这里&#xff1a; https://docs.pingca…

【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

3588 pwm android12 的操作

问题&#xff1a; 客户需要在android12 的界面上操作板卡上的 PWM 蜂鸣器设备。 过程&#xff1a; 1 了解一下 3588 android12 源码的 关于PWM 的驱动。 设备树找不到 pwm 但是&#xff0c; 还不知道&#xff0c;android12 最终包含的 设备树是哪个&#xff0c;但是经过我的…

MyCat实现分库分表

两个集群 两个库 两个表 搭建数据库服务使用docker启动两个mysql 3506 3507连接MyCat创建两个数据源连接MyCat创建集群 mycat创建逻辑库MyCat创建全局表广播表创建分片表mycat逻辑库MyCat插入数据mycat查看数据物理库3506查看数据物理库3507查看数据 ER表创建ER表mycat插入数据…