首页 > 其他分享 >13_信号量

13_信号量

时间:2024-03-28 20:34:20浏览次数:16  
标签:13 task handle PRIO void 信号量 include

信号量

信号量的简介

image-20240327143807800

image-20240327143819204

队列与信号量的对比

image-20240327143831464

二值信号量

image-20240327143845368

二值信号量相关API函数

image-20240327143859259

创建二值信号量函数

image-20240327144046949

释放二值信号量函数

image-20240327144143185

获取二值信号量函数

image-20240327144159738

二值信号量实验

image-20240327144213047

代码

freertos_demo.c

/**
 ****************************************************************************************************
 * @file        freertos.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.4
 * @date        2022-01-04
 * @brief       FreeRTOS 移植实验
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:正点原子 探索者F407开发板
 * 在线视频:www.yuanzige.com
 * 技术论坛:www.openedv.com
 * 公司网址:www.alientek.com
 * 购买地址:openedv.taobao.com
 *
 ****************************************************************************************************
 */

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_STACK_SIZE 	128
#define START_TASK_PRIO			1
TaskHandle_t start_task_handler;

#define TASK1_STACK_SIZE 		128
#define TASK1_PRIO				2
TaskHandle_t task1_handler;

#define TASK2_STACK_SIZE 		128
#define TASK2_PRIO				3
TaskHandle_t task2_handler;

QueueHandle_t semphore_handle;

void start_task( void * pvParameters );

void task1( void * pvParameters )
{
	uint8_t key = 0;
	BaseType_t err;
	while(1)
	{
		key = key_scan(0);
		if(key == KEY0_PRES)
		{
			if(semphore_handle != NULL)
			{
				err = xSemaphoreGive(semphore_handle);
				if(err == pdPASS)
				{
					printf("二值信号量释放成功!!!\r\n");
				}else
				{
					printf("二值信号量释放失败!!!\r\n");
				}
			}
		}
		vTaskDelay(10);
	}
}

void task2( void * pvParameters )
{
	BaseType_t err;
	while(1)
	{
		err = xSemaphoreTake(semphore_handle, portMAX_DELAY); //死等
		if(err == pdTRUE)
		{
			printf("二值信号量获取成功!!!\r\n");
		}else
		{
			printf("二值信号量获取失败!!!\r\n");
		}
	}
}

/******************************************************************************************************/

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
	semphore_handle = xSemaphoreCreateBinary(); //创建二值信号量
	if(semphore_handle != NULL)
	{
		printf("二值信号量创建成功!!!\r\n");
	}
    xTaskCreate(start_task, "start_task", START_TASK_STACK_SIZE, NULL, START_TASK_PRIO, &start_task_handler);
	vTaskStartScheduler();
}

void start_task( void * pvParameters )
{
	taskENTER_CRITICAL(); //进入临界区
	xTaskCreate(task1, "task1", TASK1_STACK_SIZE, NULL, TASK1_PRIO, &task1_handler);
	xTaskCreate(task2, "task2", TASK2_STACK_SIZE, NULL, TASK2_PRIO, &task2_handler);
    vTaskDelete(NULL);
	taskEXIT_CRITICAL(); //退出临界区
}

计数型信号量

image-20240327144232318

计数型信号量相关API函数

image-20240327144250965

计数型信号量创建API函数

image-20240327144309707

image-20240327144322059

计数型信号量实验

image-20240327144338023

代码

freertos_demo.c

/**
 ****************************************************************************************************
 * @file        freertos.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.4
 * @date        2022-01-04
 * @brief       FreeRTOS 移植实验
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:正点原子 探索者F407开发板
 * 在线视频:www.yuanzige.com
 * 技术论坛:www.openedv.com
 * 公司网址:www.alientek.com
 * 购买地址:openedv.taobao.com
 *
 ****************************************************************************************************
 */

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_STACK_SIZE 	128
#define START_TASK_PRIO			1
TaskHandle_t start_task_handler;

#define TASK1_STACK_SIZE 		128
#define TASK1_PRIO				2
TaskHandle_t task1_handler;

#define TASK2_STACK_SIZE 		128
#define TASK2_PRIO				3
TaskHandle_t task2_handler;

QueueHandle_t count_semphore_handle;

