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

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

3天內不再提示

實時操作系統(tǒng)FreeRTOS信號量應用

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

1.信號量簡介

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

2.二值信號量

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

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

3.二值信號量應用示例

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

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

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

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

#define Semaphore_TASK_PRIO 2     //任務優(yōu)先級
#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;
	/*創(chuàng)建任務*/
	xTaskCreate((TaskFunction_t)start_task,//任務函數
							(const char *)"start_task",//任務名稱	
							(uint16_t)START_STK_SIZE,//堆棧大小
							NULL,           //傳遞給任務函數的參數
							(UBaseType_t)START_TASK_PRIO,//任務優(yōu)先級
							(TaskHandle_t *)&StartTask_Handler//任務句柄
							);
	vTaskStartScheduler();     //開啟任務調度		
}	

開始任務

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

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

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

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接收數據緩沖區(qū)
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
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • 操作系統(tǒng)

    關注

    37

    文章

    6545

    瀏覽量

    122732
  • STM32
    +關注

    關注

    2257

    文章

    10828

    瀏覽量

    352444
  • RTOS
    +關注

    關注

    20

    文章

    804

    瀏覽量

    119113
  • FreeRTOS
    +關注

    關注

    12

    文章

    483

    瀏覽量

    61724
  • 信號量
    +關注

    關注

    0

    文章

    53

    瀏覽量

    8282
收藏 人收藏

    評論

    相關推薦

    FreeRTOS嵌入式實時操作系統(tǒng)

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

    FreeRTOS信號量使用教程

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

    FreeRTOS信號量的使用與實例

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

    Mindows操作系統(tǒng)更新到4.8節(jié),增加計數信號量功能

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

    Mindows操作系統(tǒng)更新到4.9節(jié),增加互斥信號量功能

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

    FreeRTOS信號量介紹

    FreeRTOS信號量 & ESP32實戰(zhàn)閱讀建議:有一定操作系統(tǒng)基礎知識。FreeRTOS信號量1. 二值
    發(fā)表于 01-27 07:28

    Linux操作系統(tǒng)信號量機制的實時化改造

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

    華為物聯網操作系統(tǒng) LiteOS內核教程04-信號量

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

    FreeRTOS信號量 & ESP32實戰(zhàn)

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

    FreeRTOS 隊列 信號量 互斥

    文章目錄前言Queue 隊列semaphore 信號量Mutex 互斥微信公眾號前言FreeRTOS STM32CubeMX配置 內存管理 任務管理上節(jié)介紹了用STM32CubeMX生成帶
    發(fā)表于 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信號量包括二進制信號量、計數信號量、互斥信號量(以后簡稱互斥)和遞歸互斥
    發(fā)表于 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信號量包括二進制信號量、計數信號量、互斥信號量(以后簡稱互斥)和遞歸互斥
    發(fā)表于 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中最常用到的信號量有哪些

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

    FreeRTOS的二值信號量

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

    FreeRTOS:一個迷你的實時操作系統(tǒng)內核

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