文章目錄
- 一、基礎知識點
- 二、代碼講解
- 三、結果演示
- 四、代碼下載
一、基礎知識點
[FreeRTOS 基礎知識] 互斥量 概念
[FreeRTOS 內部實現] 互斥量
本實驗是基于STM32F103開發移植FreeRTOS實時操作系統,互斥量實戰操作。
使用工具:Keil、串口工具
二、代碼講解
1、使用xSemaphoreCreateMutex函數創建信號量
// 路徑:項目\Core\Src\freertos.c
// 全局變量
SemaphoreHandle_t g_Semaphore_Mutex;
g_Semaphore_Mutex= xSemaphoreCreateBinary( );
2、使用osThreadCreate創建任務
創建兩個任務優先級不同。
// 路徑:項目\Core\Src\freertos.c
// 全局變量
osThreadId Sender1_Handle;
osThreadId Seceiver_Handle;if ( g_Semaphore != NULL )
{// 創建兩個任務osThreadDef(Sender1, vSendTask, osPriorityHigh, 0, 1000);Sender1_Handle = osThreadCreate(osThread(Sender1), NULL);if( Sender1_Handle != NULL ){printf("Succeeded in creating Sender1_Handle Queue. Procedure!\n\r");}else{printf("Fail in creating Sender1_Handle Queue. Procedure!\n\r");}osThreadDef(Seceiver, vSeceiverTask, osPriorityNormal, 0, 1000);Seceiver_Handle = osThreadCreate(osThread(Seceiver), NULL); if( Seceiver_Handle != NULL ){printf("Succeeded in creating Seceiver_Handle Queue. Procedure!\n\r");}else{printf("Fail in creating Seceiver_Handle Queue. Procedure!\n\r");}
}
函數中通過osThreadDef 宏構建osThreadDef_t 結構體,名稱os_thread_def_##name(## 表示字符拼接),結構體成員包括 :#name 任務名稱;thread 任務處理函數;priority 任務優先級;instances 實例; stacksz 棧大小;
#define osThreadDef(name, thread, priority, instances, stacksz) \
const osThreadDef_t os_thread_def_##name = \
{ #name, (thread), (priority), (instances), (stacksz), NULL, NULL }
將構建的osThreadDef_t 結構體傳入osThreadCreate函數中,實際調用xTaskCreate函數創建任務。
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument)
{TaskHandle_t handle;if (xTaskCreate((TaskFunction_t)thread_def->pthread,(const portCHAR *)thread_def->name,thread_def->stacksize, argument, makeFreeRtosPriority(thread_def->tpriority),&handle) != pdPASS) {return NULL;} return handle;
}
3、Sender1 任務函數vSendTask 實現
void vSendTask(void const * argument)
{/* USER CODE BEGIN StartDefaultTask */int32_t i;/* Infinite loop */for(;;){/* 獲得互斥量: 上鎖 */xSemaphoreTake(g_Semaphore_Mutex, portMAX_DELAY);for (i = 0; i < 26; i++)printf("vSendTask ---- %d", i);printf("\r\n"); /* 釋放互斥量: 開鎖 */xSemaphoreGive(g_Semaphore_Mutex);vTaskDelay(pdMS_TO_TICKS(250)); // 延時250ms} /* USER CODE END StartDefaultTask */
}
4、Seceiver任務函數 vSeceiverTask實現
void vSeceiverTask(void const * argument)
{/* USER CODE BEGIN StartDefaultTask */int32_t i;/* Infinite loop */for(;;){/* 獲得互斥量: 上鎖 */xSemaphoreTake(g_Semaphore_Mutex, portMAX_DELAY);for (i = 0; i < 34; i++)printf("vSeceiverTask ---- %d", i);printf("\r\n"); /* 釋放互斥量: 開鎖 */xSemaphoreGive(g_Semaphore_Mutex);vTaskDelay(pdMS_TO_TICKS(300)); // 延時300ms}
}
三、結果演示
如下圖演示結果發現,兩個任務雖然優先級不同,但沒有發現有搶占的現象。若低優先級獲取到互斥鎖沒有釋放之前,高優先級任務獲取互斥鎖失敗后會提高低優先級的任務,等低優先級釋放鎖之后,高優先級才能獲取到鎖運行。
四、代碼下載
[FreeRTOS] 互斥量 功能應用