1.开发背景
FreeRTOS 提供了队列可以在线程间快速交换信息,那么还有没有其他交互渠道?答案是有的,相对于队列传递信息,还有更轻量级的线程唤醒操作,那就是信号量,而二值信号量就是最简单的一种。
二值信号量就是二进制的 0 和 1,或者是 bool 类型的 true 和 false,二值信号量代替了传统编程中的循环等待。
2.开发需求
设计实验:
1)接收线程一直等待信号量唤醒;
2)发送线程发送信号量;
3)按键中断发送信号量;
3.开发环境
window10 + MDK + STM32F429 + FreeRTOS10.3.1
4.实现步骤
4.1 实现编码
#include "appTest.h"#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include "mspDwt.h"
#include "mspGpio.h"
#include "mspExti.h"#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"#include "appLog.h"typedef struct
{/* 信号量 */SemaphoreHandle_t signal; // 队列句柄/* 创建任务 */TaskHandle_t taskRx; // 接收线程TaskHandle_t taskTx; // 发送线程}Ctrl_t;/* 文件指针 */
static Ctrl_t s_ctrl = {0};
static Ctrl_t *p = &s_ctrl;
static void TaskRx(void *pvParameters);
static void TaskTx(void *pvParameters);/* 接收线程 */
static void TaskRx(void *pvParameters)
{vTaskDelay(100);for ( ; ; ){xSemaphoreTake(p->signal, portMAX_DELAY);Log_Debug("%s 线程接收信号量\r\n", __func__);}
}/* 发送线程 */
static void TaskTx(void *pvParameters)
{vTaskDelay(1000);xSemaphoreGive(p->signal);Log_Debug("%s 线程发送信号量\r\n", __func__);for ( ; ; ){vTaskDelay(1000);}
}/* 测试初始化 */
void aTest_Init(void)
{/* 创建二值信号量 */p->signal = xSemaphoreCreateBinary();/* 创建动态任务 */xTaskCreate(TaskRx, "TaskRx", 500, NULL, 5, &p->taskRx);xTaskCreate(TaskTx, "TaskTx", 500, NULL, 5, &p->taskTx);
}/* Key2 PC13 Key0 PH3 Key1 PH2 */
void Exti13_TriggerInterrupt(void)
{mspExti_Close(13);if (mspGpio_GetInput("PC13") == 0){/* 队列发送数据 */BaseType_t xHigherPriorityTaskWoken;xSemaphoreGiveFromISR(p->signal, &xHigherPriorityTaskWoken);portYIELD_FROM_ISR(xHigherPriorityTaskWoken);Log_Debug("%s 中断发送信号量\r\n", __func__);}
}