DA14585墨水屏學習(2)

一、user_svc2_wr_ind_handler函數

void user_svc2_wr_ind_handler(ke_msg_id_t const msgid,struct custs1_val_write_ind const *param,ke_task_id_t const dest_id,ke_task_id_t const src_id)
{// sprintf(buf2,"HEX %d :",param->length);arch_printf("cmd HEX %d:", param->length);for (int i = 0; i < param->length; i++){arch_printf("%02X", param->value[i]);}arch_printf("\r\n");if ((param->value[0] == 0xDD) && (param->length >= 5)){current_unix_time = (param->value[1] << 24) + (param->value[2] << 16) + (param->value[3] << 8) + (param->value[4] & 0xff);tm_t tm = {0};transformTime(current_unix_time, &tm);app_easy_timer_cancel(timer_used_min);time_offset = 60 - tm.tm_sec;timer_used_min = app_easy_timer(time_offset * 100, do_min_work);arch_printf("%d-%02d-%02d %02d:%02d:%02d %d\n", tm.tm_year + YEAR0,tm.tm_mon + 1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec,tm.tm_wday);}else if (param->value[0] == 0xAA){platform_reset(RESET_NO_ERROR);}else if (param->value[0] == 0x101){do_rili_show();is_part = 0;step = 1;display();}else if (param->value[0] == 0xE2){do_time_show();is_part = 0;step = 1;display();}
}

這段代碼實現了一個藍牙服務寫入指示處理函數 user_svc2_wr_ind_handler,用于解析來自客戶端的命令并執行相應操作。以下是對代碼的詳細解釋:

函數概述

該函數是一個事件處理回調,當接收到自定義藍牙服務(custs1)的寫請求時被觸發。

它會解析命令數據并執行以下操作:

1. 打印接收到的原始數據(HEX 格式)

2. 根據命令類型(首字節)執行不同邏輯

? 0xDD:設置系統時間

? 0xAA:重啟設備

? 0x101:顯示日歷

? 0xE2:顯示時間 ? ?

核心邏輯解析

1. 數據接收與打印

?arch_printf("cmd HEX %d:", param->length);
for (int i = 0; i < param->length; i++)
{
? ? arch_printf("%02X", param->value[i]);
}
arch_printf("\r\n");
? ? ?? 功能:將接收到的字節流以 HEX 格式打印輸出

? 參數:

? param->length:數據長度

? param->value[]:數據內容 ? ?

2. 時間設置命令(0xDD)

