国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

FreeRTOS事件組 基于STM32

這篇具有很好參考價值的文章主要介紹了FreeRTOS事件組 基于STM32。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概述

文章對事件組的,應用場景,運作機制,以及事件的創(chuàng)建,刪除,等待,置位,同步等操作

文章目錄

概述

一、事件標志組簡介

1、事件位(事件標志)

2、事件組

3、事件標志組和事件位的數(shù)據類型

二、事件的應用場景

三、事件運作機制

四、事件控制塊

?五、事件組函數(shù)

1.事件創(chuàng)建函數(shù) xEventGroupCreate()

2.事件刪除函數(shù) vEventGroupDelete()

3.事件組置位函數(shù) xEventGroupSetBits()(任務)

4.等待事件函數(shù) xEventGroupWaitBits()

5. xEventGroupClearBits()與 xEventGroupClearBitsFromISR()

?六、事件實驗

七、實驗現(xiàn)象


一、事件標志組簡介

1、事件位(事件標志)

事件位用來表明某個事件是否發(fā)生,事件位通常用作事件標志,比如下面的幾個例子:

● 當收到一條消息并且把這條消息處理掉以后就可以將某個位(標志)置 1,當隊列中沒有 消息需要處理的時候就可以將這個位(標志)置 0。

● 當把隊列中的消息通過網絡發(fā)送輸出以后就可以將某個位(標志)置 1,當沒有數(shù)據需要 從網絡發(fā)送出去的話就將這個位(標志)置 0。

● 現(xiàn)在需要向網絡中發(fā)送一個心跳信息,將某個位(標志)置 1?,F(xiàn)在不需要向網絡中發(fā)送 心跳信息,這個位(標志)置 0。

2、事件組

一個事件組就是一組的事件位,事件組中的事件位通過位編號來訪問,同樣,以上面列出 的三個例子為例:

● 事件標志組的 bit0 表示隊列中的消息是否處理掉。

● 事件標志組的 bit1 表示是否有消息需要從網絡中發(fā)送出去。

● 事件標志組的 bit2 表示現(xiàn)在是否需要向網絡發(fā)送心跳信息。

3、事件標志組和事件位的數(shù)據類型

事件標志組的數(shù)據類型為 EventGroupHandle_t,當 configUSE_16_BIT_TICKS 為 1 的時候 事件標志組可以存儲 8 個事件位,當 configUSE_16_BIT_TICKS 為 0 的時候事件標志組存儲 24 個事件位。

事件標志組中的所有事件位都存儲在一個無符號的 EventBits_t 類型的變量中,EventBits_t 在 event_groups.h 中有如下定義:

typedef TickType_t EventBits_t;

數(shù)據類型 TickType_t 在文件 portmacro.h 中有如下定義:

#if( configUSE_16_BIT_TICKS == 1 )
   typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff 
#else
 typedef uint32_t TickType_t;
 #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
 #define portTICK_TYPE_IS_ATOMIC 1
 #endif

可以看出當 configUSE_16_BIT_TICKS 為 0 的時候 TickType_t 是個 32 位的數(shù)據類型,因 此 EventBits_t 也是個 32 位的數(shù)據類型。EventBits_t 類型的變量可以存儲 24 個事件位,另外的 那高 8 位有其他用。事件位 0 存放在這個變量的 bit0 上,變量的 bit1 就是事件位 1,以此類推。 對于 STM32 來說一個事件標志組最多可以存儲 24 個事件位,如圖1所示

freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機

圖1 事件標志組和事件位

二、事件的應用場景

? ? ? FreeRTOS 的事件用于事件類型的通訊,無數(shù)據傳輸,也就是說,我們可以用事件來做 標志位,判斷某些事件是否發(fā)生了,然后根據結果做處理,那很多人又會問了,為什么我 不直接用變量做標志呢,豈不是更好更有效率?非也非也,若是在裸機編程中,用全局變 量是最為有效的方法,這點我不否認,但是在操作系統(tǒng)中,使用全局變量就要考慮以下問 題了:

?如何對全局變量進行保護呢,如何處理多任務同時對它進行訪問?

? ? ? 如何讓內核對事件進行有效管理呢?使用全局變量的話,就需要在任務中輪詢查 看事件是否發(fā)送,這簡直就是在浪費 CPU 資源啊,還有等待超時機制,使用全局 變量的話需要用戶自己去實現(xiàn)。

所以,在操作系統(tǒng)中,還是使用操作系統(tǒng)給我們提供的通信機制就好了,簡單方便還 實用。

