娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年02月07日(星期五)

正在發生

2021年02月07日 | STM32 系統級開發之 ucosIII 或 freeRTOS 事件標志組詳解

發布者:VS821001 來源: eefocus關鍵字:STM32  ucosIII  freeRTOS  事件標志組 手機看文章 掃描二維碼
隨時隨地手機看文章

1、輕型操作系統同步的方案詳解


1)信號量

假設有兩個任務 Task1 和 Task2,第一個任務進行按鍵的掃描,第二個任務進行LED燈的點亮

需求:

掃描到按鍵按下后點亮 LED 燈,也就是說第二個任務永遠在等待第一個任務按鍵的掃描

實現:

首先 Task1 一直檢測按鍵是否按下,如果按鍵按下以后,使用一個全局變量 flag 并設置 flag=1

而在 Task2 當中,不停檢測 flag 值是否為 1,如果為 1,點亮 led 燈并把flag清零

此時 flag 提供的是一個信號量的作用,也就是說 Task1 按下按鍵以后,開始向 Task2 發送一個信號量 flag,Task2 接收到了 flag 信號量以后,就把LED燈點亮

2)互斥性信號量

假設有兩個任務 Task1 和 Task2,都需要來訪問一個共享的資源,如要訪問一個共享的打印機

需求:

假設第一個任務 Task1 要打印 hello,第二個任務 Task2 要打印 world,Task1 在使用打印機的時候,Task2是絕對不能使用的,兩個任務屬于互斥關系

如果 Task1 在使用打印機,Task2 也在使用打印機,那打印出來的數據可能會出現亂碼

實現:

為了防止 Task1 和 Task2 共同使用打印機,配置的時候就要使用一個約束,假設還是使用一個全局變量 flag 來表示

如果 flag=1,表示這個打印機處于空閑狀態,假設這個時候 Task1 要使用打印機,它首先要判斷 flag 的狀態,如果判斷 flag=1,它就開始使用打印機并且把 flag 置 0

同樣,假設這個時候,Task2也來使用打印機,它同樣要判斷 flag 的狀態是否等于 1,如果判斷這個時候flag=0,它就知道這個時候打印機處于忙的狀態

它就要等待 Task1 把打印機使用完畢,同時會把 flag 置為 1,這個時候 Task2 任務就可以使用打印機了

3)事件標志組

假設兩個任務 Task1 和 Task2,Task1 進行按鍵掃描,Task2 進行 LED 燈的點亮

同樣的道理,按鍵按下時 LED 燈點亮,但是如果是 N 個按鍵 控制 N 個 LED

使用一個全局變量 flag,但是使用 flag 的各個位來表明了按鍵按下的狀態,flag 的第 0 位為 1 表明第一個按鍵按下

同樣 flag 的第 1 位按鍵為 1,表明第二個按鍵已經按下,依次類推

此時 flag 已經不再是一個信號量了,而是一個事件的標志,它的一位標志著一個事件是否發生,比如說第0位為0,表明這個事件沒發生,第1位為1,表明這個事件發生了,這個時候這個flag就被稱為一個事件的標志

那Task2在使用的過程中,它就需要來判斷flag這個事件的各個位

當然事件的標志還有一些其他的高級標志,比如說你各個位能判斷某一個事件,還可以判斷一個組合事件:

比如第一個按鍵按下了,并且第二個按鍵也按下了,并且第三個按鍵也按下了,那你們都按下以后,我才讓某個燈亮

這樣我們就可以通過事件標志組來通過各個標志位,來相互的判斷,那這個就被稱為事件標志組,它不是信號量,但是它還是屬于信號量的范疇

2、freeRTOS事件標志組詳解


需求:

任務可能會需要與多個事件或任務進行同步,此時信號量就無
能為力了。 FreeRTOS 為此提供了一個可選的解決方法,那就是事件標志組。

簡介:

1)、事件位(事件標志)

事件位用來表明某個事件是否發生,事件位通常用作事件標志

比如下面的幾個例子:

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

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

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

2)、事件組

一個事件組就是一組的事件位, 事件組中的事件位通過位編號來訪問

同樣,以上面列出的三個例子為例:

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

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

● 事件標志組的 bit2 表示現在是否需要向網絡發送心跳信息。

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

