日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何为BLE 设备实现OTA DFU 空中升级功能(上)?

發(fā)布時間:2023/12/18 编程问答 64 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何为BLE 设备实现OTA DFU 空中升级功能(上)? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一、BLE peripheral 如何實(shí)現(xiàn)DFU?
    • 1.1 Nordic Memory layout
    • 1.2 Device Firmware Update process
  • 二、如何實(shí)現(xiàn)Buttonless OTA DFU?
    • 2.1 如何使用SDK 提供的Buttonless BLE DFU 示例?
    • 2.2 如何執(zhí)行Buttonless BLE DFU 過程?
  • 更多文章:

我們開發(fā)的BLE peripheral 設(shè)備通常都有代碼升級的需求,不管是解決先前的bug,還是增加新的功能。我們常用的PC 或手機(jī)都是直接聯(lián)網(wǎng)在線升級系統(tǒng)或軟件的,BLE 這類不直接接入互聯(lián)網(wǎng)且人機(jī)交互受限的嵌入式設(shè)備如何升級程序代碼呢?很多BLE peripheral 僅留出一個BLE 無線通訊接口,我們?nèi)绾瓮ㄟ^OTA 方式實(shí)現(xiàn)BLE 程序代碼的空中升級呢?我們?nèi)绾螌FU OTA 功能或服務(wù)作為一個模塊添加進(jìn)我們的工程中呢?

一、BLE peripheral 如何實(shí)現(xiàn)DFU?

在博文ARM 代碼燒錄方案與原理詳解 中談到,要實(shí)現(xiàn)DFU(Device Firmware Update) 功能一般需要bootloader 啟動引導(dǎo)代碼,且bootloader 與application 代碼是存儲在不同flash 區(qū)域的。

1.1 Nordic Memory layout

如果開發(fā)過Nordic 工程,我們知道藍(lán)牙協(xié)議棧softdevice 和application 代碼也是存儲在不同flash 區(qū)域的。DFU 實(shí)際上就是把新的程序代碼下載到本地設(shè)備,經(jīng)校驗通過后,搬移到原程序代碼存儲區(qū)的過程。我們要了解DFU 工作原理,需要先了解nordic memory 布局:

Nordic memory 主要分為四個部分:

  • Application:我們實(shí)現(xiàn)業(yè)務(wù)邏輯的應(yīng)用程序代碼存放在該區(qū)域,用戶需要掉電保護(hù)的一些自定義數(shù)據(jù)存儲在Application data 區(qū)域,free 區(qū)域可用于暫存接收到的待升級固件代碼、也可用于暫存本設(shè)備產(chǎn)生的數(shù)據(jù);
  • SoftDevice(BLE Protocol Stack):Nordic 以HEX 文件形式提供的BLE 協(xié)議棧代碼存放在該區(qū)域,我們根據(jù)芯片型號、SDK版本、業(yè)務(wù)需求等因素選擇合適的softdevice 版本;
  • MBR(Master Boot Record):Nordic 引入MBR 主要是為了能借助DFU 更新Bootloader(我們可以借助Bootloader 將新的Application、Softdevice 或Bootloader 固件下載到某個Flash 空閑區(qū)域,完成校驗后使用新的固件代碼覆蓋原來的代碼,但bootloader 無法覆蓋自身,需要借助MBR 完成新bootloader 固件覆蓋舊代碼的任務(wù)), 系統(tǒng)上電都是從MBR 啟動的,所有的中斷異常也都是首先由MBR 處理再轉(zhuǎn)發(fā)給相應(yīng)的處理程序,因此MBR 也管理系統(tǒng)啟動流程,判斷是否有bootloader 代碼決定后續(xù)啟動bootloader 還是直接啟動application(MBR 代碼不可更新);
  • MBR parameter storage:當(dāng)Bootloader 需要更新自身時,將新的bootloader 固件下載到本設(shè)備flash 空閑區(qū)域并完成校驗后,需要借助MBR 搬移新固件以覆蓋舊代碼。Bootloader 需要MBR 執(zhí)行哪些指令以及指令參數(shù)如何設(shè)置,這些信息都保存在MBR parameter storage 區(qū)域(由于從bootloader 切換到MBR 需系統(tǒng)重置,這些指令及參數(shù)需要保存在Flash 中而非RAM 中);
  • Bootloader:主要用于更新固件代碼(比如application、softdevice、bootloader),當(dāng)我們有固件更新需求時,通過按鍵或者命令觸發(fā)設(shè)備進(jìn)入DFU 模式,bootloader 通過BLE、UART 或USB 方式將新的固件存儲到本設(shè)備空閑flash 內(nèi)(bootloader 可完全訪問softdevice 的API), 對新的固件進(jìn)行校驗(比如私鑰簽名校驗、Hash 完整性校驗、CRC 校驗等),校驗通過后搬移新的固件以覆蓋舊的固件(搬移bootloader 固件需借助MBR),然后激活新的固件,引導(dǎo)執(zhí)行 application;
  • Bootloader settings:主要配合bootloader 完成DFU 過程,在Bootloader settings 區(qū)域記錄當(dāng)前固件的版本 / 大小 / CRC 值、設(shè)備廣播名與綁定信息、固件校驗信息(CRC32 值、SHA-256 哈希值、ECDSA_P256 數(shù)字簽名等)、固件更新進(jìn)度、固件激活進(jìn)度 等信息。為了防止在寫入 Bootloader settings(DFU 過程需要讀寫該區(qū)域信息) 時發(fā)生復(fù)位或掉電影響DFU 過程,SDK15 以后的版本引入了settings backup 機(jī)制(實(shí)際上就是復(fù)用了MBR parameter storage 區(qū)域),當(dāng)寫入Bootloader settings 時發(fā)生復(fù)位或掉電重啟后,可以從settings backup 區(qū)域讀取備份信息恢復(fù)DFU 過程。

由于MBR 需要知道Bootloader、MBR parameter storage、SoftDevice、Application 代碼的存儲地址,Bootloader 也需要知道Bootloader settings、MBR parameter storage 信息的存儲地址,上面每個存儲區(qū)域的地址范圍對于確定的Nordic 芯片和Softdevice 版本都有默認(rèn)值(主要是不同Nordic 芯片可供Application 使用得flash 空間大小不同,不同版本的softdevice 代碼占用flash 空間大小不同):

1.2 Device Firmware Update process

BLE 連接通信需要兩個設(shè)備BLE Peripheral / Slave 和BLE Central / Master,DFU 過程也需要兩個設(shè)備DFU target 和 DFU controller。DFU target 是要接收新的固件并升級固件的設(shè)備(比如手環(huán)、心率帶等),DFU controller 是發(fā)送新的固件并控制升級過程的設(shè)備(比如手機(jī)、網(wǎng)關(guān)等)。DFU 固件升級流程圖如下:

首先,進(jìn)入DFU mode 的方式有如下四種:

// .\nRF5_SDK_17.0.2_d674dde\examples\dfu\secure_bootloader\pca10040_s132_ble\config\sdk_config.h// <h> DFU mode enter method //========================================================== // <e> NRF_BL_DFU_ENTER_METHOD_BUTTON - Enter DFU mode on button press. #define NRF_BL_DFU_ENTER_METHOD_BUTTON 1// <q> NRF_BL_DFU_ENTER_METHOD_PINRESET - Enter DFU mode on pin reset. #define NRF_BL_DFU_ENTER_METHOD_PINRESET 0// <q> NRF_BL_DFU_ENTER_METHOD_GPREGRET - Enter DFU mode when bit 0 is set in the NRF_POWER_GPREGRET register. #define NRF_BL_DFU_ENTER_METHOD_GPREGRET 1// <q> NRF_BL_DFU_ENTER_METHOD_BUTTONLESS - Enter DFU mode when the Boolean enter_buttonless_dfu in DFU settings is true. #define NRF_BL_DFU_ENTER_METHOD_BUTTONLESS 0

比較常用的是下面這兩種方式:

  • 按鍵式ButtonPress DFU:DFU target 上電時長按某個按鍵進(jìn)入DFU 模式,適合有按鍵的設(shè)備使用;
  • 非按鍵式Buttonless DFU:DFU target 接收到命令后自動進(jìn)入DFU 模式,整個升級過程DFU target 不需要任何人工干預(yù),適合完全封裝無按鍵的設(shè)備使用。該方式需要DFU target application 能夠接收并處理進(jìn)入DFU 模式的命令,Nordic SDK 示例工程 ble_app_buttonless_dfu 可以在接收到來自DFU controller 的升級命令后,將寄存器NRF_POWER->GPREGRET bit 0 設(shè)置為1,系統(tǒng)觸發(fā)軟件復(fù)位,從MBR 啟動Bootloader,Bootloader 檢測到滿足進(jìn)入DFU mode 的條件(NRF_POWER->GPREGRET 值為0xB1),便進(jìn)入DFU 模式開始固件升級過程。