?if ((param->value[0] == 0xDD) && (param->length >= 5))
{
? ? // 從字節流中解析Unix時間戳(大端格式)
? ? current_unix_time = (param->value[1] << 24) + (param->value[2] << 16) +?
? ? ? ? ? ? ? ? ? ? ? ? (param->value[3] << 8) + (param->value[4] & 0xff);
? ??
? ? // 轉換為本地時間結構
? ? tm_t tm = {0};
? ? transformTime(current_unix_time, &tm);
? ??
? ? // 重新同步定時器,確保整分鐘觸發
? ? app_easy_timer_cancel(timer_used_min);
? ? time_offset = 60 - tm.tm_sec;
? ? timer_used_min = app_easy_timer(time_offset * 100, do_min_work);
? ??
? ? // 打印格式化時間
? ? arch_printf("%d-%02d-%02d %02d:%02d:%02d %d\n",?
? ? ? ? ? ? ? ? tm.tm_year + YEAR0, tm.tm_mon + 1, tm.tm_mday,
? ? ? ? ? ? ? ? tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
}
? ? ?? 功能:通過藍牙設置系統時間

? 數據格式:

? value[0]:命令頭(0xDD)

? value[1-4]:Unix 時間戳(4 字節大端整數) ?

? 時間同步機制:

? 取消當前分鐘定時器

? 計算距離下一個整分鐘的剩余秒數(time_offset)

? 重新設置定時器,確保 do_min_work 在整分鐘觸發 ? ?

3. 系統重啟命令(0xAA)

else if (param->value[0] == 0xAA)
{
? ? platform_reset(RESET_NO_ERROR);
}
? ? ?? 功能:觸發系統軟復位

? 參數:RESET_NO_ERROR 表示正常重啟(無錯誤) ?

4. 日歷顯示命令(0x101)

else if (param->value[0] == 0x101)
{
? ? do_rili_show(); ?// 顯示日歷內容
? ? is_part = 0;
? ? step = 1;
? ? display(); ? ? ? // 更新屏幕顯示
}
? ? ?? 功能:切換到日歷顯示模式

? 狀態變量:

? is_part:可能表示部分更新標志

? step:狀態機控制變量 ? ?

5. 時間顯示命令(0xE2)

else if (param->value[0] == 0xE2)
{
? ? do_time_show(); ?// 顯示時間內容
? ? is_part = 0;
? ? step = 1;
? ? display(); ? ? ? // 更新屏幕顯示
}
? ? ?? 功能:切換到時間顯示模式

? 與日歷命令類似,但調用 do_time_show() 而非 do_rili_show() ?

潛在問題與優化建議

1. ?命令格式檢查:

? 對于 0x101 和 0xE2 命令,未檢查 param->length 是否足夠,可能導致越界訪問。 ?

2. ?定時器精度: ? time_offset * 100 可能是筆誤,應為 time_offset * 1000(毫秒轉換)。 ?

3. ?狀態管理: ? is_part 和 step 作為全局變量,多命令并發時可能引發狀態混亂。 ?

4. ?錯誤處理:

? 未處理未知命令(首字節非 0xDD/0xAA/0x101/0xE2)的情況。 ? ?

應用場景 該處理函數常見于藍牙低功耗(BLE)設備中,用于接收手機 APP 發送的控制命令,實現:

? 時間同步(通過 NTP 或手機時間)

? 遠程重啟設備 ? 界面顯示切換(時鐘 / 日歷) ?通過藍牙協議棧的 GATT 服務,客戶端可以向設備寫入特定命令,觸發相應功能。

二、app_easy_timer_cancel函數

void app_easy_timer_cancel(const timer_hnd timer_id)
{if APP_EASY_TIMER_HND_IS_VALID(timer_id){if ((timer_callbacks[APP_EASY_TIMER_HND_TO_IDX(timer_id)] != NULL) &&(timer_callbacks[APP_EASY_TIMER_HND_TO_IDX(timer_id)] != timer_canceled_handler)){// Remove the timer from the timer queueke_timer_clear(APP_EASY_TIMER_HND_TO_MSG_ID(timer_id), TASK_APP);timer_callbacks[APP_EASY_TIMER_HND_TO_IDX(timer_id)] = timer_canceled_handler;/*Send a message to the kernel in order to clear the timer callback function andfree the respective position in the timers callback array.The app_easy_timer_cancel() function cannot guarantee if a timer has enteredthe message queue or not. Therefore a message must be sent to the kernel andinform it about the requested cancel operation.*/struct cancel_timer_struct *req = KE_MSG_ALLOC(APP_CANCEL_TIMER, TASK_APP, TASK_APP,cancel_timer_struct);req->timer_id = timer_id;ke_msg_send(req);}else{ASSERT_WARNING(0);}}else{ASSERT_WARNING(0);}
}

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

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

相關文章

樹莓派5+Ubuntu24.04 LTS串口通信 保姆級教程

【背景】 各位&#xff0c;除了樹莓派4B之外&#xff0c;我又搞了個樹莓派5, 裝的也是Ubuntu24.04 LTS服務器版。裝系統的方法跟樹莓派4B一樣&#xff0c;沒什么好說的。裝完了系統之后&#xff0c;我就想裝個wiringPi來試試串口&#xff0c;卻發現這個樹莓派5的串口和樹莓派4…

【QT】UDP通訊本地調試

qt已經寫好了udp通訊代碼&#xff0c;現在要進行測試。 1、終端輸入ipconfig查看本機網卡的ipv4地址 2、 用udpBind函數&#xff0c;綁定到此ip和自定義的端口號。 3、 打開網絡調試助手&#xff0c;自動檢測到本機的ip地址&#xff0c;輸入任意一個和程序里不一樣的端口號。 …

在 Elasticsearch 中連接兩個索引

作者&#xff1a;來自 Elastic Kofi Bartlett 解釋如何使用 terms query 和 enrich processor 來連接 Elasticsearch 中的兩個索引。 更多有關連接兩個索引的查詢&#xff0c;請參閱文章 “Elastic&#xff1a;開發者上手指南” 中的 “豐富數據及 lookup” 章節。 Elasticsea…

LabVIEW的PID參數自適應控制

在工業控制領域&#xff0c;PID 控制憑借結構簡單、穩定性好、工作可靠等優點被廣泛應用。然而&#xff0c;傳統固定參數的 PID 控制在面對復雜多變的工況時&#xff0c;控制效果往往難以達到最優。基于 LabVIEW 實現 PID 控制根據情況選擇參數&#xff08;即參數自適應調整&am…

[redis進階四]分布式系統之哨兵(2)

目錄 一 利用docker搭建環境 板書: 一)準備?作: 板書: 解讀docker配置文件: 1)安裝docker和docker-compose 2) 停?之前的redis-server 3) 使?docker獲取redis鏡像 二)編排redis主從節點 板書:?編輯 1) 編寫docker-compose.yml 2) 啟動所有容器 3) 查看運??志 …