事件標志組的數據類型為 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;

數據類型 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 位的數據類型, 因此 EventBits_t 也是個 32 位的數據類型。 EventBits_t 類型的變量可以存儲 24 個事件位,另外的那高 8 位有其他用。事件位 0 存放在這個變量的 bit0 上,變量的 bit1 就是事件位 1,以此類推。對于 STM32 來說一個事件標志組最多可以存儲 24 個事件位。

3、測試試驗詳解


1)、需求

學習 FreeROTS 事件標志組的使用,包括創建事件標志組、將相應的事件位置 1、等待相應
的事件位置 1 等操作。

2)、實現

設計四個任務: start_task、 eventsetbit_task、 eventgroup_task 和 eventquery_task 

這四個任務的任務功能如下:

start_task:用來創建其他三個任務和事件標志組。

eventsetbit_task: 讀取按鍵值,根據不同的按鍵值將事件標志組中相應的事件位置 1,用來
模擬事件的發生。

eventgroup_task:同時等待事件標志組中的多個事件位,當這些事件位都置 1 的話就執行相應的處理,例程中是刷新 LCD 指定區域的背景色。

eventquery_task:查詢事件組的值,也就是各個事件位的值。獲取到事件組值以后就將其顯示到 LCD 上,并且也通過串口打印出來。

實驗中還創建了一個事件標志組: EventGroupHandler,實驗中用到了這個事件標志組的三個事件位,分別位 bit0, bit1 和 bit2。

實驗中會用到 3 個按鍵: KEY0、 KEY1 和 KEY2,其中按鍵 KEY1 和 KEY2 為普通的輸入模式。按鍵 KEY0 為中斷輸入模式,KEY0 用來演示如何在中斷服務程序調用事件標志組的 API函數。

3)、工程

●任務設置

#define START_TASK_PRIO 1 //任務優先級
#define START_STK_SIZE 256 //任務堆棧大小

TaskHandle_t StartTask_Handler; //任務句柄
void start_task(void *pvParameters); //任務函數

#define EVENTSETBIT_TASK_PRIO 2 //任務優先級
#define EVENTSETBIT_STK_SIZE 256 //任務堆棧大小

TaskHandle_t EventSetBit_Handler; //任務句柄
void eventsetbit_task(void *pvParameters); //任務函數

#define EVENTGROUP_TASK_PRIO 3 //任務優先級
#define EVENTGROUP_STK_SIZE 256 //任務堆棧大小

TaskHandle_t EventGroupTask_Handler; //任務句柄
void eventgroup_task(void *pvParameters); //任務函數

#define EVENTQUERY_TASK_PRIO 4 //任務優先級
#define EVENTQUERY_STK_SIZE 256 //任務堆棧大小

TaskHandle_t EventQueryTask_Handler; //任務句柄
void eventquery_task(void *pvParameters); //任務函數

EventGroupHandle_t EventGroupHandler; //事件標志組句柄
#define EVENTBIT_0 (1<<0) //事件位
#define EVENTBIT_1 (1<<1)
#define EVENTBIT_2 (1<<2)
#define EVENTBIT_ALL (EVENTBIT_0|EVENTBIT_1|EVENTBIT_2)

//LCD 刷屏時使用的顏色
int lcd_discolor[14]={ WHITE, BLACK, BLUE, BRED,
GRED, GBLUE, RED, MAGENTA,
GREEN, CYAN, YELLOW, BROWN,
BRRED, GRAY };

● main()函數