? ? ? ?在某些場合,可能需要多個時間發(fā)生了才能進行下一步操作,比如一些危險機器的啟 動,需要檢查各項指標,當指標不達標的時候,無法啟動,但是檢查各個指標的時候,不 能一下子檢測完畢啊,所以,需要事件來做統(tǒng)一的等待,當所有的事件都完成了,那么機 器才允許啟動,這只是事件的其中一個應用。

? ? ? ?事件可使用于多種場合,它能夠在一定程度上替代信號量,用于任務與任務間,中斷 與任務間的同步。一個任務或中斷服務例程發(fā)送一個事件給事件對象,而后等待的任務被 喚醒并對相應的事件進行處理。但是它與信號量不同的是,事件的發(fā)送操作是不可累計的, 而信號量的釋放動作是可累計的。事件另外一個特性是,接收任務可等待多種事件,即多 個事件對應一個任務或多個任務。同時按照任務等待的參數(shù),可選擇是“邏輯或”觸發(fā)還 是“邏輯與”觸發(fā)。這個特性也是信號量等所不具備的,信號量只能識別單一同步動作, 而不能同時等待多個事件的同步。

? ? ? ? 各個事件可分別發(fā)送或一起發(fā)送給事件對象,而任務可以等待多個事件,任務僅對感 興趣的事件進行關注。當有它們感興趣的事件發(fā)生時并且符合感興趣的條件,任務將被喚 醒并進行后續(xù)的處理動作。

三、事件運作機制

? ? ? 接收事件時,可以根據感興趣的參事件類型接收事件的單個或者多個事件類型。事件 接收成功后,必須使用 xClearOnExit 選項來清除已接收到的事件類型,否則不會清除已接收 到的 事件 ,這樣就需要用戶顯式清除事?位。

? ? ? 用戶可 以自 定義 通過 傳入參 數(shù) xWaitForAllBits 選擇讀取模式,是等待所有感興趣的事件還是等待感興趣的任意一個事件。?

? ? ?設置事件時,對指定事件寫入指定的事件類型,設置事件集合的對應事件位為 1,可 以一次同時寫多個事件類型,設置事件成功可能會觸發(fā)任務調度。?

? ? ? ?清除事件時,根據入參數(shù)事件句柄和待清除的事件類型,對事件對應位進行清 0 操作。 事件不與任務相關聯(lián),事件相互獨立,一個 32位的變量(事件集合,實際用于表示事 件的只有 24 位),用于標識該任務發(fā)生的事件類型,其中每一位表示一種事件類型(0 表 示該事件類型未發(fā)生、1表示該事件類型已經發(fā)生),一共 24種事件類型具體見圖2

freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機

圖2事件集合 set(一個 32 位的變量)

? ? ?事件喚醒機制,當任務因為等待某個或者多個事件發(fā)生而進入阻塞態(tài),當事件發(fā)生的 時候會被喚醒,其過程具體見圖3

freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機

圖3? 事件喚醒任務示意圖

? ? ? 任務 1 對事件 3 或事件 5 感興趣(邏輯或),當發(fā)生其中的某一個事件都會被喚醒, 并且執(zhí)行相應操作。而任務 2 對事件 3 與事件 5 感興趣(邏輯與),當且僅當事件 3 與事 件 5 都發(fā)生的時候,任務 2 才會被喚醒,如果只有一個其中一個事件發(fā)生,那么任務還是 會繼續(xù)等待事件發(fā)生。如果接在收事件函數(shù)中設置了清除事件位 xClearOnExit,那么當任 務喚醒后將把事件 3 和事件 5 的事件標志清零,否則事件標志將依然存在。

四、事件控制塊

? ? ? ?事件標志組存儲在一個 EventBits_t 類型的變量中,該變量在事件組結構體中定義,具 體見代碼清單 20-1 加粗部分。如果宏 configUSE_16_BIT_TICKS 定義為 1,那么變量 uxEventBits 就 是 16 位 的 , 其 中 有 8 個 位 用來存儲 事 件 組 , 如 果 宏 configUSE_16_BIT_TICKS 定義為 0,那么變量 uxEventBits 就是 32 位的,其中有 24 個位 用來存儲事件組,每一位代表一個事件的發(fā)生與否,利用邏輯或、邏輯與等實現(xiàn)不同事件 的不同喚醒處理。在 STM32 中,uxEventBits 是 32 位的,所以我們有 24 個位用來實現(xiàn)事件 組。除了事件標志組變量之外,F(xiàn)reeRTOS 還使用了一個鏈表來記錄等待事件的任務,所有 在等待此事件的任務均會被掛載在等待事件列表 xTasksWaitingForBits。

 typedef struct xEventGroupDefinition {
   EventBits_t uxEventBits;
    List_t xTasksWaitingForBits;
 
 #if( configUSE_TRACE_FACILITY == 1 )
   UBaseType_t uxEventGroupNumber;
 #endif
 
 #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) \
   && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
   uint8_t ucStaticallyAllocated;
 #endif
   } EventGroup_t;