spark-Schema 定義字段強類型和弱類型

在數據處理和存儲中&#xff0c;Schema&#xff08;模式&#xff09;定義了數據的結構和字段屬性&#xff0c;其中字段的強類型和弱類型是重要的概念&#xff0c;直接影響數據的驗證、存儲和處理方式。以下是詳細解釋&#xff1a; 1. 強類型&#xff08;Strongly Typed&#x…

2024睿抗編程賽國賽-題解

2024睿抗編程賽國賽題解 RC-u1 大家一起查作弊 題目重述 我們需要從給定的多行字符串中提取出所有的關鍵詞&#xff0c;并計算這些關鍵詞的可疑分數總和、總長度以及關鍵詞的數量。具體步驟如下&#xff1a; 關鍵詞定義&#xff1a;由大寫字母、小寫字母、數字組成的字符串&a…

控制LED燈設備

本章分別使用C庫和系統調用的文件操作方式控制開發板的LED燈&#xff0c;展示如何在應用層通過系統提供的設備文件控制相關硬件。 本章的示例代碼目錄為&#xff1a;base_code/linux_app/led/sys_class_leds。 9.1. LED子系統 在Linux系統中&#xff0c;絕大多數硬件設備都有…

SpringBoot學習(上) , SpringBoot項目的創建(IDEA2024版本)

目錄 1. SpringBoot介紹 SpringBoot特點 2. SpringBoot入門 2.1 創建SpringBoot項目 Spring Initialize 第一步: 選擇創建項目 第二步: 選擇起步依賴 第三步: 查看啟動類 2.2 springboot父項目 2.3 測試案例 2.3.1 數據庫 2.3.2 生成代碼 1. SpringBoot介紹 Spring B…

在 Ubuntu 中配置 Samba 實現「特定用戶可寫,其他用戶只讀」的共享目錄

需求目標 所有認證用戶可訪問 Samba 共享目錄 /path/to/home&#xff1b;**僅特定用戶&#xff08;如 developer&#xff09;**擁有寫權限&#xff1b;其他用戶僅允許讀取&#xff1b;禁止匿名訪問。 配置步驟 1. 設置文件系統權限 將目錄 /home3/guest 的所有權設為 develo…

ENSP-OSPF綜合實驗

