前言
信号量常用于控制对共享资源的访问和任务同步。
信号量说的直白一点就是:计数器。
比如我们去一个公共电话,我们知道电话的两种状态:使用和未使用状态。如果用电话的两个状态作为信号量的话,那么这个就是二值信号量。
信号量用于控制共享资源访问的场景相当于一个上锁机制,代码只有获得了这个锁的钥匙才能够执行。
信号量还有一个重要的运用场合就是任务同步,用于任务于任务或中断于任务之间的同步。
一、创建二值信号量
注意:二值信号量是基于队列的基础实现的,这个队列的长度为1,队列项长度为0.这个队列是没有存储区的队列,是通过使用队列是否为空来表示二值信号量。
新版本的的二值信号量创建函数创建的二值信号量默认是无效的。
二、释放信号量
三、获取信号量
四、二值信号量操作实验
本实验是利用串口接收数据产生中断,从而产生释放一个二值信号量,这个二值信号量由一个任务去获取。若没有这个二值信号量,就代表串口没有接收到消息,没有触发串口接收中断。在接收二值信号量的任务中获取二值信号量的方式是:阻塞一个最大时间,如果超过这个规定阻塞时间,则该任务让出CPU的控制权。
【注意:由于串口中断里面运用到了freeRTOS的API,所以串口中断的抢占优先级的值需要大于5,我是把他设置为7.】
代码具体如下:
main.c
#include "sys.h"
#include "usart.h"
#include "led.h"
#include "delay.h"
#include "FreeRTOS.h"
#include "semphr.h"//信号量的头文件
#include "task.h"
/*
本次实验通过二值信号来完成中断程序与任务之间的同步。
我们设计一个:通过串口发送指定的指令来控制开发板上的LED1 和 LED2的开关实验。
串口发送: 1 -> led1on
2 -> led1off
3 -> led2on
4 -> led2off
这些指令通过串口发送给开发板,开发板使用中断接收,
当接收到数据以后就释放二值信号,任务DataProcess_task
用来处理这些指令,改任务会一直获取二值信号量,当获取到信号量就
会从串口接收缓冲区中提取这些指令,然后根据指令控制相应的外设。
*/
#define start_task_size 52
#define start_task_pro 1
TaskHandle_t startTask_handler;
void start_task(void *pram);
#define task1_size 256
#define task1_pro 2
TaskHandle_t Task1_handler;
void task1(void *pram);
#define DataPrecess_size 256
#define DataPrecess_pro 3
TaskHandle_t DataPrecess_handler;
void DataPrecess_task(void *pram);
//extern uint8_t RxBuff[128];
extern uint8_t Rx;
//uint8_t CommendPrecess(char * str);
//信号量句柄
SemaphoreHandle_t TaskToIrqSemaphore;
//SemaphoreHandle_t TaskToTaskSema