1、 介绍互斥信号
①具有优先级继承
②创建时互斥信号量时默认开锁状态,而二值信号量刚创建时默认为信号量为空
③互斥信号量只有持有者才能释放
④互斥信号不能递归获取和递归释放,递归互斥量可以递归获取和递归释放。只有递归互斥量会使用uxRecursiveCallCount变量。
⑤互斥量不能在中断中使用。
⑥互斥锁用于实现对临界资源的独占式处理。
2、 创建任务和互斥信号量
static TaskHandle_t LowPriority_Task_Handle = NULL;
static TaskHandle_t MidPriority_Task_Handle = NULL;
static TaskHandle_t HighPriority_Task_Handle = NULL;
void m_create_mux_sem(void)
{
BaseType_t xReturn = pdPASS;
MuxSem_Handle = xSemaphoreCreateMutex();
if(NULL != MuxSem_Handle)
LOG_BLE("MuxSem_Handle ok\n");
xReturn = xSemaphoreGive( MuxSem_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");
}
}
3、 编写内存的测试任务入口函数
#ifndef TAG_BLE
#define LOG_BLE(...)
#endif
static SemaphoreHandle_t MuxSem_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(MuxSem_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( MuxSem_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(MuxSem_Handle, portMAX_DELAY);
//xSemaphoreTakeRecursive
if(pdTRUE == xReturn)
LOG_BLE("HighPriority_Task Runing\n");
TOGGLE_LED13();
LOG_BLE("HighPriority_Task give\n");
xReturn = xSemaphoreGive( MuxSem_Handle );
//xSemaphoreGiveRecursive
vTaskDelay(100);
}
}
实验说明和现象
①LowPriority_Task获取信号量后处于运行态。
②这时候HighPriority_Task延迟结束处于运行态时尝试获取信号量,获取失败后处于阻塞。
③LowPriority_Task的任务优先等级将提升为HighPriority_Task的任务优先等级。
④MidPriority_Task延迟结束处于运行态时。
⑤MidPriority_Task处理完后调用延迟,LowPriority_Task获得CPU后运行后释放二值信号量,HighPriority_Task最后运行。
在上一章实验中,多③步骤(优先级继承)。
HighPriority_Task获取信号量失败处于阻塞,MidPriority_Task处于就绪状态也不会获得CPU。