久久久国产精品视频袁燕,99re久久精品国产,亚洲欧美日韩国产综合v,天天躁夜夜躁狠狠久久,激情五月婷婷激情五月婷婷

小麥大叔
認(rèn)證:普通會(huì)員
所在專題目錄 查看專題
基于CubeIDE快速整合FreeRTOS創(chuàng)建第一個(gè)任務(wù)
【FreeRTOS學(xué)習(xí)02】源碼結(jié)構(gòu)/數(shù)據(jù)類型/命名規(guī)則總結(jié)
【FreeRTOS學(xué)習(xí)03】Task Management 任務(wù)管理基本概念介紹
【FreeRTOS學(xué)習(xí)04】Queue Management 消息隊(duì)列使用詳解
【FreeRTOS學(xué)習(xí)05】深度解剖FreeRTOSConfig.h實(shí)現(xiàn)對(duì)系統(tǒng)的自定義剪裁
【FreeRTOS學(xué)習(xí)06】深度解剖中斷與任務(wù)之間同步的具體使用場(chǎng)景
作者動(dòng)態(tài) 更多
一款輕量級(jí)的開源GUI項(xiàng)目——SimpleGUI,可以完美適配單色屏
02-22 09:47
看到這100多個(gè)軟硬件開源項(xiàng)目,真是爽爆了
2024-11-30 14:12
推薦一個(gè)高效,可靠,安全的串口通訊開源方案
2024-11-27 11:17
推薦一款開源hack硬件平臺(tái)工具
2024-11-26 13:58
新手學(xué)STM32的話,先學(xué)標(biāo)準(zhǔn)庫還是HAL庫?
2024-10-18 15:09

【FreeRTOS學(xué)習(xí)06】深度解剖中斷與任務(wù)之間同步的具體使用場(chǎng)景

嵌入式系統(tǒng)中中斷是必不可少的一部分

1 前言

本文會(huì)在中斷基礎(chǔ)上對(duì)FreeRTOS的中斷管理做一個(gè)介紹,讀者需要掌握中斷的概念,本文暫不會(huì)對(duì)此進(jìn)行深入介紹;再操作系統(tǒng)中,中斷隨處可見,從Windows的中斷,Linux的中斷,以及RTOS的中斷,其處理過程都是相同的;無論是軟件中斷還是硬件中斷,在接收到中斷源發(fā)出的中斷請(qǐng)求之后,就會(huì)觸發(fā)中斷,CPU尋找中斷向量表,然后跳轉(zhuǎn)到中斷服務(wù)函數(shù),具體如下所示;

什么是中斷源,通常就PC來說,中斷源可以是以下幾種:

  • I/O設(shè)備:鼠標(biāo),鍵盤等等;
  • 定時(shí)器中斷;
  • 內(nèi)部故障產(chǎn)生的中斷;
  • CPU主動(dòng)中斷,比如調(diào)試程序,單步執(zhí)行的情況;

那么,如何在中斷服務(wù)函數(shù)和RTOS的任務(wù)之間,安全地完成數(shù)據(jù)的交互呢?下面會(huì)進(jìn)一步介紹。

2 中斷特點(diǎn)

中斷發(fā)生的時(shí)候,會(huì)打斷正常執(zhí)行的函數(shù),這時(shí)候就會(huì)進(jìn)行現(xiàn)場(chǎng)保護(hù),即將當(dāng)前各個(gè)寄存器的值壓到入棧,執(zhí)行玩中斷之后恢復(fù)現(xiàn)場(chǎng),即出棧,重新恢復(fù)各個(gè)寄存器的值,系統(tǒng)還原到中斷之前的狀態(tài);具體如下圖所示;

FreeRTOS中,中斷需要注意幾點(diǎn):

  • 事件的檢測(cè),除了中斷方式,還可以通過輪詢方式,需要更加具體的情況進(jìn)行選擇;
  • 何時(shí)使用中斷;中斷服務(wù)函數(shù)(ISR)要處理的數(shù)據(jù)量有多大,通常我們希望中斷的切換越快越好,也就是說,ISR盡量采用耗時(shí)較少的處理方式;
  • 事件如何通知到任務(wù)(和中斷服務(wù)函數(shù)區(qū)別開,非ISR函數(shù)),如何設(shè)計(jì)程序的架構(gòu)可以完成良好的異步處理過程;
  • 事件通知的時(shí)候需要注意使用FreeRTOS提供的中斷安全API,通常這些函數(shù)接口的后綴為xxxxxISR(),例如xQueueSendFrom;

3 延遲中斷處理

上面提到過,中斷服務(wù)函數(shù)應(yīng)該盡量斷,因此這里才用中斷的前部中斷的后部來處理;

  • 前部:負(fù)責(zé)處理不耗時(shí)的操作,比如任務(wù)的同步,發(fā)送信號(hào)量去通知任務(wù);
  • 后部:負(fù)責(zé)處理耗時(shí)的操作,這時(shí)候,中斷已經(jīng)恢復(fù)現(xiàn)場(chǎng),實(shí)際執(zhí)行可以視為軟中斷,即在一個(gè)Task任務(wù)中執(zhí)行;

