野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3567|回复: 0

[freertos] 野火STM32+FreeRTOS计数信号量的例程无法使计数信号量递增

[复制链接]
发表于 2020-2-2 21:42:29 | 显示全部楼层 |阅读模式
/*
*******************************************
*                                                                        包含的头文件
*******************************************
*/
//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();
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-3 10:01 , Processed in 0.054834 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表