15,FreeRTOS计数型信号量操作
一、实验目标
创建三个动态任务,栈空间大小均为128字。startTask、Task1、Task2。startTask仅运行一次,负责二值信号量的创建,task1、task2任务的创建,startTask任务的删除。Task1负责计数型信号量的释放操作。Task2负责计数型信号量的获取操作、计数值的获取,并用串口发送是否获取成功。
注:本实验基于正点原子FreeRTOS教程的学习总结。
二、实验准备
1.FreeRTOS的Keil动态任务创建与删除程序
2.STM3F407开发板
3.所需API函数介绍
使用的API函数主要有计数型信号量动态创建函数、计数值获取函数。信号量释放函数、信号量获取函数与二值信号量的相同,可以在上一章查看。
14,FreeRTOS二值信号量操作-CSDN博客https://blog.csdn.net/LC_8575/article/details/151149446?spm=1011.2124.3001.6209
计数型信号量动态创建函数xSemaphoreCreateCounting(),创建成功返回值为计数型信号量句柄。
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
计数型信号量计数值获取函数uxSemaphoreGetCount(),获取成功返回值为计数值。
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
4.信号量相关定义
首先在freertos_demo.c中添加头文件:
#include "semphr.h"
其次定义计数型信号量的句柄:
//计数型信号量定义
SemaphoreHandle_t Count_Semaphore_Handle;//定义计数型信号量句柄
三、代码编写
3.1修改start_task的任务函数内容
start_task实现计数型信号量创建、两个任务创建、start_task任务删除。
void start_task(void *pvParameters)
{taskENTER_CRITICAL(); /* 进入临界区 */Count_Semaphore_Handle = xSemaphoreCreateCounting(100,0);if(Count_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);vTaskDelete(StartTask_Handler); /* 删除开始任务 */taskEXIT_CRITICAL(); /* 退出临界区 */
}
3.2修改Task1的任务函数内容
Task1实现按键key0按下,释放计数型信号量。
/* task1 按键key0按下释放信号量 */
void task1(void *pvParameters)
{uint8_t key = 0;while(1){key = key_scan(0);if(key == KEY0_PRES && Count_Semaphore_Handle != NULL){xSemaphoreGive(Count_Semaphore_Handle);//按键0按下释放信号量}vTaskDelay(10);//相对延时}
}
3.3修改Task2的任务函数内容
Task2实现信号量的获取,并串口发送。
/* task2 获取信号量,成功打印信息 */
void task2(void *pvParameters)
{BaseType_t err;while(1){err = xSemaphoreTake(Count_Semaphore_Handle,portMAX_DELAY);if(err != pdPASS){printf("计数型信号量获取失败\r\n");}else printf("计数型信号量获取成功,计数值数为:%d\r\n",(int)uxSemaphoreGetCount(Count_Semaphore_Handle));vTaskDelay(1000);//相对延时}
}
四、实验现象
实验现象如下所示。可以看到系统初始化显示计数型信号量创建成功。按下key0释放信号量,获取成功后发送信息和计数值。