25 freertos信号量-计数信号量

二十五、freertos信号量-计数信号量

/**
**************************************************************************************************/
#include <stdio.h>
#include "board.h"
#include "led.h"
#include "key.h"
#include "uart.h"
//#include "tim_mrt.h"


/*** System oscillator rate and clock rate on the CLKIN pin  ****/
/**/const uint32_t OscRateIn = MAIN_OSC_XTAL_FREQ_HZ;		 /**/
/**/const uint32_t ExtRateIn = EXT_CLOCK_IN_FREQ_HZ;		 /**/
 //系统复位
#define	System_restart	(LPC_SWM->PINENABLE0 = 0xffffffffUL) /**/
/***************************************************************/



#include "FreeRTOSConfig.h"
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"//事件头文件
#include "queue.h"//队列头文件
#include "semphr.h"//信号量头文件

#define TASK_STACK_SIZE 32//每个任务的栈大小
/**************************** 任务句柄 ********************************/
/* 
 * 任务句柄是一个指针,用于指向一个任务。
 */
static TaskHandle_t LED1_Task_Handle= NULL;	/* LED任务句柄 */	
static xTaskHandle KEY_Task_Handle = NULL;	
static xSemaphoreHandle CountSem_Handle=NULL;//信号量句柄
 		
 


/* Sets up system hardware 
**********************************************************************
  * @ 函数名  : BSP_Init
  * @ 功能说明: 板级外设初始化,所有板子上的初始化均可放在这个函数里面
  * @ 参数    :   
  * @ 返回值  : 无
*********************************************************************/
static void prvSetupHardware(void)
{

	SystemCoreClockUpdate();

	DEBUGINIT();
	led_Init() ;	
	Key_INIT();
//	MRT_Init();

	Board_UARTPutSTR("build date: " __DATE__ " build time: " __TIME__ "\n");

}


/**********************************************************************
  * @ 函数名  : vLED_Task0
  * @ 功能说明: LED_Task任务主体,
  * @ 参数    :   
  * @ 返回值  : 无
  ********************************************************************/

static void vLED1_Task (void *pvParameters)
{
	
	TickType_t xLastWakeTime;
	const TickType_t xFrequency = 500;
	/* 获取当前的系统时间 */
	xLastWakeTime = xTaskGetTickCount();
	 
	while (1) {
		
		Board_LED_Toggle(0);
		vTaskDelayUntil(&xLastWakeTime, xFrequency);

		
	}
}

/*
*********************************************************************************************************
*	函 数 名: vKEY_task
*	功能说明: 按键任务
*	形    参: pvParameters 是在创建该任务时传递的形参
*	返 回 值: 无
*   优 先 级: 1  (数值越小优先级越低,这个跟uCOS相反)
*********************************************************************************************************
*/
static void vKEY_task(void* pvParameters)
{

	BaseType_t xReturn = pdTRUE;
	uint8_t pcWriteBuffer[200];
	
	u8 key2=0;
	while(1)
	{
		u8 key=0;
		if(Scan_Key())
			vTaskDelay(20);
		else continue;
		if(!Scan_Key())continue;
		else
		{
			key=Scan_Key();
			key2=key;
		}
		
		while(Scan_Key()){};//等按键抬起

		if(key2)
		{

			switch(key2)
			{
				case 1:
				{
					printf("=================================================\r\n");
					printf("任务名      任务状态 优先级   剩余栈 任务序号\r\n");
					vTaskList((char *)&pcWriteBuffer);
					printf("%s\r\n", pcWriteBuffer);
				 
				}break;
				case 2:
				{
					 /* K2键按下 */
					printf("K2 键按下,获取信号量\r\n");
					xReturn = xSemaphoreTake(CountSem_Handle, /* 计数信号量句柄 */
												0); /* 等待时间: 0 */
					if ( pdTRUE == xReturn )
					{
						printf( "获取成功,成功申请到停车位。 \n" );
					}
					else
					{
						printf( "获取失败,不好意思,现在停车场已满! \n" );
					}
				}break;
				case 3:
				{
					 /* K3键按下*/
					
					
				}break;
				default:break;
			}
			key2=0;
		}
		

			
	}
}


