1、创建二值信号和创建3个任务,LowPriority_Task为最低优先级,HighPriority_Task为最高优先级。
注意:动态创建任务时要注意大小
static TaskHandle_t LowPriority_Task_Handle = NULL;
static TaskHandle_t MidPriority_Task_Handle = NULL;
static TaskHandle_t HighPriority_Task_Handle = NULL;
void m_create_priority_inversion(void)
{
BaseType_t xReturn = pdPASS;
BinarySem_Handle = xSemaphoreCreateBinary();
if(NULL != BinarySem_Handle)
{
LOG_BLE("BinarySem_Handle ok\r\n");
}
xSemaphoreGive( BinarySem_Handle );
xReturn = xTaskCreate((TaskFunction_t )LowPriority_Task,
(const char* )"LowPriority_Task",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )2,
(TaskHandle_t* )&LowPriority_Task_Handle);
if(pdPASS == xReturn)
{
LOG_BLE("low ok\r\n");
}
xReturn = xTaskCreate((TaskFunction_t )MidPriority_Task,
(const char* )"MidPriority_Task",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )3,
(TaskHandle_t* )&MidPriority_Task_Handle);
if(pdPASS == xReturn)
{
LOG_BLE("min ok\r\n");
}
xReturn = xTaskCreate((TaskFunction_t )HighPriority_Task,
(const char* )"HighPriority_Task",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )4,
(TaskHandle_t* )&HighPriority_Task_Handle);
if(pdPASS == xReturn)
{
LOG_BLE("high ok\r\n");
}
}
2、 编写内存的测试任务入口函数
#include "semphr.h"
#ifndef TAG_BLE
#define LOG_BLE(...)
#endif
static SemaphoreHandle_t BinarySem_Handle =NULL;
static void LowPriority_Task(void* parameter)
{
static uint32_t i;
BaseType_t xReturn = pdPASS;
while (1)
{
LOG_BLE("LowPriority_Task take\n");
xReturn = xSemaphoreTake(BinarySem_Handle,portMAX_DELAY);
if( xReturn == pdTRUE )
{
LOG_BLE("LowPriority_Task Runing\n");
}
for(i=0; i<200000; i++)
{
taskYIELD();
}
LOG_BLE("LowPriority_Task give\r\n");
xReturn = xSemaphoreGive( BinarySem_Handle );
TOGGLE_LED13();
vTaskDelay(500);
}
}
static void MidPriority_Task(void* parameter)
{
while (1)
{
LOG_BLE("MidPriority_Task Runing\n");
vTaskDelay(100);
}
}
static void HighPriority_Task(void* parameter)
{
BaseType_t xReturn = pdTRUE;
while (1)
{
LOG_BLE("HighPriority_Task take\n");
xReturn = xSemaphoreTake(BinarySem_Handle,
portMAX_DELAY);
if(pdTRUE == xReturn)
LOG_BLE("HighPriority_Task Runing\n");
TOGGLE_LED13();
LOG_BLE("HighPriority_Task give\n");
xReturn = xSemaphoreGive( BinarySem_Handle );
vTaskDelay(100);
}
}
实验说明和现象
①LowPriority_Task获取信号量后处于运行态。
②这时候HighPriority_Task延迟结束处于运行态时尝试获取信号量,获取失败后处于阻塞。
③MidPriority_Task延迟结束处于运行态时。
④MidPriority_Task处理完后调用延迟,LowPriority_Task获得CPU后运行后释放二值信号量,HighPriority_Task最后运行。
理论HighPriority_Task任务处于就绪态时,MidPriority_Task是不应该处于运行态。
下一章互斥信号量可以减轻优先级反转的危害。