基于隊列構建優先級搶占機制的LED燈框架設計與實現

文章目錄

  • 前言
  • 一、LED 顯示框架概述
    • 1. 框架結構圖
    • 2. 基本機制
  • 二、核心結構與接口設計
    • 1. 狀態命令結構
    • 2. 狀態項結構
    • 3. LED框架配置結構
    • 4. LED運行控制器
  • 三、LED框架邏輯流程
    • 1. 初始化邏輯
    • 2. 優先級搶占判斷與處理邏輯
    • 3. 執行隊列命令并處理tick
    • 4. 隊列為空時的默認狀態回滾
  • 四、LED狀態模塊封裝樣例
    • 1. 顏色定義與顯示
    • 2. 定義狀態項數組與配置
  • 五、框架使用接口
  • 六、總結與展望


前言

在嵌入式系統中,RGB LED狀態指示常用于設備運行狀態、故障信息或工作模式的直觀提示。在多個狀態同時存在的情況下,我們希望能讓更緊急或重要的狀態信息搶占當前的LED顯示內容,同時又能保留各狀態的獨立性和易于擴展的邏輯。

本文將詳細解析該LED顯示框架的設計思路、核心組件及其實現方式,并對關鍵代碼進行深入剖析,幫助讀者理解如何在嵌入式系統中高效地管理LED狀態顯示。它具有以下核心特性:

  • ? 支持多個狀態模塊

  • ? 支持不同狀態的優先級判斷

  • ? 狀態判斷函數獨立,便于維護

  • ? 狀態優先級支持搶占式切換

  • ? 同一優先級的狀態為先進先出

  • ? 支持插隊隊列管理顯示時序

一、LED 顯示框架概述

該LED顯示框架的設計目標是實現對LED狀態的智能化管理,具體包括:?

  • 任務優先級管理:?不同的LED狀態具有不同的優先級,高優先級的狀態可以搶占低優先級的狀態顯示。?

  • 隊列機制:?同一優先級的狀態按照先進先出的原則進行顯示,確保狀態切換的有序性。?

  • 模塊化設計:?將LED狀態的檢測、插入、執行等功能模塊化,提升代碼的可讀性和可維護性。?

1. 框架結構圖

+---------------------------+
|     led_arch_t 控制器     |
+---------------------------+
|   config 配置結構體       |
|   cmd_queue 指令隊列       |
|   cur_led_id 當前狀態ID    |
|   tick 計數器              |
+---------------------------+|| 調用周期函數v
+---------------------------+
|     led_on_tick()         |
+---------------------------+|| 查詢各狀態check函數(按優先級)v
+---------------------------+
|   判斷是否搶占并更新狀態   |
+---------------------------+|| 出隊并執行 color_exec()v
+---------------------------+
|     LED 實際顏色控制邏輯  |
+---------------------------+

2. 基本機制

  • 每個LED狀態模塊對應一個 led_arch_t 實例;

  • 每個狀態定義一個 led_item_t,包含狀態ID、優先級、檢測函數;

  • led_cmd_t 用于表示某一顏色狀態及持續時長;

  • 狀態變化以命令隊列形式插入,每周期執行一個命令;

  • 高優先級狀態搶占低優先級狀態,并清空其未執行完的命令;

  • 同一優先級狀態不會搶占,而是先進先出輪流執行。

二、核心結構與接口設計

1. 狀態命令結構

typedef struct {uint8_t color;  // 顏色枚舉值uint8_t ticks;  // 顯示該顏色的周期數
} led_cmd_t;

每條命令定義一種顏色在一定時間內保持顯示。

2. 狀態項結構

typedef struct {uint16_t id;                    // 狀態 IDuint8_t  prio;                  // 優先級,值越小優先級越高bool_t (*led_sta_check)(void);  // 檢查函數,判斷當前狀態是否激活
} led_item_t;

每種狀態都可配置一個 check 函數,若返回 true 表示狀態應被激活。

3. LED框架配置結構

typedef struct {char      *name;                  // 名稱led_cmd_t  *cmd_buf;              // 命令緩沖區(循環隊列)uint16_t   cmd_buf_size;          // 命令緩沖區大小const led_item_t    *led_item;    // 所有狀態定義數組const uint16_t      led_item_num;// 狀態總數void (*color_exec)(uint8_t color); // 執行顏色顯示函數
} led_arch_config_t;

4. LED運行控制器

