数xSemaphoreTake的阻塞设置流程

2021-10-08 11:45:15 浏览数 (1)

将获取信号量函数xSemaphoreTake的阻塞时间改为0,也就是没获取到信号量,立即返回。

代码语言:javascript复制
void vTask01_Code(void *para)
{
    static unsigned int cnt = 0;
    BaseType_t err = pdTRUE;
    for (;;)
    {
        xSemaphoreTake(BinarySemaphore, 0);
        PRINT(" task01 cnt %u...", cnt  );
        vTaskDelay(500);
    }
}

编译,运行:

代码语言:javascript复制
$ ./build/freertos-simulator 
 task01 cnt 0...
 task00 cnt 0...
 task01 cnt 1...
 task01 cnt 2...
 task01 cnt 3...
 task01 cnt 4...
 task00 cnt 1...

可以看出,任务task01不会等待信号量,而是继续执行。

9.1.4 优先级反转

使用二值信号量会出现优先级反转的问题,优先级反转在可剥夺内核中是常见的,但在实时系统中不允许出现这种现象。

上述图中,高任务H会晚于低优先级任务M执行,这就发生了优先级反转。

优先级反转实验设计:

实验设计:创建三个任务,高优先级任务获取二值信号量,获取成功后进行相应的处理,处理完之后释放信号量;中优先级任务简单运行;低优先级任务和高优先级任务一样,会获取二值信号量,获取成功后进行相应处理。

测试代码:

代码语言:javascript复制
configSTACK_DEPTH_TYPE TaskLow_STACK_SIZE = 5;
UBaseType_t  TaskLow_Priority = 2;
TaskHandle_t TaskLow_xHandle;

configSTACK_DEPTH_TYPE TaskMiddle_STACK_SIZE = 5;
UBaseType_t  TaskMiddle_Priority = 3;
TaskHandle_t TaskMiddle_xHandle;

configSTACK_DEPTH_TYPE TaskHigh_STACK_SIZE = 5;
UBaseType_t  TaskHigh_Priority = 4;
TaskHandle_t TaskHigh_xHandle;


//二值信号量
SemaphoreHandle_t BinarySemaphore;

void vTaskLow_Code(void *para)
{
    static unsigned int times = 0;
    BaseType_t err = pdTRUE;
    for (;;)
    {
        xSemaphoreTake(BinarySemaphore, portMAX_DELAY);
        PRINT(" low task running");
        for (times = 0; times < 20000000; times  )
            taskYIELD();
        err = xSemaphoreGive(BinarySemaphore);
        if (err != pdTRUE)
            PRINT("BinarySemaphore give failed!");
        vTaskDelay(1000);
    }
}

void vTaskMiddle_Code(void *para)
{
    for (;;)
    {
        PRINT(" task middle running");
        vTaskDelay(1000);
    }
}

void vTaskHigh_Code(void *para)
{
    for (;;)
    {
        vTaskDelay(500);
        PRINT(" task high Pend Sem");
        xSemaphoreTake(BinarySemaphore, portMAX_DELAY);
        PRINT(" task high running!");
        xSemaphoreGive(BinarySemaphore);
        vTaskDelay(500);
    }
}


void test_BinarySemaphore()
{
    taskENTER_CRITICAL();
    BinarySemaphore = xSemaphoreCreateBinary();
    if (BinarySemaphore != NULL)
        xSemaphoreGive(BinarySemaphore);
    
    if (xTaskCreate(vTaskLow_Code, "taskLow task", 
        TaskLow_STACK_SIZE, NULL, TaskLow_Priority,
        &TaskLow_xHandle) != pdPASS)
    {
        PRINT("creat taskLow failed!n");
    }
    
    if (xTaskCreate(vTaskMiddle_Code, "taskMiddle task", 
        TaskMiddle_STACK_SIZE, NULL, TaskMiddle_Priority,
        &TaskMiddle_xHandle) != pdPASS)
    {
        PRINT("creat taskMiddle failed!n");
    }

    if (xTaskCreate(vTaskHigh_Code, "taskHigh task", 
        TaskHigh_STACK_SIZE, NULL, TaskHigh_Priority,
        &TaskHigh_xHandle) != pdPASS)
    {
        PRINT("creat taskHigh failed!n");
    }
    taskEXIT_CRITICAL();
}


void creat_task(void)
{
    test_BinarySemaphore();
}

0 人点赞