Compare commits

...

2 Commits

Author SHA1 Message Date
jhChun ed3a8d7acd BLE TX 재시도 대기 시간 단축
- main.c: dr_binary_tx_safe 함수 nrf_delay_ms(5) × 최대 100회 -> nrf_delay_ms(2) × 최대 20회
- 전력 소모 방지
2026-03-25 16:47:48 +09:00
jhChun 7b8103a530 디버그 로그 통일(UART -> RTT)
- app_raw.c: printf() -> DBG_PRINTF(RTT)
- 전력 소모 방지: CPU 문자열 포맷팅 실행 제거
2026-03-25 16:07:28 +09:00
2 changed files with 38 additions and 44 deletions
@@ -119,20 +119,20 @@ int setup_imu_device(struct inv_imu_serif *icm_serif)
/* IMU 드라이버 초기화 — 시리얼 인터페이스 연결 및 콜백 함수 등록 */
rc = inv_imu_init(&icm_driver, icm_serif, imu_callback);
if (rc != INV_ERROR_SUCCESS) {
printf("!!! ERROR : Failed to initialize IMU!\r\n");
DBG_PRINTF("!!! ERROR : Failed to initialize IMU!\r\n");
return rc;
}
/* WHOAMI 레지스터 읽기 — 디바이스 존재 및 통신 확인 */
rc = inv_imu_get_who_am_i(&icm_driver, &who_am_i);
if (rc != INV_ERROR_SUCCESS) {
printf("!!! ERROR : Failed to read whoami!\r\n");
DBG_PRINTF("!!! ERROR : Failed to read whoami!\r\n");
return rc;
}
/* WHOAMI 값 검증 — ICM42670P의 경우 0x67이어야 함 */
if (who_am_i != ICM_WHOAMI) {
printf("!!! ERROR : Bad WHOAMI value! Read 0x%02x, expected 0x%02x\r\n", who_am_i, ICM_WHOAMI);
DBG_PRINTF("!!! ERROR : Bad WHOAMI value! Read 0x%02x, expected 0x%02x\r\n", who_am_i, ICM_WHOAMI);
return INV_ERROR;
}
@@ -354,7 +354,7 @@ void imu_callback(inv_imu_sensor_event_t *event)
* 스케일링된 데이터를 UART로 출력
*/
if (event->sensor_mask & (1 << INV_SENSOR_ACCEL) && event->sensor_mask & (1 << INV_SENSOR_GYRO))
printf("%u: %.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f\r\n",
DBG_PRINTF("%u: %.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f\r\n",
(uint32_t)timestamp,
accel_g[0], accel_g[1], accel_g[2],
temp_degc,
@@ -381,7 +381,7 @@ void imu_callback(inv_imu_sensor_event_t *event)
/* UART 모드: "Tp" 접두사로 6축 데이터를 텍스트 형식으로 출력 */
else if(cmd_type_t == CMD_UART) {
printf("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
DBG_PRINTF("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
}
/*
@@ -399,7 +399,7 @@ void imu_callback(inv_imu_sensor_event_t *event)
ssp_data[5] = (uint16_t)gyro[2];
format_data(imu_bin_buffer, "rsp:", ssp_data,12);
printf("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
DBG_PRINTF("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
dr_binary_tx_safe(imu_bin_buffer,8);
if(custom_add_data==true) {
@@ -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;
}
}