1. 程式人生 > >CC2640之OAD韌體升級(內建Flash)

CC2640之OAD韌體升級(內建Flash)

OAD是TI在BLE協議棧基礎上擴充套件的一種無線更新技術。OAD使用客戶端-伺服器的機制工作。需要韌體更新的目標晶片叫做OAD Target/Client,用來管理OAD功能的一端叫做OAD Manager/Server。

配置OAD的目標裝置,如果需要更新軟體的話,不用連線模擬器,通過BLE無線就可以更新軟體,方便使用者升級。

有些人會覺得OAD很複雜,其實並不複雜,本質就是OAD Manager/Server端將需要升級的bin檔案位元組流取出來,然後按照特定的長度(因為BLE每個包的長度是受限的)通過write方法,將資料通過帶有寫許可權的特徵值傳送給OAD Target/Client端,然後OAD Target/Client 端將收到的資料寫到特定的flash地址上。

CC2640的OAD韌體升級支援內建Flash和外接Flash兩種,我們先來了解下內建Flash的OAD配置方式,至於外接Flash的情況,後期再繼續更新。

CC2640內建Flash OAD

內建Flash的OAD韌體升級配置之後,整個Flash中地址分配情況如下圖:


下面,我們來具體瞭解一下內建Flash的裝置配置OAD的方法。

編譯ImageA

ImageA在官方文件中是指OAD Target Application,因為CC2640的工程燒錄的時候是將BIM、BLE STACK和OAD Target Application這三者hex檔案合併成OAD_merge.hex

檔案,所以我們在下面的介紹文件中用ImageA來統稱這三者合併之後的OAD_merge.hex檔案,希望大家不要混淆了,這裡這樣統稱,只是為了方便下述流程的說明。

下面,我們一起來看看編譯的方法和編譯過程中出現的問題及解決辦法:

1.先開啟IAR開發工具,然後將

C:\ti\simplelink\ble_cc26xx_2_01_00_44423\Projects\ble\OADTarget\CC26xx\IAR

目錄下的OADTarget.eww拖到IAR的左側工作區,開啟OADTarget工程,開啟之後顯示如下:


我們可以看到,開啟的工程包含了BIM、CC2640App和CC2640Stack,編譯過程為:首先編譯BIM,然後編譯CC2640Stack,最後編譯CC2640App,編譯CC2640App的時候會在編譯完成的時候呼叫

Python執行hexmerge.py指令碼來將編譯生成的三個hex檔案合併成一個。

2.BIM和CC2640Stack的編譯沒有什麼問題,我們不再講述,下面重點來看一下CC2640App編譯之後執行合成指令碼的時候出現的問題,沒有進行任何配置的情況下,會提示下面截圖的資訊:


Python安裝完成並配置環境變數之後,我們還需要下載合成指令碼,並複製到Python的安裝目錄下,合成指令碼hexmerge.py的下載連結如下:

開啟上述下載連結之後截圖如下:




下載解壓之後將檔案複製到C:\ti\simplelink\ble_cc26xx_2_00_00_42893\Projects\ble\OADTarget\CC26xx\IAR\Application\CC2640目錄中即可

這樣就可以成功編譯了,編譯成功之後會在

C:\ti\simplelink\ble_cc26xx_2_01_00_44423\Projects\ble\OADTarget\CC26xx\IAR\Application\

CC2640\FlashROM\Exe

目錄下生成OAD_merge.hex檔案,這就是我們需要的ImageA的hex檔案。

注意:用這個ImageA升級ImageB的話,如果用PC端的BLE Device Monitor或者安卓手機端的APP都會出現連線失敗,或者搜尋不到服務,或者搜尋到服務之後過一會就斷開,或者升級過程中斷開連線等問題,這個問題的主要原因是ImageA的CC2640App開啟了BLE連線成功之後自動申請修改連線引數的功能,在

C:\ti\simplelink\ble_cc26xx_2_01_00_44423\Projects\ble\OADTarget\CC26xx\Source\Application目錄下的oadTargetApp.c檔案中,相關程式碼截圖如下:


自動申請的連線引數最小是80,最大是800,這個連線間隔太長,會影響升級,所以我們將DEFAULT_ENABLE_UPDATE_REQUEST的值改為FALSE來關閉自動申請連線引數更新,進而用預設的連線引數進行升級。這樣PC端的BLE Device Monitor才能正常連線並進行升級。如果為了提高升級的速度,需要將連線間隔縮小,那用PC端的BLE Device Monitor的話可以用該工具進行設定;若用手機端進行升級的話,可以將需要的連線間隔通過某個特徵值發給從機,由從機來重新申請。

燒錄ImageA

將開發板通過XDS模擬器連結到電腦上,連線的方法、Flash Programmer工具以及驅動的安裝我們這裡不再講述,準備好之後,開啟Flash Programmer 工具,然後按照下圖進行操作:


成功燒錄之後,我們用PC端的BLE Device Monitor工具進行搜尋和連線,之後可以看到相應的服務和特徵值,截圖如下:

此處有一點需要注意,就是ImageA中固定了Mac地址,也就是,如果用協議棧中的Demo編譯ImageA,其Mac地址都是0A:D0:AD:0A:D0:AD,而後面編譯的ImageB用的是晶片本身的Mac地址,這樣可以避免用安卓手機等方式升級時,因為藍芽快取的原因導致裝置名、服務和特性沒有改變的問題。

當然ImageA的Mac地址也可以根據自己的需求進行修改,但是要保證跟現有的已經分配的Mac地址不衝突,所以除非必須改,否則不要動這個地方。程式碼中設定的地方截圖如下:


編譯ImageB

我們先用TI協議棧中的Demo進行測試和整個流程的熟悉。如何在一個沒有配置過OAD的工程中配置OAD ImageB的相關內容在另一篇博文中講解,連結如下所示:

1.開啟協議棧中的SimpleBLEPeripheral工程,CC2640App選擇FlashOnly_OAD_ImgB,截圖如下:


2.首先編譯CC2640Stack,然後編譯CC2640App,成功編譯之後,會在
C:\ti\simplelink\ble_cc26xx_2_01_00_44423\Projects\ble\SimpleBLEPeripheral\CC26xx\IAR\Application\

CC2640\FlashOnly_OAD_ImgB\Exe

目錄下生成OADbin.bin檔案,這個就是ImageB的bin檔案。

3.用PC端的BLE Device Monitor工具或者安卓手機端工具將該檔案更新到裝置端之後,會發現裝置端重啟之後不再廣播,程式跑不起來,如果出現這種情況,開啟

C:\ti\simplelink\ble_cc26xx_2_01_00_44423\Projects\ble\SimpleBLEPeripheral\CC26xx\IAR\Config

目錄下的appBLE.cfg檔案,將開頭的如下兩行程式碼遮蔽掉:

  1. //var ROM = xdc.useModule('ti.sysbios.rom.ROM');
  2. //ROM.romName = ROM.CC2650;

操作截圖如下:

至於這個地方為什麼要這樣,TI官方文件其實有說明。官方文件中的說明如下:


升級ImageB

ImageB用PC端BLE Device Monitor工具升級過程如下:

1.用BLE Device Monitor工具,搜尋並連線我們要升級的裝置,然後點選選單欄上的File”,在下拉選單中選擇Program(OAD),操作截圖如下:


2.點選Program(OAD)之後,會彈出如下所示的框框:


File Image裡面要選擇的檔案就是我們要更新的韌體,我的是在

C:/ti/simplelink/ble_cc26xx_2_01_00_44423/Projects/ble/SimpleBLEPeripheral/CC26xx/IAR/Application/

CC2640/FlashOnly_OAD_ImgB/Exe/OADbin.bin目錄下的該檔案,選擇之後,點選Start進行升級,升級過程如下:


待進度條走完,升級就完成了,該提示框會自動消隱。

3.升級完成之後,然後重新用PC端的BLE Device Monitor工具進行搜尋和連線(如果搜尋不到,就重啟下裝置然後再試試),截圖如下:


ImageB的裝置名我特意進行了修改,目的是與ImageA的進行區分,並且看右側跟之前ImageA的相比較也明顯能看出服務和特性都不一樣了,證明我們的升級成功了。

4.到了這一步,ImageB的韌體就升級到我們的目標裝置上了,但是ImageB本身不帶升級功能,所以沒有辦法來升級ImageA,有人會問,那我們要更新ImageB怎麼辦呢?也就是我們如何從ImageB切換到ImageA,然後重新升級新的韌體ImageB呢?

TI考慮到了這一點,所以增加了一個UUID為FFD0的服務和UUID為FFD1的特徵值,使用者可以向該特徵值寫入任意值,裝置端就會切換回ImageA,截圖如下:


重新搜尋裝置,就會發現裝置切換到ImageA了。

因為本人是個愛學習的小學生,所以我們再一起來看看上述切換的實現程式碼及原理,實現程式碼在

C:\ti\simplelink\ble_cc26xx_2_01_00_44423\Projects\ble\Profiles\OAD\CC26xx

目錄下的oadResetService.c檔案中,原始碼截圖如下:


關鍵的部分就是紅圈裡面的內容,原始碼如下:

  1. uint16_t crc[2] = {0x0000, 0x0000};  
  2. // Invalidate the image.
  3. OADTarget_writeFlash(OAD_IMG_R_PAGE, OAD_IMG_R_OSET + OAD_IMG_CRC_OSET,  
  4.         (uint8_t *)crc, 4);  
  5. // Reset.
  6. HAL_SYSTEM_RESET();  

從上述程式碼中不難看出,所謂的ImageB切換回ImageA,其實就是將Flash中ImageB校驗位元組寫成0,因為重啟裝置的時候執行到BIM中會先去判斷ImageB的校驗位元組,如果全為0,就認為ImageB不完整或者沒有,然後去判斷ImageA的校驗位元組,如果ImageA的校驗位元組完整非0,就去執行ImageA。有的人覺得為了這個功能單獨配置一個服務和特徵值太浪費了,那我們可以將這個服務和特徵值刪掉,然後在你必須要保留的特徵值中找一個帶有寫許可權的,然後在主機通過該特徵值寫入某個命令的時候執行上述程式碼即可。