文章

開發 nRF54L15 低功耗藍芽模組,以 Zephyr 範例程式說明

圖片
前一文章講解 nRF54L15 模組在 VS Code 環境的開發,本文則說明藍芽程式的開發。在 SDK 中,與藍芽相關功能的範例放在 \ncs\v3.1.1\zephyr\samples\bluetooth 目錄,如下所示。我們選擇 peripheral 範例程式,並添加 build configuration 後,開啟 prj.conf 檔案,裡面定義了藍芽服務的參數,如下方圖所示。   BAS 是定義電池的服務, HRS 是定義心律的服務, IAS 是定義即時告警的服務, CTS 是定義目前時間的服務。編譯前,我們可以設 y 或 n 決定啟用或關閉服務,設定好之後,先重新生成 build config ( 最好執行 Clean Build Configuration ,再生成 ) ,然後再重新編譯所有的 code 。底下這個函數 API 是廣播設備的屬性,其中 ad 是屬性內容和 sd 是設備名稱。 bt_le_adv_start (BT_LE_ADV_CONN_FAST_1, ad , ARRAY_SIZE(ad), sd , ARRAY_SIZE(sd)); 在手機端,下載 nRF Connect for Mobile ,安裝後打開 APP 。先掃描藍芽設備,看到藍芽名為 Zephyr Peripheral… ,就是上圖程式中定義的名稱。連線後,如下圖,顯示這設備的屬性,包含 Heart Rate 的屬性 (Notify 、 Read 、 Write) 。 除了藍芽所定義的服務之外,下圖是這設備 GATT 的通用屬性 配置屬性的 API 函數,包含 vnd 變數與 uuid 。 bt_gatt_find_by_uuid ( vnd_svc .attrs,   vnd_svc .attr_count,   &vnd_enc_uuid.uuid); 範例中,開啟藍芽認證模式, API 函數如下,其中 GATT 的某些欄位需要認證才能進行讀與寫。 bt_conn_auth_cb_register ( &auth_cb_display ); 變更 BT 位址 在原始範例所生成的 prj.conf 檔案中,定義 CONFIG_BT_PRIVACY=y ,意思是隨...

開箱 NORA-B2 開發板 -- 核心是低功耗 nRF54L15 藍芽晶片

圖片
NORA-B2 開發板上面有一小塊由  u-blox  公司所製造的低功耗藍芽模組,該模組已經取得無線的認證,可提供給第三方整合使用。目前開發板上的模組型號為 NORA-B206 ,其內部核心為 Nordic 半導體的 nRF54L15 晶片,內建 256kB 記憶體, 1.5MB NVRAM 。此外,這個型號自帶有 PCB 的天線,無須外接天線。開發板的電路圖連結如下: https://github.com/u-blox/evk_designs_sho_altium/tree/main/EVK-NORA-B20/EVK-NORA-B2-C.3/Deliverables 。 開發軟體 VS Code : Nordic Semi 透過這套 IDE 進行開發 SEGGER J-Link/J-Trace Software :開發板上面已經自建 debugger ,但需要安裝這套軟體。                 韌體開發的環境推薦在 VS Code ,然後再安裝 nRF Connect 套件,透過套件才能安裝 SDK 與 toolchains 。安裝最新的 SDK 3.1.1 之後,這塊開發板尚未列入 SDK 裡面 ( 板子太新還來不及支援 ) ,不過我們可以暫時選用 nrf54l15dk 開發板的資料來編譯系統程式碼。所有支援的板卡資訊都存放在這個目錄底下, C:\ncs\v3.1.1\zephyr\boards ,能找到對應的板卡。此外,採用手動的方式來新增這塊開發板,先到 GitHub 網站,如下鏈結 https://github.com/u-blox/u-blox-sho-OpenCPU/tree/master/zephyr/boards/u-blox 。下載 ubx_evknorab2 的資料,放到上述的目錄底下,這樣在 VS Code 環境裡便能列出這開發板了。 需安裝 VS Code 的套件,如下:         nRF Connect for VS Code Extension Pack :這套件會自動安裝其他六個相關套件。  ...

STM32H7x 最佳化的數學運算,採用 CMSIS-DSP 函數庫

