精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

實時操作系統FreeRTOS信號量應用

嵌入式技術 ? 來源:嵌入式技術 ? 作者:嵌入式技術 ? 2022-06-08 09:24 ? 次閱讀

1.信號量簡介

信號量常用于控制對共享資源的訪問與任務同步。資源共享例如火車票售賣,所有用戶都可以進行買票和退票操作,對于所用用戶來說火車票就是共享資源,當賣出一張票信號量減一、有人退一張票信號量加一,這種案例就屬于計數型信號量。常用的信號量還有二值信號量。例如使用公共電話,同一時間只能一個人使用,此時電話就只有兩種狀態:使用或者未使用,若將電話這兩個狀態作為信號量的話則就是二值信號量。
信號量的另一應用場合就是任務同步。用于任務與任務間或任務與中斷間同步。在執行中斷服務函數時可以向任務發送信號量通知任務該事件發生了,在退出中斷服務函數以后任務調度器的調度下同步的任務就會執行。因為中斷服務函數需要快進快出,代碼簡潔,一般在中斷服務函數中設置標志位,然后在其它地方根據標志位來實現具體功能,在FreeRTOS中就可使用信號量來完成此功能。

2.二值信號量

二值信號量通常用于互斥訪問或同步,二值信號量和互斥信號量非常相似,但還是有細微差別,互斥信號量擁有優先級繼承機制,二值信號沒有。因此二值信量適合于同步(任務與任務、任務與中斷同步),而互斥信號量適合于簡單的互斥訪問。
二值信號量其實就是一個只有一個隊列項的隊列,這個特殊的隊列要么是滿的,要么是空的。使用二值信號量必須包含semphr.h頭文件。

函數名 功能
vSemaphoreCreateBinary() 動態創建二值信號量,老版FreeRTOS創建二值信號量函數
xSemaphoreCreateBinary() 動態創建二值信號量,新版FreeRTOS創建二值信號量函數
xSemaphoreCreateBinaryStatic() 靜態創建二值信號量

3.二值信號量應用示例

此示例通過創建3個任務,start_task、LED0_task、Semaphore_task。通過任務start_task創建另外兩個任務。

#include "freeRTOS.h"
#include "task.h"http://創建相關頭文件
#include "queue.h"http://消息隊列相關頭文件
#include "semphr.h"http://信號量相關頭文件

#define START_TASK_PRIO 1        //任務優先級
#define START_STK_SIZE 128       //任務堆棧大小
TaskHandle_t StartTask_Handler;   //任務句柄
void start_task(void *pvParameters);//任務函數

#define LED0_TASK_PRIO 2     //任務優先級,數字越大優先級越高
#define LED0_STK_SIZE 128     //任務堆棧大小
TaskHandle_t LED0Task_Handler; //任務句柄
void LED0_task(void);         //任務函數

#define Semaphore_TASK_PRIO 2     //任務優先級
#define Semaphore_STK_SIZE 128      //任務堆棧大小
TaskHandle_t SemaphoreTask_Handler; //任務句柄
void Semaphore_task(void);          //任務函數

主函數

int main()
{
	Beep_Init();//蜂鳴器初始化
	LED_Init();//LED初始化
	KEY_Init();
	Usart1_Init(115200);//串口1初始化
	TIMx_Init(TIM2,72,20000);//20ms
	TIMx_Init(TIM3,7200,5000);//500ms
	TIM3->CR1|=1<<0;
	/*創建任務*/
	xTaskCreate((TaskFunction_t)start_task,//任務函數
							(const char *)"start_task",//任務名稱	
							(uint16_t)START_STK_SIZE,//堆棧大小
							NULL,           //傳遞給任務函數的參數
							(UBaseType_t)START_TASK_PRIO,//任務優先級
							(TaskHandle_t *)&StartTask_Handler//任務句柄
							);
	vTaskStartScheduler();     //開啟任務調度		
}	

開始任務

SemaphoreHandle_t BinarySemaphore;	//二值信號量句柄
/*開始任務函數*/
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();  //進入臨界區
	/*創建二值信號量*/
	BinarySemaphore=xSemaphoreCreateBinary();//創建二值信號量
	//創建LED0任務
	xTaskCreate( (TaskFunction_t  )LED0_task,//任務函數
							(const char    *)"LED0_task",//任務名稱
							 (uint16_t)LED0_STK_SIZE,//堆棧大小
								NULL,           //傳遞給任務函數的參數
							 (UBaseType_t   )LED0_TASK_PRIO,//任務優先級
							 (TaskHandle_t *)&LED0Task_Handler);//任務句柄

	xTaskCreate(  (TaskFunction_t )Semaphore_task,//任務函數
							(const char    *)"Semaphore_task",//任務名稱
							(uint16_t )Semaphore_STK_SIZE,//堆棧大小
								NULL,           //傳遞給任務函數的參數
							(UBaseType_t    )Semaphore_TASK_PRIO,//任務優先級
		                   (TaskHandle_t  *)&SemaphoreTask_Handler);//任務句柄

	vTaskDelete(StartTask_Handler); //刪除開始任務	
	taskEXIT_CRITICAL();    //退出臨界區					
}