?五、事件組函數(shù)

1.事件創(chuàng)建函數(shù) xEventGroupCreate()

? ? 事件創(chuàng)建函數(shù),顧名思義,就是創(chuàng)建一個事件,與其他內核對象一樣,都是需要先創(chuàng) 建才能使用的資源,F(xiàn)reeRTOS 給我們提供了一個創(chuàng)建事件的函數(shù) xEventGroupCreate(),當 創(chuàng)建一個事件時,系統(tǒng)會首先給我們分配事件控制塊的內存空間,然后對該事件控制塊進 行基本的初始化,創(chuàng)建成功返回事件句柄;創(chuàng)建失敗返回 NULL。所以,在使用創(chuàng)建函數(shù) 之前,我們需要先定義有個事件的句柄。

/* 創(chuàng)建一個事件組,返回它的句柄。
 * 此函數(shù)內部會分配事件組結構體 
 * 返回值: 返回句柄,非NULL表示成功
 */
EventGroupHandle_t xEventGroupCreate( void );

/* 創(chuàng)建一個事件組,返回它的句柄。
 * 此函數(shù)無需動態(tài)分配內存,所以需要先有一個StaticEventGroup_t結構體,并傳入它的指針
 * 返回值: 返回句柄,非NULL表示成功
 */
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer );

2.事件刪除函數(shù) vEventGroupDelete()

? ? ?vEventGroupDelete()用于刪除由函數(shù) xEventGroupCreate()創(chuàng)建的事件組,只有被創(chuàng)建 成功的事件才能被刪除,但是需要注意的是該函數(shù)不允許在中斷里面使用。當事件組被刪 除之后,阻塞在該事件組上的任務都會被解鎖,并向等待事件的任務返回事件組的值為 0, 其使用是非常簡單的。

/*
 * xEventGroup: 事件組句柄,你要刪除哪個事件組
 */
void vEventGroupDelete( EventGroupHandle_t xEventGroup )

3.事件組置位函數(shù) xEventGroupSetBits()(任務)

? ? ? ? xEventGroupSetBits()用于置位事件組中指定的位,當位被置位之后,阻塞在該位上的 任務將會被解鎖。使用該函數(shù)接口時,通過參數(shù)指定的事件標志來設定事件的標志位,然 后遍歷等待在事件對象上的事件等待列表,判斷是否有任務的事件激活要求與當前事件對 象標志值匹配,如果有,則喚醒該任務。簡單來說,就是設置我們自己定義的事件標志位 為 1,并且看看有沒有任務在等待這個事件,有的話就喚醒它。

xEventGroupSetBits()函數(shù)說明

freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機

xEventGroupSetBits()函數(shù)使用實例

#define KEY1_EVENT  (0x01 << 0)//設置事件掩碼的位0
#define KEY2_EVENT  (0x01 << 1)//設置事件掩碼的位1
static EventGroupHandle_t Event_Handle =NULL;
Event_Handle = xEventGroupCreate();	 
  if(NULL != Event_Handle)
    printf("Event_Handle 事件創(chuàng)建成功!\r\n");
static void KEY_Task(void* parameter)
{	 
    /* 任務都是一個無限循環(huán),不能返回 */
  while (1)
  {
    if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON )       //如果KEY2被單擊
		{
      printf ( "KEY1被按下\n" );
			/* 觸發(fā)一個事件1 */
			xEventGroupSetBits(Event_Handle,KEY1_EVENT);  					
		}
    
		if( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON )       //如果KEY2被單擊
		{
      printf ( "KEY2被按下\n" );	
			/* 觸發(fā)一個事件2 */
			xEventGroupSetBits(Event_Handle,KEY2_EVENT); 				
		}
		vTaskDelay(20);     //每20ms掃描一次		
  }
}

4.等待事件函數(shù) xEventGroupWaitBits()