圖片
        STM32H750 的晶片核心是  ARM Cortex-M7,它是以  Armv7-M 架構所設計而成。內建浮點運算單元 (FPU - Floating Point Unit),以及數位訊號處理(DSP)模組,不過需要搭配適合的函數庫才能編譯成適合機器執行的指令碼。ARM 提供一套開源的 CMSIS-DSP 函數庫,支援 Cortext-M 系列的數學運算,能提升運算的速度。在 Keil IDE 開發環境下,STM32H750 的項目中打開下圖的選單,將CMSIS Core 和 DSP 模組載入,完成第一步驟。         接下來,我們要了解 CMSIS-DSP 有支援三種 ARM 的核心架構,這將影響程式碼的定義。 ARM_MATH_NEON 是第一種定義,代表 Neon 的核心, ARM Neon 技術是一種先進單指令多資料 (SIMD) 架構延伸,應用於 Arm Cortex-A 系列及 Cortex-R 系列處理器。 ARM_MATH_HELIUM 是第二種定義 ,代表 Helium 的核心 , ARM Helium  技術是 Arm Cortex-M 處理器系列的 M 系列向量擴充方案 (MVE)。Helium 為 Armv8.1-M 架構的延伸,可協助機器學習 (ML) 與數位訊號處理 (DSP) 應用大幅提升效能。STM32H750 並不屬於前面兩種的定義,就不用將它們放進編譯的過程裡。不過,我們要將這三個定義放進編譯,分別是 ARM_MATH_DSP ︑ ARM_MATH_MATRIX_CHECK ︑ ARM_MATH_ROUNDING 才行 。因為 STM32H750 晶片支援浮點運算,所以下圖的選單要開啟,如果不開啟的話,數學運算將會花費數倍的時間,甚至更多。         最後我們測試三角函數的運算,Cos(x)*Cos(x) + Sin(x)*Sin(x),運算一百萬次後,比較有無採用 DSP 的兩者效能。 下圖的程式碼,上半段是採用一般數學函數的運算,沒有 DSP 優化。下半段是採用 DSP 優化的函數,然後比較兩者的效能差異。     ...

[筆記] RAG 檢索增強生成的技術概念

圖片
Q :為何需要 RAG 資料檢索? A :光靠 LLM 大語言模型無法準確回答問題,反而出現一本正經地胡說八道,專業術語稱為 LLM 的幻覺 (Hallucination) 。為了解決這問題,有兩種方法:第一種是對 LLM 的預訓練模型進行微調訓練,第二種是加入 RAG 做資料檢索和 LLM 的語句生成。前者需要花費硬體設備進行訓練,後者採用 LLM+RAG 架構可大幅節省成本,市面上比較接受後者方案。其系統架構如下: Q : RAG 的開發與架構? A :初期 RAG 開發階段,需要對資料進行多模態的處理,比如對 PDF 檔案擷取文字、表格、圖片 … 等多種模態,過程包含資料清洗,剔除一些符號、重複語句、無意義文字 … 等。然後,對清洗後的資料進行分塊和向量化,最後寫入向量資料庫。這裡的分塊和向量化會使用到現有的演算法來實現,向量資料庫也有現有的架構可使用。 前面是前期 RAG 的資料處理階段,後期是指 RAG 運行階段,需要對接到 LLM 模型,如下圖。 Q :如何資料擷取與清洗? A :客戶提供技術文件,可能是 TXT 或 PDF 檔案。首先,將檔案的文字擷取下來存放成自訂格式 (JSON) ,對於 PDF 檔案而言,內容包含文字、表格、圖片都必須分別寫 python 程式處理。即使把文字從檔案取出,在這一大堆文字裡面包含換行符號,語句切割不連續,無意義的詞或標題數字 … 等問題,這些問題需要靠程式來做清洗後才能進到下階段。 Q :如何向量化? A :資料清洗後,資料要進行切塊 (chunk) ,再將其向量化,這過程稱為 embedding 。有人研究中文 embedding 的檢索能力,參考 https://ihower.tw/blog/archives/12167 ,需要導入有支援多語言的 embedding model 效果最好。 切塊採用 Jieba 分詞的算法,文本會切成小的詞彙,以便之後檢索。這些詞彙換算成向量,而典型檢索的演算法為 BM25 ,優點為方法簡單效果不錯,因此使用廣泛,缺點是單純根據詞頻等統計和關鍵字檢索做判斷,無法理解語意。而 Word2Vec 使用高維向量來表示單詞,能分辨細微語意之差別。 向量化的數據要存放在向量資料庫,基礎型的有 ChromaDB 、 MilvusDB… 等可本地部署。

[筆記] 製作一個 STM32H750 的外部 Flash 燒錄器