void start_task( void * pvParameters );

void task1( void * pvParameters )
{
	uint8_t key = 0;
	BaseType_t err;
	while(1)
	{
		key = key_scan(0);
		if(key == KEY0_PRES)
		{
			if(count_semphore_handle != NULL)
			{
				err = xSemaphoreGive(count_semphore_handle);
				if(err == pdPASS)
				{
					printf("计数型信号量释放成功!!!\r\n");
				}else
				{
					printf("计数型信号量释放失败!!!\r\n");
				}
			}
		}
		vTaskDelay(10);
	}
}

void task2( void * pvParameters )
{
	BaseType_t err;
	UBaseType_t count = 0;
	while(1)
	{
		err = xSemaphoreTake(count_semphore_handle, portMAX_DELAY); //死等
		if(err == pdTRUE)
		{
			printf("计数型信号量获取成功!!!\r\n");
			count = uxSemaphoreGetCount(count_semphore_handle);
			printf("信号量计数值为:%ld\r\n", count);
		}else
		{
			printf("计数型信号量获取失败!!!\r\n");
		}
		vTaskDelay(1000);
	}
}

/******************************************************************************************************/

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
	count_semphore_handle = xSemaphoreCreateCounting(100, 0); //创建计数型信号量
	if(count_semphore_handle != NULL)
	{
		printf("计数型信号量创建成功!!!\r\n");
	}
    xTaskCreate(start_task, "start_task", START_TASK_STACK_SIZE, NULL, START_TASK_PRIO, &start_task_handler);
	vTaskStartScheduler();
}

void start_task( void * pvParameters )
{
	taskENTER_CRITICAL(); //进入临界区
	xTaskCreate(task1, "task1", TASK1_STACK_SIZE, NULL, TASK1_PRIO, &task1_handler);
	xTaskCreate(task2, "task2", TASK2_STACK_SIZE, NULL, TASK2_PRIO, &task2_handler);
    vTaskDelete(NULL);
	taskEXIT_CRITICAL(); //退出临界区
}

优先级翻转简介

image-20240327144352270

image-20240327144402619

优先级翻转实验

image-20240327144426709

代码

freertos_demo.c

/**
 ****************************************************************************************************
 * @file        freertos.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.4
 * @date        2022-01-04
 * @brief       FreeRTOS 移植实验
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:正点原子 F407电机开发板
 * 在线视频:www.yuanzige.com
 * 技术论坛:www.openedv.com
 * 公司网址:www.alientek.com
 * 购买地址:openedv.taobao.com
 *
 ****************************************************************************************************
 */

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    low_task_handler;
void low_task( void * pvParameters );


/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    middle_task_handler;
void middle_task( void * pvParameters );


/* TASK3 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK3_PRIO         4
#define TASK3_STACK_SIZE   128
TaskHandle_t    high_task_handler;
void high_task( void * pvParameters );

/******************************************************************************************************/
QueueHandle_t semphore_handle;
/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    semphore_handle = xSemaphoreCreateBinary();
    if(semphore_handle != NULL)
    {
        printf("二值信号量创建成功!!!\r\n");
    }
    xSemaphoreGive(semphore_handle);        /* 释放一次信号量 */
    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();               /* 进入临界区 */
    xTaskCreate((TaskFunction_t         )   low_task,
                (char *                 )   "low_task",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &low_task_handler );
                
    xTaskCreate((TaskFunction_t         )   middle_task,
                (char *                 )   "middle_task",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &middle_task_handler );
                
    xTaskCreate((TaskFunction_t         )   high_task,
                (char *                 )   "high_task",
                (configSTACK_DEPTH_TYPE )   TASK3_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK3_PRIO,
                (TaskHandle_t *         )   &high_task_handler );
                             
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}

/* 任务一,低优先级任务 */
void low_task( void * pvParameters )
{
    while(1) 
    {
        printf("low_task获取信号量\r\n");
        xSemaphoreTake(semphore_handle,portMAX_DELAY);
        printf("low_task正在运行!!!\r\n");
        delay_ms(3000);
        printf("low_task释放信号量\r\n");
        xSemaphoreGive(semphore_handle); 
        vTaskDelay(1000);
    }
}