? ? ? ?既然標記了事件的發(fā)生,那么我怎么知道他到底有沒有發(fā)生,這也是需要一個函數(shù)來 獲 取 事 件 是 否 已 經 發(fā) 生 , FreeRTOS 提 供 了 一 個 等 待 指 定 事 件 的 函 數(shù) — — xEventGroupWaitBits(),通過這個函數(shù),任務可以知道事件標志組中的哪些位,有什么事 件發(fā)生了,然后通過 “邏輯與”、“邏輯或”等操作對感興趣的事件進行獲取,并且這個 函數(shù)實現(xiàn)了等待超時機制,當且僅當任務等待的事件發(fā)生時,任務才能獲取到事件信息。 在這段時間中,如果事件一直沒發(fā)生,該任務將保持阻塞狀態(tài)以等待事件發(fā)生。當其它任 務或中斷服務程序往其等待的事件設置對應的標志位,該任務將自動由阻塞態(tài)轉為就緒態(tài)。 當任務等待的時間超過了指定的阻塞時間,即使事件還未發(fā)生,任務也會自動從阻塞態(tài)轉 移為就緒態(tài)。這樣子很有效的體現(xiàn)了操作系統(tǒng)的實時性,如果事件正確獲?。ǖ却剑﹦t 返回對應的事件標志位,由用戶判斷再做處理,因為在事件超時的時候也會返回一個不能 確定的事件值,所以需要判斷任務所等待的事件是否真的發(fā)生。

xEventGroupWaitBits()函數(shù)說明?

freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機

xEventGroupWaitBits()使用實例

static void LED_Task(void* parameter)
{	
  EventBits_t r_event;  /* 定義一個事件接收變量 */
  /* 任務都是一個無限循環(huán),不能返回 */
  while (1)
	{
    /*******************************************************************
     * 等待接收事件標志 
     * 
     * 如果xClearOnExit設置為pdTRUE,那么在xEventGroupWaitBits()返回之前,
     * 如果滿足等待條件(如果函數(shù)返回的原因不是超時),那么在事件組中設置
     * 的uxBitsToWaitFor中的任何位都將被清除。 
     * 如果xClearOnExit設置為pdFALSE,
     * 則在調用xEventGroupWaitBits()時,不會更改事件組中設置的位。
     *
     * xWaitForAllBits如果xWaitForAllBits設置為pdTRUE,則當uxBitsToWaitFor中
     * 的所有位都設置或指定的塊時間到期時,xEventGroupWaitBits()才返回。 
     * 如果xWaitForAllBits設置為pdFALSE,則當設置uxBitsToWaitFor中設置的任何
     * 一個位置1 或指定的塊時間到期時,xEventGroupWaitBits()都會返回。 
     * 阻塞時間由xTicksToWait參數(shù)指定。          
      *********************************************************/
    r_event = xEventGroupWaitBits(Event_Handle,  /* 事件對象句柄 */
                                  KEY1_EVENT|KEY2_EVENT,/* 接收線程感興趣的事件 */
                                  pdTRUE,   /* 退出時清除事件位 */
                                  pdTRUE,   /* 滿足感興趣的所有事件 */
                                  portMAX_DELAY);/* 指定超時事件,一直等 */
                        
    if((r_event & (KEY1_EVENT|KEY2_EVENT)) == (KEY1_EVENT|KEY2_EVENT)) 
    {
      /* 如果接收完成并且正確 */
      printf ( "KEY1與KEY2都按下\n");		
      LED1_TOGGLE;       //LED1	反轉
    }
    else
      printf ( "事件錯誤!\n");	
  }
}

5. xEventGroupClearBits()與 xEventGroupClearBitsFromISR()

? ? ? ?xEventGroupClearBits()與 xEventGroupClearBitsFromISR()都是用于清除事件組指定的 位,如果在獲取事件的時候沒有將對應的標志位清除,那么就需要用這個函數(shù)來進行顯式 清除,xEventGroupClearBits()函數(shù)不能在中斷中使用,而是由具有中斷保護功能 的 xEventGroupClearBitsFromISR() 來代替,中斷清除事件標志位的操作在守護任務(也叫定 時 器 服 務 任 務 ) 里 面 完 成 。 守 護 進 程 的 優(yōu) 先 級 由 FreeRTOSConfig.h 中 的 宏 configTIMER_TASK_PRIORITY 來定義 。 要 想 使 用 該 函 數(shù) 必 須 把 FreeRTOS/source/event_groups.c 這個 C 文件添加到工程中。

xEventGroupClearBits()與 xEventGroupClearBitsFromISR()函數(shù)說明

freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機

?xEventGroupClearBits()函數(shù)使用實例

 #define BIT_0 ( 1 << 0 )
 #define BIT_4 ( 1 << 4 )
 
 void aFunction( EventGroupHandle_t xEventGroup )
 {
    EventBits_t uxBits;
 
    /* 清楚事件組的 bit 0 and bit 4 */ 
     uxBits = xEventGroupClearBits( 
      xEventGroup, 
     BIT_0 | BIT_4 ); 
 
     if ( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) {
     /* 在調用 xEventGroupClearBits()之前 bit0 和 bit4 都置位
      但是現(xiàn)在是被清除了*/
       } else if ( ( uxBits & BIT_0 ) != 0 ) {
      /* 在調用 xEventGroupClearBits()之前 bit0 已經置位
     但是現(xiàn)在是被清除了*/
      } else if ( ( uxBits & BIT_4 ) != 0 ) {
     /* 在調用 xEventGroupClearBits()之前 bit4 已經置位
      但是現(xiàn)在是被清除了*/
     } else {
    /* 在調用 xEventGroupClearBits()之前 bit0 和 bit4 都沒被置位 */
    }
 }