上述的方式也可以稱之為延遲中斷處理,具體的思路是:對(duì)應(yīng)的中斷創(chuàng)建一個(gè)相應(yīng)的handler task,使用二值信號(hào)量去同步,在某個(gè)特殊的中斷發(fā)生時(shí),發(fā)送信號(hào)量,讓任務(wù)解除阻塞,相當(dāng)于讓任務(wù)與中斷同步。這樣就可以讓中斷事件處理量大的工作在同步任務(wù)中完成,中斷服務(wù)例程(ISR)中只是快速處理少部份工作,幾點(diǎn)羅列一下;

  1. 中斷處理可以說是被推遲(deferred)到一個(gè)處理(handler)任務(wù)中;
  2. 如果某個(gè)中斷處理要求特別緊急,其延遲處理任務(wù)的優(yōu)先級(jí)可以設(shè)為最高,以保證延遲處理任務(wù)隨時(shí)都搶占系統(tǒng)中的其它任務(wù)。
  3. 延遲處理任務(wù)就成為其對(duì)應(yīng)的 ISR退出后第一個(gè)執(zhí)行的任務(wù),在時(shí)間上緊接著 ISR 執(zhí)行,相當(dāng)于所有的處理都在 ISR 中完成一樣。1

具體如下所示;

3.1 信號(hào)量的使用

關(guān)于信號(hào)量(Semaphore):通俗的解釋,信號(hào)量是一個(gè)數(shù),二值信號(hào)量,互斥信號(hào)量,只能表示01,假設(shè)一個(gè)信號(hào)量X,兩個(gè)任務(wù)A,B;

  • 任務(wù)A獲取了信號(hào)量,則該信號(hào)量X被設(shè)為0,B任務(wù)都處于堵塞狀態(tài),等待A任務(wù)釋放信號(hào)量;
  • 當(dāng)A任務(wù)釋放了信號(hào)量,則該信號(hào)量X被設(shè)為1,B任務(wù)獲取了信號(hào)量,則進(jìn)入運(yùn)行狀態(tài); 2FreeRTOS中對(duì)于信號(hào)量操作給出了以下相應(yīng)的API
  • vSemaphoreCreateBinary:創(chuàng)建二值信號(hào)量;
  • xSemaphoreTake:獲取信號(hào)量;
  • xSemaphoreGiveFromISR:發(fā)送信號(hào)量;這是一組宏定義,具體的實(shí)現(xiàn)在頭文件semphr.h中,下面進(jìn)一步介紹;

通常信號(hào)量的同步操作如下圖所示;

3.2 vSemaphoreCreateBinary

FreeRTOS 中各種信號(hào)量的句柄都存儲(chǔ)在 xSemaphoreHandle類型的變量中,在使用信號(hào)量之前,必須先通過vSemaphoreCreateBinary創(chuàng)建信號(hào)量,其具體函數(shù)原型如下;

#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define vSemaphoreCreateBinary( xSemaphore )																							\
		{																																	\
			( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE );	\
			if( ( xSemaphore ) != NULL )																									\
			{																																\
				( void ) xSemaphoreGive( ( xSemaphore ) );																					\
			}																																\
		}
#endif
 

可以看到這個(gè)接口是通過調(diào)用xQueueGenericCreate函數(shù)創(chuàng)建了大小為1個(gè)semSEMAPHORE_QUEUE_ITEM_LENGTH的信號(hào)量,并且創(chuàng)建成功之后,通過xSemaphoreGive將信號(hào)量設(shè)置為1,此時(shí)信號(hào)量有效;

3.3 xSemaphoreTake

“帶走(Taking)”一個(gè)信號(hào)量意為”獲取(Obtain)”或”接收(Receive)”信號(hào)量。只有當(dāng)信號(hào)量有效的時(shí)候才可以被獲取。在經(jīng)典信號(hào)量術(shù)中,xSemaphoreTake()等同于一次P()操作。函數(shù)原型如下所示;

#define xSemaphoreTake( xSemaphore, xBlockTime )		\
		xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )

3.4 xSemaphoreGiveFromISR

xSemaphoreGiveFromISR() xSemaphoreGive()的特殊形式, 專門用于中斷服務(wù)函數(shù)中,其函數(shù)原型如下;

#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )	\
		xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )

4 計(jì)數(shù)信號(hào)量

上面講的二值信號(hào)量最多只能鎖存一個(gè)事件,通俗的講只能進(jìn)行一對(duì)一的觸發(fā),也就是說在中斷頻率相對(duì)較低的情況下,使用二值信號(hào)量是比較完美的,但是在中斷頻率較高的情況下,會(huì)出現(xiàn)這種情況:

  • 產(chǎn)生了中斷,任務(wù)A獲取信號(hào)量,并開始運(yùn)行;
  • 新的中斷產(chǎn)生,任務(wù)A還沒有運(yùn)行結(jié)束(任務(wù)A占有了信號(hào)量),此時(shí)信號(hào)量無效,因此這個(gè)中斷信號(hào)沒有處理就丟失了;這里通過使用計(jì)數(shù)信號(hào)量可以解決這種情況,通過使用xSemaphoreCreateCounting函數(shù),函數(shù)原型如下所示;
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) \
	xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
#endif

創(chuàng)建一個(gè)計(jì)數(shù)信號(hào)量;

xCountingSemaphore = xSemaphoreCreateCounting( 10, 0 );

具體中斷和任務(wù)通過計(jì)數(shù)信號(hào)量的同步過程可以參考下圖;

5 總結(jié)

本文對(duì)FreeRTOS中如何對(duì)中斷服務(wù)函數(shù)和任務(wù)進(jìn)行同步做了簡(jiǎn)單介紹,分析了通過二值信號(hào)量和計(jì)數(shù)信號(hào)量這兩種場(chǎng)景的應(yīng)用和注意事項(xiàng),另外作者能力有限,難免存在錯(cuò)誤和紕漏,請(qǐng)不吝賜教。

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場(chǎng)。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請(qǐng)聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯(cuò)的朋友,別忘了一鍵三連哦!
贊 3
收藏 2
關(guān)注 145
成為作者 賺取收益
全部留言
0/200
成為第一個(gè)和作者交流的人吧