圖片
        STM32H750這顆晶片是 Cortex-M7 核心,內部時脈 480MHz,在同級的 STM32 系列中屬於高效能晶片。不過,它有個問題就是內部 Flash 容量太小,只有 128MB 而已,為了解決這問題,通常外部會掛一顆 Flash 晶片。此時,我們需要自製一個燒錄程式,如下圖所示,紅線標示的 On-chip Flash 是官方提供的燒錄程式,而另一紅線標示的 Ext Flash SPI 就是我們要提供給 Keil IDE 的燒錄程式。         如何自製一套燒錄程式給 Keil IDE 使用呢?放心,IDE 有提供一個範例項目,放在 \Keil_v5\ARM\Flash\_Template 目錄底下,我們工作就是將 FlashDev.c 和 FlashPrg.c 兩個檔案的函數給實現了即可。在 FlashDev.c,我們填入外掛 Flash 的屬性,比如容量大小﹑STM32 存取的位址﹑Sector size, Sector Addr...等,如下。         在 FlashPrg.c,我們必須實現底下幾個函式的驅動。由於外掛 Flash 晶片型號為 W25Q256,也就是寫一套驅動這顆晶片的程式碼。不必擔心!這部分可以從網路的開源找到相關的驅動程式碼 ( https://pan.baidu.com/s/1LuH_zhXgZMqHJcKoLcepdQ   提取码:kmbf )。         筆者下載後,還是會遇上驅動的問題,必須再進行 debug 後才能使用。這裡有一點要注意的,W25Q256 預設的 SPI 通訊指令是 3-byte Address Mode,但是整個驅動程式都採用 4-byte 模式,於是在初始化過程要先設定為 4-byte Addr Mode 才能成功使驅動程式執行,如下圖。         最後,將這個 Flash 項目編譯後,產生的 .axf  複製成 .FLM 檔案,再把這檔案放到  \Keil_v5\ARM\Flash 目錄底下,這樣就完成自製外部燒錄器的功...

[筆記] STM32H750 如何宣告一塊外部記憶體? 而不發生 HardFault 異常。

圖片
        STM32H750 內部記憶體不到 1MB,在記憶空間使用大的情況下,我們需要在晶片外部增加外部 SRAM 以滿足空間需求。如何宣告一個變數映射到這外部記憶體?對於編譯器版本 AC5 或 AC6 最安全的做法是底下這樣宣告:                 uint16_t    *myTest = (uint16_t *) 0xC0000000;   直接將變數的位址映射到外部記憶體位址上,然後計算好這個變數的 array 長度大小。 另一個宣告方式,如下,但僅適用於 AC5 版本,                     uint8_t myTest[128] __attribute__((section(" .exsram "))); 這樣宣告後,需要在 Keil IDE 的 scatter 檔案中,添加一個記憶體空間,如下圖所示。上面變數宣告的 section 名稱為 .exsram ,正好對應到下面 scatter 檔裡面的定義空間。如此一來,變數與外部記憶體的綁在一起了。 不過,光這樣做還不夠,因為在系統 SystemInit 函數執行後,跳到 main 函數前會對變數進行初始化,此時的外部記憶體與晶片之間的介面還未配置好,系統就直接存取外部記憶體會發生硬體異常,掉進 HardFault_Handler( ) 中斷裡面。因此,在 跳到 main 函數前必須執行 FMC 介面的初始化,把外部 SRAM 介面參數配置好,這樣就能存取外部空間了,而不發生異常情況。

[筆記] 兩款 STM32H7xx 攝影模組開發板 (H750XBH6 / H743VIT6)

圖片
        最近動手研究兩款 STM32H7xx 系列的開發板,去年已經做過 STM32H750 相關的案子,這次是研究攝像頭模組。購買一塊是 H750XBH6,另一塊是 H743VIT6,兩款的核心都是 Cortext-M7,最高時脈 480MHz ,屬於 STM32 系列的高效能晶片,開發板適合實現照相﹑攝影﹑記錄...等功能。兩款的主要差別在於 Flash 和 SRAM 容量的大小,如下圖。Flash 128kB vs 2MB ,H743可以用來開發更大型複雜的程式。內部可使用的 SRAM 都是 864kB ,透過擴充介面,可以外部再增加 SRAM 容量,H750 開發板外部又多了 16MB SRAM,可惜 H743 開發板沒有外增 SRAM。         若要開發邊緣運算的功能,所占用的 Flash 和 SRAM 空間都不少,這兩款開發板以 STM32H743 最為適合,但是需要再外增 SRAM 容量才行。實際上,STM32 市面上的開發板還沒看到帶有特大的記憶空間,反觀 ESP32-S3 Cam 模組很容易買到 Flash 8MB / SRAM 8MB 的型號板子,因此未來想要開發影像方面的功能,或許用 ESP32 做為前期研究較為適合,且價格更便宜。