int main(void)
{
  HAL_Init(); //初始化 HAL 庫
  Stm32_Clock_Init(360,25,2,8); //設置時鐘,180Mhz
  delay_init(180); //初始化延時函數
  uart_init(115200); //初始化串口
  LED_Init(); //初始化 LED
  KEY_Init(); //初始化按鍵
  PCF8574_Init(); //初始化 PCF8574
  EXTI_Init(); //初始化外部中斷
  SDRAM_Init(); //初始化 SDRAM
  LCD_Init(); //初始化 LCD
  my_mem_init(SRAMIN); //初始化內部內存池
  POINT_COLOR = RED;
  LCD_ShowString(30,10,200,16,16,"Apollo STM32F4/F7");
  LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 16-1");
  LCD_ShowString(30,50,200,16,16,"Event Group");
  LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
  LCD_ShowString(30,90,200,16,16,"2016/11/11");
  POINT_COLOR = BLACK;
  LCD_DrawRectangle(5,130,234,314); //畫矩形


  POINT_COLOR = BLUE;
  LCD_ShowString(30,110,220,16,16,"Event Group Value:0");
  //創建開始任務
  xTaskCreate((TaskFunction_t )start_task, //任務函數
  (const char* )"start_task", //任務名稱
  (uint16_t )START_STK_SIZE, //任務堆棧大小
  (void* )NULL, //傳遞給任務函數的參數
  (UBaseType_t )START_TASK_PRIO, //任務優先級
  (TaskHandle_t* )&StartTask_Handler); //任務句柄
  vTaskStartScheduler(); //開啟任務調度
}


● 任務函數
//開始任務任務函數
void start_task(void *pvParameters)
{
  taskENTER_CRITICAL(); //進入臨界區
  //創建事件標志組
  EventGroupHandler=xEventGroupCreate(); //創建事件標志組 (1)
  //創建設置事件位的任務
  xTaskCreate((TaskFunction_t )eventsetbit_task,
              (const char* )"eventsetbit_task",
              (uint16_t )EVENTSETBIT_STK_SIZE,
              (void* )NULL,
              (UBaseType_t )EVENTSETBIT_TASK_PRIO,
              (TaskHandle_t* )&EventSetBit_Handler);
  //創建事件標志組處理任務
  xTaskCreate((TaskFunction_t )eventgroup_task,
              (const char* )"eventgroup_task",
              (uint16_t )EVENTGROUP_STK_SIZE,
              (void* )NULL,
              (UBaseType_t )EVENTGROUP_TASK_PRIO,
              (TaskHandle_t* )&EventGroupTask_Handler);
  //創建事件標志組查詢任務
  xTaskCreate((TaskFunction_t )eventquery_task,
              (const char* )"eventquery_task",
              (uint16_t )EVENTQUERY_STK_SIZE,
              (void* )NULL,
              (UBaseType_t )EVENTQUERY_TASK_PRIO,
              (TaskHandle_t* )&EventQueryTask_Handler);
  vTaskDelete(StartTask_Handler); //刪除開始任務
  taskEXIT_CRITICAL(); //退出臨界區
}


