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-