fix: BLE TX 먹통 해결 및 메모리 안전성 개선

- binary_tx_handler를 dr_binary_tx_safe로 전체 교체 (APP_ERROR_CHECK 제거)
- data_tx_handler APP_ERROR_CHECK → DBG_PRINTF 교체
- memset/memcpy 하드코딩 크기를 define 상수로 교체 (버퍼 오버런 수정)
- SERIAL_NO_LENGTH, HW_NO_LENGTH, PASSKEY_LENGTH를 main.h로 통합
- 미사용 HW 드라이버/EEPROM 코드 삭제, TWI를 i2c_manager.c로 통합
- EEPROM → FDS 전환, 코드 리뷰 현황 문서 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-16 16:39:26 +09:00
parent a77919b4d3
commit 831dbc2844
76 changed files with 43253 additions and 16370 deletions

View File

@@ -39,7 +39,7 @@ extern void param_error(const char *cmd);
/* BLE transmission */
extern void single_format_data(uint8_t *buffer, const char *tag, uint16_t value);
extern void ascii_format_data(uint8_t *buffer, const char *tag, const char *ascii, uint8_t len);
extern void binary_tx_handler(const uint8_t *buffer, uint16_t length);
extern void dr_binary_tx_safe(const uint8_t *buffer, uint16_t length);
extern void dr_sd_delay_ms(uint32_t ms); /* Softdevice-friendly delay */
/* FDS config (fstorage) */
@@ -83,7 +83,8 @@ extern bool go_device_power_off;
extern bool go_NVIC_SystemReset;
extern bool bond_data_delete;
extern uint8_t m_reset_status;
extern ret_code_t eeprom_write_byte(uint16_t mem_address, uint8_t data);
extern void config_save(void);
extern config_data_t m_config;
/* AGC_GAIN_SW is a macro in measurements.h - replicate here */
#include "nrf_gpio.h"
@@ -302,7 +303,7 @@ static int Cmd_mfv(const ParsedCmd *cmd);
static int Cmd_msp(const ParsedCmd *cmd); /* IMU 6-axis raw data (single shot) */
static int Cmd_mpa(const ParsedCmd *cmd); /* Piezo TX/RX Activate */
static int Cmd_mpb(const ParsedCmd *cmd); /* Piezo TX/RX Deactivate 26.03.13 */
static int Cmd_mpb(const ParsedCmd *cmd); /* Piezo TX/RX Deactivate */
static int Cmd_mpc(const ParsedCmd *cmd); /* Piezo Burst Capture */
static int Cmd_mdc(const ParsedCmd *cmd); /* Piezo ADC Capture */
static int Cmd_mec(const ParsedCmd *cmd); /* Piezo Burst + ADC capture */
@@ -427,7 +428,7 @@ int dr_cmd_parser(const uint8_t *buf, uint8_t len)
/* CRC 실패 시 에러 응답 전송 */
if (g_plat.crc_check && g_plat.tx_bin) {
single_format_data(ble_bin_buffer, "crc!", 65530);
binary_tx_handler(ble_bin_buffer, 3);
dr_binary_tx_safe(ble_bin_buffer, 3);
}
return -1; /* CRC 실패 또는 파싱 실패 → 음수로 old parser에 위임 */
}
@@ -474,7 +475,7 @@ static int Cmd_mta(const ParsedCmd *cmd)
if (g_plat.tx_bin) {
single_format_data(ble_bin_buffer, "rta:", mode);
binary_tx_handler(ble_bin_buffer, 3);
dr_binary_tx_safe(ble_bin_buffer, 3);
}
return 1;
@@ -515,7 +516,7 @@ static int Cmd_sta(const ParsedCmd *cmd)
if (g_plat.tx_bin) {
single_format_data(ble_bin_buffer, "sta:", mode);
binary_tx_handler(ble_bin_buffer, 3);
dr_binary_tx_safe(ble_bin_buffer, 3);
}
return 1;
@@ -683,7 +684,7 @@ static int Cmd_ssq(const ParsedCmd *cmd)
g_plat.log("[Cmd_ssq] Power off\r\n");
}
single_format_data(ble_bin_buffer, "rsq:", val);
binary_tx_handler(ble_bin_buffer, 2);
dr_binary_tx_safe(ble_bin_buffer, 2);
go_device_power_off = true;
main_timer_start();
return 1;
@@ -698,11 +699,12 @@ static int Cmd_ssr(const ParsedCmd *cmd)
g_plat.log("[Cmd_ssr] Bond delete + reset\r\n");
}
single_format_data(ble_bin_buffer, "rsr:", val);
binary_tx_handler(ble_bin_buffer, 2);
dr_binary_tx_safe(ble_bin_buffer, 2);
bond_data_delete = true;
eeprom_write_byte(0x0060, (uint8_t)bond_data_delete);
m_config.bond_data_delete = (uint8_t)bond_data_delete;
m_reset_status = 2;
eeprom_write_byte(0x0065, m_reset_status);
m_config.reset_status = m_reset_status;
config_save();
nrf_delay_ms(5);
go_NVIC_SystemReset = true;
main_timer_start();
@@ -718,9 +720,10 @@ static int Cmd_sss(const ParsedCmd *cmd)
g_plat.log("[Cmd_sss] Device reset\r\n");
}
single_format_data(ble_bin_buffer, "rss:", val);
binary_tx_handler(ble_bin_buffer, 2);
dr_binary_tx_safe(ble_bin_buffer, 2);
m_reset_status = 2;
eeprom_write_byte(0x0065, m_reset_status);
m_config.reset_status = m_reset_status;
config_save();
nrf_delay_ms(5);
go_NVIC_SystemReset = true;
main_timer_start();
@@ -736,7 +739,7 @@ static int Cmd_sst(const ParsedCmd *cmd)
g_plat.log("[Cmd_sst] Ready\r\n");
}
single_format_data(ble_bin_buffer, "rst:", val);
binary_tx_handler(ble_bin_buffer, 2);
dr_binary_tx_safe(ble_bin_buffer, 2);
return 1;
}
@@ -747,7 +750,7 @@ static int Cmd_mfv(const ParsedCmd *cmd)
g_plat.log("[Cmd_mfv] FW=%s\r\n", DR_DEVICE_VERSION);
}
ascii_format_data(ble_bin_buffer, "rfv:", DR_DEVICE_VERSION, 12);
binary_tx_handler(ble_bin_buffer, 8);
dr_binary_tx_safe(ble_bin_buffer, 8);
return 1;
}
@@ -764,7 +767,7 @@ static int Cmd_mpa(const ParsedCmd *cmd)
if (g_plat.tx_bin) {
single_format_data(ble_bin_buffer, "rpa:", 1);
binary_tx_handler(ble_bin_buffer, 3);
dr_binary_tx_safe(ble_bin_buffer, 3);
}
return 1;
@@ -783,7 +786,7 @@ static int Cmd_mpb(const ParsedCmd *cmd)
if (g_plat.tx_bin) {
single_format_data(ble_bin_buffer, "rpb:", 1);
binary_tx_handler(ble_bin_buffer, 3);
dr_binary_tx_safe(ble_bin_buffer, 3);
}
return 1;
@@ -856,9 +859,9 @@ static int Cmd_mpc(const ParsedCmd *cmd)
case 4:
dr_piezo_burst_sw_22mhz((uint8_t)cycles);
break;
case 9:
/*case 9:
dr_piezo_burst_sw_19mhz((uint8_t)cycles);
break;
break;*/
case 1:
default:
dr_piezo_burst_sw((uint8_t)cycles); /* 2.1MHz */
@@ -982,7 +985,7 @@ static int Cmd_mdc(const ParsedCmd *cmd)
ble_bin_buffer[11] = (uint8_t)(echo.baseline_raw >> 8);
ble_bin_buffer[12] = (uint8_t)(echo.num_samples & 0xFF);
ble_bin_buffer[13] = (uint8_t)(echo.num_samples >> 8);
binary_tx_handler(ble_bin_buffer, 7); /* 14 bytes = 7 words */
dr_binary_tx_safe(ble_bin_buffer, 7); /* 14 bytes = 7 words */
nrf_delay_ms(100); /* Wait for BLE stack */
/* Packet 2~N: rdd: data packets with packed 12-bit samples */
@@ -1009,7 +1012,7 @@ static int Cmd_mdc(const ParsedCmd *cmd)
/* Ensure even byte count for word alignment */
if (dst_idx & 1) ble_bin_buffer[dst_idx++] = 0;
binary_tx_handler(ble_bin_buffer, dst_idx / 2); /* bytes to words */
dr_binary_tx_safe(ble_bin_buffer, dst_idx / 2); /* bytes to words */
nrf_delay_ms(100); /* Inter-packet delay */
}
@@ -1020,7 +1023,7 @@ static int Cmd_mdc(const ParsedCmd *cmd)
ble_bin_buffer[3] = ':';
ble_bin_buffer[4] = (uint8_t)(total_packets & 0xFF);
ble_bin_buffer[5] = (uint8_t)(total_packets >> 8);
binary_tx_handler(ble_bin_buffer, 3); /* 6 bytes = 3 words */
dr_binary_tx_safe(ble_bin_buffer, 3); /* 6 bytes = 3 words */
if (g_plat.log && g_log_enable) {
g_plat.log("[Cmd_mdc] sent rdb+rdd*%u+rde (%u samples)\r\n",
@@ -1295,7 +1298,7 @@ static int Cmd_mwh(const ParsedCmd *cmd)
}
ascii_format_data(ble_bin_buffer, "rwh:", buf, 12);
binary_tx_handler(ble_bin_buffer, 8);
dr_binary_tx_safe(ble_bin_buffer, 8);
return 1;
}
@@ -1321,7 +1324,7 @@ static int Cmd_mws(const ParsedCmd *cmd)
}
ascii_format_data(ble_bin_buffer, "rws:", buf, 12);
binary_tx_handler(ble_bin_buffer, 8);
dr_binary_tx_safe(ble_bin_buffer, 8);
return 1;
}
@@ -1331,7 +1334,7 @@ static int Cmd_mrh(const ParsedCmd *cmd)
(void)cmd;
memcpy(HW_NO, m_config.hw_no, 12);
ascii_format_data(ble_bin_buffer, "rrh:", HW_NO, 12);
binary_tx_handler(ble_bin_buffer, 8);
dr_binary_tx_safe(ble_bin_buffer, 8);
return 1;
}
@@ -1341,7 +1344,7 @@ static int Cmd_mrs(const ParsedCmd *cmd)
(void)cmd;
memcpy(SERIAL_NO, m_config.serial_no, 12);
ascii_format_data(ble_bin_buffer, "rrs:", SERIAL_NO, 12);
binary_tx_handler(ble_bin_buffer, 8);
dr_binary_tx_safe(ble_bin_buffer, 8);
return 1;
}