/*
*********************************************************************************************************
*	函 数 名: vTaskMsgPro
*	功能说明: 使用函数  
*	形    参: pvParameters 是在创建该任务时传递的形参
*	返 回 值: 无
*   优 先 级: 3  
*********************************************************************************************************
*/
static void vTaskMsgPro(void *pvParameters)
{
	BaseType_t xReturn = pdTRUE;
	u8 key;

    while(1)
    {
			
		if(Scan_Key())
		{
			key=Scan_Key();
		}
		while(Scan_Key());
		if(3==key)
		{
			key=0;
			printf("K3 键按下,释放信号量\r\n");
			xReturn = xSemaphoreGive(CountSem_Handle);//给出计数信号量
			if ( pdTRUE == xReturn )
			{
				printf( "释放成功,释放1个停车位。 \n" );
			}
			else
			{
				printf( "释放失败,已无车位可以释放! \n" );
			}
			
		}
		vTaskDelay(20);
    }
}

/*
*********************************************************************************************************
*	函 数 名: AppObjCreate
*	功能说明: 创建任务通信机制
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
static void AppObjCreate (void)
{
	
	/* 初始化有5个可用资源,当前可用资源为5,*/
	CountSem_Handle = xSemaphoreCreateCounting(5,5);
	if(NULL != CountSem_Handle)
		DEBUGOUT("计数信号量创建成功 \n");
	else{}
		 
}
/***********************************************************************
  * @ 函数名  : AppTaskCreate
  * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
  * @ 参数    : 无  
  * @ 返回值  : 无
  **********************************************************************/
static void AppTaskCreate()
{
	BaseType_t xReturn=pdPASS;/*定义任务返回值*/
	
	taskENTER_CRITICAL();//进入临界区,禁止中断打断

 
	xReturn=xTaskCreate(vLED1_Task, 
						"vLED1_Task",
						TASK_STACK_SIZE*2, 
						NULL, 
						(tskIDLE_PRIORITY + 1UL),
						(TaskHandle_t *) &LED1_Task_Handle);

	xReturn=xTaskCreate(vKEY_task, 
						"vKEY_Task",
						TASK_STACK_SIZE*4, 
						NULL, 
						(tskIDLE_PRIORITY + 1UL),
						(TaskHandle_t *) &KEY_Task_Handle);
	
	xReturn=xTaskCreate(vTaskMsgPro, 
						"vTaskMsgPro",
						TASK_STACK_SIZE*5, 
						NULL, 
						(tskIDLE_PRIORITY + 1UL),
						NULL);
				
	if(pdPASS==xReturn)
	{
		printf("创建LED_Task任务成功\r\n");
	}	

	
	

	taskEXIT_CRITICAL(); //退出临界区
	

}

/**
 * @brief	main routine for blinky example
 * @return	Function should not exit.
 */
int main(void)
{
	
	prvSetupHardware();
	Board_UARTPutSTR("LPC824 FreeRTOS 任务管理\n\r");
	printf("车位默认值为 5 个,按下 KEY1 申请车位,按下 KEY2 释放车位!\r\n");

	AppTaskCreate();
	
	/* 创建任务通信机制 */
	AppObjCreate();
	
	vTaskStartScheduler();//任务调度

	
	
	/* Loop forever */
	while (1) {
			printf("FreeRTOS 运行失败\n\r");
 	}
	
	
}


计数信号量
在创建信号量的时候初始化 5 个可用的信号量,并且创建了两个任务:
一个是获取信号量任务,一个是释放信号量任务,两个任务独立运行,
获取信号量任务是通过
按下 KEY1 按键进行信号量的获取,模拟停车场停车操作,其等待时间是 0,在串口调试助手输出相应信息。
释放信号量任务则是信号量的释放,释放信号量任务也是通过
按下 KEY2 按键进行信号量的释放,模拟停车场取车操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值