BLE TX 재시도 대기 시간 단축
- main.c: dr_binary_tx_safe 함수 nrf_delay_ms(5) × 최대 100회 -> nrf_delay_ms(2) × 최대 20회 - 전력 소모 방지
This commit is contained in:
@@ -271,6 +271,11 @@ bool erase_bonds; /* 본딩 삭제 플래그 (부팅 시 버튼 상
|
||||
volatile bool ble_connection_st; /* BLE 연결 상태 (1=연결됨, 0=미연결) */
|
||||
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 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();
|
||||
}
|
||||
/* 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;
|
||||
|
||||
maa_async_abort(); // 비동기 측정 상태에 의한 먹통 현상 방지
|
||||
s_tx_pending = false; // pending TX 클리어
|
||||
|
||||
if (device_status == true)
|
||||
{
|
||||
@@ -1530,78 +1547,55 @@ void param_error(const char *cmd)
|
||||
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) // BLE로 바이너리 데이터를 안전하게 전송하는 함수
|
||||
void dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length)
|
||||
{
|
||||
uint32_t err_code;
|
||||
static uint8_t tx_buffer[BLE_NUS_MAX_DATA_LEN] = {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)) { // 길이 검증 (CRC 2바이트 공간 확보)
|
||||
data_tx_in_progress = false;
|
||||
return;
|
||||
}
|
||||
if (length * sizeof(uint16_t) > (BLE_NUS_MAX_DATA_LEN - 2)) return;
|
||||
|
||||
if (ble_connection_st == BLE_CONNECTED_ST)
|
||||
{
|
||||
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) + 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;
|
||||
|
||||
/* 재시도 루프 - 재시도 사이에 SoftDevice가 이벤트를 처리할 수 있도록 함 */
|
||||
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);
|
||||
|
||||
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를 완료할 때까지 대기 */
|
||||
/* BLE 스택이 TX 완료 이벤트를 처리할 수 있도록 짧은 딜레이 */
|
||||
nrf_delay_ms(5); /* ~5ms 대기하여 TX 슬롯 확보 -> 대기 중 3.2mA 전력 소모 */
|
||||
|
||||
nrf_delay_ms(2); /* 기존 5ms → 2ms */
|
||||
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");
|
||||
data_tx_in_progress = false;
|
||||
return;
|
||||
}
|
||||
else // 기타 에러 -> 로그 출력 후 리턴
|
||||
else
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Err:0x%X\r\n", err_code);
|
||||
data_tx_in_progress = false;
|
||||
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);
|
||||
data_tx_in_progress = false;
|
||||
/* ble_connection_st = 0 설정하지 않음 - 해당 패킷만 드롭하고 연결은 유지 */
|
||||
return;
|
||||
}
|
||||
|
||||
data_tx_in_progress = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user