FreeRTOS【11】递归互斥锁使用

1.开发背景

       基于上一个篇章,解释了 FreeRTOS 的互斥锁,可以看出互斥锁是可以保护资源访问的完整性,但是,随着代码的复杂程度提高,有可能存在代码段递归的情况,这样就有可能会出现多次上锁的情况,而 FreeRTOS 提供了递归上锁的操作,即一个锁可以在一个线程中多次上锁,只有解锁同等次数才能真正解锁。

        实际上,递归互斥锁是互斥锁的一种特殊形态,类似计数信号量和二值信号量的关系,当然,递归互斥锁拥有和互斥锁相同的特性,那就是优先级继承。

2.开发需求

        设计实验:

        1)创建 2 个线程

        2)其中一个线程多次上锁后解锁同等次数

        3)另一个线程等待多次解锁完成

3.开发环境

        window10 + MDK + STM32F429 + FreeRTOS10.3.1

4.实现步骤

4.1 实现编码

#include "appTest.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "mspDwt.h"
#include "mspGpio.h"
#include "mspExti.h"

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

#include "appLog.h"

typedef struct
{
    /* 信号量 */
    SemaphoreHandle_t lock;     // 信号锁
    
    /* 创建任务 */
    TaskHandle_t taskCtrl;
    TaskHandle_t taskLow;       // 低优先级线程
    TaskHandle_t taskHigh;      // 高优先级线程
    
}Ctrl_t;

/* 文件指针 */
static Ctrl_t s_ctrl = {0};
static Ctrl_t *p = &s_ctrl;
static void TaskCtrl(void *pvParameters);
static void TaskLow(void *pvParameters);
static void TaskHigh(void *pvParameters);

static void TaskCtrl(void *pvParameters)
{
    for ( ; ; )
    {
        vTaskDelay(1000);
        
    }
}

/* 接收线程 */
static void TaskLow(void *pvParameters)
{
    vTaskDelay(100);
    
    for ( ; ; )
    {
        Log_Debug("%s 准备取锁\r\n", __func__);
        xSemaphoreTakeRecursive(p->lock, portMAX_DELAY);
        Log_Debug("%s 获取到递归锁\r\n", __func__);
        
        vTaskDelay(1000);
        xSemaphoreGiveRecursive(p->lock);
    }
}

/* 发送线程 */
static void TaskHigh(void *pvParameters)
{
    vTaskDelay(100);
    
    #define COUNT_MAX_NUM   (5)
    int count = 1;
    
    for ( ; ; )
    {
        xSemaphoreTakeRecursive(p->lock, portMAX_DELAY);
        Log_Debug("%s 获取到递归锁[%d]\r\n", __func__, count);
        
        if (count < COUNT_MAX_NUM)
        {
            vTaskDelay(1000);
            count++;
            continue;
        }
        
        /* 释放所有已获取的锁 */
        while (count > 0)
        {
            Log_Debug("%s 释放递归锁[%d]\r\n", __func__, count);
            xSemaphoreGiveRecursive(p->lock);
            vTaskDelay(1000);
            count--;
        }
        
        /* 挂起线程自身 */
        vTaskSuspend(NULL);
    }
}

/* 测试初始化 */
void aTest_Init(void)
{
    /* 创建信号锁 */
    p->lock = xSemaphoreCreateRecursiveMutex();
    
    /* 创建动态任务 */
    xTaskCreate(TaskCtrl, "TaskCtrl",  500, NULL, 4, &p->taskCtrl);
    xTaskCreate(TaskLow,  "TaskLow",   500, NULL, 4, &p->taskLow);
    xTaskCreate(TaskHigh, "TaskHigh",  500, NULL, 5, &p->taskHigh);
}

/* Key2 PC13   Key0 PH3 Key1 PH2 */
void Exti13_TriggerInterrupt(void)
{
    mspExti_Close(13);
    
    if (mspGpio_GetInput("PC13") == 0)
    {
    }
}

4.2 结果显示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值