/* 任务二,中优先级任务 */
void middle_task( void * pvParameters )
{
    while(1)
    {
        printf("middle_task正在运行!!!\r\n");
        vTaskDelay(1000);
    }
}

/* 任务三,高优先级任务 */
void high_task( void * pvParameters )
{
    while(1)
    {
        printf("high_task获取信号量\r\n");
        xSemaphoreTake(semphore_handle,portMAX_DELAY);
        printf("high_task正在运行!!!\r\n");
        delay_ms(1000);
        printf("high_task释放信号量\r\n");
        xSemaphoreGive(semphore_handle); 
        vTaskDelay(1000);
    }
}

互斥信号量

image-20240327144439059

优先级继承示例

image-20240327144451756

image-20240327144509257

互斥信号量相关API函数

image-20240327144523070

互斥信号量创建API函数

image-20240327144542581

互斥信号量实验

image-20240327144553453

代码

freertos_demo.c

/**
 ****************************************************************************************************
 * @file        freertos.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.4
 * @date        2022-01-04
 * @brief       FreeRTOS 移植实验
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:正点原子 探索者F407开发板
 * 在线视频:www.yuanzige.com
 * 技术论坛:www.openedv.com
 * 公司网址:www.alientek.com
 * 购买地址:openedv.taobao.com
 *
 ****************************************************************************************************
 */

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_STACK_SIZE 	128
#define START_TASK_PRIO			1
TaskHandle_t start_task_handler;

#define TASK1_STACK_SIZE 		128
#define TASK1_PRIO				2
TaskHandle_t low_task_handler;

#define TASK2_STACK_SIZE 		128
#define TASK2_PRIO				3
TaskHandle_t middle_task_handler;

#define TASK3_STACK_SIZE 		128
#define TASK3_PRIO				4
TaskHandle_t high_task_handler;

QueueHandle_t mutex_semphore_handle;

void start_task( void * pvParameters );

void low_task( void * pvParameters )
{
	while(1)
	{
		printf("low_task获取信号量\r\n");
        xSemaphoreTake(mutex_semphore_handle,portMAX_DELAY);
        printf("low_task正在运行!!!\r\n");
        delay_ms(3000);
        printf("low_task释放信号量\r\n");
        xSemaphoreGive(mutex_semphore_handle); 
        vTaskDelay(1000);
	}
}

void middle_task( void * pvParameters )
{
	while(1)
	{
		printf("middle_task正在运行!!!\r\n");
		vTaskDelay(1000);
	}
}

void high_task( void * pvParameters )
{
	while(1)
	{
		printf("high_task获取信号量\r\n");
        xSemaphoreTake(mutex_semphore_handle,portMAX_DELAY);
        printf("high_task正在运行!!!\r\n");
        delay_ms(1000);
        printf("high_task释放信号量\r\n");
        xSemaphoreGive(mutex_semphore_handle); 
        vTaskDelay(1000);
	}
}

/******************************************************************************************************/

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
	mutex_semphore_handle = xSemaphoreCreateMutex(); //创建互斥信号量,会自动释放一次信号量
	if(mutex_semphore_handle != NULL)
	{
		printf("互斥信号量创建成功!!!\r\n");
	}
	
    xTaskCreate(start_task, "start_task", START_TASK_STACK_SIZE, NULL, START_TASK_PRIO, &start_task_handler);
	vTaskStartScheduler();
}

void start_task( void * pvParameters )
{
	taskENTER_CRITICAL(); //进入临界区
	xTaskCreate(low_task, "low_task", TASK1_STACK_SIZE, NULL, TASK1_PRIO, &low_task_handler);
	xTaskCreate(middle_task, "middle_task", TASK2_STACK_SIZE, NULL, TASK2_PRIO, &middle_task_handler);
	xTaskCreate(high_task, "high_task", TASK3_STACK_SIZE, NULL, TASK3_PRIO, &high_task_handler);
    vTaskDelete(NULL);
	taskEXIT_CRITICAL(); //退出临界区
}

标签:13,task,handle,PRIO,void,信号量,include
From: https://www.cnblogs.com/mzx233/p/18102552