?六、事件實驗

? ? ? ?事件標志組實驗是在 FreeRTOS 中創(chuàng)建了兩個任務,一個是設置事件任務,一個是等 待事件任務,兩個任務獨立運行,設置事件任務通過檢測按鍵的按下情況設置不同的事件 標志位,等待事件任務則獲取這兩個事件標志位,并且判斷兩個事件是否都發(fā)生,如果是 則輸出相應信息,LED 進行翻轉。等待事件任務的等待時間是 portMAX_DELAY,一直在等待事件的發(fā)生,等待到事件之后清除對應的事件標記位,具體見代碼清單 20-13 加粗部 分。


/* FreeRTOS頭文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
/* 開發(fā)板硬件bsp頭文件 */
#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_key.h"
/**************************** 任務句柄 ********************************/
/* 
 * 任務句柄是一個指針,用于指向一個任務,當任務創(chuàng)建好之后,它就具有了一個任務句柄
 * 以后我們要想操作這個任務都需要通過這個任務句柄,如果是自身的任務操作自己,那么
 * 這個句柄可以為NULL。
 */
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 創(chuàng)建任務句柄 */
static TaskHandle_t LED_Task_Handle = NULL;/* LED_Task任務句柄 */
static TaskHandle_t KEY_Task_Handle = NULL;/* KEY_Task任務句柄 */

/********************************** 內核對象句柄 *********************************/
/*
 * 信號量,消息隊列,事件標志組,軟件定時器這些都屬于內核的對象,要想使用這些內核
 * 對象,必須先創(chuàng)建,創(chuàng)建成功之后會返回一個相應的句柄。實際上就是一個指針,后續(xù)我
 * 們就可以通過這個句柄操作這些內核對象。
 *
 * 內核對象說白了就是一種全局的數(shù)據結構,通過這些數(shù)據結構我們可以實現(xiàn)任務間的通信,
 * 任務間的事件同步等各種功能。至于這些功能的實現(xiàn)我們是通過調用這些內核對象的函數(shù)
 * 來完成的
 * 
 */
static EventGroupHandle_t Event_Handle =NULL;

/******************************* 全局變量聲明 ************************************/
/*
 * 當我們在寫應用程序的時候,可能需要用到一些全局變量。
 */


/******************************* 宏定義 ************************************/
/*
 * 當我們在寫應用程序的時候,可能需要用到一些宏定義。
 */
#define KEY1_EVENT  (0x01 << 0)//設置事件掩碼的位0
#define KEY2_EVENT  (0x01 << 1)//設置事件掩碼的位1

/*
*************************************************************************
*                             函數(shù)聲明
*************************************************************************
*/
static void AppTaskCreate(void);/* 用于創(chuàng)建任務 */

static void LED_Task(void* pvParameters);/* LED_Task 任務實現(xiàn) */
static void KEY_Task(void* pvParameters);/* KEY_Task 任務實現(xiàn) */

static void BSP_Init(void);/* 用于初始化板載相關資源 */

/*****************************************************************
  * @brief  主函數(shù)
  * @param  無
  * @retval 無
  * @note   第一步:開發(fā)板硬件初始化 
            第二步:創(chuàng)建APP應用任務
            第三步:啟動FreeRTOS,開始多任務調度
  ****************************************************************/
int main(void)
{	
  BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值,默認為pdPASS */
  
  /* 開發(fā)板硬件初始化 */
  BSP_Init();
	printf("這是一個FreeRTOS事件標志組實驗!\n");
   /* 創(chuàng)建AppTaskCreate任務 */
  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,  /* 任務入口函數(shù) */
                        (const char*    )"AppTaskCreate",/* 任務名字 */
                        (uint16_t       )512,  /* 任務棧大小 */
                        (void*          )NULL,/* 任務入口函數(shù)參數(shù) */
                        (UBaseType_t    )1, /* 任務的優(yōu)先級 */
                        (TaskHandle_t*  )&AppTaskCreate_Handle);/* 任務控制塊指針 */ 
  /* 啟動任務調度 */           
  if(pdPASS == xReturn)
    vTaskStartScheduler();   /* 啟動任務,開啟調度 */
  else
    return -1;  
  
  while(1);   /* 正常不會執(zhí)行到這里 */    
}


