14,FreeRTOS二值信号量操作
一、实验目标
创建三个动态任务,栈空间大小均为128字。startTask、Task1、Task2。startTask仅运行一次,负责二值信号量的创建,task1、task2任务的创建,startTask任务的删除。Task1负责二值信号量的释放操作。Task2负责二值信号量的获取操作,并用串口发送是否获取成功。
注:本实验基于正点原子FreeRTOS教程的学习总结。
二、实验准备
1.FreeRTOS的Keil动态任务创建与删除程序
2.STM3F407开发板
3.所需API函数介绍
使用的API函数主要有二值信号量动态创建函数、信号量释放函数、信号量获取函数。
二值信号量动态创建函数xSemaphoreCreateBinary(),创建成果返回值为二值信号量句柄。
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
信号量释放函数xSemaphoreGive(),输入值为信号量句柄,释放成功返回pdTRUE。
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
信号量获取函数xSemaphoreTake(),输入值为信号量句柄,阻塞时间。获取成功返回pdPASS。
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
4.信号量相关定义
首先在freertos_demo.c中添加头文件:
#include "semphr.h"
其次定义二值信号量的句柄:
//二值信号量定义
SemaphoreHandle_t xBinarySemaphore;//定义二值信号量句柄
三、代码编写
3.1修改Task1的任务函数内容
Task1实现按键key0按下,释放二值信号量。
/* task1 按键key0按下释放二值信号量 */
void task1(void *pvParameters)
{uint8_t key = 0;BaseType_t err = 0;while(1){key = key_scan(0);if(key == KEY0_PRES && xBinarySemaphore != NULL){err = xSemaphoreGive(xBinarySemaphore);if(err != pdPASS){printf("xBinarySemaphore二值信号量释放失败\r\n");}elseprintf("xBinarySemaphore二值信号量释放成功\r\n");}vTaskDelay(10);//相对延时}
}
3.2修改Task2的任务函数内容
Task2实现信号量的获取,并串口发送。
/* task2 获取信号量,成功打印信息 */
void task2(void *pvParameters)
{BaseType_t err;uint8_t i = 0;while(1){err = xSemaphoreTake(xBinarySemaphore,portMAX_DELAY);if(err != pdPASS){printf("xBinarySemaphore二值信号量获取失败\r\n");}else printf("xBinarySemaphore二值信号量获取成功,次数:%d\r\n",++i);}
}
四、实验现象
实验现象如下所示。可以看到系统初始化显示二值信号量创建成功。按下key0释放信号量,获取成功后发送信息。