LED0任務,此任務1000ms進行LED翻轉

void LED0_task(void)
{
	while(1)
	{
		LED1=!LED1;
		Delay_Ms(1000);	
	}
}

Semaphore函數,此任務函數獲取信號量,處理串口1中斷接收數據。

void Semaphore_task(void)//任務函數
{
	BaseType_t err=pdFALSE;
	while(1)
	{
		if(BinarySemaphore!=NULL)
		{
			err=xSemaphoreTake(BinarySemaphore,portMAX_DELAY);	//獲取信號量
			if(err==pdTRUE)
			{
				usart1_rx_buff[usart1_cnt]='\0';
				printf("rx=%s\r\n",usart1_rx_buff);
				usart1_cnt=0;
			}
		}
	}
}

串口中斷服務函數

#include "FreeRTOS.h"					//FreeRTOS使用
#include "task.h" 
#include "queue.h"	 //消息隊列
#include "semphr.h"http://信號量
u8 usart1_rx_buff[1024];//串口1接收數據緩沖區
u16 usart1_cnt=0;//保存數組下班
u8 usart1_flag;//接收完成標志符
extern SemaphoreHandle_t BinarySemaphore;	//二值信號量句柄
void USART1_IRQHandler(void)
{
	u8 c;
	BaseType_t pxHigherPriorityTaskWoken;//保存任務是否需要切換的值
	if(USART1->SR&1<<5)
	{
		c=USART1->DR;
		if(usart1_flag==0)//判斷上一次數據是否處理完成
		{
			if(usart1_cnt<1024)	
			{
				usart1_rx_buff[usart1_cnt++]=c;
				TIM2->CNT=0;//清空計數器值
				TIM2->CR1|=1<<0;//開啟定時
			}
			else usart1_flag=1;
		}
	}
	if( usart1_flag && (BinarySemaphore!=NULL))
	{
//釋放信號量
	xSemaphoreGiveFromISR(BinarySemaphore,&pxHigherPriorityTaskWoken);	
//如果需要的話,進行一次上下文切換
	portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
		usart1_flag=0;
	}
}

定時器中斷服務函數

#include "FreeRTOS.h"					//FreeRTOS使用
#include "semphr.h"
extern SemaphoreHandle_t BinarySemaphore;	//二值信號量句柄//消息隊列句柄
void TIM2_IRQHandler(void)
{
	BaseType_t pxHigherPriorityTaskWoken;//保存任務是否需要切換的值
	if(TIM2->SR&1<<0)//判斷是否為更新中斷
	{
		TIM2->CR1&=~(1<<0);//關閉定時器2
		usart1_flag=1;
		if( usart1_flag && (BinarySemaphore!=NULL))
		{
             //釋放信號量
			xSemaphoreGiveFromISR(BinarySemaphore,&pxHigherPriorityTaskWoken);
            //如果需要的話,進行一次上下文切換
			portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);		
	usart1_flag=0;
		}
	}
	TIM2->SR=0;//清除標志位
}

實現效果

poYBAGKXEqmAaxw_AABsyvIK1BQ061.png
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 操作系統
    +關注

    關注

    37

    文章

    6747

    瀏覽量

    123204
  • STM32
    +關注

    關注

    2266

    文章

    10876

    瀏覽量

    354928
  • RTOS
    +關注

    關注

    22

    文章

    809

    瀏覽量

    119453
  • FreeRTOS
    +關注

    關注

    12

    文章

    483

    瀏覽量

    62018
  • 信號量
    +關注

    關注

    0

    文章

    53

    瀏覽量

    8315