/***********************************************************************
  * @ 函數(shù)名  : AppTaskCreate
  * @ 功能說明: 為了方便管理,所有的任務創(chuàng)建函數(shù)都放在這個函數(shù)里面
  * @ 參數(shù)    : 無  
  * @ 返回值  : 無
  **********************************************************************/
static void AppTaskCreate(void)
{
  BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值,默認為pdPASS */
  
  taskENTER_CRITICAL();           //進入臨界區(qū)
  
  /* 創(chuàng)建 Event_Handle */
  Event_Handle = xEventGroupCreate();	 
  if(NULL != Event_Handle)
    printf("Event_Handle 事件創(chuàng)建成功!\r\n");
    
  /* 創(chuàng)建LED_Task任務 */
  xReturn = xTaskCreate((TaskFunction_t )LED_Task, /* 任務入口函數(shù) */
                        (const char*    )"LED_Task",/* 任務名字 */
                        (uint16_t       )512,   /* 任務棧大小 */
                        (void*          )NULL,	/* 任務入口函數(shù)參數(shù) */
                        (UBaseType_t    )2,	    /* 任務的優(yōu)先級 */
                        (TaskHandle_t*  )&LED_Task_Handle);/* 任務控制塊指針 */
  if(pdPASS == xReturn)
    printf("創(chuàng)建LED_Task任務成功!\r\n");
  
  /* 創(chuàng)建KEY_Task任務 */
  xReturn = xTaskCreate((TaskFunction_t )KEY_Task,  /* 任務入口函數(shù) */
                        (const char*    )"KEY_Task",/* 任務名字 */
                        (uint16_t       )512,  /* 任務棧大小 */
                        (void*          )NULL,/* 任務入口函數(shù)參數(shù) */
                        (UBaseType_t    )3, /* 任務的優(yōu)先級 */
                        (TaskHandle_t*  )&KEY_Task_Handle);/* 任務控制塊指針 */ 
  if(pdPASS == xReturn)
    printf("創(chuàng)建KEY_Task任務成功!\n");
  
  vTaskDelete(AppTaskCreate_Handle); //刪除AppTaskCreate任務
  
  taskEXIT_CRITICAL();            //退出臨界區(qū)
}



/**********************************************************************
  * @ 函數(shù)名  : LED_Task
  * @ 功能說明: LED_Task任務主體
  * @ 參數(shù)    :   
  * @ 返回值  : 無
  ********************************************************************/
static void LED_Task(void* parameter)
{	
  EventBits_t r_event;  /* 定義一個事件接收變量 */
  /* 任務都是一個無限循環(huán),不能返回 */
  while (1)
	{
    /*******************************************************************
     * 等待接收事件標志 
     * 
     * 如果xClearOnExit設置為pdTRUE,那么在xEventGroupWaitBits()返回之前,
     * 如果滿足等待條件(如果函數(shù)返回的原因不是超時),那么在事件組中設置
     * 的uxBitsToWaitFor中的任何位都將被清除。 
     * 如果xClearOnExit設置為pdFALSE,
     * 則在調用xEventGroupWaitBits()時,不會更改事件組中設置的位。
     *
     * xWaitForAllBits如果xWaitForAllBits設置為pdTRUE,則當uxBitsToWaitFor中
     * 的所有位都設置或指定的塊時間到期時,xEventGroupWaitBits()才返回。 
     * 如果xWaitForAllBits設置為pdFALSE,則當設置uxBitsToWaitFor中設置的任何
     * 一個位置1 或指定的塊時間到期時,xEventGroupWaitBits()都會返回。 
     * 阻塞時間由xTicksToWait參數(shù)指定。          
      *********************************************************/
    r_event = xEventGroupWaitBits(Event_Handle,  /* 事件對象句柄 */
                                  KEY1_EVENT|KEY2_EVENT,/* 接收線程感興趣的事件 */
                                  pdTRUE,   /* 退出時清除事件位 */
                                  pdTRUE,   /* 滿足感興趣的所有事件 */
                                  portMAX_DELAY);/* 指定超時事件,一直等 */
                        
    if((r_event & (KEY1_EVENT|KEY2_EVENT)) == (KEY1_EVENT|KEY2_EVENT)) 
    {
      /* 如果接收完成并且正確 */
      printf ( "KEY1與KEY2都按下\n");		
      LED1_TOGGLE;       //LED1	反轉
    }
    else
      printf ( "事件錯誤!\n");	
  }
}

/**********************************************************************
  * @ 函數(shù)名  : KEY_Task
  * @ 功能說明: KEY_Task任務主體
  * @ 參數(shù)    :   
  * @ 返回值  : 無
  ********************************************************************/