DFU target 進(jìn)入DFU mode 后,開始等待接收數(shù)據(jù),這里分為兩個階段:

  • Receive init packet and Prevalidation:DFU target 先接收到init packet,主要包含firmware 類型、大小、版本、hash 值、固件支持的硬件版本和softdevice ID、固件簽名類型及數(shù)字簽名等信息,DFU target 接收完init packet 后對這些信息進(jìn)行前期Prevalidation,主要是校驗待升級的固件是否由受信任方提供、是否跟當(dāng)前固件和硬件兼容等。如果預(yù)校驗通過,則更新Bootloader settings page 并準(zhǔn)備開始接收firmware;
  • Receive firmware and Postvalidation:DFU target Prevalidation OK 后,開始接收firmware data,每接收4 KB 數(shù)據(jù)(也即1 page)回復(fù)一次CRC 校驗值,直到整個固件接收完畢,對其進(jìn)行Postvalidation,主要是Hash 完整性校驗。如果后期校驗通過,就會invalidate 無效化當(dāng)前固件,更新Bootloader settings page 并觸發(fā)軟件復(fù)位。

固件傳輸過程,根據(jù)傳輸方式的不同,可以分為有線升級和無線升級兩種:

  • Wired DFU:通過有線通信方式來傳輸固件,比如UART、USB 等(目前Nordic SDK 僅對nRF52840 支持USB DFU);
  • Wireless DFU(OTA DFU):通過無線通信方式來傳輸固件,比如BLE、ANT 等。

固件校驗過程,根據(jù)是否需要校驗數(shù)字簽名,也可分為開放升級和安全升級兩種:

  • Open DFU:不對新的固件進(jìn)行數(shù)字簽名校驗(bootloader 除外),且優(yōu)先使用Single-bank 升級方式(目前Nordic SDK 僅支持通過USB 傳輸固件的方式進(jìn)行Open DFU);
  • Secure DFU:需要對新的固件進(jìn)行數(shù)字簽名校驗,以防止惡意攻擊者偽造固件被接受并升級,特別是對OTA DFU 應(yīng)要求數(shù)字簽名校驗(Nordic SDK 建議對所有固件進(jìn)行數(shù)字簽名校驗)。

完成固件傳輸和校驗后,就開始進(jìn)行copy new firmware 的過程了,實(shí)際上就是使用新的固件覆蓋舊的固件。根據(jù)新固件和舊固件占用的存儲分區(qū)個數(shù),可分為雙分區(qū)升級和單分區(qū)升級兩種:

  • Dual-bank DFU:將接收到的新固件先暫存在空閑存儲區(qū)Bank 1 中,完成數(shù)字簽名校驗和完整性校驗后,再擦除現(xiàn)有固件代碼(假設(shè)存儲在Bank 0 中),然后將Bank 1 中的新固件復(fù)制到Bank 0 處并激活(如果新固件校驗失敗,不影響現(xiàn)有固件的正常運(yùn)行)。雙分區(qū)升級需要足夠的空閑存儲區(qū)Bank 1 來存儲新固件,對存儲空間的要求較高,如果空閑存儲區(qū)不足以存儲新固件,則根據(jù)配置選擇是拒絕升級還是轉(zhuǎn)為單分區(qū)升級。下圖左邊展示了SoftDevice + Bootloader 的雙分區(qū)升級過程,右邊展示了Application 的雙分區(qū)升級過程:
  • Single-bank DFU:進(jìn)入DFU 模式后先擦除當(dāng)前application 代碼,再把接收到的新固件存儲到原應(yīng)用所在的Bank 0 中(實(shí)際上相當(dāng)于直接使用新應(yīng)用替換舊應(yīng)用代碼),新固件接收完畢并通過校驗后直接激活(如果新固件校驗失敗,系統(tǒng)將保持DFU 模式繼續(xù)嘗試再次升級,因為原應(yīng)用程序已被擦除而不能再執(zhí)行)。單分區(qū)升級相比雙分區(qū)升級節(jié)省了一個Bank 空間,在系統(tǒng)資源比較緊張的情況下可以選用,Nordic SDK 默認(rèn)優(yōu)先使用雙分區(qū)升級方案。下圖左邊展示了SoftDevice + Bootloader 的單分區(qū)升級過程(因該過程會擦除application,完成SoftDevice + Bootloader 升級后還需要再進(jìn)行application 升級),右邊展示了Application 的單分區(qū)升級過程:

設(shè)備固件升級過程中,工程pca10040_s132_ble 中跟固件傳輸方式、固件版本校驗、固件簽名校驗、固件單雙區(qū)升級控制 等相關(guān)的宏變量配置如下:

// .\nRF5_SDK_17.0.2_d674dde\examples\dfu\secure_bootloader\pca10040_s132_ble\config\sdk_config.h// <e> NRF_DFU_TRANSPORT_BLE - BLE transport settings //========================================================== #define NRF_DFU_TRANSPORT_BLE 1 // <s> NRF_DFU_BLE_ADV_NAME - Default advertising name. #define NRF_DFU_BLE_ADV_NAME "DfuTarg"// <h> DFU security - nrf_dfu_validation - DFU validation //========================================================== // <q> NRF_DFU_APP_ACCEPT_SAME_VERSION - Whether to accept application upgrades with the same version as the current application. #define NRF_DFU_APP_ACCEPT_SAME_VERSION 1 // <q> NRF_DFU_APP_DOWNGRADE_PREVENTION - Check the firmware version and SoftDevice requirements of application (and SoftDevice) updates. #define NRF_DFU_APP_DOWNGRADE_PREVENTION 1 // <q> NRF_DFU_EXTERNAL_APP_VERSIONING - Require versioning for external applications. #define NRF_DFU_EXTERNAL_APP_VERSIONING 1 // <o> NRF_DFU_HW_VERSION - Device hardware version. #define NRF_DFU_HW_VERSION 52// <q> NRF_DFU_REQUIRE_SIGNED_APP_UPDATE - Require a valid signature to update the application or SoftDevice. #define NRF_DFU_REQUIRE_SIGNED_APP_UPDATE 1// <q> NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES - Accept only dual-bank application updates. #define NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES 0 // <q> NRF_DFU_SINGLE_BANK_APP_UPDATES - Place the application and the SoftDevice directly where they are supposed to be. #define NRF_DFU_SINGLE_BANK_APP_UPDATES 0// <h> BLE DFU security //========================================================== // <q> NRF_DFU_BLE_REQUIRES_BONDS - Require bond with peer. #define NRF_DFU_BLE_REQUIRES_BONDS 0

Nordic SDK 提供的secure_bootloader 工程pca10040_s132_ble,默認(rèn)優(yōu)先采用Dual-bank DFU 方式,當(dāng)沒有足夠的空閑flash 空間時將切換到Single-bank DFU 方式,開發(fā)者可配置宏變量NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES 為1 強(qiáng)制使用Dual-bank DFU (若空間不足則停止DFU 過程)。

Nordic SDK 默認(rèn)提供的是后臺式升級,對于工程ble_app_buttonless_dfu 來說,系統(tǒng)有兩段完全獨(dú)立的代碼:Application 和Bootloader,其中SoftDevice 是共用的,兩段獨(dú)立的程序都可以訪問SoftDevice API,也都有自己的藍(lán)牙廣播和藍(lán)牙連接。當(dāng)需要進(jìn)行DFU 時,在Application 中觸發(fā)進(jìn)入DFU mode,后面就交由Bootloader 完成固件的傳輸、校驗、激活過程。當(dāng)DFU target 從Application 跳轉(zhuǎn)到Bootloader 后,DFU controller 怎么判斷兩者是同一個設(shè)備呢?

DFU controller 可以通過相同的廣播名或設(shè)備地址來辨識出DFU target 的Application 連接和Bootloader 連接來自同一設(shè)備,但由于多數(shù)手機(jī)為了加快BLE 連接速度,常將首次連接發(fā)現(xiàn)的GATT Service 緩存到本地,下次連接若判斷為同一設(shè)備就會跳過服務(wù)發(fā)現(xiàn)過程直接從緩存讀取服務(wù)數(shù)據(jù),這就導(dǎo)致DFU controller 不能發(fā)現(xiàn)Bootloader 提供的DFU 服務(wù),也就無法順利完成DFU 過程。由此可見,DFU controller 應(yīng)不僅能辨識Application 連接和Bootloader 連接來自同一設(shè)備,還需要辨識當(dāng)前連接是Application 連接還是Bootloader 連接,這個問題該如何解決呢?