相关文章

  • L2-025 分而治之(与L2-013 红色警戒 差不多一模一样)
    原题链接题目:分而治之,各个击破是兵家常用的策略之一。在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破。为此参谋部提供了若干打击方案。本题就请你编写程序,判断每个方案的可行性。输入输出格式:输入在第一行给出两个正整数N......
  • 从CF1373D看最大子段和与奇偶段的分析
    Problem-1373D-Codeforces先看出了一个很显然的东西,逆转的子序列的长度必须是偶数。但之后就想错了,想到双指针和其他方法去求这个最大段。但我粗暴的通过\(a_{i+1}-a_i\)来贪心双指针明显是不对的。最大子段和只要把\(a_{i+1}-a_{i}\)转成一个数组\(b_i\)......
  • P1353 [USACO08JAN] Running S
    原题链接这道题让我对状态转移的理解更深题解1.对于任意一个点,不是在休息就是在锻炼,因此可以设\(dp[i][j]\)又因为疲劳值对答案也会有影响,或者说,当确定时间,决策,疲劳值时,所走过的路的最大值是可以确定的所以再加一维code#include<bits/stdc++.h>usingnamespacestd;int......
  • 【性能优化】 【回溯】 【字符串】1307. 口算难题
    作者推荐视频算法专题本文涉及知识点数学回溯字符串性能优化LeetCode1307.口算难题给你一个方程,左边用words表示,右边用result表示。你需要根据以下规则检查方程是否可解:每个字符都会被解码成一位数字(0-9)。每对不同的字符必须映射到不同的数字。每个word......
  • CF1392H ZS Shuffles Cards 题解
    题目传送门前置知识概率DP解法设\(f_{i}\)表示有\(i\)张数字牌没进入\(S\),即\(S\)中只有\(n-i\)张数字牌时的期望轮数,有\(f_{i}=\frac{i}{i+m}f_{i-1}+\frac{m}{i+m}(f_{i}+1)\),解得\(f_{i}=f_{i-1}+\frac{m}{i}\),边界为\(f_{0}=1\)。由于每一张数字牌在joke......
  • Ubuntu20.04安装openCV+contrib报错:fatal error: boostdesc_bgm.i: No such file or d
    把文件前面的数字去掉,改成boostdesc_bgm.i,不可用!!!!文件可能没有下载成功!!当时可能会编译成功,但是之后还是会报错下载缺少的相关依赖https://pan.baidu.com/s/17XhXX_cLz46bsj9ZWRkNIg提取码:p50x最好在本地解压后压缩成zip格式的,否则直接解压rar格式的会报错; 如果继续出现以......
  • 013、青溪
    013、青溪唐●王维言入黄花川,每逐青溪水。随山将万转,趣途无百里。声喧乱石中,色静深松里。漾漾泛菱荇,澄澄映葭苇。我心素已闲,清川澹如此。请留磐石上,垂钓将已矣。 【现代诗意译】青溪 我每次进入黄花川游玩,都要沿着青溪水前行。青溪随着山势弯曲转湾很多,可是距离......
  • 【前端面试题-13】目前主流的几种图片格式以及特性和使用场景
    目前主流的图片格式及其特性和使用场景包括:JPEG(.jpg):特性:JPEG是一种有损压缩格式,能够大幅度减少文件大小,但压缩过程中会有一定的图像质量损失。它支持渐进式显示,即先呈现低质量预览再逐渐加载高清晰度版本。使用场景:JPEG适用于需要较小文件尺寸的照片、网页图片、......
  • P1339 [USACO09OCT] Heat Wave G
    题解Dijkstra算法的应用,我这里采用了堆结构优化+反向索引堆优化最大化的优化了时间复杂度。题解区的复杂度是O(mlogm)而我优化后达到了O((n+m)logn)即复杂度和点的个数相关,而非边的条数。code #include<bits/stdc++.h>usingnamespacestd;constintN=6200*2+5;intn,m,s,t,......
  • 20231325贾罗祁 2023-2024-2《Python程序设计》实验二报告
    20231325贾罗祁2023-2024-2《Python程序设计》实验二报告课程:《Python程序设计》班级:2313姓名:贾罗祁学号:20231325实验教师:王志强实验日期:2024年3月27日必修/选修:公选课1.实验内容设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善;考核基本语法、判定......