static void KEY_Task(void* parameter)
{	 
    /* 任務都是一個無限循環(huán),不能返回 */
  while (1)
  {
    if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON )       //如果KEY2被單擊
		{
      printf ( "KEY1被按下\n" );
			/* 觸發(fā)一個事件1 */
			xEventGroupSetBits(Event_Handle,KEY1_EVENT);  					
		}
    
		if( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON )       //如果KEY2被單擊
		{
      printf ( "KEY2被按下\n" );	
			/* 觸發(fā)一個事件2 */
			xEventGroupSetBits(Event_Handle,KEY2_EVENT); 				
		}
		vTaskDelay(20);     //每20ms掃描一次		
  }
}

/***********************************************************************
  * @ 函數(shù)名  : BSP_Init
  * @ 功能說明: 板級外設初始化,所有板子上的初始化均可放在這個函數(shù)里面
  * @ 參數(shù)    :   
  * @ 返回值  : 無
  *********************************************************************/
static void BSP_Init(void)
{
	/*
	 * STM32中斷優(yōu)先級分組為4,即4bit都用來表示搶占優(yōu)先級,范圍為:0~15
	 * 優(yōu)先級分組只需要分組一次即可,以后如果有其他的任務需要用到中斷,
	 * 都統(tǒng)一用這個優(yōu)先級分組,千萬不要再分組,切忌。
	 */
	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
	
	/* LED 初始化 */
	LED_GPIO_Config();

	/* 串口初始化	*/
	USART_Config();
  
  /* 按鍵初始化	*/
  Key_GPIO_Config();

}

/********************************END OF FILE****************************/

七、實驗現(xiàn)象

? ? ? ? 程序編譯好,用 USB 線連接電腦和開發(fā)板的 USB 接口(對應絲印為 USB 轉串口), 用?仿真器把配套程序下載到?STM32 開發(fā)板,在電腦上打開串口調試助手,然后復位開發(fā)板就可 以在調試助手中看到串口的打印信息,按下開發(fā)版的 KEY1 按鍵發(fā)送事件 1,按下 KEY2 按鍵發(fā)送事件 2;我們按下 KEY1 與 KEY2 試試,在串口調試助手中可以看到運行結果, 并且當事件 1 與事件 2都發(fā)生的時候,開發(fā)板的 LED 會進行翻轉。

freertos,FreeRTOS,筆記,stm32,系統(tǒng)架構,單片機文章來源地址http://www.zghlxwxcb.cn/news/detail-674022.html

