<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      RT-Thread之事件集使用示例

      一、事件集概述

      事件集(Event)是 RT-Thread 中用于線程間同步的輕量級(jí) IPC 機(jī)制,核心特性是 “多標(biāo)志位” 與 “靈活觸發(fā)”:通過 32 個(gè)事件標(biāo)志位(bit0~bit31)表示不同事件狀態(tài),支持線程按 “邏輯與(AND)” 或 “邏輯或(OR)” 關(guān)系等待多個(gè)事件,實(shí)現(xiàn)一對多、多對多的線程同步。

      典型應(yīng)用場景

      • 線程等待多個(gè)外部觸發(fā)條件(如按鍵按下 + 傳感器數(shù)據(jù)就緒),滿足任意條件或全部條件時(shí)執(zhí)行;
      • 狀態(tài)機(jī)切換同步(如設(shè)備初始化完成 + 網(wǎng)絡(luò)連接成功后,觸發(fā)業(yè)務(wù)線程啟動(dòng));
      • 中斷與線程間通信(中斷服務(wù)程序發(fā)送事件,線程等待事件處理異步通知)。

      二、事件集核心 API 函數(shù)

      事件集的操作圍繞 “創(chuàng)建 / 初始化 / 發(fā)送事件 / 接收事件 / 刪除 / 脫離” 展開,需區(qū)分動(dòng)態(tài)創(chuàng)建(依賴內(nèi)存堆)與靜態(tài)初始化(基于全局 / 靜態(tài)變量),核心函數(shù)與參數(shù)說明如下。

      2.1 事件集的創(chuàng)建與初始化

      用于完成事件集的初始化工作,動(dòng)態(tài)創(chuàng)建會(huì)從堆中分配內(nèi)存,靜態(tài)初始化需提前定義全局 / 靜態(tài)事件集對象。

      2.1.1 動(dòng)態(tài)創(chuàng)建

      通過函數(shù)從內(nèi)存堆中分配事件集資源,返回事件集句柄用于后續(xù)操作。

      rt_event_t rt_event_create(const char *name, rt_uint8_t flag);
      
      • name:事件集名稱。
      • flag:等待隊(duì)列排序方式,可選值為 RT_IPC_FLAG_FIFO(先進(jìn)先出)或 RT_IPC_FLAG_PRIO(按線程優(yōu)先級(jí)排序)。

      2.1.2 靜態(tài)初始化

      基于已定義的全局 / 靜態(tài)事件集對象進(jìn)行初始化,無需分配堆內(nèi)存。

      rt_err_t rt_event_init(rt_event_t event, const char *name, rt_uint8_t flag);
      
      • event:提前定義的全局 / 靜態(tài)事件集對象(如 struct rt_event event_test)。
      • name:事件集名稱,功能同動(dòng)態(tài)創(chuàng)建。
      • flag:等待隊(duì)列排序方式,功能同動(dòng)態(tài)創(chuàng)建。

      2.2 事件的發(fā)送與接收

      發(fā)送事件用于設(shè)置事件集中的標(biāo)志位,接收事件用于等待指定標(biāo)志位滿足條件,支持按邏輯關(guān)系觸發(fā)。

      2.2.1 發(fā)送事件

      設(shè)置事件集中的一個(gè)或多個(gè)標(biāo)志位,可喚醒等待該事件的線程。

      rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set);
      
      • event:目標(biāo)事件集句柄 / 對象。
      • set:待設(shè)置的事件標(biāo)志位(如 0x01 表示 bit0,0x03 表示 bit0 + bit1)。
      • 注意:可在中斷服務(wù)程序(ISR)中調(diào)用,用于通知線程處理異步事件。

      2.2.2 接收事件

      等待事件集中的指定標(biāo)志位,滿足邏輯關(guān)系(AND / OR)時(shí)喚醒線程,支持超時(shí)機(jī)制。

      rt_err_t rt_event_recv(rt_event_t event, rt_uint32_t set, rt_uint8_t option, rt_int32_t timeout, rt_uint32_t *recved);
      
      • event:目標(biāo)事件集句柄 / 對象。
      • set:待等待的事件標(biāo)志位(如 0x03 表示等待 bit0 或 bit1)。
      • option:對標(biāo)志位的配置,RT_EVENT_FLAG_AND(全部標(biāo)志位滿足)或 RT_EVENT_FLAG_OR(任意標(biāo)志位滿足),也可以選用RT_EVENT_FLAG_CLEAR,表示接收事件后自動(dòng)清除已滿足的標(biāo)志位
      • timeout:等待時(shí)間(單位:tick),可選值為 RT_WAITING_FOREVER(永久等待)、0(無等待)或具體數(shù)值。
      • recved:輸出參數(shù),用于返回實(shí)際接收到的事件標(biāo)志位(可設(shè)為 RT_NULL)。

      2.3 事件集的刪除與脫離

      用于回收事件集占用的系統(tǒng)資源,動(dòng)態(tài)創(chuàng)建的事件集需刪除,靜態(tài)初始化的事件集需脫離。

      2.3.1 動(dòng)態(tài)刪除

      用于銷毀通過 rt_event_create 動(dòng)態(tài)創(chuàng)建的事件集,釋放其占用的堆內(nèi)存。

      rt_err_t rt_event_delete(rt_event_t event);
      
      • event:動(dòng)態(tài)創(chuàng)建的事件集句柄。
      • 適用場景:動(dòng)態(tài)創(chuàng)建的事件集不再使用時(shí),需調(diào)用此函數(shù)避免內(nèi)存泄漏。

      2.3.2 靜態(tài)脫離

      用于脫離通過 rt_event_init 靜態(tài)初始化的事件集,僅注銷其在系統(tǒng)中的登記信息,不釋放內(nèi)存。

      rt_err_t rt_event_detach(rt_event_t event);
      
      • event:靜態(tài)初始化的事件集對象。
      • 適用場景:靜態(tài)事件集不再使用時(shí),需調(diào)用此函數(shù)釋放系統(tǒng)資源(如等待隊(duì)列)。

      三、事件集使用示例

      3.1 源代碼

      #include "thread_task.h"
      #include "main.h"
      #include <stdio.h>      
      #include "rtthread.h"
      #include <rthw.h>
      
      /******************************************** 線程 1 ******************************************************/
      #define THREAD_1_PRIORITY  		4           /* 線程優(yōu)先級(jí)(值越小優(yōu)先級(jí)越高) */
      #define THREAD_1_STACK_SIZE		512         /* 線程棧空間大小(單位:字節(jié)) */
      #define THREAD_1_TIMESLICE		10           /* 線程時(shí)間片個(gè)數(shù)(單位:tick) */
      static struct rt_thread *thread_1_handle;    /* 線程句柄 */
      
      /******************************************** 線程 2 ******************************************************/
      #define THREAD_2_PRIORITY  		5           /* 線程優(yōu)先級(jí)(低于線程1) */
      #define THREAD_2_STACK_SIZE		512         /* 線程棧空間大小 */
      #define THREAD_2_TIMESLICE		10           /* 線程時(shí)間片個(gè)數(shù) */
      static struct rt_thread *thread_2_handle;    /* 線程句柄 */
      
      /* 靜態(tài)事件集對象(全局定義,提前分配內(nèi)存) */
      struct rt_event event_test;
      /* 事件標(biāo)志位定義:bit0 表示線程1觸發(fā)事件,bit1 表示線程2觸發(fā)事件 */
      #define EVENT1_FLAG    (1 << 0)  /* 0x01 */
      #define EVENT2_FLAG    (1 << 1)  /* 0x02 */
      #define EVENT3_FLAG    (1 << 2)  /* 0x04 */
      
      /**
       * @brief  LED閃爍函數(shù)(固定閃爍6次,即3個(gè)完整周期)
       * @param  time:每次翻轉(zhuǎn)后的延遲時(shí)間(單位:tick)
       */
      void LED_toggle(uint16_t time)
      {   
          for(uint8_t i = 0; i < 6; i++)  
          {
              HAL_GPIO_TogglePin(GPIOC, LED1_Pin);
              rt_thread_delay(time);      
          }
      }
      
      /**
       * @brief  線程1入口函數(shù)(高優(yōu)先級(jí),接收事件觸發(fā)LED慢速閃爍)
       * @param  param:線程參數(shù)(未使用,設(shè)為RT_NULL)
       */
      void thread_1_entry(void* param)
      {
          rt_uint32_t recved = 0;
          while(1)
          {
              /* 接收事件:等待EVENT1+EVENT2,AND邏輯,永久等待,接收后清除標(biāo)志位 */
              if (rt_event_recv(&event_test, EVENT2_FLAG | EVENT1_FLAG , 
                              RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,  // 補(bǔ)充RT_EVENT_FLAG_CLEAR
                              RT_WAITING_FOREVER, &recved) == RT_EOK)
              {
                  /* 接收到事件后,慢速閃爍LED(0.5Hz) */  // 修正頻率描述
                  LED_toggle(1000);
                  rt_event_send(&event_test, EVENT3_FLAG);
              }
          }
      }
      
      /**
       * @brief  線程2入口函數(shù)(低優(yōu)先級(jí),接收事件觸發(fā)LED快速閃爍)
       * @param  param:線程參數(shù)(未使用,設(shè)為RT_NULL)
       */
      void thread_2_entry(void* param)
      {   
          rt_uint32_t recved = 0;
          while(1)
          {
              /* 接收事件:等待EVENT3_FLAG,AND邏輯,永久等待,接收后清除標(biāo)志位 */  // 修正筆誤
              if (rt_event_recv(&event_test, EVENT3_FLAG, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER , &recved) == RT_EOK)
              {
                  rt_event_send(&event_test, EVENT2_FLAG);
                  LED_toggle(100);
                  rt_thread_delay(500); 
                  LED_toggle(100);
                  rt_event_send(&event_test, EVENT1_FLAG);
              }
          }
      }
      
      /**
       * @brief  初始化事件集并創(chuàng)建啟動(dòng)線程(先初始化事件集,再啟動(dòng)線程)
       */
      void ThreadStart(void)
      {
          rt_base_t level = rt_hw_interrupt_disable();  
      
          /* 靜態(tài)初始化事件集 */
          rt_event_init(
              &event_test,            /* 事件集對象 */
              "event_test",           /* 事件集名稱(用于finsh調(diào)試) */
              RT_IPC_FLAG_FIFO        /* 等待隊(duì)列按FIFO排序 */
          );
          rt_event_send(&event_test, EVENT3_FLAG);
      
          /* 動(dòng)態(tài)創(chuàng)建并啟動(dòng)線程1 */
          thread_1_handle = rt_thread_create(
              "thread_1",				/* 線程名稱 */
              thread_1_entry,			/* 線程入口函數(shù) */
              RT_NULL,				/* 線程參數(shù) */
              THREAD_1_STACK_SIZE,	/* 線程棧大小 */
              THREAD_1_PRIORITY,		/* 線程優(yōu)先級(jí) */
              THREAD_1_TIMESLICE  	/* 線程時(shí)間片 */
          );
          if (thread_1_handle != RT_NULL)
              rt_thread_startup(thread_1_handle);  
      
          /* 動(dòng)態(tài)創(chuàng)建并啟動(dòng)線程2 */
          thread_2_handle = rt_thread_create(
              "thread_2",				/* 線程名稱 */
              thread_2_entry,			/* 線程入口函數(shù) */
              RT_NULL,				/* 線程參數(shù) */
              THREAD_2_STACK_SIZE,	/* 線程棧大小 */
              THREAD_2_PRIORITY,		/* 線程優(yōu)先級(jí) */
              THREAD_2_TIMESLICE  	/* 線程時(shí)間片 */
          );
          if (thread_2_handle != RT_NULL)
              rt_thread_startup(thread_2_handle);  
      
          rt_hw_interrupt_enable(level);  
      }
      
      

      3.2 代碼執(zhí)行流程

      1. 初始化:初始化事件集(rt_event_init)并發(fā)送 EVENT3_FLAG,啟動(dòng)線程 1(高優(yōu))、線程 2(低優(yōu));
      2. 線程 1 阻塞:線程 1 等EVENT1+EVENT2,不滿足→阻塞;
      3. 線程 2 執(zhí)行:接收EVENT3(清標(biāo)志)→發(fā)EVENT2→快速閃爍→發(fā)EVENT1
      4. 線程 1 喚醒EVENT1+EVENT2滿足→搶占 CPU→慢速閃爍→發(fā)EVENT3
      5. 閉環(huán)循環(huán):線程 1 阻塞→線程 2 再執(zhí)行,重復(fù)步驟 3-4。

      3.3 核心同步效果

      • 標(biāo)志位無殘留:RT_EVENT_FLAG_CLEAR自動(dòng)清位;
      • LED 規(guī)律:線程 2→5Hz 快速閃,線程 1→0.5Hz 慢速閃;
      • 優(yōu)先級(jí)生效:線程 1 僅阻塞時(shí),線程 2 才執(zhí)行。

      四、關(guān)鍵設(shè)計(jì)注意事項(xiàng)

      1. 事件標(biāo)志位的復(fù)用:事件集的標(biāo)志位被接收后默認(rèn)不清除,需通過 rt_event_recv 的返回值手動(dòng)記錄狀態(tài),或在接收時(shí)通過 RT_EVENT_FLAG_CLEAR 選項(xiàng)自動(dòng)清除;
      2. 中斷中安全使用rt_event_send 可在中斷服務(wù)程序中調(diào)用(無阻塞操作),但 rt_event_recv 禁止在中斷中使用(可能導(dǎo)致阻塞);
      3. 避免事件丟失:若多個(gè)線程發(fā)送同一事件,標(biāo)志位會(huì)被重復(fù)設(shè)置(無累計(jì)計(jì)數(shù)),需確保接收線程能及時(shí)處理;
      4. 初始化時(shí)機(jī):靜態(tài)事件集必須在線程啟動(dòng)前完成初始化,避免線程接收未初始化的事件集;
      5. 邏輯關(guān)系選擇:根據(jù)場景選擇 RT_EVENT_FLAG_AND(需全部事件滿足)或 RT_EVENT_FLAG_OR(任意事件滿足),避免邏輯錯(cuò)誤導(dǎo)致線程無法喚醒。

      總結(jié)

      本文詳細(xì)解析了 RT-Thread 事件集的核心特性、API 函數(shù)與實(shí)操示例,重點(diǎn)說明了多事件標(biāo)志位如何實(shí)現(xiàn)線程間靈活同步。通過靜態(tài)初始化事件集、雙線程交替觸發(fā) LED 閃爍的案例,驗(yàn)證了事件集在復(fù)雜同步場景中的有效性。實(shí)際開發(fā)中,需結(jié)合業(yè)務(wù)需求設(shè)計(jì)標(biāo)志位邏輯,合理使用超時(shí)機(jī)制與清除選項(xiàng),確保系統(tǒng)同步的可靠性與實(shí)時(shí)性。

      posted @ 2025-10-27 19:37  比特向陽  閱讀(8)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 在国产线视频A在线视频| 新版天堂资源中文8在线| 国产精品午夜福利小视频| 国产日韩一区二区在线| 亚洲日韩国产中文其他| 国产av无码国产av毛片| 风韵丰满熟妇啪啪区老老熟妇| 乱色欧美激惰| 蜜芽久久人人超碰爱香蕉| 无码国模国产在线观看免费| 成人精品自拍视频免费看| 999精品全免费观看视频| 亚洲综合欧美在线…| 亚洲 制服 丝袜 无码| 亚洲精品成人福利网站| 风骚少妇久久精品在线观看| 高清国产精品人妻一区二区| 成人一区二区三区久久精品| 国产精一品亚洲二区在线播放| 天堂一区二区三区av| 99福利一区二区视频| 武夷山市| 青青草成人免费自拍视频| 久久午夜无码鲁丝片午夜精品 | 中文字幕国产精品日韩| 国产裸体无遮挡免费精品| 国产成人综合色视频精品| 老熟女多次高潮露脸视频| 狠狠噜天天噜日日噜| 亚洲AV日韩AV综合在线观看 | 男女激情一区二区三区| 蜜臀久久综合一本av| 天堂在线最新版在线天堂| 亚洲成熟女人毛毛耸耸多| 97久久精品午夜一区二区| 国产69精品久久久久99尤物 | 高潮迭起av乳颜射后入| 亚洲乱码中文字幕小综合 | 国产福利酱国产一区二区| 久草热大美女黄色片免费看| 最新国产在线拍揄自揄视频|