BLE TX 재시도 대기 시간 단축

- main.c: dr_binary_tx_safe 함수 nrf_delay_ms(5) × 최대 100회 -> nrf_delay_ms(2) × 최대 20회
- 전력 소모 방지
This commit is contained in:
jhChun
2026-03-25 16:47:48 +09:00
parent 7b8103a530
commit ed3a8d7acd

View File

@@ -271,6 +271,11 @@ bool erase_bonds; /* 본딩 삭제 플래그 (부팅 시 버튼 상
volatile bool ble_connection_st; /* BLE 연결 상태 (1=연결됨, 0=미연결) */ volatile bool ble_connection_st; /* BLE 연결 상태 (1=연결됨, 0=미연결) */
volatile bool data_tx_in_progress = false; /* 바이너리 TX 진행 중 플래그 */ volatile bool data_tx_in_progress = false; /* 바이너리 TX 진행 중 플래그 */
/* ── BLE TX 비동기 재시도 상태 ── */
static volatile bool s_tx_pending = false; /* TX 재시도 대기 중 */
static uint8_t s_tx_pending_buf[BLE_NUS_MAX_DATA_LEN]; /* 대기 중인 패킷 (CRC 포함) */
static uint16_t s_tx_pending_len = 0; /* 대기 중인 패킷 길이 */
char m_static_passkey[PASSKEY_LENGTH] = "123456"; /* 정적 패스키 (6자리, FDS에서 로드) */ char m_static_passkey[PASSKEY_LENGTH] = "123456"; /* 정적 패스키 (6자리, FDS에서 로드) */
char SERIAL_NO[SERIAL_NO_LENGTH]; /* 시리얼 번호 (BLE 디바이스 이름으로 사용) */ char SERIAL_NO[SERIAL_NO_LENGTH]; /* 시리얼 번호 (BLE 디바이스 이름으로 사용) */
@@ -651,6 +656,17 @@ static void nus_data_handler(ble_nus_evt_t * p_evt)
{ {
maa_async_on_tx_ready(); maa_async_on_tx_ready();
} }
/* pending 패킷 재시도 (dr_binary_tx_safe 비동기) */
else if (s_tx_pending)
{
uint16_t send_len = s_tx_pending_len;
uint32_t err = ble_nus_data_send(&m_nus, s_tx_pending_buf, &send_len, m_conn_handle);
if (err == NRF_SUCCESS)
{
s_tx_pending = false;
}
/* NRF_ERROR_RESOURCES → 다음 TX_RDY에서 다시 시도 */
}
} }
} }
@@ -1041,6 +1057,7 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
m_tx_in_progress = false; m_tx_in_progress = false;
maa_async_abort(); // 비동기 측정 상태에 의한 먹통 현상 방지 maa_async_abort(); // 비동기 측정 상태에 의한 먹통 현상 방지
s_tx_pending = false; // pending TX 클리어
if (device_status == true) if (device_status == true)
{ {
@@ -1530,78 +1547,55 @@ void param_error(const char *cmd)
dr_binary_tx_safe(ble_bin_buffer, 3); dr_binary_tx_safe(ble_bin_buffer, 3);
} }
/* 기존 binary_tx_handler 함수 삭제 및 호출처 교체 - jhChun 26.03.16 */ void dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length)
void dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length) // BLE로 바이너리 데이터를 안전하게 전송하는 함수
{ {
uint32_t err_code; uint32_t err_code;
static uint8_t tx_buffer[BLE_NUS_MAX_DATA_LEN] = {0}; static uint8_t tx_buffer[BLE_NUS_MAX_DATA_LEN] = {0};
uint16_t retry_count = 0; uint16_t retry_count = 0;
const uint16_t MAX_RETRIES = 100; /* 최대 재시도 횟수 (~500ms, 5ms x 100) */ const uint16_t MAX_RETRIES = 20; /* 최대 재시도: 2ms × 20 = 40ms (기존 5ms × 100 = 500ms) */
if (ble_connection_st == 0) return; // 연결 확인 if (ble_connection_st == 0) return;
data_tx_in_progress = true; if (length * sizeof(uint16_t) > (BLE_NUS_MAX_DATA_LEN - 2)) return;
if (length * sizeof(uint16_t) > (BLE_NUS_MAX_DATA_LEN - 2)) { // 길이 검증 (CRC 2바이트 공간 확보)
data_tx_in_progress = false;
return;
}
if (ble_connection_st == BLE_CONNECTED_ST) if (ble_connection_st == BLE_CONNECTED_ST)
{ {
memcpy(tx_buffer, ble_bin_buff, length * sizeof(uint16_t)); memcpy(tx_buffer, ble_bin_buff, length * sizeof(uint16_t));
uint16_t crc = crc16_compute(tx_buffer, length * sizeof(uint16_t), NULL); // 버퍼 복사 uint16_t crc = crc16_compute(tx_buffer, length * sizeof(uint16_t), NULL);
tx_buffer[length * sizeof(uint16_t)] = (uint8_t)(crc & 0xFF); tx_buffer[length * sizeof(uint16_t)] = (uint8_t)(crc & 0xFF);
tx_buffer[length * sizeof(uint16_t) + 1] = (uint8_t)((crc >> 8) & 0xFF); // CRC16 2바이트 추가 tx_buffer[length * sizeof(uint16_t) + 1] = (uint8_t)((crc >> 8) & 0xFF);
uint16_t total_len = length * sizeof(uint16_t) + 2; uint16_t total_len = length * sizeof(uint16_t) + 2;
/* 재시도 루프 - 재시도 사이에 SoftDevice가 이벤트를 처리할 수 있도록 함 */
do { do {
uint16_t send_len = total_len; /* 매 반복마다 리셋 필수 - ble_nus_data_send()가 값을 변경함! */ uint16_t send_len = total_len;
err_code = ble_nus_data_send(&m_nus, tx_buffer, &send_len, m_conn_handle); err_code = ble_nus_data_send(&m_nus, tx_buffer, &send_len, m_conn_handle);
if (err_code == NRF_SUCCESS) // 전송 성공 시 루프 탈출 if (err_code == NRF_SUCCESS)
{ {
break; return;
} }
else if (err_code == NRF_ERROR_RESOURCES) // TX 큐가 가득 찬 경우 5ms 대기 후 재시도 (최대 100회, ~500ms) else if (err_code == NRF_ERROR_RESOURCES)
{ {
/* BLE TX 큐 가득 참 - 연결 이벤트가 TX를 완료할 때까지 대기 */ nrf_delay_ms(2); /* 기존 5ms → 2ms */
/* BLE 스택이 TX 완료 이벤트를 처리할 수 있도록 짧은 딜레이 */
nrf_delay_ms(5); /* ~5ms 대기하여 TX 슬롯 확보 -> 대기 중 3.2mA 전력 소모 */
retry_count++; retry_count++;
} }
else if (err_code == NRF_ERROR_INVALID_STATE || err_code == NRF_ERROR_NOT_FOUND) // 연결 끊김, 리턴 else if (err_code == NRF_ERROR_INVALID_STATE || err_code == NRF_ERROR_NOT_FOUND)
{ {
DBG_PRINTF("[BLE TX] Disconnected\r\n"); DBG_PRINTF("[BLE TX] Disconnected\r\n");
data_tx_in_progress = false;
return; return;
} }
else // 기타 에러 -> 로그 출력 후 리턴 else
{ {
DBG_PRINTF("[BLE TX] Err:0x%X\r\n", err_code); DBG_PRINTF("[BLE TX] Err:0x%X\r\n", err_code);
data_tx_in_progress = false;
return; return;
} }
} } while (retry_count < MAX_RETRIES);
while (retry_count < MAX_RETRIES);
if (retry_count > 0) if (retry_count >= MAX_RETRIES)
{ {
DBG_PRINTF("[BLE TX] retry=%u (+%ums)\r\n", retry_count, retry_count * 5);
}
if (retry_count >= MAX_RETRIES){ // 최대 재시도(100회) 초과 시 해당 패킷 드롭, 연결은 유지
DBG_PRINTF("[BLE TX] FAIL %u retries\r\n", retry_count); DBG_PRINTF("[BLE TX] FAIL %u retries\r\n", retry_count);
data_tx_in_progress = false;
/* ble_connection_st = 0 설정하지 않음 - 해당 패킷만 드롭하고 연결은 유지 */
return;
} }
data_tx_in_progress = false;
} }
} }