//設置事件位的任務
void eventsetbit_task(void *pvParameters)
{
  u8 key;
  while(1)
  {
    if(EventGroupHandler!=NULL)
    {
      key=KEY_Scan(0);
      switch(key)
      {
        case KEY1_PRES:
          xEventGroupSetBits(EventGroupHandler,EVENTBIT_1); (2)
        break;
        case KEY2_PRES:
          xEventGroupSetBits(EventGroupHandler,EVENTBIT_2); (3)
        break;
       }
}
}
  
//事件標志組處理任務
void eventgroup_task(void *pvParameters)
{
  u8 num;
  EventBits_t EventValue;
  while(1)
  {
    if(EventGroupHandler!=NULL)
    {
      //等待事件組中的相應事件位
      EventValue=xEventGroupWaitBits((EventGroupHandle_t )EventGroupHandler, (4)
      (EventBits_t ) EVENTBIT_ALL,
      (BaseType_t )pdTRUE,
      (BaseType_t )pdTRUE,
      (TickType_t )portMAX_DELAY);
      printf("事件標志組的值:%drn",EventValue);ALIENTEK 阿波羅 FreeRTOS 開發教程
      303
      STM32F429 FreeRTOS 開發手冊
      LCD_ShowxNum(174,110,EventValue,1,16,0);
      num++;
      LED1=!LED1;
      LCD_Fill(6,131,233,313,lcd_discolor[num%14]);
}
    else
    {
      vTaskDelay(10); //延時 10ms,也就是 10 個時鐘節拍
    }
   }
}


//事件查詢任務
void eventquery_task(void *pvParameters)
{
  u8 num=0;
  EventBits_t NewValue,LastValue;
  while(1)
  {
    if(EventGroupHandler!=NULL)
    {
      NewValue=xEventGroupGetBits(EventGroupHandler); //獲取事件組的 (5)
      if(NewValue!=LastValue)
      {
        LastValue=NewValue;
        printf("事件標志組的值:%drn",NewValue);
        LCD_ShowxNum(174,110,NewValue,1,16,0);
      }
      num++;
      if(num==0) //每 500msLED0 閃爍一次
      {
        num=0;
        LED0=!LED0;
      }
        vTaskDelay(50); //延時 50ms,也就是 50 個時鐘節拍
    }
}


(1)、首先調用函數 xEventGroupCreate()創建一個事件標志組 EventGroupHandler。


(2)、按下 KEY1 鍵的時候就調用函數 xEventGroupSetBits()將事件標志組的 bit1 置 1。


(3)、按下 KEY2 鍵的時候調用函數 xEventGroupSetBits()將事件標志組的 bit2 值 1。


(4)、調用函數 xEventGroupWaitBits()同時等待事件標志組的 bit0, bit1 和 bit2,只有當這三個事件都置 1 的時候才會執行任務中的其他代碼。


(5)、調用函數 xEventGroupGetBits()查詢事件標志組 EventGroupHandler 的值變化,通過查看這些值的變化就可以分析出當前哪個事件位置 1 了。


● 中斷初始化及處理過程


事件標志組 EventGroupHandler的事件位 bit0 是通過 KEY0 的外部中斷服務函數來設置的,


注意中斷優先級的設置!本例程的中斷優先級設置如下:
//中斷線 3-PH3
HAL_NVIC_SetPriority(EXTI3_IRQn,6,0); //搶占優先級為 6,子優先級為 0
HAL_NVIC_EnableIRQ(EXTI3_IRQn); //使能中斷線 3
KEY0 的外部中斷服務函數如下:
//事件標志組句柄
extern EventGroupHandle_t EventGroupHandler;
//中斷服務函數
void EXTI3_IRQHandler(void)
{
  BaseType_t Result,xHigherPriorityTaskWoken;
  delay_xms(50); //消抖
  if(KEY0==0)
  {
    Result=xEventGroupSetBitsFromISR(EventGroupHandler,EVENTBIT_0, (1)
    &xHigherPriorityTaskWoken);
    if(Result!=pdFAIL)
    {
      portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
  }
  __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_3); //清除中斷標志位
}


(1)、 在中斷服務函數中通過調用 xEventGroupSetBitsFromISR()來將事件標志組的事件位
bit0 置 1。

[1] [2]
關鍵字:STM32  ucosIII  freeRTOS  事件標志組 引用地址:STM32 系統級開發之 ucosIII 或 freeRTOS 事件標志組詳解

上一篇:STM32Cube 工具說明和安裝淺析
下一篇:STM32 IIC 詳解 之 stm32 IIC 從機模式(中斷方式收發數據)

推薦閱讀

集微網消息(文/羅明)去年對于小米來說是值得慶祝的一年,得益于全球市場表現搶眼,印度連續兩個季度第一,全球十六個國家進入前五,10月提前實現年初提出的營收過千億目標。雷軍在小米年會中表示其市場份額已從去年第二季度的世界前五,提升至第四季度的世界第四。?雷軍除了總結小米過去一年取得的一系列成就,還指出新的一年要大力開拓海外市場,同時...
像任何的技術一樣,當新硬件進入市場時,舊的技術要么被取而代之,要么接受改造。2018年的一些新技術,從許多方面改變了我們的生活。從家庭助手到幫助拯救環境,機器人將繼續進化,承擔起我們分配的任何任務。下面就來看看過去一年出現的一些新機器人,順便展望一下未來。1.波士頓動力公司的Atlas人形機器人表演跑酷自2013年推出以來,波士頓動力公司(Bost...
內容說明本實用新型涉及安裝檢測領域,特別涉及一種電磁流量計校準裝置。發明背景電磁流量計,是應用電磁感應原理,根據導電流體通過外加磁場時感生的電動勢來測量導電流體流量的一種儀器。目前,電磁流量計一般包括供待測量液體流過的測量導管、設于測量導管兩端的法蘭盤,法蘭盤上沿自身圓周方向等間距間隔設置有安裝孔,法蘭盤用于將電磁流量計連接于待...
1、堆棧存儲器堆棧存儲區是在片上存儲器中的SRAM(或RAM)中由用戶自行開辟的一片數據存儲區域,并且堆棧區的大小可根據用戶的需要任意指定(只要不超過SRAM或RAM的大小),而堆棧區的位置由編譯器指定分配。 Cortex-M3/M4處理器的堆棧指針SP是“滿遞減,空遞增”,呈現向下逆生長的特點。 堆棧區數據的存儲特點是“先進后出,后進先出”。這種特點是由堆...

史海拾趣

問答坊 | AI 解惑

定點DSP芯片TMS320F2812實現快速算法應用

定點運算DSP在應用中已取得了極大的成功,而且仍然是DSP應用的主體。然而,隨著對DSP處理速度與精度、存儲器容量、編程的靈活性和方便性要求的不斷提高、自80年代中后期以來,各DSP生產廠家陸續推出了各自的32bit浮點運算DSP。…

查看全部問答∨

自制印刷電路板描繪劑

自己制作電路板時劃好線總想把多余的銅去掉,如果你用刀子在上面劃沒有什么用處,只好是將制作好的板子放在三氯化鐵中這樣多余的銅才會去掉,用覆蓋劑劃好圖<油漆當覆蓋劑也可以>然后放在三氯化鐵中溶解掉銅,業余制作印刷板有很多方法,用什 ...…

查看全部問答∨

現在的三軸加速度傳感器很便宜了,可以用于報警器的的振動傳感器嗎?

有人用三軸加速度計做振動傳感器嗎?實測效果如何,反應靈敏否?對鞭炮聲應該不敏感.…

查看全部問答∨

請幫幫我

請大家幫忙,我現在要搞一個項目,需要用到用vb.net調用evc4.0做的.dll,可是我每次調用時都不成功,各位能否幫我解決一下,不勝感激…

查看全部問答∨

月薪1萬找藍牙開發工程師【上海】

我們公司要招一名Linux下的藍牙開發工程師。公司地址在上海中山公園附近。薪資待遇1萬/月。 職位要求: 1、精通LINUX系統以及C/C++編程(必須)。 2、熟悉嵌入式系統、單片機的開發。 3、精通藍牙協議、藍牙應用開發(必須)。 4、至少三年以 ...…

查看全部問答∨

如何區分是USB 還是SD卡的插拔

如題。 現在要做USB插入和拔除的探測,并得到其盤符。 我是直接解析系統廣播的消息:DBT_DEVICEREMOVECOMPLETE 和 DBT_DEVICEARRIVAL 但是問題比較奇怪,拔插U盤,與拔插SD卡得到的消息與參數是一樣的: DEV_BROADCAST_HDR 結構的dbcp_devicety ...…

查看全部問答∨

無線傳輸數據,發射端移動的時候,對傳輸質量影響很大,請問有沒有什么好的解決方法?

現在有一個無線的項目(不采用跳頻),我對無線接觸不多,碰到這樣的問題,發射端在移動的時候,對發射質量影響特別大,請教一下這方面的知識,和解決這個問題的方法。謝謝!…

查看全部問答∨

如何在ftp中顯示板子上文件的修改時間

ftp連接上后,選擇詳細信息,有的文件有修改時間,有的沒有,并且顯示的時間也不對 mpc860/tffs…

查看全部問答∨

在脈沖RD的上升沿將內存的數據讀到芯片的數據端口DOUT,怎樣實現?

可以讓這個脈沖信號直接做clock使用嗎?? 例如下面這樣寫:always @(posedge RD )  DOUT_EN==1\'b1;產生一個enable 信號,綜合時要對這個RD create clock 嗎??…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 晋中市| 麻城市| 迁西县| 古交市| 岳阳市| 上杭县| 韩城市| 绵竹市| 施甸县| 宁海县| 沂源县| 宜宾县| 股票| 开封县| 志丹县| 抚州市| 田东县| 托里县| 马边| 息烽县| 罗甸县| 昂仁县| 天峨县| 平潭县| 铅山县| 土默特右旗| 南漳县| 久治县| 江口县| 汝州市| 兴安盟| 滦平县| 比如县| 珠海市| 胶南市| 鄯善县| 布拖县| 北宁市| 北海市| 延寿县| 略阳县|