電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 213|回復: 0
收起左側(cè)

嵌入式事件標志組

[復制鏈接]

483

主題

483

帖子

2830

積分

三級會員

Rank: 3Rank: 3

積分
2830
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-9-23 11:38:00 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
事件標志組 嵌入式事件標志組是一種在嵌入式系統(tǒng)中廣泛使用的同步機制,主要用于實現(xiàn)多任務間的同步與通信。
事件標志組是一組事件標志位的集合,每個位代表一個事件是否發(fā)生。它允許任務等待特定的事件發(fā)生,當事件發(fā)生時,相關(guān)任務將被喚醒并執(zhí)行相應的操作。
特點
  • 靈活性:用戶可以根據(jù)需要自定義每個位事件的含義,如bit0表示按鍵是否按下。支持一對多、多對多的同步模式,即一個任務可以等待多個事件的發(fā)生,也可以是多個任務同步多個事件。
  • 高效性:使用位操作,效率高,占用資源少。
  • 擴展性:雖然常用的是16位或32位無符號的數(shù)據(jù)類型來存儲事件標志,但其中的高8位可能用作控制信息,低24位用作存儲事件標志,因此可以存儲多個事件標志。工作原理
  • 等待事件:任務通過調(diào)用相應的API函數(shù)(如FreeRTOS中的xEventGroupWaitBits)來等待一個或多個事件標志位的發(fā)生?梢栽O置等待條件,如等待所有指定的事件標志位都為1,或等待其中任意一個事件標志位為1。
  • 觸發(fā)事件:當事件發(fā)生時,通過調(diào)用相應的API函數(shù)(如FreeRTOS中的xEventGroupSetBits)來設置相應的事件標志位為1,從而觸發(fā)等待該事件的任務。喚醒所有符合條件的任務,類似于“廣播”的作用。
  • 執(zhí)行任務:被喚醒的任務根據(jù)事件標志位的狀態(tài)執(zhí)行相應的操作,并可以選擇是否清除事件標志位。應用場景
  • 多任務同步:在需要多個任務協(xié)同工作的場景中,可以使用事件標志組來同步這些任務,但無數(shù)據(jù)傳輸。
  • 中斷處理:在中斷服務程序中設置事件標志位,以通知主任務或其他任務進行相應的處理。
  • 狀態(tài)監(jiān)控:用于監(jiān)控系統(tǒng)的各種狀態(tài),如設備是否就緒、數(shù)據(jù)是否到達等。例子:在嵌入式系統(tǒng)中,處理USB數(shù)據(jù)的同步發(fā)送通常涉及多線程編程,并使用適當?shù)耐綑C制來確保數(shù)據(jù)的一致性和完整性。在這種情況下,可以使用事件標志和消息隊列來協(xié)調(diào)一個生產(chǎn)線程(生成USB數(shù)據(jù))和一個消費線程(發(fā)送USB數(shù)據(jù))。
    設計思路:
  • 消息隊列:用于存儲從生產(chǎn)線程到消費線程的數(shù)據(jù)。每個數(shù)據(jù)項可能是一個指向USB數(shù)據(jù)包緩沖區(qū)的指針或包含數(shù)據(jù)包信息的結(jié)構(gòu)體。
  • 事件標志:用于通知消費線程有新的數(shù)據(jù)可供處理,或者當隊列為空時通知生產(chǎn)線程暫停生產(chǎn)。
  • 互斥鎖:保護消息隊列和事件標志的訪問,防止競態(tài)條件。
    實現(xiàn)步驟:
    1. 定義消息隊列和事件標志
  • 使用RTOS提供的API來創(chuàng)建消息隊列和事件標志。
  • 消息隊列應能夠存儲指向USB數(shù)據(jù)包的指針或相關(guān)結(jié)構(gòu)體。2. 生產(chǎn)線程生產(chǎn)線程負責生成USB數(shù)據(jù),并將其放入消息隊列中。
    void producer_thread(void *arg)
    {  
        while (1)
        {  
            // 生成USB數(shù)據(jù)包  
            usb_packet_t *packet = generate_usb_packet();  
      
            // 鎖定互斥鎖  
            rtos_mutex_lock(&mutex);  
      
            // 將數(shù)據(jù)包放入隊列  
            if (rtos_queue_send(&usb_queue, &packet, portMAX_DELAY) == pdPASS)
            {  
                // 通知消費線程有新數(shù)據(jù)  
                rtos_event_group_set_bits(&event_group, EVENT_BIT_DATA_READY);  
            }  
      
            // 解鎖互斥鎖  
            rtos_mutex_unlock(&mutex);  
      
            // 等待一段時間或根據(jù)其他條件繼續(xù)生成數(shù)據(jù)  
            vTaskDelay(pdMS_TO_TICKS(100));  
        }  
    }
    3. 消費線程消費線程從消息隊列中取出數(shù)據(jù),并發(fā)送USB數(shù)據(jù)包。
    void consumer_thread(void *arg)
    {  
        usb_packet_t *packet;  
      
        while (1)
        {  
            // 等待數(shù)據(jù)就緒事件  
            EventBits_t uxBits = xEventGroupWaitBits(  
                &event_group,   
                EVENT_BIT_DATA_READY,   
                pdTRUE,   
                pdFALSE,   
                portMAX_DELAY  
            );  
      
            if (uxBits & EVENT_BIT_DATA_READY)
            {  
                // 鎖定互斥鎖  
                rtos_mutex_lock(&mutex);  
      
                // 從隊列接收數(shù)據(jù)包  
                if (rtos_queue_receive(&usb_queue, &packet, portMAX_DELAY) == pdPASS)
                {  
                    // 發(fā)送USB數(shù)據(jù)包  
                    send_usb_packet(packet);  
      
                    // 釋放數(shù)據(jù)包(如果需要)  
                    free_usb_packet(packet);  
                }  
      
                // 解鎖互斥鎖  
                rtos_mutex_unlock(&mutex);  
            }  
        }  
    }
    4. 初始化與啟動創(chuàng)建消息隊列、事件標志和互斥鎖,并啟動生產(chǎn)者和消費者線程。
    void app_main(void)
    {  
        // 初始化消息隊列、事件標志和互斥鎖  
        rtos_queue_create(&usb_queue, ...);  
        rtos_event_group_create(&event_group);  
        rtos_mutex_create(&mutex);  
      
        // 創(chuàng)建并啟動生產(chǎn)者和消費者線程  
        xTaskCreate(producer_thread, "Producer", STACK_SIZE, NULL, PRIORITY, NULL);  
        xTaskCreate(consumer_thread, "Consumer", STACK_SIZE, NULL, PRIORITY, NULL);  
      
        // 其他初始化...  
    }
    注意事項
  • 在使用事件標志組時,需要注意避免競態(tài)條件,確保任務間的同步與通信的正確性。
  • 合理安排事件標志位的數(shù)量和使用方式,避免資源浪費和效率低下。
  • 在設計系統(tǒng)時,應充分考慮任務間的依賴關(guān)系和同步需求,以選擇合適的同步機制。猜你喜歡:
    WiFi6+藍牙+星閃,三合一開發(fā)板,真香!
    Github上熱門 C 語言項目匯總!
    嵌入式,可測試性軟件設計!
    一些低功耗軟件設計的要點!
    嵌入式 C 保護結(jié)構(gòu)體的方式
    實用 | 10分鐘教你通過網(wǎng)頁點燈
    談談嵌入式軟件的兼容性!
    分享一個嵌入式代碼生成器設計思路!
    點擊閱讀原文,查看更多分享。
  • 回復

    使用道具 舉報

    發(fā)表回復

    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規(guī)則

    關(guān)閉

    站長推薦上一條 /1 下一條


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表