AR4中通過ospf獲取的其他區域路由信息&#xff0c;并且通過路由匯總后簡化路由信息 實現全網通&#xff0c;以及單向重發布&#xff0c;以及通過缺省雙向訪問&#xff0c; 通過stub簡化過濾四類五類lsa&#xff0c;簡化ospf路由信息 通過nssa簡化ospf信息 區域匯總簡化R4路由信…

linux(centos)聯網情況下部署

nginx部署 1.linux(centos)聯網情況下部署 1.下載nginx所需依賴 # 安裝開發工具組&#xff08;若未安裝&#xff09; sudo yum groupinstall "Development Tools"# 安裝 OpenSSL 開發包 sudo yum install openssl-devel# 安裝 PCRE 開發包 sudo yum install pcre-…

LeetCode 1550.存在連續三個奇數的數組:遍歷

【LetMeFly】1550.存在連續三個奇數的數組&#xff1a;遍歷 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/three-consecutive-odds/ 給你一個整數數組 arr&#xff0c;請你判斷數組中是否存在連續三個元素都是奇數的情況&#xff1a;如果存在&#xff0c;請返回 tr…

Android Framework學習四:init進程實現

文章目錄 init流程簡介init源碼執行順序執行順序 init進程的具體工作事項掛載文件系統設置 SELinuxSecondStageMaininit.rc啟動zygote和serviceManager進程的重要性serviceManager工作原理 Framework學習之系列文章 init流程簡介 下面圖片主要圍繞 Android 系統中init進程的運…

HTTP/3展望、我應該遷移到HTTP/2嗎

1. HTTP/3展望 HTTP/3 基于 QUIC 協議&#xff0c;完全解決了“隊頭阻塞”問題&#xff0c;弱網環境下的表現會優于 HTTP/2&#xff1b;QUIC 是一個新的傳輸層協議&#xff0c;建立在 UDP 之上&#xff0c;實現了可靠傳輸&#xff1b;QUIC 內含了 TLS1.3&#xff0c;只能加密通…

【大模型面試每日一題】Day 15:流水線并行的Bubble問題及其緩解方法

【大模型面試每日一題】Day 15&#xff1a;流水線并行的Bubble問題及其緩解方法 &#x1f4cc; 題目重現 &#x1f31f;&#x1f31f; 面試官&#xff1a;解釋流水線并行&#xff08;Pipeline Parallelism&#xff09;的bubble問題及其緩解方法。 #mermaid-svg-Uz7WGsO8akW5F…

Windows環境下maven的安裝與配置

1.檢查JAVA_HOME環境變量 Maven是使用java開發的&#xff0c;所以必須知道當前系統環境中的JDK的安裝目錄。 搜索欄直接輸入“cmd” 或者 WinR 輸入cmd 在打開的終端窗口輸入“echo %JAVA_HOME”&#xff0c;就可以看到jdk的位置了。 如果沒有的話&#xff0c;請參考我的文章&a…

Kubernetes 集群部署應用

部署 Nginx 應用 命令行的方式 1. 創建 deployment 控制器的 pod # --imagenginx&#xff1a;這個會從 docker.io 中拉取&#xff0c;這個網站拉不下來 # kubectl create deployment mynginx --imagenginx# 使用國內鏡像源拉取 kubectl create deployment mynginx --imaged…

如何使用依賴注入來實現依賴倒置原則?

依賴注入(Dependency Injection, DI)是實現依賴倒置原則(DIP)的具體技術手段,它通過將依賴對象的創建和管理交給外部容器,從而實現高層模塊與低層模塊的解耦。下面從原理、實現方式、框架應用及最佳實踐四個方面詳細解析: 一、依賴倒置原則(DIP)的核心思想 高層模塊不…

python使用AES進行加密和解密

如果需要加密和解密功能,可以使用AES算法。以下是使用Python實現AES加密和解密的示例: from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytesdef aes_encrypt(data,