Nordic 為該問題提供了兩套方案:

  • Unbonded DFU:DFU target 設(shè)備Application 和Bootloader 程序采用不同的藍(lán)牙設(shè)備地址,且Bootloader 程序的藍(lán)牙設(shè)備地址 = Application 程序的藍(lán)牙設(shè)備地址 + 1,這樣DFU controller 就可以區(qū)分Application 連接和Bootloader 連接,同時辨識出二者來自同一設(shè)備,由于藍(lán)牙設(shè)備地址不同,DFU controller 也會對Bootloader 連接執(zhí)行服務(wù)發(fā)現(xiàn)過程,發(fā)現(xiàn)Bootloader 提供的DFU 服務(wù),繼續(xù)進(jìn)行DFU 過程;
  • Bonded DFU:DFU target 設(shè)備Application 和Bootloader 程序采用相同的藍(lán)牙設(shè)備地址,由于DFU target 和DFU controller 進(jìn)行了配對綁定過程,DFU target 可以主動向DFU controller 發(fā)送service changed indication,讓DFU controller 再執(zhí)行一次服務(wù)發(fā)現(xiàn)過程,讓DFU controller 可以發(fā)現(xiàn)Bootloader 提供的DFU 服務(wù),繼續(xù)進(jìn)行DFU 過程。

二、如何實(shí)現(xiàn)Buttonless OTA DFU?

對于BLE peripheral,通常都是電池供電,因此對其進(jìn)行固件升級通常都采用OTA DFU 方式(也即BLE DFU)。很多BLE peripheral 并沒有留出按鍵,需要人工干預(yù)的升級方式也不夠友好,因此BLE DFU 更多采用Buttonless DFU 方式升級固件。

本文使用的開發(fā)工具和示例工程如下:

  • Development Kit:nRF52 DK;
  • nRF5 SDK:nRF5_SDK_17.0.2_d674dde
  • SoftDevice:s132_nrf52_7.2.0_softdevice.hex
  • Bootloader:secure_bootloader_ble_s132_pca10040
  • Application:ble_app_buttonless_dfu_pca10040_s132
  • nRF Command Line Tools:nRF-Command-Line-Tools_10_10_0_Installer_64.exe(包含J-Link、nrfjprog、mergehex 命令集,可用于Nordic Soc 開發(fā)、燒錄 和調(diào)試)
  • nRF Util:nrfutil-6.1.0.exe(提供nrfutil 命令集,可用于DFU package生成、Cryptographic key生成/管理/存儲、Bootloader settings 生成等),需Python 3.7 or later 支持
  • Other Tools:Setup_EmbeddedStudio_ARM_v540b_win_x64.exe,nRF Connect-v4.24.3.apk,nRF Connect-setup-v3.6.1-ia32.exe,nRF.Toolbox.2.9.0.apk

2.1 如何使用SDK 提供的Buttonless BLE DFU 示例?

