生活随笔
收集整理的這篇文章主要介紹了
FreeRTOS学习笔记——互斥型信号量
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
來自:http://blog.csdn.net/xukai871105/article/details/43456985
0.前言
? ? 在嵌入式操作系統中互斥型信號量是任務間資源保護的重要手段。下面結合一個具體例子說明FreeRTOS中的互斥型信號量如何使用。
? ? 【相關博文】
? ? 【FreeRTOS STM32移植筆記
】 【FreeRTOS學習筆記——任務間使用隊列同步數據】 【FreeRTOS學習筆記——二值型信號量】 【如何在FreeRTOS下實現低功耗——MSP430F5438平臺】 【代碼鏈接】——示例代碼存于百度網盤
1.基本說明
互斥型信號量的使用方法如圖1所示。在多數情況下,互斥型信號量和二值型信號非常相似,但是從功能上二值型信號量用于同步,而互斥型信號量用于資源保護?;コ庑托盘柫亢投敌托盘柫窟€有一個最大的區別,互斥型信號量可以有效解決優先級反轉現象。
圖1 互斥型信號量使用方法
2.參考代碼
? ? 本例具有兩個任務,兩個任務都試圖通過串口打印內容,此時串口就好比一個“資源”,某個任務使用串口資源時必須保護該資源,使用完串口之后在釋放資源。保護和釋放動作便對應互斥型信號量的兩個基本操作,xSemaphoreTake和xSemaphoreGive。
【代碼】
[cpp]?view plaincopy
?? #include?<stdio.h>?? #include?<string.h>?? ?? ?? #include?"FreeRTOS.h"?? #include?"task.h"?? #include?"queue.h"?? #include?"semphr.h"?? ?? ?? #include?"stm32f10x.h"?? ?? #define?LED0_ON()???GPIO_SetBits(GPIOB,GPIO_Pin_5);?? #define?LED0_OFF()??GPIO_ResetBits(GPIOB,GPIO_Pin_5);?? ?? static?void?Setup(void);?? void?TaskA(?void?*pvParameters?);?? void?TaskB(?void?*pvParameters?);?? ?? void?LedInit(void);?? void?UART1Init(void);?? ?? ?? SemaphoreHandle_t?xSemaphore?=?NULL;?? ?? int?main(void)?? {?? ?????? ????Setup();?? ?????? ????xSemaphore?=?xSemaphoreCreateMutex();?? ?????? ????xTaskCreate(?TaskA,?"TaskA",?configMINIMAL_STACK_SIZE,?NULL,?tskIDLE_PRIORITY+3,?NULL?);?? ????xTaskCreate(?TaskB,?"TaskB",?configMINIMAL_STACK_SIZE,?NULL,?tskIDLE_PRIORITY+4,?NULL?);?? ?????? ????vTaskStartScheduler();?? ?????? ????return?0;?? }?? ?? void?TaskA(?void?*pvParameters?)?? {?? ????for(?;;?)?? ????{?? ????????xSemaphoreTake(?xSemaphore,?portMAX_DELAY?);?? ????????{?? ????????????printf("Task?A\r\n");?? ????????}?? ????????xSemaphoreGive(?xSemaphore?);?? ????????vTaskDelay(?2000/portTICK_RATE_MS?);?? ????}?? }?? ?? void?TaskB(?void?*pvParameters?)?? {?? ????for(?;;?)?? ????{?? ????????xSemaphoreTake(?xSemaphore,?portMAX_DELAY?);?? ????????{?? ????????????printf("Task?B\r\n");?? ????????}?? ????????xSemaphoreGive(?xSemaphore?);?? ????????vTaskDelay(?1000/portTICK_RATE_MS?);?? ????}?? }?? ?? static?void?Setup(?void?)?? {?? ????LedInit();?? ????UART1Init();?? }?? ?? void?LedInit(?void?)?? {?? ????GPIO_InitTypeDef?GPIO_InitStructure;?? ????RCC_APB2PeriphClockCmd(?RCC_APB2Periph_GPIOB,?ENABLE?);?? ?????? ????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_5;?? ????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;?? ????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_Out_PP;?? ????GPIO_Init(?GPIOB,?&GPIO_InitStructure?);?????? }?? ?? void?UART1Init(void)?? {?? ????GPIO_InitTypeDef?GPIO_InitStructure;?? ????USART_InitTypeDef?USART_InitStructure;?? ?????? ?????? ????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA?|?RCC_APB2Periph_USART1,?ENABLE);?? ?????? ?????? ????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_9;?? ????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_PP;?? ????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;?? ????GPIO_Init(GPIOA,?&GPIO_InitStructure);?? ?????? ?????? ????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_10;?? ????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_IN_FLOATING;?? ????GPIO_Init(GPIOA,?&GPIO_InitStructure);?? ????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;?? ????GPIO_Init(GPIOA,?&GPIO_InitStructure);?? ?????? ????? ? ? ? ? ? ? ?? ????USART_InitStructure.USART_BaudRate?=?9600;?? ????USART_InitStructure.USART_WordLength?=?USART_WordLength_8b;?? ????USART_InitStructure.USART_StopBits?=?USART_StopBits_1;?? ????USART_InitStructure.USART_Parity?=?USART_Parity_No;?? ????USART_InitStructure.USART_HardwareFlowControl?=?USART_HardwareFlowControl_None;?? ????USART_InitStructure.USART_Mode?=?USART_Mode_Rx?|?USART_Mode_Tx;?? ????USART_Init(USART1,?&USART_InitStructure);?? ?????? ?????? ????USART_Cmd(USART1,?ENABLE);?? ?????? ?????? ????USART_ClearFlag(USART1,?USART_FLAG_TC);?? ?????? ?????? ????NVIC_InitTypeDef?NVIC_InitStructure;?? ?????? ?????? ????NVIC_InitStructure.NVIC_IRQChannel?=?USART1_IRQn;?? ????NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority?=?configLIBRARY_KERNEL_INTERRUPT_PRIORITY;??? ????NVIC_InitStructure.NVIC_IRQChannelSubPriority?=?0;?? ????NVIC_InitStructure.NVIC_IRQChannelCmd?=?ENABLE;?? ????NVIC_Init(&NVIC_InitStructure);?? ?????? ?????? }?? ?? int?fputc(int?ch,?FILE?*f)?? {?? ?????? ????USART_SendData(USART1,?(uint8_t)?ch);?? ?????? ????while?(USART_GetFlagStatus(USART1,?USART_FLAG_TXE)?==?RESET)?? ????{}?? ????return?ch;?? }??
3.簡單說明
SemaphoreHandle_t xSemaphore = NULL;
申明互斥型信號量,在FreeRTOS中二值型信號量和互斥型信號量類型完全相同。
xSemaphore = xSemaphoreCreateMutex();
創建互斥型信號量。
xSemaphoreTake( xSemaphore, portMAX_DELAY ); //Take:拿資源
獲得資源的使用權,此處的等待時間為
portMAX_DELAY(掛起最大時間),如果任務無法獲得資源的使用權,任務會處于掛起狀態。
?xSemaphoreGive( xSemaphore ); //Give:給出資源
? ? 釋放資源的使用權。
4.總結
? ? 互斥型信號量和二值型信號量使用方法相似,但二值型信號量用于同步而互斥型信號量用于資源保護。
總結
以上是生活随笔為你收集整理的FreeRTOS学习笔记——互斥型信号量的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。