16,FreeRTOS互斥信号量操作

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

  一、实验目标


        创建四个动态任务,栈空间大小均为128字。startTask、Task1、Task2、Task3。startTask仅运行一次,负责互斥信号量的创建,task1、task2、task3任务的创建,startTask任务的删除。Task1(低优先级)负责互斥信号量的获取后绝对延时3S后释放。Task2(中优先级)负责串口打印运行状态。Task3(高优先级)负责互斥信号量的获取后绝对延时1S后释放。

注:本实验基于正点原子FreeRTOS教程的学习总结。

 二、实验准备

1.FreeRTOS的Keil动态任务创建与删除程序

2.STM3F407开发板

3.互斥信号量介绍

        互斥信号量是具有优先级继承的二值信号量,可以降低优先级翻转带来的影响,但不能彻底解决。

        优先级继承:当低优先级的任务先获取到互斥信号量,高优先级的任务获取互斥信号量时,会将低优先级的优先级提升到高优先级任务一样的优先级(优先级上升)。

        互斥信号量创建时,会主动释放一次信号量。

4.所需API函数介绍

        使用的API函数主要有互斥信号量动态创建函数、计数值获取函数。信号量释放函数、信号量获取函数与二值信号量的相同,可以在上一章查看。

14,FreeRTOS二值信号量操作-CSDN博客https://blog.csdn.net/LC_8575/article/details/151149446?spm=1011.2124.3001.6209

        互斥信号量动态创建函数xSemaphoreCreateMutex(),创建成功返回值为互斥信号量句柄,创建失败返回NULL。

    #define xSemaphoreCreateMutex()    xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )

5.信号量相关定义

        首先在freertos_demo.c中添加头文件:

#include "semphr.h"

        其次定义互斥信号量的句柄:

//互斥信号量定义
SemaphoreHandle_t Mutex_Semaphore_Handle;//定义互斥信号量句柄

        在FreeRTOSConfig.h中开启宏定义。

#define configUSE_MUTEXES                               1                       /* 1: 使能互斥信号量, 默认: 0 */

三、代码编写

3.1修改start_task的任务函数内容

        start_task实现计数型信号量创建、两个任务创建、start_task任务删除。

void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
		Mutex_Semaphore_Handle = xSemaphoreCreateMutex();//创建互斥信号量,主动式释放一次
		if(Mutex_Semaphore_Handle != NULL) printf("互斥信号量创建成功\r\n");
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
		/* 创建任务2 */
    xTaskCreate((TaskFunction_t )task2,
                (const char*    )"task2",
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler);
		/* 创建任务3 */
    xTaskCreate((TaskFunction_t )task3,
                (const char*    )"task3",
                (uint16_t       )TASK3_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK3_PRIO,
                (TaskHandle_t*  )&Task3Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

3.2修改Task1的任务函数内容

        Task1低优先级  获取信号量后,绝对延时3S后释放信号量。

/* task1 低优先级  获取信号量后,死延时3S后释放信号量*/
void task1(void *pvParameters)
{
    while(1)
    {
				printf("low_task获取信号量\r\n");
				xSemaphoreTake(Mutex_Semaphore_Handle,portMAX_DELAY);
				printf("low_task正在运行\r\n");
				delay_ms(3000);
				printf("low_task释放信号量\r\n");
				xSemaphoreGive(Mutex_Semaphore_Handle);
				vTaskDelay(1000);//相对延时
    }
}

 3.3修改Task2的任务函数内容

        Task2实现中优先级 打印。

/* task2 中优先级 打印 */
void task2(void *pvParameters)
{
	BaseType_t err;
	while(1)
	{
			printf("middle_task正在运行\r\n");
			vTaskDelay(1000);//相对延时
	}
}

 3.4修改Task3的任务函数内容

        Task3实现高优先级 获取信号量后,死延时1s后释放。

/* task3 高优先级 获取信号量后,绝对延时1s后释放 */
void task3(void *pvParameters)
{
	BaseType_t err;
	while(1)
	{
				printf("high_task获取信号量\r\n");
				xSemaphoreTake(Mutex_Semaphore_Handle,portMAX_DELAY);
				printf("high_task正在运行\r\n");
				delay_ms(1000);
				printf("high_task释放信号量\r\n");
				xSemaphoreGive(Mutex_Semaphore_Handle);
				vTaskDelay(1000);//相对延时
	}
}

 四、实验现象

        实验现象如下所示。可以看到系统初始化显示互斥型信号量创建成功。首先高优先级的任务抢占,成功获取互斥信号量进行运行。接着中优先级任务抢占。再接着低优先级的任务抢占,并延时,此时高优先级任务抢占并获取不到信号量。

        可以看到标注部分,低优先级的任务优先级继承,先于中优先级任务执行。执行完毕后高优先级任务执行。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值