生活随笔
收集整理的這篇文章主要介紹了
FreeRTOS学习笔记——互斥型信号量
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
來自:http://blog.csdn.net/xukai871105/article/details/43456985
0.前言
? ? 在嵌入式操作系統(tǒng)中互斥型信號(hào)量是任務(wù)間資源保護(hù)的重要手段。下面結(jié)合一個(gè)具體例子說明FreeRTOS中的互斥型信號(hào)量如何使用。
? ? 【相關(guān)博文】
? ? 【FreeRTOS STM32移植筆記
】 【FreeRTOS學(xué)習(xí)筆記——任務(wù)間使用隊(duì)列同步數(shù)據(jù)】 【FreeRTOS學(xué)習(xí)筆記——二值型信號(hào)量】 【如何在FreeRTOS下實(shí)現(xiàn)低功耗——MSP430F5438平臺(tái)】 【代碼鏈接】——示例代碼存于百度網(wǎng)盤
1.基本說明
互斥型信號(hào)量的使用方法如圖1所示。在多數(shù)情況下,互斥型信號(hào)量和二值型信號(hào)非常相似,但是從功能上二值型信號(hào)量用于同步,而互斥型信號(hào)量用于資源保護(hù)。互斥型信號(hào)量和二值型信號(hào)量還有一個(gè)最大的區(qū)別,互斥型信號(hào)量可以有效解決優(yōu)先級(jí)反轉(zhuǎn)現(xiàn)象。
圖1 互斥型信號(hào)量使用方法
2.參考代碼
? ? 本例具有兩個(gè)任務(wù),兩個(gè)任務(wù)都試圖通過串口打印內(nèi)容,此時(shí)串口就好比一個(gè)“資源”,某個(gè)任務(wù)使用串口資源時(shí)必須保護(hù)該資源,使用完串口之后在釋放資源。保護(hù)和釋放動(dòng)作便對(duì)應(yīng)互斥型信號(hào)量的兩個(gè)基本操作,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.簡(jiǎn)單說明
SemaphoreHandle_t xSemaphore = NULL;
申明互斥型信號(hào)量,在FreeRTOS中二值型信號(hào)量和互斥型信號(hào)量類型完全相同。
xSemaphore = xSemaphoreCreateMutex();
創(chuàng)建互斥型信號(hào)量。
xSemaphoreTake( xSemaphore, portMAX_DELAY ); //Take:拿資源
獲得資源的使用權(quán),此處的等待時(shí)間為
portMAX_DELAY(掛起最大時(shí)間),如果任務(wù)無法獲得資源的使用權(quán),任務(wù)會(huì)處于掛起狀態(tài)。
?xSemaphoreGive( xSemaphore ); //Give:給出資源
? ? 釋放資源的使用權(quán)。
4.總結(jié)
? ? 互斥型信號(hào)量和二值型信號(hào)量使用方法相似,但二值型信號(hào)量用于同步而互斥型信號(hào)量用于資源保護(hù)。
總結(jié)
以上是生活随笔為你收集整理的FreeRTOS学习笔记——互斥型信号量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。