FreeRtos(3)-----二值信号量

freeRTOS实时操作系统移植
FreeRtos(1)-----任务创建与管理
FreeRtos(2)-----消息队列
以上是历史FreeRtos博客。FreeRtos系列我会坚持更下去

二值信号量

其实简单点二值信号量就像Linux里面的进程同步,也就是说一个进程需要另一个进程的运行结果才能运行。

二值信号量API

头文件:#include "semphr.h"
二值信号量的创建

SemaphoreHandle_t  xSemaphoreCreateBinary();
参数:无
返回值:创建成功返回一个二值信号量的句柄

xSemaphoreCreateBinary()用于创建一个二值信号量,并返回一个句柄。其实二值信号量和互斥量都共同使用一个类型 SemaphoreHandle_t 的句柄,该句柄的原型是一个 void 型 的指针。使用该函数创建的二值信号量是空的,在使用函数 xSemaphoreTake()获取之前必 须先调用函数 xSemaphoreGive() 释放后才可以获取。如果是使用老式的函数 vSemaphoreCreateBinary()创建的二值信号量,则为 1,在使用之前不用先释放。要想使用 该函数必须在 FreeRTOSConfig.h 中把宏 configSUPPORT_DYNAMIC_ALLOCATION 定义为1

二值信号量的获取

xSemaphoreTake( xSemaphore, xBlockTime )
参数:
	xSemaphore:二值信号量句柄
	xBlockTime: portMAX_DELAY 既没有申请到资源阻塞,申请到立马返回
返回值:成功返回pdPASS			

二值信号量的释放

xSemaphoreGive(SemaphoreHandle_t xSemaphore )
参数:
	xSemaphore :二值信号量句柄
返回值:成功返回pdPASS	

信号量的删除
注意:

无论是二值信号量还是计数信号量,删除函数都是这个

void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )
参数: xSemaphore 二值信号量句柄

示例

创建两个任务,任务A阻塞.任务B循环10次输出a,b,c
然后释放信号量,解除任务A阻塞

#include "stm32f10x.h"
#include "led.h"
#include "stdio.h"
#include "usart1.h"
#include "systick.h"
#include "delay.h"
#include "my_key.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

#define QUEUE_LEN 8
#define QUEUE_SIZE 8
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 创建任务句柄 */
static TaskHandle_t server_Task_Handle = NULL;/* server 任务句柄 */
static TaskHandle_t client_Task_Handle = NULL;/* client 任务句柄 */
static void AppTaskCreate(void);/* 用于创建任务 */
static void server_Task(void* pvParameters);
static void client_Task(void* pvParameters);

SemaphoreHandle_t BinarySem_Handle =NULL;//二值信号量句柄

int main(void)
{
 BaseType_t xReturn = pdPASS;//创建任务返回值
 NVIC_SetPriorityGrouping(3);
 usrat1_config();
 systick_config();
 key_init();
 led_config();
 printf("hello\r\n");

 //创建任务
 /* 创建 AppTaskCreate 任务 */
  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,/* 任务入口函数 */
												(const char *)"AppTaskCreate",/* 任务名字 */
												(uint16_t )512,
												(void *)NULL,
												(UBaseType_t )1,
												(TaskHandle_t* )&AppTaskCreate_Handle);/* 任务控制块指针 */
	
 /* 启动任务调度 */
	if (pdPASS == xReturn) 
	{
	  vTaskStartScheduler(); 
	}
	else 
	{
	return -1; 
	}
	 
 while (1); /* 正常不会执行到这里 */
}
static void AppTaskCreate(void)
{
 BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
 taskENTER_CRITICAL();
	BinarySem_Handle=xSemaphoreCreateBinary();
 xReturn = xTaskCreate((TaskFunction_t )server_Task,/* 任务入口函数 */
												(const char *)"server_Task",/* 任务名字 */
												(uint16_t )128,
												(void *)NULL,
												(UBaseType_t )2,
												(TaskHandle_t* )&server_Task_Handle);/* 任务控制块指针 */
 if(pdPASS == xReturn)
 {
	printf("任务创建成功\r\n");
 }
 
  xReturn = xTaskCreate((TaskFunction_t )client_Task,/* 任务入口函数 */
												(const char *)"client_Task",/* 任务名字 */
												(uint16_t )128,
												(void *)NULL,
												(UBaseType_t )2,
												(TaskHandle_t* )&client_Task_Handle);/* 任务控制块指针 */
 if(pdPASS == xReturn)
 {
	printf("任务创建成功\r\n");
 }
 
vTaskDelete(AppTaskCreate_Handle); //删除 AppTaskCreate 任务 
taskEXIT_CRITICAL();//退出临界区

}
//定义一个任务
static void server_Task(void* parameter)
{

 while(1)
 {
	xSemaphoreTake(BinarySem_Handle,portMAX_DELAY);
	printf("1\r\n");
	printf("2\r\n");
	printf("3\r\n");
	
 }
}
static void client_Task(void* parameter)
{
 int n=10;
 while(n--)
 {
	
	printf("a\r\n");
	printf("b\r\n");
	printf("c\r\n");
 }
 xSemaphoreGive(BinarySem_Handle);
 while(1);//防止任务凋亡
}

实验结果:
在这里插入图片描述
-END-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值