到了這里,關于FreeRTOS事件組 基于STM32的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • STM32操作系統(tǒng)FreeRTOS學習——基于hal庫

    STM32操作系統(tǒng)FreeRTOS學習——基于hal庫

    目錄 一、基礎概念 1、FreeRTOS 2、單片機編程的系統(tǒng)概念 a、裸機系統(tǒng),包括輪詢系統(tǒng)(不包括中斷)和前后臺系統(tǒng)(中斷為前臺,輪詢?yōu)楹笈_) b、多任務系統(tǒng) 3、FreeRTOS編程風格 a、數(shù)據類型 b、變量名的定義 c、函數(shù)名 d、宏定義 二、Cubemx創(chuàng)建工程 1、創(chuàng)建任務 2、創(chuàng)建隊列

    2024年02月10日
    瀏覽(41)
  • STM32基于HAL庫和STM32CubeMX的實時操作系統(tǒng)FreeRtOS開發(fā)

    STM32基于HAL庫和STM32CubeMX的實時操作系統(tǒng)FreeRtOS開發(fā)

    1、FreeRTOS RTOS是一類操作系統(tǒng),μC/OS,F(xiàn)reeRTOS,RTX,RT-Thread 等這些都是RTOS 類的操作系統(tǒng) FreeRTOS 是眾多RTOS 類操作系統(tǒng)中的一種,F(xiàn)reeRTOS 十分的小巧,可以在資源有限的微控制器中運行,F(xiàn)reeRTOS 也不僅僅局限于在微控制器中使用。就單從文件數(shù)量上來看FreeRTOS 要比μC/OS 少得多

    2024年02月21日
    瀏覽(19)
  • FreeRTOS內存管理 基于STM32

    FreeRTOS內存管理 基于STM32

    目錄 一、內存管理的基本概念 二、內存管理的應用場景 三、heap_4.c 1.內存申請函數(shù) pvPortMalloc() 2.內存釋放函數(shù) vPortFree() ?四、內存管理的實驗 五、內存管理的實驗現(xiàn)象 ? ? ? 在計算系統(tǒng)中,變量、中間數(shù)據一般存放在系統(tǒng)存儲空間中,只有在實際使用時才將 它們從存儲空

    2024年02月14日
    瀏覽(18)
  • 【STM32/FreeRTOS】SysTick定時器及FreeRTOS系統(tǒng)節(jié)拍

    【STM32/FreeRTOS】SysTick定時器及FreeRTOS系統(tǒng)節(jié)拍

    目錄 一、SysTick定時器 1、SysTick寄存器介紹 (1)控制及狀態(tài)寄存器 (2)重裝載數(shù)值寄存器 (3)當前數(shù)值寄存器 2、SysTick寄存器配置函數(shù) 二、FreeRTOS中的SysTick定時器 1、SysTick配置函數(shù)及分析 2、SysTick中斷函數(shù) 三、其他操作配置FreeRTOS的SysTick 1、找到頭文件 FreeRTOSConfig.h 有如

    2024年01月24日
    瀏覽(24)
  • STM32 CubeMX (第二步Freertos任務通信:隊列、信號量、互斥量,事件組,任務通知)

    STM32 CubeMX (第二步Freertos任務通信:隊列、信號量、互斥量,事件組,任務通知)

    學習使用Freertos第二步 在 FreeRTOS 中,任務通信可以通過以下函數(shù)來實現(xiàn): xQueueCreate() :用于創(chuàng)建一個消息隊列??梢栽O置隊列長度和每個消息的大小。 xQueueSend() :將一條消息發(fā)送到隊列中??梢赃x擇阻塞或非阻塞發(fā)送。 xQueueReceive() :從隊列中接收一條消息??梢赃x擇阻塞

    2024年02月11日
    瀏覽(24)
  • FreeRTOS軟件定時器 基于STM32

    FreeRTOS軟件定時器 基于STM32

    文章目錄 一·、軟件定時器的基本概念 二、軟件定時器應用場景 三、軟件定時器的精度 四、軟件定時器的運作機制 五、軟件定時器函數(shù)接口講解 1.軟件定時器創(chuàng)建函數(shù) xTimerCreate() 2.軟件定時器啟動函數(shù) xTimerStart() ?3.軟件定時器停止函數(shù)? xTimerStop() ?4.軟件定時器任務 5.軟件

    2024年02月11日
    瀏覽(23)
  • STM32移植FreeRTOS操作系統(tǒng)

    STM32移植FreeRTOS操作系統(tǒng)

    一、FreeRTOS源碼下載 (1)移植錢得準備前菜對吧,我們先來去官網瞄一瞄 網址:FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions 第一步:點擊下載FreeRTOS 第二步:選擇版本下載(我選擇穩(wěn)定版本) 注:我們下載的穩(wěn)定版本不包含DEMO例

    2024年01月17日
    瀏覽(19)
  • STM32FreeRTOS操作系統(tǒng)移植

    STM32FreeRTOS操作系統(tǒng)移植

    移植好的FreeRTOS模板: 鏈接:https://pan.baidu.com/s/1_87VQAWXUl4jTqSCZ0MFjw?pwd=dw52? 提取碼:dw52 1.在工程中新建FreeRTOS文件夾 2.把源碼source里面的文件全部粘貼進FreeRTOS文件夾中 ?3.在portable文件中只保留一下文件,其余刪除 ?4.新建如下兩個文件夾 ?5.在FreeRTOS_CODE目錄下添加以下文件

    2024年02月08日
    瀏覽(31)
  • 基于STM32+FreeRTOS的四軸機械臂

    基于STM32+FreeRTOS的四軸機械臂

    目錄 代碼: 注釋寫的較少,但本文出現(xiàn)的代碼都有注釋,所以請直接在本文里看注釋 項目概述: 一 準備階段(都是些廢話) ?二 裸機測試功能 1.搖桿控制 接線: CubeMX配置: 代碼 2.藍牙控制 接線: CubeMX配置 代碼: 3.示教器控制 4.記錄動作信息 5.執(zhí)行記錄的動作 注: 三

    2024年02月12日
    瀏覽(18)
  • 基于STM32CubeMX創(chuàng)建FreeRTOS—以STM32F429為例

    基于STM32CubeMX創(chuàng)建FreeRTOS—以STM32F429為例

    目錄 1. 實驗任務 2. 使用STM32CubeMX創(chuàng)建基礎工程 2.1 使用STM32CubeMX創(chuàng)建項目 2.2 創(chuàng)建新項目 2.3 時鐘設置 2.4 時鐘配置樹 2.5 修改時鐘基準,打開串行調試 2.6 配置串口 2.7 配置狀態(tài)指示燈 2.8 FreeRTOS配置 2.9 配置工程輸出項 3. 代碼編輯 3.1 printf重映射 3.1.1 使用ARMCC 5編譯器時的print

    2024年01月22日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包