發布成功
讚賞金額:
您輸入的金額有誤,請重新輸入
支付金額:5元
支付方式:
讚賞成功!
你的讚賞是對作者最大的肯定~?
【編者按 】關(guan) 於(yu) BlueNRG係列如何使用靜態協議棧 - Copy,適用範圍:BlueNRG-LP 軟件, BlueNRG-1/2的也可以參考此方法,本文主要描述使用BlueNRG-LP SDK進行開發時,如何搭建使用靜態協議棧環境。
在使用BlueNRG-LP調試的時候,有時遇到Flash空間不夠的問題,如果應用還需要包含OTA,如果OTA中又包含協議棧,為(wei) 了解決(jue) Flash空間不夠這個(ge) 問題,我推薦使用靜態協議棧的方式,節省空間,加速OTA的升級過程。
下文描述具體(ti) 的操作,我默認你已經知曉ST 官方的BlueNRG-xx 基本開發環境搭建和OTA基本知識,ST官方提供比較多類型的OTA方式,詳細請自行看官方文檔《AN4869 Application note The BlueNRG-1, BlueNRG-2 BLE OTA (over-the-air) firmware upgrade.pdf》 或者《AN5463 Application note The BlueNRG-LP (over-the-air) firmware upgrade.pdf》。
溫馨提示:請使用最新版本SDK進行開發
ST官方SDK中已經提供了靜態協議棧的Demo:
• C:\Users\Lucien\ST\BlueNRG-LP DK 1.0.0\Projects\BLE_Examples\BLE_StaticStack
– Release
• OTA_BTL_ResetManager
• C:\Users\Lucien\ST\BlueNRG-LP DK 1.0.0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack
– Release
• LowerApp_OTA
• HigherApp_OTA
其中,一個(ge) 工程負責生成協議棧,另一個(ge) 工程負責應用,那麽(me) 這裏BLE_StaticStack中的Release與(yu) OTA_BTL_ResetManager怎麽(me) 和Release,LowerApp_OTA和HigherApp_OTA組合呢?
• BLE_StaticStack中的Release + BLE_SensorDemo_StaticStack中的Release //不帶OTA的使用固定協議棧的方法
• BLE_StaticStack中的OTA_BTL_ResetManager + BLE_SensorDemo_StaticStack中的 LowerApp_OTA or HigherApp_OTA //帶OTA的使用固定協議棧的方法
如果你的應用工程移植起來不繁瑣或者還沒有開發應用並且ST官方SDK中已經提供了靜態協議棧的Demo滿足你的基本要求,你可以直接使用它。如果不是,那可能就需要直接在你目標的工程上改為(wei) 靜態協議棧,並且可能需要裁剪協議棧。下麵我介紹一個(ge) 比較複雜些的使用靜態協議棧的修改方法。我們(men) 先通過了解Flash分布來知曉接下來這個(ge) 實驗的整個(ge) 框架。
Flash區域 | 說明 |
NVM | 4KB |
APP | 客戶應用程序,暫定92KB |
Boot + BLE_OTA_ServiceManager | 應用OTA,12kb |
BLE Stack | 協議棧,暫定138KB,可以裁剪 |
2.4G OTA (10KB 升級協議棧) | 占10KB 升級協議棧和應用代碼 |
BlueNRG-355 的Flash空間是256kB,實現的基本思路是:由於(yu) 協議棧的升級幾率比較低,這裏又不太想占用太多的代碼空間,所以協議棧的升級改用走2.4G私有協議進行升級,如果是非安全性要求很高很高的應用(一般的應用)我個(ge) 人認為(wei) 不需要升級協議棧。這裏對協議棧的空中升級隻是留一手,萬(wan) 一需要升級,又不想通過串口或者SW口升級。
• 2.4G OTA 使用的工程是RADIO_OTA_ResetManager中的Client,
• 如果對協議棧和應用一起升級的工程是RADIO_OTA_ResetManager中的Server_FixedImage。
• BLE full Stack 的工程是 BLE_StaticStack
• Boot + BLE_OTA_ServiceManager 的工程是BLE_OTA_ServiceManager ,主要實現不備份方式的OTA(即OTA服務程序和應用不捆綁在一起)
• APP 客戶應用程序,這塊可使用的大小可以根據實際使用BLE Stack size進行調整,後麵會(hui) 描述調整的方法
下麵我們(men) 一步一步,一個(ge) 工程一個(ge) 工程調試,從(cong) “基本的協議棧+app”到“支持應用OTA的協議棧+app”再到“支持協議棧OTA和支持應用OTA的靜態協議棧Demo".我主要給出基於(yu) Keil 優(you) 化分析過程,IAR的操作類似,相對更簡單一些,可以同樣類比過去。
1. 編譯生成靜態協議棧: BlueNRG-LP DK 1.0.0\Projects\BLE_Examples\BLE_StaticStack 編譯成功後,會(hui) 在目錄BlueNRG-LP DK 1.0.0\Middlewares\ST\Bluetooth_LE\library\static_stack下生成libbluenrg_lp_static_stack.a文件,這裏Keil 和IAR都一樣,但想要成功編譯並且生成static_stack下生成libbluenrg_lp_static_stack.a 需要使用安裝arm-none-eabi工具鏈,none表示不帶操作係統(普通的RTOS不算在這類操作係統中,這裏主要是稍微大型一些的如Linux操作係統)。工具鏈請自行到GNU官網上下載,安裝好後,然後設置環境變量.
安裝工具鏈和測試可以參考文檔:BlueNRG-LP DK 1.0.0\Projects\BLE_Examples\BLE_StaticStack\README.txt
這裏主要是keil或者IAR編譯後,運行腳本: "..........\Utility\create_sym_lib.exe --symbols ....\sym_export.txt --rename BLE_STACK_Init=BLE_STACK_Init_nocallbacks Release\Objects\BLE_StaticStack.axf ..........\Middlewares\ST\Bluetooth_LE\Library\static_stack\libbluenrg_lp_static_stack.a" 主要作用是把文件sym_export.txt中的列表中的函數,從(cong) 編譯生成的*.axf文件中找出對應的地址信息,然後通過create_sym_lib.exe生成.a庫, 這個(ge) *.a文件就是應用於(yu) 協議棧的橋梁,應用層是在協議棧之上的,這個(ge) 是接口,就算將來升級協議棧,接口一般都是不允許改動的,這樣不會(hui) 影響應用。
1. 修改BLE_MultipleConnections調用靜態協議棧
默認BLE_MultipleConnections工程,使用的不是固定協議棧的方式。我們(men) 需要更換為(wei) 調用上一步驟生成的*.a文件 此過程可以參考官方文件: BlueNRG-LP DK 1.0.0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack\README.txt
操作步驟如下:
– 移除或者禁止加入編譯老的libbluenrg_lp_stack.a和stack_user_cfg.c
• Keil平台禁止加入編譯可以右擊該文件,然後選擇Option for File xxx ... 接著把Include target build 去掉,最後點擊OK,可以看到文件前麵有個(ge) 紅色的禁止圖標
– IAR平台禁止加入編譯可以右擊該文件,然後選擇Options,接著勾選左上角的Exclude form build,最後點擊OK,可以看到文件圖標顏色變灰色。
– 禁止整個(ge) 文件夾加入編譯也是如是操作,後續不再囉嗦。
– 移除或者禁止整個(ge) NVM文件夾,Middlewares/Profiles文件夾和bluenrg_lp_hal_vtimer.c bluenrg_lp_ll_radio.c, 這兩(liang) 部分已經在協議棧中包含了,如果不禁止掉會(hui) 重複包含重新定義(yi) 。
– 添加文件libbluenrg_lp_static_stack.a和bluenrg_lp_stack_init_if.c到工程,文件路徑:Middlewares\ST\Bluetooth_LE\Library\static_stack
• Keil 平台添加*.a庫後,需要將其文件類型手動選擇為(wei) 庫文件類型。 //右擊*.a文件,Options for file *.a ,然後選擇File type 下拉框選擇Library file。
– 定義(yi) 宏MEMORY_FLASH_APP_OFFSET,這個(ge) 宏定義(yi) 的值能決(jue) 定生成文件的絕對地址,由於(yu) Flash的擦除必須是每次一整頁(2KB),所以加入協議棧的bin文件占用地址0x1A438 Byte(105.05KB) 則應用偏移為(wei) 0x1A800(106KB)
• Keil 平台MEMORY_FLASH_APP_OFFSET這個(ge) 宏定義(yi) 需要定義(yi) 在Options for target -> linker->Misc controls中,格式可以參考BLE_SensorDemo_StaticStack工程。
– IAR 平台MEMORY_FLASH_APP_OFFSET這個(ge) 宏定義(yi) 需要定義(yi) 在Options->linker->config->configuration file symbol definitions中,格式也可以參考BLE_SensorDemo_StaticStack工程。
– 定義(yi) MEMORY_RAM_APP_OFFSET宏,因為(wei) 靜態協議棧這種方式,變量在兩(liang) 個(ge) 不同的工程中,所以協議棧的變量和應用的變量得區分開來,這個(ge) 宏需要根據協議棧變量占用RAM的大小來決(jue) 定,查看默認的工程,可以看到BLE_StaticStack.map文件中變量存放的最後一行是:
Base Addr | Size | Type | Attr | Idx | E Section Name | Object |
0x200007ec | 0x00000024 | Zero | RW | 4255 | .bss | libbluenrg_lp_stack.a(mem_alloc.o) |
• RAM的起始地址為(wei) 0x20000000, 可以算出協議棧占用的內(nei) 存總數為(wei) 0x7EC+ 0x24 = 0x810, IAR平台下這個(ge) 數值很可能是不一樣(0x7AC),IAR的編譯效率一般會(hui) 更高一些,這裏如果擔心算得不準,也可以設置稍微偏大一點點。
– 還有一點需要注意的是協議棧中定義(yi) 的宏BLE_STACK_FULL_CONF 需要和應用中保持一致,如果不一致可能有有些問題。
– 協議棧中代碼裁剪可以精確到函數,除了選擇合適的協議棧配置宏定義(yi) 外,可以通過是否注釋bluenrg_lp_cmd_if.c中cmd_call_table[]數組中的函數,用來決(jue) 定是否將該函數編譯進協議棧。(這種方式相當靈活,暫時沒有看到過可以做到這樣的其他藍牙芯片廠家)
– 編譯成功後,分別通過下載BLE_StaticStack.hex 和 BLE_MultipleConnections_MasterSlave.hex, 可以使用Keil 或者IAR直接download,也可以使用Flash utility下載。實際測試發現,如果在線調試,可能會(hui) 有些錯誤,應該是平台工具的問題,RAM變量的銜接問題,建議使用靜態協議棧後就不要用在線debug單步調試了,如果想用單步調試則先不要改成靜態協議棧這種方式。
• 如果下載bin文件,可以合稱後直接下載,也可以分別下載,但需要設定下載地址,操作和合成細節在這就先不說。
– 小結: 這個(ge) 階段我們(men) 將一個(ge) 普通使用非靜態協議棧工程改成了使用靜態協議棧的方式,將協議棧占用的Flash和RAM 區分開來,然後通過不同的協議棧宏配置和注釋cmd_call_table[]數組中的函數,可以實現對協議棧的裁剪
固件 | MEMORY_FLASH_APP_SIZE [Linker] | MEMORY_FLASH_APP_OFFSET[Linker] | MEMORY_RAM_APP_OFFSET[Linker] | RESET_MANAGER_SIZE[PreDefine] | |||
BLE_StaticStack | 0x22800 | none(default 0) | none(default 0) | 0x22800 | |||
BLE_MultipleConnections | none | 0x22800 | 0x810 | none | |||
• 測試: 成功更改後,應該可以通過串口日誌和使用BLE測試工具成功看到應用程序跑起來
Flash分布:
Flash | 說明 |
NVM | 4KB |
APP | 114KB |
BLE Stack | 138KB |
• 將BLE_OTA_ServiceManager更改為(wei) 支持靜態協議棧版本比較簡單,和上述步驟很類似,我就不一一描述了,下麵我隻描述一些細節,供參考。
• 更改OTA處代碼OTA_btl.h中將
#define SERVICE_MANAGER_OFFSET (0x0)
#ifdef CONFIG_DEVICE_BLUENRG_LP
#define SERVICE_MANAGER_SIZE PAGE_SIZE_ROUND(90* 1024) /* BlueNRG-LP, BLE stack v3.x with modular approach TBR*/
#endif
#define SM_APP_SIZE PAGE_SIZE_TRUNC((_MEMORY_FLASH_SIZE_-SERVICE_MANAGER_SIZE-NVM_SIZE))
更改為(wei) :
#ifndef SERVICE_MANAGER_OFFSET
#define SERVICE_MANAGER_OFFSET (0)
#endif
#ifndef SERVICE_MANAGER_SIZE
#define SERVICE_MANAGER_SIZE PAGE_SIZE_ROUND(90* 1024) /* BlueNRG-LP, BLE stack v3.x with modular approach TBR*/
#endif
#define SM_APP_SIZE PAGE_SIZE_TRUNC((_MEMORY_FLASH_SIZE_-SERVICE_MANAGER_SIZE-NVM_SIZE-SERVICE_MANAGER_OFFSET))
• 注意修改BLE_OTA_ServiceManager中協議棧配置宏和靜態協議棧保持一致(我這裏是BLE_STACK_FULL_CONF)
• BLE_MultipleConnections做如下修改:
– 在linker中增加宏定義(yi) (注意Keil格式和IAR格式稍微有點不一樣):
CONFIG_OTA_USE_SERVICE_MANAGER=1 // 修改鏈接文件使按照CONFIG_OTA_USE_SERVICE_MANAGER格式劃分
MEMORY_FLASH_APP_OFFSET=0x25800 // 應用其實偏移地址修改為(wei) : BLE_StaticStack+BLE_OTA_ServiceManager
MEMORY_RAM_APP_OFFSET=0x0810 // 內(nei) 存不能占用到協議棧使用那部分的
+ 增加 修改鏈接腳本文件: BlueNRG_LP.sct or BlueNRG_LP.icf
Keil: // #ifdef CONFIG_OTA_USE_SERVICE_MANAGER分支下
#define SERVICE_MANAGER_SIZE (0x16800)
#define MEMORY_FLASH_APP_SIZE (_MEMORY_FLASH_SIZE_ - SERVICE_MANAGER_SIZE - FLASH_NVM_DATASIZE)
#define MEMORY_FLASH_APP_OFFSET (SERVICE_MANAGER_SIZE)
更改為(wei) :
#ifndef SERVICE_MANAGER_SIZE
#define SERVICE_MANAGER_SIZE (0x16800)
#endif
#ifndef MEMORY_FLASH_APP_OFFSET
#define MEMORY_FLASH_APP_OFFSET (SERVICE_MANAGER_SIZE)
#endif
#define MEMORY_FLASH_APP_SIZE (_MEMORY_FLASH_SIZE_ - MEMORY_FLASH_APP_OFFSET - FLASH_NVM_DATASIZE)
IAR: // CONFIG_OTA_USE_SERVICE_MANAGER分支下
同樣類比更改,這裏不再複述
固件 | MEMORY FLASH APP SIZE [Linker] | MEMORY FLASH APP OFFSET [Linker] | MEMORY RAM APP OFFSET [Linker] | RESET MANAGER SIZE [PreDefine] | SERVICE MANAGER SIZE [PreDefine] | SERVICE MANAGER OFFSET [PreDefine] | |
BLE_StaticStack | 0x22800 | none(default 0) | none(default 0) | 0 | none | none | |
BLE_OTA_ServiceManager | 0x3000 | 0x22800 | 0x810 | none | 0x25800 | 0x22800 | |
BLE_MultipleConnections | none | 0x25800 | 0x810 | none | none | none | |
• Flash分布如下圖
Flash | 說明 |
NVM | 4KB |
APP | 102KB |
BLE_OTA_ServiceManager | 12KB |
BLE Stack | 138KB |
• 這裏協議棧的升級由於(yu) 空間不夠,這裏就采用2.4G 升級方式。工程路徑: BlueNRG-LP DK 1.0.0\Projects\Peripheral_Examples\Examples_MIX\RADIO\RADIO_OTA_ResetManager-->Client
• 主要修改配置宏,前麵描述比較詳細,這裏我就不一一描述了。主要羅列一些不同工程的linker配置和宏配置。
– RADIO_OTA_ResetManager:
linker:
MEMORY_FLASH_APP_SIZE=0x2800
MEMORY_RAM_APP_OFFSET=0x0810
Preprocessor Defined symbols:
SERVICE_MANAGER_SIZE=0x2800
• BLE_StaticStack:
linker:
MEMORY_FLASH_APP_SIZE=0x22800
MEMORY_FLASH_APP_OFFSET=0x2800
Preprocessor Defined symbols:
RESET_MANAGER_SIZE=0x25000
BLE_STACK_FULL_CONF
• BLE_OTA_ServiceManager:
linker:
MEMORY_FLASH_APP_SIZE=0x3000
MEMORY_FLASH_APP_OFFSET=0x25000
MEMORY_RAM_APP_OFFSET=0x0810
Preprocessor Defined symbols:
BLE_STACK_FULL_CONF
SERVICE_MANAGER_OFFSET=0x25000
SERVICE_MANAGER_SIZE=0x3000
• BLE_OTA_ServiceManager:
linker:
CONFIG_OTA_USE_SERVICE_MANAGER=1
MEMORY_FLASH_APP_OFFSET=0x28000
MEMORY_RAM_APP_OFFSET=0x0810
Preprocessor Defined symbols:
BLE_STACK_FULL_CONF
Flash | 說明 |
NVM | 4KB |
APP | 92KB |
BLE_OTA_ServiceManager | 12KB |
BLE Stack | 138KB |
2.4G_OTA_ServiceManager | 10KB |
通過上述一步一步的優(you) 化,我們(men) 完成了將普通工程改成使用靜態協議棧的方式,並且支持OTA。
實際應用可能有各種不同的應用需求,用戶可以根據同樣原理去優(you) 化適配合適你們(men) 的工程。
作者:LucienKUANG, 多年BLE 和Mesh相關(guan) 開發和支持經驗,先後開發過,空氣波壓力治療儀(yi) 係統,共享單車鎖,自拍杆,點讀筆電子價(jia) 簽係統等等嵌入式軟件產(chan) 品的嵌入式軟件開發。支持過ST,Dialog等大廠BLE相關(guan) 產(chan) 品的開發。在必威官方网站手机網的個(ge) 人店鋪為(wei) “路恩”,有類似的項目開發需求者歡迎聯係。