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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FreeRTOS学习笔记——互斥型信号量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來自:http://blog.csdn.net/xukai871105/article/details/43456985

0.前言

? ? 在嵌入式操作系統中互斥型信號量是任務間資源保護的重要手段。下面結合一個具體例子說明FreeRTOS中的互斥型信號量如何使用。


? ? 【相關博文】 ? ? 【FreeRTOS STM32移植筆記 【FreeRTOS學習筆記——任務間使用隊列同步數據】 【FreeRTOS學習筆記——二值型信號量】 【如何在FreeRTOS下實現低功耗——MSP430F5438平臺】 【代碼鏈接】——示例代碼存于百度網盤
1.基本說明 互斥型信號量的使用方法如圖1所示。在多數情況下,互斥型信號量和二值型信號非常相似,但是從功能上二值型信號量用于同步,而互斥型信號量用于資源保護?;コ庑托盘柫亢投敌托盘柫窟€有一個最大的區別,互斥型信號量可以有效解決優先級反轉現象。
圖1 互斥型信號量使用方法
2.參考代碼 ? ? 本例具有兩個任務,兩個任務都試圖通過串口打印內容,此時串口就好比一個“資源”,某個任務使用串口資源時必須保護該資源,使用完串口之后在釋放資源。保護和釋放動作便對應互斥型信號量的兩個基本操作,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);??
  • ??
  • /*?互斥信號量句柄?*/??
  • 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?);??
  • ????/*?啟動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時鐘?*/??
  • ????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA?|?RCC_APB2Periph_USART1,?ENABLE);??
  • ??????
  • ????/*?第2步:將USART1?Tx@PA9的GPIO配置為推挽復用模式?*/??
  • ????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參數?
  • ????波特率???=?9600?
  • ????數據長度?=?8?
  • ????停止位???=?1?
  • ????校驗位???=?No?
  • ????禁止硬件流控(即禁止RTS和CTS)?
  • ????使能接收和發送?
  • ????*/??
  • ????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);??
  • ??????
  • ????/*?清除發送完成標志?*/??
  • ????USART_ClearFlag(USART1,?USART_FLAG_TC);??
  • ??????
  • ????/*?使能USART1發送中斷和接收中斷,并設置優先級?*/??
  • ????NVIC_InitTypeDef?NVIC_InitStructure;??
  • ????//?NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);??
  • ????/*?設定USART1?中斷優先級?*/??
  • ????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)??
  • {??
  • ????/*?寫一個字節到USART1?*/??
  • ????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学习笔记——互斥型信号量的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。