DFU 진행 watchdog
- 앱만 멈추고 BLE 링크가 유지되는 경우 대비 - DFU 업로드 중 30초동안 CHUNK가 오지 않는 경우 강제 disconnect 후 SMP로 재광고(초록 LED 점멸, 10분 타임아웃) - 초록 LED 무한 점등 상황 방지
This commit is contained in:
@@ -806,11 +806,23 @@ int ble_dfu_advertising_enable(void)
|
||||
return ble_advertising_start();
|
||||
}
|
||||
|
||||
/* DFU 진입용 disconnect */
|
||||
bool ble_dfu_advertising_is_enabled(void)
|
||||
{
|
||||
return dfu_advertising_mode;
|
||||
}
|
||||
|
||||
/* DFU watchdog */
|
||||
int ble_disconnect_active(void)
|
||||
{
|
||||
if (current_conn == NULL)
|
||||
{
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
return bt_conn_disconnect(current_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
|
||||
}
|
||||
|
||||
int ble_data_send(const uint8_t *data, uint16_t len)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -34,5 +34,6 @@ int ble_data_send(const uint8_t *data, uint16_t len);
|
||||
int ble_dfu_advertising_enable(void);
|
||||
bool ble_dfu_advertising_is_enabled(void);
|
||||
bool ble_is_connected(void);
|
||||
int ble_disconnect_active(void);
|
||||
|
||||
#endif /* BLE_SERVICE_H__ */
|
||||
|
||||
+27
-13
@@ -31,6 +31,7 @@ LOG_MODULE_REGISTER(vesiscan, LOG_LEVEL_INF);
|
||||
#define BLE_CMD_WORKQ_STACK_SZ 8192
|
||||
#define DFU_RESUME_MAGIC 0xD5U
|
||||
#define DFU_RESUME_GPREGRET_REG 1U
|
||||
#define DFU_STALL_TIMEOUT_SEC 30 // DFU 업로드 무진행 시 강제 disconnect 임계
|
||||
#define IMG_MGMT_ID_STATE 0U
|
||||
#define IMG_MGMT_ID_UPLOAD 1U
|
||||
/*
|
||||
@@ -88,6 +89,8 @@ static struct k_work bond_reset_work; // 전원 버튼 15초 롱프레스
|
||||
static bool dfu_led_active; // DFU 업로드 중 초록 LED ON
|
||||
static const char *power_off_pending_reason = "none";
|
||||
static bool bond_reset_pending; // 본드 삭제 work 중복 예약 방지
|
||||
static struct k_work_delayable dfu_watchdog_work; // DFU 업로드 무진행 감시 work
|
||||
static void dfu_watchdog_handler(struct k_work *work);
|
||||
|
||||
static enum mgmt_cb_return dfu_status_cb(uint32_t event,
|
||||
enum mgmt_cb_return prev_status,
|
||||
@@ -524,6 +527,9 @@ static void timers_init(void)
|
||||
// 전원 버튼 15초 롱프레스 본드 삭제 work
|
||||
k_work_init(&bond_reset_work, bond_reset_work_handler);
|
||||
|
||||
// DFU 업로드 무진행 감시 work
|
||||
k_work_init_delayable(&dfu_watchdog_work, dfu_watchdog_handler);
|
||||
|
||||
// BLE 명령 처리 work queue
|
||||
k_work_init(&ble_cmd_work, ble_cmd_work_handler);
|
||||
k_work_queue_start(&ble_cmd_work_q, ble_cmd_workq_stack, K_THREAD_STACK_SIZEOF(ble_cmd_workq_stack), BLE_CMD_WORKQ_PRIORITY, NULL);
|
||||
@@ -544,13 +550,21 @@ static void timers_start(void)
|
||||
k_timer_start(&m_power_on_delay_timer, K_MSEC(POWER_ON_DELAY), K_NO_WAIT);
|
||||
}
|
||||
|
||||
static enum mgmt_cb_return dfu_status_cb(uint32_t event,
|
||||
enum mgmt_cb_return prev_status,
|
||||
int32_t *rc,
|
||||
uint16_t *group,
|
||||
bool *abort_more,
|
||||
void *data,
|
||||
size_t data_size)
|
||||
/* DFU 업로드가 멈춘 채(청크 무진행) 링크만 살아있는 경우, 연결을 강제로 끊어
|
||||
* SMP 재광고(10분 타임아웃)로 전환한다. 초록 LED 무한 점등/무한 대기 방지. */
|
||||
static void dfu_watchdog_handler(struct k_work *work)
|
||||
{
|
||||
ARG_UNUSED(work);
|
||||
|
||||
if (ble_is_connected())
|
||||
{
|
||||
DBG_PRINTF("[DFU] upload stalled (%ds), forcing disconnect\r\n",
|
||||
DFU_STALL_TIMEOUT_SEC);
|
||||
(void)ble_disconnect_active();
|
||||
}
|
||||
}
|
||||
|
||||
static enum mgmt_cb_return dfu_status_cb(uint32_t event, enum mgmt_cb_return prev_status, int32_t *rc, uint16_t *group, bool *abort_more, void *data, size_t data_size)
|
||||
{
|
||||
ARG_UNUSED(prev_status);
|
||||
ARG_UNUSED(rc);
|
||||
@@ -563,19 +577,19 @@ static enum mgmt_cb_return dfu_status_cb(uint32_t event,
|
||||
{
|
||||
case MGMT_EVT_OP_IMG_MGMT_DFU_STARTED:
|
||||
case MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK:
|
||||
// DFU 업로드 중에는 초록 LED ON
|
||||
dfu_led_active = true;
|
||||
led_ble_solid();
|
||||
led_ble_solid(); // DFU 업로드 중에는 초록 LED ON
|
||||
// 청크가 올 때마다 무진행 감시 타이머 리셋
|
||||
k_work_reschedule(&dfu_watchdog_work, K_SECONDS(DFU_STALL_TIMEOUT_SEC));
|
||||
break;
|
||||
|
||||
case MGMT_EVT_OP_IMG_MGMT_DFU_PENDING:
|
||||
// 업로드 완료 후 리셋 전까지 초록 LED ON
|
||||
dfu_led_active = true;
|
||||
led_ble_solid();
|
||||
led_ble_solid(); // 업로드 완료 후 리셋 전까지 초록 LED ON
|
||||
k_work_cancel_delayable(&dfu_watchdog_work); // 업로드 완료: 감시 종료
|
||||
|
||||
// DFU 리셋 후 버튼 없이 전원 ON
|
||||
#if NRF_POWER_HAS_GPREGRET
|
||||
nrf_power_gpregret_set(NRF_POWER, DFU_RESUME_GPREGRET_REG, DFU_RESUME_MAGIC);
|
||||
nrf_power_gpregret_set(NRF_POWER, DFU_RESUME_GPREGRET_REG, DFU_RESUME_MAGIC); // DFU 리셋 후 버튼 없이 전원 ON
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user