typedef struct {const led_arch_config_t *config;ring_queue_t cmd_queue;   // 實際的命令隊列結構(環形隊列)uint32_t tick;            // 當前命令已經執行的tick數uint16_t cur_led_id;      // 當前正在運行的狀態IDuint8_t  init_flag;       // 是否已經初始化
} led_arch_t;

三、LED框架邏輯流程

1. 初始化邏輯

if(p->init_flag == 0)
{p->init_flag = 1;init_queue(&p->cmd_queue, NULL, p->config->cmd_buf_size);p->tick = 0;p->cur_led_id = LED_STA_ID_DEFAULT;if(p->config->led_item[LED_ID_INIT].led_sta_check){p->cur_led_id = LED_ID_INIT;p->config->led_item[LED_ID_INIT].led_sta_check();}
}

首次調用 led_on_tick() 時自動初始化,并調用 INIT 狀態的 check 函數插入初始命令。

2. 優先級搶占判斷與處理邏輯

for(uint16_t id=(LED_ID_INIT+1); id<p->config->led_item_num; ++id)
{if(p->config->led_item[id].prio < p->config->led_item[p->cur_led_id].prio){if(p->config->led_item[id].led_sta_check && p->config->led_item[id].led_sta_check()){// 搶占當前低優先級狀態for(uint16_t i=0; i<queue_length(&p->cmd_queue); ++i)rdIdx_add(&p->cmd_queue); // 清空現有命令p->cur_led_id = id;  // 切換當前狀態break;}}else break;
}
  • 只檢測優先級更高的狀態

  • 如果檢測為真,則清除命令隊列,實現搶占

  • 切換當前狀態ID

3. 執行隊列命令并處理tick

if(queue_empty(&p->cmd_queue) == FALSE)
{uint16_t rdIdx = get_queue_rdIdx_index(&p->cmd_queue);p->config->color_exec(p->config->cmd_buf[rdIdx].color);++p->tick;if(p->tick >= p->config->cmd_buf[rdIdx].ticks){rdIdx_add(&p->cmd_queue);p->tick = 0;}
}

每次 tick 調用:

  • 從隊頭讀取一條命令

  • 調用 color_exec 真實點燈

  • 達到tick數后出隊

4. 隊列為空時的默認狀態回滾

else 
{if (p->config->led_item[p->cur_led_id].led_sta_check() != TRUE){p->cur_led_id = p->config->led_item_num - 1; // 默認態for(uint16_t id=(LED_ID_INIT+1); id<p->config->led_item_num; ++id) {if(p->config->led_item[id].led_sta_check && p->config->led_item[id].led_sta_check()){p->cur_led_id = id;break;}}}
}

若當前狀態失效且隊列為空,回退到默認狀態。

四、LED狀態模塊封裝樣例

1. 顏色定義與顯示

typedef enum {LED_OFF,LED_RED,LED_GREEN,LED_BLUE,LED_YELLOW,LED_WHITE,
} color_t;void sta_led_color_exec(uint8_t color)
{switch(color){case LED_RED:   LED_show(RED); break;case LED_GREEN: LED_show(GREEN); break;case LED_BLUE:  LED_show(BLUE); break;case LED_YELLOW:LED_show(YELLOW); break;case LED_WHITE: LED_show(WHITE); break;case LED_OFF:   LED_show(0); break;default:        break;}
}

2. 定義狀態項數組與配置

const static led_item_t led_sta_item[] = {{LED_INIT,    0, led_init},{LED_TASK1,   1, led_task1},{LED_TASK2,   2, led_task2},{LED_TASK3,   3, led_task3},{LED_TASK4,   4, led_task4},
};const static led_arch_config_t led_sta_config = {.name = "sys sta led",.cmd_buf = led_sta_cmd_buf,.cmd_buf_size = 16,.led_item = led_sta_item,.led_item_num = sizeof(led_sta_item) / sizeof(led_item_t),.color_exec = sta_led_color_exec,
};static led_arch_t led_sta_arch = {.config = &led_sta_config,
};

五、框架使用接口

void led_sta_on_tick(void)
{led_on_tick(&led_sta_arch);  // 每周期調用
}void led_sta_clean(void)
{led_on_clean(&led_sta_arch); // 清除命令
}

六、總結與展望

本框架結合優先級調度、命令隊列、顏色執行解耦等技術手段,構建了一個靈活而強大的LED指示燈狀態控制方案。其特點如下:

  • 支持多個狀態同時注冊;

  • 通過優先級實現緊急狀態的插隊處理;

  • 支持FIFO隊列展示同優先級下的多個狀態指示;

  • 支持動態插入狀態指令,適應復雜系統場景;

  • 框架通用,可在多個產品中復用。

后續可擴展功能包括:

  • 狀態時間動態可調;

  • LED閃爍模式定義;

  • 多燈協同控制(如多個LED協同構成特定圖案);

  • 低功耗模式下的燈效優化等。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75149.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75149.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75149.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PyQt6實例_A股財報數據維護工具_解說并數據與完整代碼分享

目錄 1 20250403之前的財報數據 2 整個項目代碼 3 工具使用方法 3.1 通過akshare下載 3.2 增量更新 3.3 查看當前數據情況 3.4 從數據庫中下載數據 視頻 1 20250403之前的財報數據 通過網盤分享的文件&#xff1a;財報三表數據20250403之前.7z 鏈接: https://pan.ba…

React 之 Redux 第三十一節 useDispatch() 和 useSelector()使用以及詳細案例

使用 Redux 實現購物車案例 由于 redux 5.0 已經將 createStore 廢棄&#xff0c;我們需要先將 reduxjs/toolkit 安裝一下&#xff1b; yarn add reduxjs/toolkit// 或者 npm install reduxjs/toolkit使用 vite 創建 React 項目時候 配置路徑別名 &#xff1a; // 第一種寫法…

Spring Boot 中集成 Knife4j:解決文件上傳不顯示文件域的問題

Spring Boot 中集成 Knife4j&#xff1a;解決文件上傳不顯示文件域的問題 在使用 Knife4j 為 Spring Boot 項目生成 API 文檔時&#xff0c;開發者可能會遇到文件上傳功能不顯示文件域的問題。本文將詳細介紹如何解決這一問題&#xff0c;并提供完整的解決方案。 Knife4j官網…

OpenCV 圖形API(17)計算輸入矩陣 src 中每個元素的平方根函數sqrt()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 描述 計算數組元素的平方根。 cv::gapi::sqrt 函數計算每個輸入數組元素的平方根。對于多通道數組&#xff0c;每個通道會獨立處理。其精度大約與內置的 …

大學論文書寫規范與格式說明

大學論文書寫規范與格式說明 (適用于人文社科、理工科通用框架) 一、論文整體結構 1. 基本組成部分 封面 包含論文標題、作者姓名、學院/專業、學號、指導教師、提交日期等(按學校模板填寫)。 中英文摘要 中文摘要:300~500字,概述研究背景、方法、結論與創新點,末尾附…

C# 串口通信

1. 導入 using System.IO.Ports;2. 初始化定義 SerialPort sp new SerialPort(); // 設置串口 sp.PortName "COM3"; // 串口 sp.BaudRate 9600; // 波特率 sp.Parity Parity.None; // 校驗位 sp.DataBits 8; // 數據位 sp.StopBits StopBits.One; // 停…

android14 keycode 上報 0 解決辦法

驅動改完后發現上報了keycode=0 04-07 13:02:33.201 2323 2662 D WindowManager: interceptKeyTq keycode=0 interactive=false keyguardActive=true policyFlags=2000000 04-07 13:02:33.458 2323 2662 D WindowManager: interceptKeyTq keycode=0 interactive=false key…

C++day9

思維導圖 牛客練習 練習&#xff1a; 將我們寫的 myList 迭代器里面 operator[] 和 operator 配合異常再寫一遍 #include <iostream> #include <cstring> #include <cstdlib> #include <unistd.h> #include <sstream> #include <vector>…

批量合并多張 jpg/png 圖片為長圖或者 PDF 文件,支持按文件夾合并圖片

我們經常會碰到需要將多張圖片拼成一張圖片的場景&#xff0c;比如將多張圖片拼成九宮格圖片&#xff0c;或者將多張圖片拼成一張長圖。還有可能會碰到需要將多張圖片合并成一個完整的 PDF 文件來方便我們進行打印或者傳輸等操作。那這些將圖片合并成一張圖片或者一個完整的文檔…

程序化廣告行業(73/89):買賣雙方需求痛點及應對策略深度剖析

程序化廣告行業&#xff08;73/89&#xff09;&#xff1a;買賣雙方需求痛點及應對策略深度剖析 大家好&#xff01;一直以來&#xff0c;我都熱衷于在技術領域探索學習&#xff0c;也深知知識的分享能讓我們共同進步。寫這篇博客的目的&#xff0c;就是希望能和大家一起深入了…

[隨筆] nn.Embedding的前向傳播與反向傳播

nn.Embedding的前向傳播與反向傳播 nn.Embedding的前向計算過程 embedding module 的前向過程其實是一個索引&#xff08;查表&#xff09;的過程 表的形式是一個 matrix&#xff08;embedding.weight, learnable parameters&#xff09; matrix.shape: (v, h) v&#xff1a;…

構建實時、融合的湖倉一體數據分析平臺:基于 Delta Lake 與 Apache Iceberg

1. 執行摘要 挑戰&#xff1a; 傳統數據倉庫在處理現代數據需求時面臨諸多限制&#xff0c;包括高昂的存儲和計算成本、處理海量多樣化數據的能力不足、以及數據從產生到可供分析的端到端延遲過高。同時&#xff0c;雖然數據湖提供了低成本、靈活的存儲&#xff0c;但往往缺乏…

Maven error:Could not transfer artifact

問題描述 當項目從私有倉庫下載依賴時&#xff0c;Maven 報錯&#xff0c;無法從遠程倉庫下載指定的依賴包&#xff0c;錯誤信息如下&#xff1a; Could not transfer artifact com.ding.abcd:zabk-java:pom from/to releases (http://192.1122.101/repory/mavenleases/): 此…

Dify 生成提示詞的 Prompt

Dify 生成提示詞的 Prompt **第1次提示詞****第2次提示詞****第3次提示詞**總結 Dify 生成提示詞是&#xff0c;會和LLM進行3次交互&#xff0c;下面是和LLM進行交互是的Prompt。 以下是每次提示詞的概要、目標總結以及原始Prompt&#xff1a; 第1次提示詞 概要&#xff1a; …

sqli-labs靶場 less4

文章目錄 sqli-labs靶場less 4 聯合注入 sqli-labs靶場 每道題都從以下模板講解&#xff0c;并且每個步驟都有圖片&#xff0c;清晰明了&#xff0c;便于復盤。 sql注入的基本步驟 注入點注入類型 字符型&#xff1a;判斷閉合方式 &#xff08;‘、"、’、“”&#xf…

【什么是動態鏈接?這里的動態是什么意思?鏈接了什么?】

動態鏈接&#xff08;Dynamic Linking&#xff09;詳解 1. 什么是動態鏈接&#xff1f; 動態鏈接是 Java 虛擬機&#xff08;JVM&#xff09;在運行時將字節碼中的符號引用&#xff08;Symbolic Reference&#xff09;轉換為直接引用&#xff08;Direct Reference&#xff09;…

AWS S3深度剖析:云存儲的瑞士軍刀

1. 引言 在當今數據驅動的世界中,高效、可靠、安全的數據存儲解決方案至關重要。Amazon Simple Storage Service (S3)作為AWS生態系統中的核心服務之一,為企業和開發者提供了一個強大而靈活的對象存儲平臺。本文將全面解析S3的核心特性,幫助讀者深入理解如何充分利用這一&q…

【Game】Powerful——Martial Arts Challenge(6)

文章目錄 攻略關卡一&#xff08;虎子&#xff09;關卡二關卡三關卡四關卡五關卡六——奇窮 攻略 關卡一&#xff08;虎子&#xff09; 參戰選手 出手順序 關卡二 參戰選手 出手順序 關卡三 參戰選手 出手順序 關卡四 參戰選手 出手順序 關卡五 參戰選手 出手順序 關卡六…

PPIO × UI-TARS:用自然語言操控電腦,AI Agent 的極致體驗

Manus的爆火預示著AI 正在從單純的文本生成和圖像識別邁向更復雜的交互場景。字節跳動近期推出的開源項目 UI-TARS Desktop 為我們展示了一種全新的可能性&#xff1a;能夠通過自然語言理解和處理來控制計算機界面。這款工具代表了人工智能與人機交互領域的重大突破&#xff0c…

電腦屏保壁紙怎么設置 桌面壁紙設置方法詳解

電腦桌面壁紙作為我們每天面對的第一視覺元素&#xff0c;不僅能夠彰顯個人品味&#xff0c;還能營造舒適的工作或娛樂氛圍。電腦桌面壁紙怎么設置呢&#xff1f;下面本文將為大家介紹Windows和macOS兩大主流操作系統中設置電腦桌面壁紙的方法&#xff0c;幫助大家快速設置個性…