高中生
最后登录1970-1-1
在线时间 小时
注册时间2019-8-12
|
/*
*******************************************
* 包含的头文件
*******************************************
*/
//FreeRTOS头文件
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
//STM32F103外围硬件的头文件均定义在global.h中
#include "global.h"
/****************************任务句柄**********************/
/*
*任务句柄是一个指针,用于指向一个任务,当任务创建好之后,
*它就具有了一个任务句柄,如果是自身的任务操作自己,那么
*这个句柄就可以为NULL
*
*/
//创建任务句柄
static TaskHandle_t AppTaskCreateHandle = NULL;
// LED
static TaskHandle_t RedLedTaskHandle = NULL;
static TaskHandle_t YellowLedTaskHandle = NULL;
// KEY
static TaskHandle_t KeyTaskHandle = NULL;
//发送和接收任务句柄
static TaskHandle_t ReceiveQueueTaskHandle = NULL;
static TaskHandle_t SendQueueTaskHandle = NULL;
static TaskHandle_t ReceiveBinarySemaphoreTaskHandle = NULL;
static TaskHandle_t SendBinarySemaphoreTaskHandle = NULL;
static TaskHandle_t TakeCountSemaphoreTaskHandle = NULL;//获取计数信号量任务句柄
static TaskHandle_t GiveCountSemaphoreTaskHandle = NULL;//释放计数信号量任务句柄
/**********************内核对象句柄*******************/
/*
*信号量,消息队列,事件标志组,软件定时器这些都属
*于内核的对象,要想使用这些内核对象,必须先创建,
*创建成功之后会返回一个相应的句柄。实际上就是一个
*指针
*
*
*
*内核对象是一种全局的数据结构,通过这些数据结构可以
*实现任务间的通信,任务间的事件同步等各种功能。至于
*这些功能的实现我们是通过调用这些内核对象的函数
* 来完成的
*
*
*
*/
QueueHandle_t TestQueueHandle;
SemaphoreHandle_t BinarySemaphoreHandle = NULL;//二值信号量
SemaphoreHandle_t CountSemaphoreHandle = NULL;//计数信号量
/*********************全局变量声明*****************/
/************************宏定义********************/
#define QUEUE_LEN 4//队列的长度,最大可包含多少个消息
#define QUEUE_SIZE 4//队列中每个消息大小
/*
*******************************************
* 函数声明
*******************************************
*/
static void AppTaskCreate(void);//用于创建任务
static void RedLedTask(void *pvParameters);
static void YellowLedTask(void *pvParameters);
static void KeyTask(void *pvParameters);
static void ReceiveQueueTask(void *pvParameters);//接收消息队列任务
static void SendQueueTask(void *pvParameters);//发送消息队列任务
static void ReceiveBinarySemaphoreTask(void *pvParameters);//接收二值信号量任务
static void SendBinarySemaphoreTask(void *pvParameters);//发送二值信号量任务
static void TakeCountSemaphoreTask(void *pvParameters);//获取计数信号量任务
static void GiveCountSemaphoreTask(void *pvParameters);//释放计数信号量任务
static void BspInit(void);//初始化板载STM32F103外设硬件
int main(void)
{
BaseType_t xReturn = pdPASS;//定义一个创建信息返回值,默认为 pdPASS
BspInit();
printf("FreeRTOSTask\r\n");
printf("Please send queue message by press KEY2 or KEY_UP\n");
printf("ReceiveTask receive message echo in USART\n\n");
xReturn = xTaskCreate((TaskFunction_t)AppTaskCreate,//任务入口函数
(const char* )"AppTaskCreate",//函数名字
(uint16_t )512,//任务栈入口大小
(void* )NULL,//任务入口函数参数
(UBaseType_t )1,//任务的优先级
(TaskHandle_t* )&AppTaskCreateHandle);//任务控制块指针
//启动任务调度
if(pdPASS == xReturn)
{
vTaskStartScheduler();//启动任务,开始调度
}
else
{
return -1;
}
while(1);//正常不会执行到这里
}
/*
*@brief:为了方便管理,所有的任务创建函数都放在这个函数里面
*@function:AppTaskCreate
*@param:none
*@retval:none
*/
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdPASS;//定义一个创建信息返回值默认为pdPASS
taskENTER_CRITICAL();//进入临界区
//消息队列创建
TestQueueHandle = xQueueCreate((UBaseType_t)QUEUE_LEN,//消息队列的长度
(UBaseType_t)QUEUE_SIZE);//消息队列的大小
if(NULL != TestQueueHandle)
{
printf("Create TestQueueHandle Success!\n");
}
//创建二值信号量BinarySemaphore
BinarySemaphoreHandle = xSemaphoreCreateBinary();
if(NULL != BinarySemaphoreHandle)
{
printf("BinarySemaphoreHandle create success!\n");
}
//创建计数信号量
CountSemaphoreHandle = xSemaphoreCreateCounting(5,5);//最大5个信号量,默认5个信号量
if(NULL != CountSemaphoreHandle)
{
printf("CountSemaphoreHandle create success!\n");
}
//创建TakeCountSemaphoreTask任务,获取计数信号量
xReturn = xTaskCreate((TaskFunction_t )TakeCountSemaphoreTask,//任务入口函数
(const char* )"TakeCountSemaphoreTask",//任务名
(uint16_t )512,//任务栈大小
(void* )NULL,//任务入口函数参数
(UBaseType_t )3,//任务的优先级,获取的优先级低于计数的优先级
(TaskHandle_t* )&TakeCountSemaphoreTaskHandle);//任务控制块指针
if(pdPASS == xReturn)
{
printf("Create TakeCountSemaphoreTask Success!\n");//
}
//创建GiveCountSemaphoreTask任务,释放计数信号量
xReturn = xTaskCreate((TaskFunction_t )GiveCountSemaphoreTask,
(const char* )"GiveCountSemaphoreTask",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )2,
(TaskHandle_t* )&GiveCountSemaphoreTaskHandle);
if(pdPASS == xReturn)
{
printf("Create GiveCountSemaphoreTask Success!\n\n");
}
vTaskDelete(AppTaskCreateHandle);//删除AppTaskCreate任务
taskEXIT_CRITICAL();//退出临界区
}
/*
*@brief:获取计数信号量
*@function:
*@param:none
*@retval:none
*/
static void TakeCountSemaphoreTask(void *parameter)
{
BaseType_t xReturn = pdTRUE;//定义一个创建信息返回值,默认为 pdTRUE
while(1)
{
if(KeyScan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY012_ON)
{
xReturn = xSemaphoreTake(CountSemaphoreHandle,//内核计数信号量句柄
0);//等待时间 0
}
if(pdTRUE == xReturn)
{
printf("KEY2 was pressed,allocate success!\n\n");
}
else
{
printf("KEY2 was pressed,but allocate none!\n\n");
}
vTaskDelay(100);//延时100个tick,串口打印更稳定
}
}
/*
*@brief:释放信号量
*@function:
*@param:none
*@retval:none
*/
static void GiveCountSemaphoreTask(void *parameter)
{
BaseType_t xReturn = pdTRUE;//定义一个创建信息返回值,默认为 pdTRUE
while(1)
{
if(KeyScan(KEY_UP_GPIO_PORT,KEY_UP_GPIO_PIN) == KEY_UP_ON)
{
//KEY_UP被按下
xReturn = xSemaphoreGive(CountSemaphoreHandle);//内核计数信号量句柄
if(xReturn == pdTRUE)
{
printf("KEY_UP was pressed,free 1 allocate!\n\n");
}
else
{
printf("KEY_UP was pressed,but no allocate!\n\n");
}
}
vTaskDelay(100);//延时100个tick,串口打印更稳定
}
}
/*
*@brief:板级支持包,初始化STM32F103外围硬件
*@function:BspInit
*@param:none
*@retval:none
*/
static void BspInit()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置NVIC中断优先级分组,2位抢占优先级和2位响应优先级
LedGpioConfig();
UsartConfig();
KeyConfig();
}
|
|