日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

FreeRTOS学习笔记——互斥型信号量

發(fā)布時(shí)間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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è)基本操作,xSemaphoreTakexSemaphoreGive 【代碼】 [cpp]?view plaincopy
  • /*?Standard?includes.?*/??
  • #include?<stdio.h>??
  • #include?<string.h>??
  • ??
  • /*?Scheduler?includes.?*/??
  • #include?"FreeRTOS.h"??
  • #include?"task.h"??
  • #include?"queue.h"??
  • #include?"semphr.h"??
  • ??
  • /*?Library?includes.?*/??
  • #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);??
  • ??
  • /*?互斥信號(hào)量句柄?*/??
  • SemaphoreHandle_t?xSemaphore?=?NULL;??
  • ??
  • int?main(void)??
  • {??
  • ????/*?初始化硬件平臺(tái)?*/??
  • ????Setup();??
  • ????/*?創(chuàng)建互斥信號(hào)量?*/??
  • ????xSemaphore?=?xSemaphoreCreateMutex();??
  • ????/*?建立任務(wù)?*/??
  • ????xTaskCreate(?TaskA,?"TaskA",?configMINIMAL_STACK_SIZE,?NULL,?tskIDLE_PRIORITY+3,?NULL?);??
  • ????xTaskCreate(?TaskB,?"TaskB",?configMINIMAL_STACK_SIZE,?NULL,?tskIDLE_PRIORITY+4,?NULL?);??
  • ????/*?啟動(dòng)OS?*/??
  • ????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?);??
  • ????/*LED0?@?GPIOB.5*/??
  • ????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;??
  • ??????
  • ????/*?第1步:打開GPIO和USART時(shí)鐘?*/??
  • ????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA?|?RCC_APB2Periph_USART1,?ENABLE);??
  • ??????
  • ????/*?第2步:將USART1?Tx@PA9的GPIO配置為推挽復(fù)用模式?*/??
  • ????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);??
  • ??????
  • ????/*?第3步:將USART1?Rx@PA10的GPIO配置為浮空輸入模式?*/??
  • ????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);??
  • ??????
  • ????/*?第4步:配置USART1參數(shù)?
  • ????波特率???=?9600?
  • ????數(shù)據(jù)長(zhǎng)度?=?8?
  • ????停止位???=?1?
  • ????校驗(yàn)位???=?No?
  • ????禁止硬件流控(即禁止RTS和CTS)?
  • ????使能接收和發(fā)送?
  • ????*/??
  • ????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);??
  • ??????
  • ????/*?第5步:使能?USART1,?配置完畢?*/??
  • ????USART_Cmd(USART1,?ENABLE);??
  • ??????
  • ????/*?清除發(fā)送完成標(biāo)志?*/??
  • ????USART_ClearFlag(USART1,?USART_FLAG_TC);??
  • ??????
  • ????/*?使能USART1發(fā)送中斷和接收中斷,并設(shè)置優(yōu)先級(jí)?*/??
  • ????NVIC_InitTypeDef?NVIC_InitStructure;??
  • ????//?NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);??
  • ????/*?設(shè)定USART1?中斷優(yōu)先級(jí)?*/??
  • ????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);??
  • ????/*?使能接收中斷?*/??
  • ????//?USART_ITConfig(USART1,?USART_IT_RXNE,?ENABLE);???
  • }??
  • ??
  • int?fputc(int?ch,?FILE?*f)??
  • {??
  • ????/*?寫一個(gè)字節(jié)到USART1?*/??
  • ????USART_SendData(USART1,?(uint8_t)?ch);??
  • ????/*?等待發(fā)送結(jié)束?*/??
  • ????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ò),歡迎將生活随笔推薦給好友。