nRF52810 buttonless DFU 환경설정 및 프로그램 수정

2020년 09월 27일 by 진아사랑해

    nRF52810 buttonless DFU 환경설정 및 프로그램 수정 목차
반응형

과제를 수행하면서 buttonless dfu를 수행해달라는 요청이 들어왔다

삽질을 하면서 과정을 진행하고자 한다.

개발 진행중임으로 오류가 작성될 수 있다. 완성되면 수정을 하겠다

사용 SDK는 15.3이며 ble_peripheral\ble_app_uart(이하 uart")에 dfu를 구현하여야 하며, 

ble_peripheral\ble_app_buttonless_dfu(이하 "dfu") 를 참고하였다

 

1. Preprocessor -> Define 변경

Preprocessor -> Define에 3가지가 추가되어 있다

BL_SETTINGS_ACCESS_ONLY, NRF_DFU_SVCI_ENABLED, NRF_DFU_TRANSPORT_BLE=1

이 부분도 uart에 추가한다.

 

2. ble_dfu 관련 Library를 추가한다.( nRF_DFU 및 nRF_SVC )

..\..\..\..\..\..\components\ble\ble_services\ble_dfu 위치에 3개의 파일이 있다(nRF_DFU 그룹에 추가한다)

..\..\..\..\..\..\components\libraries\bootloader\dfu\nrf_dfu_svci.c(nRF_SVC 그룹네 추가한다)

 

3. 3번에서 추가한 파일들을 위한 Path를 설정한다.

C/C++ -> Include Pathes

..\..\..\..\..\..\components\libraries\bootloader\dfu

..\..\..\..\..\..\components\ble\ble_services\ble_dfu

..\..\..\..\..\..\components\libraries\bootloader

 

4. sdk_config.h 수정

#define BLE_DFU_ENABLED 0 -> 1 : DFU 서비스를 활성화 시킨다.

#define NRF_SDH_BLE_VS_UUID_COUNT 1 -> 2 : UART와 DFU 서비스를 사용함으로 2로 변경

#define NRF_SDH_BLE_SERVICE_CHANGED 0 -> 1 : 서비스 변경에 대한 특성을 Attribute Table에 포함

#define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 0 -> 1 

 

5. 여기까지 하고 build를 하니

..\..\..\..\..\..\components\ble\ble_services\ble_dfu\ble_dfu.c(55): error:  #5: cannot open source input file "nrf_bootloader_info.h": No such file or directory

=> 4번에 아래의 Path를 추가한다.

..\..\..\..\..\..\components\libraries\bootloader

=> build error가 사라졌다

 

6. main.c에 DFU 서비스를 위한 헤더 파일과 함수 추가

(1) 헤더 파일 추가

#include "nrf_dfu_ble_svci_bond_sharing.h"
#include "nrf_svci_async_function.h"
#include "nrf_svci_async_handler.h"
#include "ble_dfu.h"
#include "nrf_bootloader_info.h"

(2) 함수 추가

/***
1) 첫 번째 기능은 DFU 서비스로 전송되는 데이터에 대해 작동하는 이벤트 핸들러입니다.
***/
/**@brief Function for handling DFU events
*
* @details This function is called when entering buttonless DFU
*
* @param[in] event Buttonless DFU event.
Add Nordic Semiconductor DFU to SDK Example - Application note
UBX-19050198 - R01 Buttonless DFU Page 23 of 32
*/
static void ble_dfu_buttonless_evt_handler(ble_dfu_buttonless_evt_type_t event)
{
 switch (event)
 {
case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
NRF_LOG_INFO("Device is preparing to enter bootloader mode\r\n");
break;
case BLE_DFU_EVT_BOOTLOADER_ENTER:
NRF_LOG_INFO("Device will enter bootloader mode\r\n");
break;
case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
NRF_LOG_ERROR("Device failed to enter bootloader mode\r\n");
break;
default:
NRF_LOG_INFO("Unknown event from ble_dfu.\r\n");
break;
}
}

/***
2) 두 번째 기능은 전원 관리를 처리합니다.
부트 로더 서비스는 영구 레지스터에 값을 쓴 다음 시스템 재설정을 실행합니다.
부트 로더는이 값을 읽어서 계속할지 아니면 응용 프로그램에 제어를 전달할지 결정합니다.
여기에 코드를 추가하여 응용 프로그램 내에서 중요한 일이 발생하는 경우 DFU가 시작되지 않도록 할 수 있습니다.
***/

/**@brief Function for handling bootloader power management events
*
* @details This function is called to set a persistent register which informs the
* bootloader it should continue or pass control back to the application
*
* @param[in] event Power management event.
*/
static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
{
switch (event)
{
case NRF_PWR_MGMT_EVT_PREPARE_DFU:
NRF_LOG_INFO("Power management wants to reset to DFU mode\r\n");
// Change this code to tailor to your reset strategy.
// Returning false here means that the device is not ready
// to jump to DFU mode yet.
//
// Here is an example using a variable to delay resetting the device:
//
/* if (!im_ready_for_reset)
{
return false;
}
*/
break;
default:
// Implement any of the other events available
// from the power management module:
// -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF
// -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP
// -NRF_PWR_MGMT_EVT_PREPARE_RESET
return true;
}
NRF_LOG_INFO("Power management allowed to reset to DFU mode\r\n");
return true;
}

NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);

 

3) 서비스를 등록한다

static void services_init(void)
{
    uint32_t           err_code;
    ble_nus_init_t     nus_init;
    nrf_ble_qwr_init_t qwr_init = {0};

    // Initialize Queued Write Module.
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);

    // Initialize NUS.
    memset(&nus_init, 0, sizeof(nus_init));

    nus_init.data_handler = nus_data_handler;

    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);

// BEGIN Block Added for DFU
// ONLY ADD THIS BLOCK TO THE EXISTING FUNCTION
// Initialize the DFU service
ble_dfu_buttonless_init_t dfus_init =
{
.evt_handler = ble_dfu_buttonless_evt_handler
};
err_code = ble_dfu_buttonless_init(&dfus_init);
APP_ERROR_CHECK(err_code);
// END Block Added for DFU
}

 

4) main( ) 함수에 아래를 추가한다.

int main(void)
{
    bool       erase_bonds;
    ret_code_t err_code;

    log_init();

    // Initialize the async SVCI interface to bootloader before any interrupts are enabled.
    err_code = ble_dfu_buttonless_async_svci_init();

 

지금까지 추가한 내용으로 Build를 하니, 에러는 발생하지 않았다

 

다음 번에는 Secure Bootloader 를 만들겠다

 

참조) www.u-blox.com/sites/default/files/Add-NordicSemiconductorDFU-to-SDKexample_AppNote_%28UBX-19050198%29.pdf

 

 

반응형