一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

嵌入式技術(shù) ? 來源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-06-08 09:24 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.信號量簡介

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

2.二值信號量

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

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

3.二值信號量應(yīng)用示例

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

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

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

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

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

主函數(shù)

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

開始任務(wù)

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

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

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

LED0任務(wù),此任務(wù)1000ms進(jìn)行LED翻轉(zhuǎn)

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

Semaphore函數(shù),此任務(wù)函數(shù)獲取信號量,處理串口1中斷接收數(shù)據(jù)。

void Semaphore_task(void)//任務(wù)函數(shù)
{
	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;
			}
		}
	}
}

串口中斷服務(wù)函數(shù)

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

定時器中斷服務(wù)函數(shù)

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

實(shí)現(xiàn)效果

poYBAGKXEqmAaxw_AABsyvIK1BQ061.png
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 操作系統(tǒng)
    +關(guān)注

    關(guān)注

    37

    文章

    7152

    瀏覽量

    125592
  • STM32
    +關(guān)注

    關(guān)注

    2293

    文章

    11032

    瀏覽量

    364991
  • RTOS
    +關(guān)注

    關(guān)注

    24

    文章

    851

    瀏覽量

    121176
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    493

    瀏覽量

    64358
  • 信號量
    +關(guān)注

    關(guān)注

    0

    文章

    53

    瀏覽量

    8569
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

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

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

    FreeRTOS信號量使用教程

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

    FreeRTOS信號量的使用與實(shí)例

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

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

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

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

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

    FreeRTOS信號量介紹

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

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

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

    華為物聯(lián)網(wǎng)操作系統(tǒng) LiteOS內(nèi)核教程04-信號量

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

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

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

    FreeRTOS 隊(duì)列 信號量 互斥

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

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

    FreeRTOS信號量包括二進(jìn)制信號量、計(jì)數(shù)信號量、互斥信號量(以后簡稱互斥)和遞歸互斥
    發(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函數(shù)

    FreeRTOS信號量包括二進(jìn)制信號量、計(jì)數(shù)信號量、互斥信號量(以后簡稱互斥)和遞歸互斥
    發(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函數(shù)

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

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

    FreeRTOS的二值信號量

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

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

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