要實(shí)現(xiàn)無按鍵式的BLE 空中升級,需要往nRF52 DK 中燒錄SoftDevice(包含MBR)、Bootloader、Application 三部分。由于在DFU 過程中需要對新固件進(jìn)行Prevalidation 和Postvalidation,校驗過程主要是信息比對,Bootloader settings page 保存了當(dāng)前固件的屬性及校驗信息,init packet 包含了新固件的屬性及校驗信息。因此,首次向nRF52 DK 中燒錄Bootloader 和Application 時,也應(yīng)包含Bootloader settings page 信息(可由nrfutil 生成),制作DFU package 也應(yīng)包含固件版本及校驗信息(可由nrfutil 生成)。

  • Install nrf_crypto backend(micro-ecc)
  • 首先,我們打開工程secure_bootloader_ble_s132_pca10040,編譯提示“uECC.h: No such file or directory”,我們在infocenter.nordicsemi.com 搜索關(guān)鍵詞“uECC” 得知micro_ecc backend 需要安裝(可能受限于版權(quán)要求,不能直接放到SDK 中),在.\nRF5_SDK_17.0.2_d674dde\external\micro-ecc 目錄下有自動化腳本build_all.bat,我們直接執(zhí)行該腳本即可自動安裝micro_ecc 密碼庫(需要電腦安裝Git、make 命令集和GCC compiler toolchain for ARM),安裝完成后會多一個micro-ecc 文件夾,里面就有uECC.h 文件和uECC.c 文件:

    Nordic Cryptography library - nrf_crypto 分為nrf_crypto frontend 和nrf_crypto backends 兩部分,nrf_crypto frontend 對應(yīng)用程序提供統(tǒng)一的API,隱藏了不同nrf_crypto backends 的API 差異。我們可以根據(jù)硬件資源、版權(quán)等要求選擇合適的nrf_crypto backends,比如nRF52840 支持Arm CryptoCell CC310 cryptographic accelerator 建議選用CC310 backend(配合CryptoCell CC310 可以提高加解密效率),其它nRF52 芯片建議優(yōu)先選用micro-ecc backend(占用的存儲空間更小),若micro-ecc 無法滿足需求且不支持CryptoCell CC310 可選用mbed TLS backend(ARM 為嵌入式設(shè)備開發(fā)的支持TLS 協(xié)議的加解密算法,功能比micro-ecc 更強(qiáng)大):

    工程secure_bootloader_ble_s132_pca10040 的sdk_config.h 中跟nrf_crypto 配置相關(guān)的宏變量如下(通過插件CMSIS_Configuration_Wizard.jar 查看sdk_config.h):

  • Generating DFU public/private key pair
  • 繼續(xù)編譯工程secure_bootloader_ble_s132_pca10040,提示#error “Debug public key not valid for production. Please see https://github.com/NordicSemiconductor/pc-nrfutil/blob/master/README.md to generate it”,大意是說dfu_public_key.c 文件中的公鑰是無效的,需要我們使用nrfutil 工具重新生成公私密鑰對。

    如何利用nrfutil 生成公私密鑰對呢?我們可以查看Nordic 在線文檔Generating and displaying keys,也可以使用nrfutil keys --help 命令,獲知生成公私密鑰對的命令如下:

    # Generate a private key and store it in a file named private.pem nrfutil keys generate private.pem# Display the public key that corresponds to the generated private key (in code format to be used with DFU) nrfutil keys display --key pk --format code private.pem# Write the public key that corresponds to the generated private key to the file public_key.c (in code format) nrfutil keys display --key pk --format code private.pem --out_file dfu_public_key.c

    該工程中的公鑰用于驗證DFU package 的數(shù)字簽名,與該公鑰配對的私鑰則用于為DFU package 進(jìn)行數(shù)字簽名。由于DFU 過程主要靠簽名校驗判斷固件升級包來源的可信性,為了保證DFU 過程的安全性,我們需要保管好生成的私鑰,后續(xù)每次升級固件都需要該私鑰對其簽名。

    我們將生成的公鑰文件dfu_public_key.c 放到目錄.\nRF5_SDK_17.0.2_d674dde\examples\dfu 下并替換原有的同名文件。繼續(xù)編譯工程secure_bootloader_ble_s132_pca10040,這次工程順利編譯完成,將編譯生成的secure_bootloader_ble_s132_pca10040.hex 文件復(fù)制出來,這就是我們實(shí)現(xiàn)Buttonless BLE DFU 的Bootloader 程序代碼。

    我們打開工程ble_app_buttonless_dfu_pca10040_s132,編譯完成后,將生成的ble_app_buttonless_dfu_pca10040_s132.hex 文件復(fù)制出來,這就是我們實(shí)現(xiàn)Buttonless BLE DFU 的Application 代碼。

    SoftDevice 不需要我們編譯,Nordic SDK 直接提供的HEX 文件,我們從目錄.\nRF5_SDK_17.0.2_d674dde\components\softdevice\s132\hex 將s132_nrf52_7.2.0_softdevice.hex 文件復(fù)制出來,這就是我們實(shí)現(xiàn)Buttonless BLE DFU 的SoftDevice 代碼。

  • Generating Bootloader settings HEX
  • 準(zhǔn)備好SoftDevice、Bootloader、Application 代碼文件,為方便后續(xù)DFU 過程的固件校驗,還需要生成包含固件版本等屬性信息的Bootloader settings 文件。

    如何利用nrfutil 生成Bootloader settings 呢?我們可以查看Nordic 在線文檔Generating and displaying bootloader settings,也可以使用nrfutil settings generate --help 命令,獲知生成Bootloader settings的命令如下:

    # Generate a bootloader settings page for an nRF52 device with the application ble_app_buttonless_dfu_pca10040_s132.hex installed, with application version string “1.0.0”, bootloader version 1, and bootloader settings version 2 (for SDK v17.0.2), and store it in a file named bl-settings.hex: nrfutil settings generate --family NRF52 --application ble_app_buttonless_dfu_pca10040_s132.hex --application-version-string "1.0.0" --bootloader-version 1 --bl-settings-version 2 bl-settings.hex# display the contents of the generated HEX file: nrfutil settings display bl-settings.hex

    生成實(shí)現(xiàn)Buttonless BLE DFU 功能的Bootloader settings 文件都包含哪些信息呢?我們可以查看生成的bl-settings.hex 文件內(nèi)容如下:

    每個字段的含義都可以在struct nrf_dfu_settings_t 中查得,該數(shù)據(jù)結(jié)構(gòu)的聲明如下:

    // .\nRF5_SDK_17.0.2_d674dde\components\libraries\bootloader\dfu\nrf_dfu_types.h/**@brief DFU settings for application and bank data.*/ typedef struct {uint32_t crc; /**< CRC for the stored DFU settings, not including the CRC itself. If 0xFFFFFFF, the CRC has never been calculated. */uint32_t settings_version; /**< Version of the current DFU settings struct layout. */uint32_t app_version; /**< Version of the last stored application. */uint32_t bootloader_version; /**< Version of the last stored bootloader. */uint32_t bank_layout; /**< Bank layout: single bank or dual bank. This value can change. */uint32_t bank_current; /**< The bank that is currently used. */nrf_dfu_bank_t bank_0; /**< Bank 0. */nrf_dfu_bank_t bank_1; /**< Bank 1. */uint32_t write_offset; /**< Write offset for the current operation. */uint32_t sd_size; /**< Size of the SoftDevice. */dfu_progress_t progress; /**< Current DFU progress. */uint32_t enter_buttonless_dfu;uint8_t init_command[INIT_COMMAND_MAX_SIZE]; /**< Buffer for storing the init command. */uint32_t boot_validation_crc;boot_validation_t boot_validation_softdevice;boot_validation_t boot_validation_app;boot_validation_t boot_validation_bootloader;nrf_dfu_peer_data_t peer_data; /**< Not included in calculated CRC. */nrf_dfu_adv_name_t adv_name; /**< Not included in calculated CRC. */ } nrf_dfu_settings_t;
  • Merge and program hex files
  • 我們已經(jīng)生成了需要燒錄到nRF52 DK 中實(shí)現(xiàn)Buttonless BLE DFU 功能的四個程序文件,四個文件分別燒錄略繁瑣,我們可以先將其合并為一個hex 文件,再將其燒錄到目標(biāo)芯片中。

    我們可以使用mergehex 命令實(shí)現(xiàn)多個hex 文件的合并,可以查看Nordic 在線文檔Merging files with mergehex,也可以使用mergehex --help 命令,獲知合并多個hex 文件的命令如下:

    # Merge four HEX files into one file named all_ble_buttonless_dfu_nrf52832_s132.hexmergehex --merge s132_nrf52_7.2.0_softdevice.hex secure_bootloader_ble_s132_pca10040.hex bl-settings.hex ble_app_buttonless_dfu_pca10040_s132.hex --output all_ble_buttonless_dfu_nrf52832_s132.hex

    使用mergehex 命令將softdevice、bootloader、settings、application 合并為一個文件all_ble_buttonless_dfu_nrf52832_s132.hex 后,可以使用nrfjprog 命令將其燒錄到nRF52 DK 中(也可以使用nRF Connect for desktop --> Programmer 燒錄hex 文件)。我們可以查看Nordic 在線文檔Programming SoCs with nrfjprog,也可以使用nrfjprog --help 命令,獲知將hex 文件燒錄到目標(biāo)芯片中的命令如下:

    # Erase all available user flash (including UICR) and program the file all_ble_buttonless_dfu_nrf52832_s132.hex to an nRF52 SoC nrfjprog --family NRF52 --program all_ble_buttonless_dfu_nrf52832_s132.hex --chiperase --verify --reset

    我們借助上面提供的nrfjprog 命令將合并后的代碼文件all_ble_buttonless_dfu_nrf52832_s132.hex 燒錄到nRF52 DK 中,系統(tǒng)正常啟動,我們可以通過nRF Connect 掃描并發(fā)現(xiàn)“Nordic_Buttonless” 設(shè)備。點(diǎn)擊“Connect” 連接成功后,可以看到“Secure DFU Service” 服務(wù),該服務(wù)包含“Buttonless DFU” Characteristic,下文嘗試使用該服務(wù)執(zhí)行BLE DFU 空中升級過程。

    2.2 如何執(zhí)行Buttonless BLE DFU 過程?

    要使用“Secure DFU Service” 進(jìn)行空中升級,還需要準(zhǔn)備DFU package。通常Bootloader 和Softdevice 更新頻率很低,Application 更新頻率較高,本文以空中升級application 固件為例,說明Buttonless BLE DFU 過程。

    版本更新,最直觀的判斷標(biāo)識是版本號,工程ble_app_buttonless_dfu_pca10040_s132 暫不支持查詢軟件版本的命令,為了更直觀辨識新舊版本的差異,我們修改該工程的廣播名稱,原廣播名為"Nordic_Buttonless",我們修改為"Nordic_DFU_V110":

    // .\nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_buttonless_dfu\main.c #define DEVICE_NAME "Nordic_DFU_V110" /**< Name of device. Will be included in the advertising data. */

    重新編譯工程,將生成的hex 文件添加版本號,修改后的app 文件為ble_app_buttonless_dfu_pca10040_s132_v110.hex,然后使用nrfutil 工具生成DFU package。

    如何利用nrfutil 生成DFU package 呢?我們可以查看Nordic 在線文檔Generating DFU packages,也可以使用nrfutil pkg generate --help 命令,獲知生成DFU package 的命令如下:

    # Generate a package called SDK1702_app_s132_v110.zip from the application file ble_app_buttonless_dfu_pca10040_s132_v110.hex with application version "1.1.0" that requires hardware version 52 and SoftDevice S132 v7.2.0 (0x0101) and is signed with the private key that is stored in private.pem nrfutil pkg generate --application ble_app_buttonless_dfu_pca10040_s132_v110.hex --application-version-string "1.1.0" --hw-version 52 --sd-req 0X0101 --key-file private.pem SDK1702_app_s132_v110.zip# Display the contents of the created dfu package SDK1702_app_s132_v110.zip nrfutil pkg display SDK1702_app_s132_v110.zip

    值得一提的是,nrfutil pkg generate 命令 “–sd-req” 參數(shù)需要制定SoftDevice firmware ID,幫助界面給出的列表并沒有包含s132_nrf52_7.2.0,我們該如何獲得s132_nrf52_7.2.0 的firmware ID 呢?到s132 所在的目錄 .\nRF5_SDK_17.0.2_d674dde\components\softdevice\s132\doc\s132_nrf52_7.2.0_release-notes.pdf,可以查得:

    The Firmware ID of s132_nrf52_7.2.0 is 0x0101.

    我們可以通過nrfutil pkg display ZIP_FILE 命令查看DFU package 的內(nèi)容,主要是 init packet file 和 firmware image file 相關(guān)的信息如下:


    由于各部分hex 文件名都比較長,上面的命令也比較長,我們可以將其編輯進(jìn)shell 腳本里面(對于windows 系統(tǒng)就是.bat 批處理文件 ),后續(xù)制作DFU package 只需要執(zhí)行腳本即可:

    • Unbonded BLE DFU procedure

    有了DFU package(SDK1702_app_s132_v110.zip),我們就可以使用“Secure DFU Service” 進(jìn)行空中升級了,比如使用手機(jī)端nRF Connect for mobile 掃描發(fā)現(xiàn)并連接“Nordic_Buttonless” 設(shè)備 --> 點(diǎn)擊“DFU” 圖標(biāo) --> 選擇DFU package(SDK1702_app_s132_v110.zip)便開始DFU 過程(需將DFU package 傳到手機(jī)上),DFU 完成后設(shè)備廣播名變?yōu)?#34;Nordic_DFU_V110",說明固件升級成功了,操作圖示如下:

    注意上圖“Nordic_Buttonless” 和“DFUTARG” 的藍(lán)牙設(shè)備地址關(guān)系,印證了前面介紹的Unbonded DFU 過程中DFU target 設(shè)備Bootloader 程序的藍(lán)牙設(shè)備地址 = Application 程序的藍(lán)牙設(shè)備地址 + 1,方便DFU controller 區(qū)分Application 連接和Bootloader 連接,發(fā)現(xiàn)Bootloader 提供的DFU 服務(wù)。

    • Bonded BLE DFU procedure

    Bootloader 如果啟用了NRF_DFU_BLE_REQUIRES_BONDS,則在執(zhí)行BLE DFU 前需要先執(zhí)行配對綁定過程,DFU target 拒絕來自未綁定DFU controller 的DFU 請求,Bonded DFU 安全性比Unbonded DFU 更高。我們在工程secure_bootloader_ble_s132_pca10040 中均啟用NRF_DFU_BLE_REQUIRES_BONDS 如下:

    // .\nRF5_SDK_17.0.2_d674dde\examples\dfu\secure_bootloader\pca10040_s132_ble\config\sdk_config.h // <h> BLE DFU security //========================================================== // <q> NRF_DFU_BLE_REQUIRES_BONDS - Require bond with peer. #define NRF_DFU_BLE_REQUIRES_BONDS 1

    編譯工程,提示“#error NRF_DFU_BLE_REQUIRES_BONDS requires NRF_SDH_BLE_SERVICE_CHANGED. Please update the SoftDevice BLE stack configuration in sdk_config.h”。前面我們提到,Bonded DFU 過程中,DFU target 需要主動向DFU controller 發(fā)送service changed indication,讓DFU controller 可以發(fā)現(xiàn)Bootloader 提供的DFU 服務(wù),因此還需要啟用NRF_SDH_BLE_SERVICE_CHANGED 如下:

    // .\nRF5_SDK_17.0.2_d674dde\examples\dfu\secure_bootloader\pca10040_s132_ble\config\sdk_config.h //========================================================== // <q> NRF_SDH_BLE_SERVICE_CHANGED - Include the Service Changed characteristic in the Attribute Table. #define NRF_SDH_BLE_SERVICE_CHANGED 1

    重新編譯工程,順利完成,我們將生成的secure_bootloader_ble_s132_pca10040.hex 文件復(fù)制出來(也可以添加_bond 以區(qū)別與前面的unbond)。然后,在工程ble_app_buttonless_dfu_pca10040_s132 中啟用NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS 如下:

    // .\nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_buttonless_dfu\pca10040\s132\config\sdk_config.h // <h> ble_dfu - Device Firmware Update //========================================================== // <q> NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS - Buttonless DFU supports bonds. #define NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS 1

    重新編譯工程,順利完成,我們將生成的ble_app_buttonless_dfu_pca10040_s132.hex 文件復(fù)制出來(也可以添加_bond 以區(qū)別與前面的unbond),執(zhí)行前面介紹的生成Bootloader settings、合并燒錄hex 文件的過程,nRF52 DK 系統(tǒng)正常啟動,通過nRF Connect 連接“Nordic_Buttonless” 設(shè)備可以看到“Secure DFU Service” 服務(wù)。

    我們將工程ble_app_buttonless_dfu_pca10040_s132 的DEVICE_NAME 改為“Nordic_DFU_V120”:

    // .\nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_buttonless_dfu\main.c #define DEVICE_NAME "Nordic_DFU_V120" /**< Name of device. Will be included in the advertising data. */

    重新編譯工程,將生成的hex 文件改為ble_app_buttonless_dfu_pca10040_s132_v120.hex,執(zhí)行前面介紹的生成生成DFU package 過程,獲得DFU 升級包SDK1702_app_s132_v120.zip,將其傳到手機(jī)上用于DFU 升級。

    手機(jī)端nRF Connect 執(zhí)行DFU 的操作跟前面Unbonded BLE DFU 類似,主要區(qū)別是在進(jìn)行DFU 之前需要先執(zhí)行配對綁定操作,圖示如下(點(diǎn)擊“DFU” 圖標(biāo)選擇DFU package 的過程跟前面完全一致,這里省略了):

    Bonded BLE DFU procedure 不再出現(xiàn)“DFUTARG” 設(shè)備了,這樣印證了前面說到的,Bonded DFU 過程中DFU target 設(shè)備Application 和Bootloader 程序采用相同的藍(lán)牙設(shè)備地址,配對綁定后DFU target 可以主動向DFU controller 發(fā)送service changed indication,讓DFU controller 可以發(fā)現(xiàn)Bootloader 提供的DFU 服務(wù),繼續(xù)執(zhí)行DFU 過程。

    本工程源碼下載地址:https://github.com/StreamAI/Nordic_nRF5_Project/tree/main/BLE_Buttonless_DFU。

    更多文章:

    • 《如何為BLE 設(shè)備添加OTA DFU 空中升級服務(wù)(下)?》
    • 《如何實(shí)現(xiàn)BLE 最大數(shù)據(jù)吞吐率并滿足設(shè)計功耗要求?》
    • 《如何抓包分析BLE 空口報文(GAP + GATT + LESC)?》
    • 《如何實(shí)現(xiàn)掃碼連接BLE 設(shè)備的功能?》
    • 《Nordic_nRF5_Project》
    • 《Nordic nRF5 SDK documentation》
    • 《BLE 技術(shù)(五)— Generic Access Profile + Pairing and Bonding》
    • 《BLE 技術(shù)(六)— GATT Profile + Security Manager Protocol》
    • 《Bluetooth Core Specification_v5.2》

    總結(jié)

    以上是生活随笔為你收集整理的如何为BLE 设备实现OTA DFU 空中升级功能(上)?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    日韩欧美一区二区三区在线 | 精品福利视频在线 | 国产伦精品一区二区三区… | 91在线播放视频 | 五月婷香蕉久色在线看 | 国产精品一区二区免费看 | 五月天激情在线 | 欧洲av在线| 久久久精品国产免费观看同学 | 国产免费又爽又刺激在线观看 | 国产九九九视频 | 特级西西444www高清大视频 | 日韩av影视在线 | 免费一级片在线观看 | 中文字幕在线视频一区 | 在线黄色av电影 | 精品国产免费一区二区三区五区 | 免费在线色视频 | 九九热精品国产 | 久久成人资源 | 中文成人字幕 | 能在线看的av | 蜜桃视频日本 | 免费在线一区二区 | 色播五月激情综合网 | 成人cosplay福利网站 | 精品视频免费看 | 香蕉91视频 | 久久福利剧场 | 国产无遮挡又黄又爽馒头漫画 | 黄色成人av在线 | 在线观看的av | 亚洲精品在线一区二区 | 久久一二三四 | 亚洲视屏 | 在线看成人av | 欧美一区二区三区免费观看 | 午夜视频在线观看欧美 | 国产999精品久久久久久绿帽 | 天天做天天爱天天综合网 | 伊人电影在线观看 | 成年人黄色大全 | 免费看黄在线网站 | 国产日韩视频在线观看 | 国产黄色精品 | 91精品视频在线 | 玖玖视频在线 | 精品一区二区日韩 | 亚洲日本中文字幕在线观看 | 5月丁香婷婷综合 | ww亚洲ww亚在线观看 | 婷婷成人亚洲综合国产xv88 | 精品网站999www | 91av手机在线 | 国产成人综合在线观看 | 91精品国产91 | 国产在线视频资源 | .国产精品成人自产拍在线观看6 | 日韩欧美网站 | www日韩欧美 | 国产精品一区二区免费在线观看 | 麻豆影视网站 | 国产伦精品一区二区三区免费 | 国产精品一区免费在线观看 | 久久久久久久久久久久久久av | 97成人在线观看 | 最近中文字幕免费大全 | 中文国产字幕在线观看 | 日本黄色特级片 | 99精品欧美一区二区三区 | 手机av在线不卡 | 久久精品国产精品亚洲 | 国产区免费在线 | 日本久久影视 | 伊人春色电影网 | 国产天天综合 | 久久国产精品区 | 天天色天天 | 51精品国自产在线 | 国产精品久久久久久久免费观看 | 国产精品精品久久久久久 | 久久久国产精品电影 | 久久久国产视频 | 成人免费视频视频在线观看 免费 | 国产精品久久久久久久久久免费看 | 国产剧情一区在线 | 激情综合六月 | 九九久久免费 | 一区精品久久 | 天无日天天操天天干 | 黄色av三级在线 | 久久久久久毛片精品免费不卡 | 欧美精品久久 | 久久手机免费观看 | 日韩午夜视频在线观看 | 国产成人在线精品 | 探花在线观看 | 亚洲国产黄色片 | 欧美午夜精品久久久久久孕妇 | 超碰在线人人艹 | 97视频在线观看播放 | 在线观看亚洲视频 | 伊人五月 | 国产精品人人做人人爽人人添 | 99中文字幕在线观看 | 国产精品毛片一区二区在线看 | 国产一级片不卡 | 91c网站色版视频 | 玖玖在线看| 久久国产一区二区三区 | 国产精品永久久久久久久久久 | 国产高清绿奴videos | 国产精品久久久久久久久久久杏吧 | 欧美成人猛片 | 99久热在线精品视频 | 免费三级黄 | 九九色在线观看 | 日韩不卡高清视频 | 色在线免费观看 | 亚洲永久精品一区 | 91传媒免费观看 | av久久在线 | 最近2019好看的中文字幕免费 | 中文字幕亚洲在线观看 | 一区二区三区四区不卡 | 国产精品精品国产色婷婷 | 日韩高清一 | 99精品视频免费全部在线 | 天天在线视频色 | 九九视频一区 | www色片| 99热99re6国产在线播放 | 亚洲成人黄色在线观看 | 最近中文字幕免费 | 天天插天天操天天干 | 成人免费亚洲 | 国产麻豆果冻传媒在线观看 | av 一区二区三区 | 精品国偷自产国产一区 | 久久综合九色综合欧美就去吻 | 欧美狠狠色 | 91亚洲精 | 97视频在线观看网址 | 91成人免费看 | 国产高清视频免费在线观看 | 91原创在线观看 | 91在线公开视频 | 444av| 天天爱天天舔 | 99久久精品无免国产免费 | 最近日本中文字幕 | 成人在线播放视频 | 欧美日韩免费观看一区二区三区 | 成人国产精品一区 | 精品国产自在精品国产精野外直播 | 午夜在线资源 | 在线日韩视频 | 中文字幕免费不卡视频 | 久久久久久久久久久网 | 丁香婷婷激情国产高清秒播 | 久久久精品高清 | 超碰免费久久 | 日韩av成人 | 丁香六月婷婷开心婷婷网 | 国产午夜小视频 | 欧美成人猛片 | 国产一级免费观看 | 国产在线播放不卡 | 美女视频是黄的免费观看 | av免费看在线 | 97视频总站 | 麻豆视频国产精品 | 日本精品二区 | 成人av在线网址 | 日韩午夜在线观看 | 国产91精品一区二区 | 亚洲精品一区二区精华 | 97在线观视频免费观看 | 少妇精品久久久一区二区免费 | 亚洲视频久久久久 | 在线三级播放 | 99福利影院 | 九九热精 | 久久国产经典视频 | 精品你懂的 | 亚洲精品在线观看网站 | 天天射天天爱天天干 | 在线播放亚洲激情 | 日日干av| 亚洲日本精品视频 | 中文字幕传媒 | 免费在线激情电影 | 国产日韩精品视频 | 国产精品久久久久久久久大全 | 奇米影视8888在线观看大全免费 | 综合色婷婷 | 91自拍视频在线观看 | 手机在线欧美 | 韩日在线一区 | 97成人资源站| 青青啪 | 久久久久久久久久久国产精品 | 国内一级片在线观看 | 久草在线久草在线2 | www视频在线播放 | 亚洲国产精品视频 | 日本中文字幕网站 | 福利视频网站 | 久久不射电影网 | 狠狠干夜夜爱 | 国产极品尤物在线 | 激情 亚洲 | 亚洲视频国产 | 久久永久视频 | 久久精品99久久久久久 | 国产精品久久久久久久久免费看 | 在线视频18在线视频4k | 99999精品视频 | 欧美做受69 | 亚洲精品在线免费播放 | 天天操天天操一操 | 99精品视频免费观看视频 | 欧美另类v| 国产黄色片免费观看 | 永久免费av在线播放 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产精品18久久久久久不卡孕妇 | 久久久久久久久久久久久影院 | 国产在线一区二区三区播放 | 97国产在线播放 | 黄色亚洲精品 | 91中文字幕视频 | 国产精品成人一区 | 久久久污| 又黄又爽又色无遮挡免费 | 亚洲一区精品二人人爽久久 | 日韩大陆欧美高清视频区 | 三级av在线播放 | 免费福利在线视频 | 99国产精品久久久久久久久久 | 亚洲天堂自拍视频 | 欧美一级久久久久 | 插综合网 | 91久久精品一区二区三区 | 99精品视频在线播放观看 | 99在线视频播放 | 人人草在线视频 | 亚洲精品动漫在线 | 婷婷色网址| 欧美欧美 | 黄色一级大片在线免费看产 | 69国产精品视频免费观看 | 中文字幕乱在线伦视频中文字幕乱码在线 | 久久亚洲私人国产精品 | 又爽又黄又无遮挡网站动态图 | 日韩亚洲国产精品 | 国产在线中文字幕 | 亚洲国内精品在线 | 免费网站黄 | 91精品国产乱码 | 国产成人精品一区二区三区在线 | 91精品国产91 | 日韩视频中文 | 国内精品美女在线观看 | 婷婷精品国产一区二区三区日韩 | 黄色av电影| 狠狠狠狠狠狠操 | 主播av在线| 婷婷色网视频在线播放 | 最新av在线网站 | 久久精品久久99精品久久 | 91九色网站 | www操操| av在线网站大全 | 日韩理论在线视频 | 久久精品在线免费观看 | 日韩免费二区 | 在线 精品 国产 | 色综合久久精品 | 91精品国产一区二区在线观看 | 亚洲最大av网 | 国产精品美女在线 | 成人免费xxx在线观看 | 久久系列 | 国产一级免费观看 | 99久久精品免费看国产 | 人人干人人超 | 在线观看网站黄 | 日本中文字幕高清 | 丁香花中文字幕 | 在线看片视频 | av中文字幕网站 | 中文字幕一区二区三区在线视频 | 蜜桃视频精品 | 超碰在线观看av.com | 国产一线天在线观看 | 91精品视频在线免费观看 | 日韩精品在线看 | 热热热热热色 | 又色又爽的网站 | 国产小视频在线免费观看 | 日本黄色免费在线 | 免费观看一级特黄欧美大片 | 久久99国产精品视频 | 亚洲91网站| www.香蕉视频| 日本大片免费观看在线 | 夜色.com| 88av网站 | 久久99热精品这里久久精品 | 亚洲综合射 | 久久综合九色综合欧美狠狠 | 国产一区二区在线免费观看 | 国产精品亚洲a | 少妇性色午夜淫片aaaze | 国产精品视频永久免费播放 | 亚洲精品久久在线 | 欧美日韩高清一区二区 | 国产精品久久久av | 免费精品视频在线 | 黄色电影在线免费观看 | av先锋影音少妇 | 久久综合九九 | 久久伊人精品一区二区三区 | а天堂中文最新一区二区三区 | 国产美女精品视频免费观看 | 在线观看中文字幕 | 久久精品欧美日韩精品 | 蜜臀久久99精品久久久久久网站 | 国产精品免费观看国产网曝瓜 | 亚洲麻豆精品 | 欧美日韩不卡一区二区三区 | 亚州精品一二三区 | 欧洲不卡av| 久久精品日韩 | 中文字幕色综合网 | 亚洲一区久久 | 美女搞黄国产视频网站 | 久久国内免费视频 | 亚洲 中文 在线 精品 | 黄色成年片 | 久久免费公开视频 | 99高清视频有精品视频 | 有码视频在线观看 | 国产一区二区三区四区在线 | 欧美综合在线视频 | 天天色天天爱天天射综合 | 国产不卡一二三区 | 成人黄色在线 | 亚洲欧洲久久久 | 在线视频成人 | 精品一二 | 国语精品免费视频 | 99久久婷婷国产精品综合 | 超碰在线人人艹 | 国产白浆在线观看 | 五月天久久狠狠 | 亚洲日韩精品欧美一区二区 | 91日韩精品视频 | 免费a网址 | 最新av电影网址 | 日韩在线免费播放 | 日韩一区二区三区在线观看 | 人人添人人澡人人澡人人人爽 | 日韩视频 一区 | 国产午夜精品一区二区三区欧美 | 国产专区欧美专区 | 欧美午夜性生活 | 精品久久久久国产免费第一页 | 正在播放久久 | 综合在线色 | 欧美日韩中文字幕在线视频 | 日韩久久一区二区 | 国产精品手机播放 | 亚洲精品xxx | 国产成人61精品免费看片 | 日日日操 | 天天射天天干天天操 | 亚洲国产精品成人av | 丁香六月国产 | 国产麻豆果冻传媒在线观看 | 亚洲综合色视频在线观看 | 久久久久久草 | 成人小视频在线观看免费 | 久久国产视屏 | 久久精品美女视频 | 中文字幕亚洲不卡 | 国产高清中文字幕 | 天天艹天天 | 九九热视频在线播放 | 日韩专区中文字幕 | 午夜精品久久一牛影视 | 日韩av一区二区三区四区 | 成人高清在线 | 久草视频精品 | 麻豆网站免费观看 | 久久成人午夜 | 日韩在线视频网站 | 精品久久久久久久久久久久久久久久 | 二区三区毛片 | 亚洲精选在线观看 | 在线播放国产一区二区三区 | 国产视频中文字幕 | 亚洲最新毛片 | 天天综合网 天天 | 99久久久久成人国产免费 | 麻豆91精品| 一区二区三区四区在线免费观看 | 日本激情视频中文字幕 | 国产色资源| 99热这里只有精品8 久久综合毛片 | 欧美一二三视频 | 一区二区三区免费在线观看视频 | av中文字幕av | 碰天天操天天 | 国产成人一区三区 | 丁香综合网| 亚洲亚洲精品在线观看 | 在线免费观看羞羞视频 | 日本高清dvd| 国产欧美精品一区aⅴ影院 99视频国产精品免费观看 | 操操操夜夜操 | 日韩视频图片 | 国产高清在线免费视频 | 午夜视频一区二区三区 | av三区在线 | 制服丝袜成人在线 | 成人小视频在线观看免费 | 国产一区免费在线观看 | 精品中文字幕在线观看 | 在线观看中文字幕一区二区 | 欧美网站黄色 | 99久久精品免费看国产一区二区三区 | 伊人久久电影网 | 久草干 | 日韩一区在线免费观看 | 天天天干天天天操 | 欧美激情h | 中文字幕影视 | 亚洲精品小视频 | 色狠狠久久av五月综合 | 国产精品99久久免费观看 | 在线观看视频一区二区三区 | 久久99久久99精品免费看小说 | 日韩动漫免费观看高清完整版在线观看 | 亚洲精品18日本一区app | 久久麻豆精品 | 久草网站在线 | 公与妇乱理三级xxx 在线观看视频在线观看 | 日韩欧美在线综合网 | 精品国产一区二区三区久久影院 | 国产精品9区 | 免费观看91| 精品亚洲成人 | 国产97av| 免费看的黄色小视频 | 亚洲精品一区二区三区新线路 | 日韩69av| 最近中文字幕免费视频 | 色婷婷激情电影 | 久久精品7| 亚洲尺码电影av久久 | 婷婷色社区| 波多野结衣在线观看一区 | av三级在线播放 | 蜜臀av夜夜澡人人爽人人桃色 | 中文字幕免费高清av | 色婷婷精品大在线视频 | 在线视频 精品 | 人人插人人草 | 国产精品人成电影在线观看 | 亚洲精品视频在线观看视频 | 亚洲国产视频a | 亚洲国产精品va在线看黑人 | 国产正在播放 | 久久久久久久久久久久亚洲 | 蜜臀av夜夜澡人人爽人人桃色 | 午夜av在线电影 | 国产色秀视频 | 国产精品久久久久一区二区三区 | 亚洲天天综合网 | 黄色亚洲 | 日韩精品一区二区三区中文字幕 | 日韩专区视频 | 久久 一区 | 国产精品久久片 | 五月天综合网站 | 成人黄色在线电影 | 成人av在线亚洲 | 永久av免费在线观看 | 色婷婷www | 日韩欧美v | 免费毛片一区二区三区久久久 | 亚洲国产日韩一区 | 国产99自拍 | 中文字幕在线看人 | 黄色软件在线观看 | 在线电影91 | 亚洲欧美激情插 | 免费日韩精品 | 一区二区三区观看 | 婷婷在线综合 | 欧美91av| 亚洲有 在线 | 日本中文字幕高清 | 99精品视频免费看 | 手机看片午夜 | 婷婷av色综合 | 91女神的呻吟细腰翘臀美女 | 亚洲午夜不卡 | 美女免费黄网站 | 精品国产综合区久久久久久 | 国产精品 日本 | 狠狠干狠狠色 | 欧美日韩在线观看一区二区三区 | 天天草天天草 | 西西www444 | 天堂av免费 | 久久最新 | 视频91在线 | 国产视频欧美视频 | 久久y| 欧美另类xxxxx | 亚洲国产精品免费 | 91高清在线看 | 久久99国产一区二区三区 | 精品美女在线视频 | 91探花视频| 欧美午夜一区二区福利视频 | 日韩精品一区二区三区在线播放 | 天天操天天操 | 欧美aaa级片 | 看国产黄色大片 | 超级av在线 | 日韩午夜在线观看 | 黄色网大全 | 成人av一区二区在线观看 | 日本久久久亚洲精品 | 亚洲在线视频网站 | 911久久| 97天天综合网 | 91av在线国产| av在线小说 | 日韩在线第一区 | 久久久久免费精品国产小说色大师 | 九色精品免费永久在线 | 欧美日韩国产亚洲乱码字幕 | 天天狠狠操 | jizzjizzjizz亚洲| 黄色影院在线免费观看 | 欧美成人性战久久 | 久久在视频 | 丝袜美腿亚洲 | 在线小视频你懂得 | 精品一二三四在线 | 国产天天综合 | 精品播放 | a久久久久 | 天天爱综合 | 欧美日本高清视频 | 日韩91av | 超碰在线成人 | 成人av片免费观看app下载 | 三级在线视频观看 | 91视频在线看 | 亚洲九九九在线观看 | 久久久国产99久久国产一 | 亚洲精品视频在线免费播放 | 韩国精品在线 | 九九爱免费视频 | 91在线视频播放 | 国内精品在线观看视频 | 国产999精品久久久久久麻豆 | 成人免费在线电影 | 国产五月色婷婷六月丁香视频 | 久草在线资源网 | 亚洲va综合va国产va中文 | 亚洲人片在线观看 | 99免费精品| 久久社区视频 | 免费a v在线 | 在线观看日韩国产 | 免费观看的黄色片 | 日日草天天干 | 国产三级午夜理伦三级 | 91成人在线视频 | 国产精品18p | 免费在线电影网址大全 | 亚洲国产精品成人av | 久久精品99 | 成人国产精品免费观看 | 亚洲国产精品视频在线观看 | www.啪啪.com| 国产香蕉视频 | 在线久热| 国产在线观看免费观看 | 免费一级片久久 | 国产一区视频免费在线观看 | 婷婷色综 | 色婷婷亚洲综合 | 日韩专区在线播放 | 男女拍拍免费视频 | 久久久久网址 | 在线观看www视频 | 国产99久久久精品 | 久久成人高清 | 91豆麻精品91久久久久久 | www黄色软件 | www.av在线播放| 日韩电影在线视频 | 久久婷婷丁香 | 99久热在线精品 | 精品一区电影国产 | 日韩精品一区二区三区不卡 | 久草在线 | 91女神的呻吟细腰翘臀美女 | 天天亚洲综合 | 99国产精品久久久久老师 | 成人免费大片黄在线播放 | 国产视频在线观看一区 | 亚洲综合狠狠干 | 亚洲伊人成综合网 | 免费看污网站 | 国产精品69av | 99精品国产99久久久久久97 | 午夜影院一级 | 国内三级在线 | 99视频网站| 一本一本久久a久久精品牛牛影视 | 最新av网址在线 | 日韩色一区二区三区 | 国产高清在线a视频大全 | 天天躁日日躁狠狠躁av中文 | 中国黄色一级大片 | 亚洲激情视频 | 狠狠色狠狠色终合网 | 日韩区欧美久久久无人区 | av在线com| 日韩精品久久中文字幕 | 久久理论片 | 欧美日韩免费一区 | 一区二区三区日韩视频在线观看 | 精品一区二区在线免费观看 | 成人黄色电影在线 | 日本精品二区 | 免费观看一级成人毛片 | 国产精品毛片一区二区 | 欧美91精品| 欧美日韩中| 国产精品久久久久免费 | 伊人亚洲综合网 | 色视频在线免费观看 | 日韩专区在线观看 | 日本精品久久久久中文字幕5 | 综合久久精品 | 久久精品国产一区二区电影 | 国产精品永久免费在线 | 91视频com | 国产在线一线 | 一区二区三区在线视频观看58 | 精品久久久久一区二区国产 | 人人草在线视频 | 国产91小视频 | 婷婷亚洲最大 | 99精品成人| 久久精品毛片基地 | 午夜精品久久久99热福利 | 色婷婷电影网 | 五月天六月婷婷 | 欧美另类z0zx | 欧美成人按摩 | 午夜精品一区二区国产 | 国产丝袜一区二区三区 | av中文天堂 | 国产日韩欧美在线 | 国产精品99久久99久久久二8 | 亚洲免费不卡 | 区一区二区三在线观看 | 天天干.com| 亚洲精品视频在线免费播放 | 久久 地址 | 亚洲黄色一级视频 | 国产精品久久久久av免费 | 夜夜骑首页 | 日韩av成人在线观看 | 亚洲精品久久久蜜臀下载官网 | 久久综合狠狠综合久久狠狠色综合 | 久久久精品国产一区二区三区 | 成人黄色电影免费观看 | 天天干,天天操,天天射 | 国产精品免费一区二区 | 久久久99精品免费观看app | 九九视频网站 | www.在线观看av | 91精品国自产在线观看欧美 | 日韩特黄av| 97看片| 成人黄色在线观看视频 | 成人欧美一区二区三区黑人麻豆 | 在线看国产日韩 | 91网免费看 | 国产乱码精品一区二区三区介绍 | 亚洲专区欧美 | 国产丝袜一区二区三区 | 天天婷婷 | 久久天堂影院 | 色香蕉网| 天天草天天| 最新中文字幕在线观看视频 | 亚洲天堂视频在线 | 美女一区网站 | 中文字幕在线观看免费 | 国产精品视频你懂的 | 国产精品人人做人人爽人人添 | 91福利免费 | 日日日日 | 免费碰碰 | 久久精品系列 | 日韩av影片在线观看 | 欧美成人h版在线观看 | 国产成人1区 | 国产高清视频色在线www | 久久久久久久综合色一本 | 国产永久免费高清在线观看视频 | 在线成人一区二区 | 亚洲永久国产精品 | 一级大片在线观看 | av免费网 | 国产精品毛片完整版 | 久久人人爽人人爽人人片 | 西西444www大胆高清图片 | 久久久免费毛片 | 黄色一级大片在线免费看国产一 | 五月婷婷一区 | 久久久久久久久久久黄色 | 欧美日韩精品综合 | 色综合久久久久久久 | 一区三区视频在线观看 | 久久久久久久久久电影 | 亚洲精品乱码久久久久久蜜桃不爽 | 日韩免费一区二区三区 | 香蕉免费在线 | 亚洲一级免费电影 | 色综合久久久久久久 | 91免费黄视频 | 欧美精品成人在线 | 国产剧情一区二区在线观看 | 亚洲综合精品在线 | 久久亚洲综合色 | 国产色秀视频 | 香蕉视频免费看 | 超碰在线公开免费 | 在线天堂中文在线资源网 | 欧美日韩成人 | 国产无限资源在线观看 | 午夜色场| 五月开心婷婷 | 99精品国产福利在线观看免费 | 国产高清在线一区 | 9在线观看免费高清完整版在线观看明 | 久久精品国产精品亚洲 | 一区在线观看 | 日韩av一区在线观看 | 久久国产欧美日韩精品 | 亚洲精品视频网 | 草久在线观看视频 | 亚洲精品视| 国产精品久久久久久五月尺 | 成人久久视频 | 亚洲精品国偷拍自产在线观看 | 免费影视大全推荐 | 在线视频一区二区 | 日韩在线视频网址 | 欧美精品国产综合久久 | 欧美性粗大hdvideo | 国产一区二区免费 | 日韩av黄| 婷婷五月情 | 91精品久久久久久综合乱菊 | 久草在线国产 | 日韩另类在线 | 日韩一区二区三区在线观看 | 亚洲国产精品99久久久久久久久 | 91av小视频| 免费在线一区二区 | 国产黄色大片免费看 | www.国产在线观看 | 黄在线免费看 | 午夜精品三区 | 这里只有精品视频在线 | 激情av在线资源 | 成人av亚洲 | 国产精品久久99综合免费观看尤物 | 国产精品乱码一区二三区 | 999男人的天堂 | 涩涩网站在线播放 | 二区三区视频 | 国产视频一 | 天堂网一区 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 福利精品在线 | 日韩一二区在线 | 午夜精品一区二区三区四区 | 91专区在线观看 | 一区二区三区免费看 | 国产精品淫片 | 九九九九热精品免费视频点播观看 | 欧美在线1区 | av大全在线播放 | 国产精品国产精品 | 欧洲亚洲激情 | 午夜精品福利一区二区 | 精品久久在线 | 黄色在线观看网站 | 亚洲午夜av电影 | 国产男女无遮挡猛进猛出在线观看 | 亚洲综合在线播放 | 成人三级视频 | 日韩免费不卡av | 久久99精品久久久久久秒播蜜臀 | 日本三级国产 | 香蕉视频18 | 99热99热| 国产日韩欧美在线免费观看 | 日韩成人免费在线电影 | 日韩精品一区二区在线 | 国产麻豆剧果冻传媒视频播放量 | 日韩一级电影在线观看 | 黄色网址国产 | 久久综合日 | 精品一区二区免费在线观看 | 久久综合色一综合色88 | 91自拍91| 2019精品手机国产品在线 | 亚洲日日射 | 夜夜操网站 | 免费又黄又爽 | 韩日电影在线免费看 | 美女黄网站视频免费 | 成人免费网视频 | 国产在线视频资源 | 最近中文字幕视频网 | 久久久久成人精品亚洲国产 | 国产一区二区三区视频在线 | 一区 在线 影院 | 99免费视频| 99性视频| 亚洲 欧洲av | 91中文字幕在线视频 | 亚洲日本va中文字幕 | 九九综合久久 | 欧美精品v国产精品v日韩精品 | 国产精品xxxx18a99| 久久久麻豆视频 | 黄色在线看网站 | 中文字幕国产视频 | 成人小视频在线观看免费 | 色综合天天色综合 | 国产精品av免费在线观看 | 色丁香综合 | 国产精品一区二区久久 | 国产a视频免费观看 | 日日夜夜精品 | 国产在线成人 | 五月天精品视频 | 久久精彩免费视频 | 亚洲永久精品在线 | 成人午夜免费福利 | 欧美日韩视频在线观看一区二区 | 国产v在线播放 | 亚洲午夜精品久久久久久久久 | 久久色在线播放 | 成人国产精品av | 欧美美女激情18p | 久久国产精彩视频 | 97超碰精品| 国产99免费| 欧美久久久久久久久久久 | 国产精品美女久久久久久久网站 | 免费福利在线观看 | 日韩欧美精品免费 | 99久在线精品99re8热视频 | 久久久精品欧美一区二区免费 | 国产又粗又猛又黄又爽 | 在线天堂中文www视软件 | 国产又粗又猛又色 | 日韩高清不卡在线 | 国产高清在线永久 | 一级黄色片在线 | 国产高清区| 亚洲精品在线播放视频 | 亚洲成熟女人毛片在线 | 色多多污污在线观看 | 久久久国产在线视频 | 在线观看免费观看在线91 | 狠狠色狠狠色综合系列 | 奇米影视999 | 久射网| 探花视频免费观看高清视频 | 国产成人av电影在线观看 | 激情视频免费在线 | 国产91成人在在线播放 | 国产在线精 | 一区二区三区四区免费视频 | 欧美日韩国产精品久久 | 亚洲国产精品va在线看 | 国产一区二区视频在线 | av九九| 91激情小视频 | 久久久久日本精品一区二区三区 | 中文字幕欧美日韩va免费视频 | 综合久久精品 | 97精品国产aⅴ | 色婷婷激情电影 | 欧美一区在线观看视频 | 在线电影播放 | 成 人 a v天堂 | 亚洲精品一区二区三区新线路 | 久久精品欧美一区 | 日本黄色免费观看 | 狠狠色丁香婷综合久久 | 蜜桃视频成人在线观看 | av免费观看高清 | 最近日本字幕mv免费观看在线 | 97在线成人 | 狠狠色丁香婷婷综合久久片 | 超碰av在线 | 97国产超碰在线 | 婷婷激情影院 | 在线欧美国产 | 精产嫩模国品一二三区 | 久久少妇免费视频 | 欧美日韩免费观看一区=区三区 | 国产成人一级电影 | 久久久久久久久久免费视频 | 黄色成人在线网站 | 久久色中文字幕 | 99热高清| 国产在线观看二区 | 在线观看一级片 | 九九久久国产精品 | 国产精品不卡一区 | 国际精品久久久久 | 婷婷六月在线 | 精壮的侍卫呻吟h | 一级a性色生活片久久毛片波多野 | 在线成人性视频 | 日韩com| 国产爽妇网 | 久久蜜桃av | 深夜免费福利视频 | 久久国产精品第一页 | 99精品久久99久久久久 | 久久蜜臀av| 国产成人亚洲在线电影 | 二区三区中文字幕 | 欧美人人爱 | 96久久欧美麻豆网站 | 日韩在线视频不卡 | 日本精品一区二区 | 亚洲国产一区在线观看 | 超碰九九| 狠狠狠色丁香综合久久天下网 | 粉嫩av一区二区三区四区五区 | 在线 国产一区 | av一区二区三区在线观看 | 日本中文字幕在线播放 | av中文字幕剧情 | 免费在线播放黄色 | 黄色网址在线播放 | 亚洲精品乱码久久 | 国产精品中文久久久久久久 | 九月婷婷人人澡人人添人人爽 | 香蕉久草 | 国产高清av在线播放 | 色噜噜狠狠狠狠色综合 | 91天堂素人约啪 | 精品国产精品国产偷麻豆 | 一区二区三区国 | 一区二区三区福利 | 日韩系列 | 亚洲精品乱码久久久久久 | 久久精品久久精品 | 成人资源网 | 国产高清永久免费 | 亚洲另类视频 | 丝袜美腿亚洲 | 在线观看亚洲免费视频 | 日日夜夜天天人人 | 奇米影视777影音先锋 | 国产福利91精品一区 | www.神马久久 | 日韩在线首页 | 右手影院亚洲欧美 | 97超碰资源 | 99性视频 | 国产精品24小时在线观看 | 亚洲成人精品在线 |