收藏 人收藏

    評論

    相關推薦

    FreeRTOS嵌入式實時操作系統

      1 FreeRTOS操作系統功能   作為一個輕量級的操作系統FreeRTOS提供的功能包括:任務管理、時間管理、信號量、消息隊列、
    發表于 07-06 11:07 ?6573次閱讀
    <b class='flag-5'>FreeRTOS</b>嵌入式<b class='flag-5'>實時</b><b class='flag-5'>操作系統</b>

    FreeRTOS信號量使用教程

    信號量操作系統中重要的一部分,信號量一般用來進行資源管理和任務同步, FreeRTOS信號量又分為二值
    的頭像 發表于 12-19 09:22 ?3121次閱讀
    <b class='flag-5'>FreeRTOS</b><b class='flag-5'>信號量</b>使用教程

    FreeRTOS信號量的使用與實例

    在嵌入式系統中,任務管理是一個重要的部分,它涉及到任務之間的通信和同步,信號量,隊列,互斥鎖和事件標志組等概念。本文將以 FreeRTOS 為例,詳細講解這些內容。
    的頭像 發表于 12-12 15:25 ?2399次閱讀

    Mindows操作系統更新到4.8節,增加計數信號量功能

    。/***************************************************************************/Wanlix是一個內核非常小的嵌入式操作系統,只有幾百個字節,但功能少,只提供任務切換功能,非常適合資源特別少但又需要任務切換的小項目。Mindows可提供多種
    發表于 12-07 16:55

    Mindows操作系統更新到4.9節,增加互斥信號量功能

    Mindows操作系統更新到4.9節,增加互斥信號量功能,更多資料請登陸www.ifreecoding.com下載。前面2節我們實現了二進制信號量和計數信號量,本節我們將實現最后一種
    發表于 12-12 17:21

    FreeRTOS信號量介紹

    FreeRTOS信號量 & ESP32實戰閱讀建議:有一定操作系統基礎知識。FreeRTOS信號量1. 二值
    發表于 01-27 07:28

    Linux操作系統信號量機制的實時化改造

    為了提高Linux操作系統實時性,研究了Linux操作系統System V信號量機制在內核中的實現,發現其在實時應用中存在的不足,提出并實
    發表于 06-25 16:41 ?18次下載

    華為物聯網操作系統 LiteOS內核教程04-信號量

    1. LiteOS內核的信號量 1.1.信號量 在多任務操作系統中,不同的任務之間需要同步運行,信號量功能可以為用戶提供這方面的支持。信號量
    發表于 03-12 17:06 ?1673次閱讀

    FreeRTOS信號量 & ESP32實戰

    FreeRTOS信號量 & ESP32實戰閱讀建議:有一定操作系統基礎知識。FreeRTOS信號量1. 二值
    發表于 12-03 18:06 ?1次下載
    <b class='flag-5'>FreeRTOS</b><b class='flag-5'>信號量</b> & ESP32實戰

    FreeRTOS 隊列 信號量 互斥

    文章目錄前言Queue 隊列semaphore 信號量Mutex 互斥微信公眾號前言FreeRTOS STM32CubeMX配置 內存管理 任務管理上節介紹了用STM32CubeMX生成帶
    發表于 12-09 09:51 ?0次下載
    <b class='flag-5'>FreeRTOS</b> 隊列 <b class='flag-5'>信號量</b> 互斥<b class='flag-5'>量</b>

    FreeRTOS高級篇6---FreeRTOS信號量分析

    FreeRTOS信號量包括二進制信號量、計數信號量、互斥信號量(以后簡稱互斥)和遞歸互斥
    發表于 01-26 17:39 ?7次下載
    <b class='flag-5'>FreeRTOS</b>高級篇6---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>信號量</b>分析

    FreeRTOS系列第20篇---FreeRTOS信號量API函數

    FreeRTOS信號量包括二進制信號量、計數信號量、互斥信號量(以后簡稱互斥)和遞歸互斥
    發表于 01-26 17:44 ?4次下載
    <b class='flag-5'>FreeRTOS</b>系列第20篇---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>信號量</b>API函數

    freeRTOS中最常用到的信號量有哪些

    操作系統系統中,信號量通常用于控制對共享資源的訪問和任務之間進行同步,信號量操作系統中是很常用的,也是學習
    的頭像 發表于 02-10 11:04 ?2026次閱讀
    <b class='flag-5'>freeRTOS</b>中最常用到的<b class='flag-5'>信號量</b>有哪些

    FreeRTOS的二值信號量

    FreeRTOS中的信號量是一種任務間通信的方式,信號量包括:二值信號量、互斥信號量、計數信號量
    的頭像 發表于 02-10 15:07 ?1467次閱讀

    FreeRTOS:一個迷你的實時操作系統內核

    ** 1、FreeRTOS** FreeRTOS是一個迷你的實時操作系統內核。作為一個輕量級的操作系統,功能包括:任務管理、時間管理、
    的頭像 發表于 06-29 17:15 ?967次閱讀
    <b class='flag-5'>FreeRTOS</b>:一個迷你的<b class='flag-5'>實時</b><b class='flag-5'>操作系統</b>內核