# VesiScan-Basic 코드 리뷰 현황 보고서 작성일: 2026-03-16 대상: VesiScan BASIC 펌웨어 전체 (nRF52840 + S140 SoftDevice) 기준 문서: CODE_REVIEW.pdf (2026-03-15) 현재 빌드: DEBUG_MINIMAL_BOOT=1, BLE_DEV_MODE=1 ## 목차 1. 삭제 대상: 미사용 하드웨어 드라이버 2. 삭제 대상: 미사용 코드 3. DEBUG_MINIMAL_BOOT 조건부 컴파일 정리 4. Keil 프로젝트 파일 정리 5. 버그 및 오류 수정 6. 저전력 최적화 7. 코드 품질 개선 8. 작업 우선순위 요약 --- ## 1. 삭제 대상: 미사용 하드웨어 드라이버 ### 1.1 회로 기반 분석 변경 없음. VB0HW0100 회로 기준 IC 목록은 CODE_REVIEW.pdf 1.1절과 동일. ### 1.2 회로에 없는 IC의 드라이버 (삭제 대상) | 파일 | IC/기능 | 판정 | 현재 상태 | |------|--------|------|----------| | ad5272_i2c.c/h | AD5272 디지털 포텐시오미터 | 삭제 | **완료** | | ada2200_spi.c/h | ADA2200 동기 복조기 | 삭제 | **완료** | | mcp4725_i2c.c/h | MCP4725 DAC | 삭제 | **완료** | | mcp4725_adc.c/h | MCP4725 ADC 피드백 | 삭제 | **완료** | | ir_i2c.c/h | IR LED 센서 (0x50~0x57) | 삭제 | **완료** | | LED_Parse.c/h | LED ROM 파싱 | 삭제 | **완료** | ### 1.3 기능적으로 미사용인 드라이버 (삭제 대상) | 파일 | 기능 | 판정 | 현재 상태 | |------|------|------|----------| | measurements.c/h | 레거시 측정 루프 | 삭제 | **완료** | | measurements_20.c/h | 20-샘플 측정 변형 | 삭제 | **완료** | | meas_pd_imm.c/h | 즉시 PD 측정 | 삭제 | **완료** | | meas_pd_buff.c/h | 버퍼드 PD 측정 | 삭제 | **완료** | | meas_pd_voltage_simple.c/h | 단순 전압 측정 | 삭제 | **완료** | | meas_pd_voltage_half.c/h | 반파 전압 측정 | 삭제 | **완료** | | meas_pd_voltage_full.c/h | 전파 전압 측정 | 삭제 | **완료** | | meas_pd_voltage_custom.c/h | 커스텀 전압 측정 | 삭제 | **완료** | | full_agc.c/h | 자동 이득 제어 | 삭제 | **완료** | | debuf_print.h | 오타 파일 | 삭제 | **완료** | ### 1.4 삭제 시 의존성 영향 cmd_parse.h에서 제거할 include 목록: | include | 현재 상태 | |---------|----------| | #include "ir_i2c.h" | **완료** (제거됨) | | #include "ad5272_i2c.h" | **완료** (제거됨) | | #include "ada2200_spi.h" | **완료** (제거됨) | | #include "mcp4725_i2c.h" | **완료** (제거됨) | | #include "measurements.h" | **완료** (제거됨) | | #include "meas_pd_voltage_simple.h" | **완료** (제거됨) | | #include "meas_pd_voltage_half.h" | **완료** (제거됨) | | #include "meas_pd_voltage_full.h" | **완료** (제거됨) | | #include "full_agc.h" | **완료** (제거됨) | | #include "meas_pd_imm.h" | **완료** (제거됨) | ### 1.5 cat_interface.c (EEPROM 드라이버) 삭제 분석 #### 1.5.1 결론: EEPROM 삭제 완료, TWI는 i2c_manager.c로 통합 현재 상태: **완료** - jhChun 26.03.16 cat_interface.c 삭제(EEPROM/AES 코드 전체 삭제). TWI 인스턴스(m_twi) 및 초기화/해제 함수는 i2c_manager.c로 통합. #### 1.5.2 cat_interface.c가 제공하는 것 | 기능 | 판정 | 현재 상태 | |------|------|----------| | m_eeprom TWI 인스턴스 | i2c_manager.c로 이동, m_twi로 리네이밍 | **완료** | | eeprom_initialize() / uninitialize() | i2c_manager.c로 이동, twi_initialize/uninitialize로 리네이밍 (static) | **완료** | | eeprom_read/write_byte/word/page/bytes | 삭제 | **완료** | | eeprom_read/write_uint16_array | 삭제 | **완료** | | eeprom_read/write_uint32 | 삭제 | **완료** | | eeprom_write_encrypted() / read_decrypted() | 삭제 | **완료** | | encrypt_data() / decrypt_data() | 삭제 | **완료** | | aes_key[16], aes_iv[16] | 삭제 | **완료** | #### 1.5.3 권장 작업 | # | 작업 | 현재 상태 | |---|------|----------| | 1 | TWI 인스턴스/init/uninit → i2c_manager.c로 통합 | **완료** | | 2 | m_eeprom → m_twi 리네이밍 | **완료** | | 3 | EEPROM read/write 전체 삭제, AES 전체 삭제 | **완료** | | 4 | cmd_parse.c EEPROM 호출 -> FDS 전환 | **완료** | | 5 | main.c 버튼 롱프레스 리셋: EEPROM -> FDS | **완료** | | 6 | power_control.c: cat_interface.h include 제거 | **완료** | #### 1.5.4 cmd_parse.c EEPROM -> FDS 전환 목록 | EEPROM 호출 | 위치 | FDS 대체 방법 | 현재 상태 | |------------|------|------------|----------| | eeprom_init_values_read() | cmd_parse.c | 삭제 (FDS config_load 대체) | **완료** | | eeprom_write_byte(0x0070, m_pd_adc_cnt) | cmd_parse.c | m_config.pd_adc_cnt = val; config_save(); | **완료** | | eeprom_write_word(0x0080, m_pd_delay_us) | cmd_parse.c | m_config.pd_delay_us = val; config_save(); | **완료** | | eeprom_write_byte(0x0060, bond_data_delete) | cmd_parse.c | m_config.bond_data_delete = val; config_save(); | **완료** | | eeprom_write_byte(0x0065, m_reset_status) | cmd_parse.c | m_config.reset_status = val; config_save(); | **완료** | | eeprom_write_encrypted(0x0020, passkey, 6) | cmd_parse.c | memcpy(m_config.static_passkey, val, 6); config_save(); | **완료** | | eeprom_read_decrypted(0x0020, passkey, 6) | cmd_parse.c | memcpy(buf, m_config.static_passkey, 6); | **완료** | | eeprom_write_uint32(0x0090, m_life_cycle) | cmd_parse.c | m_config.life_cycle = val; config_save(); (FDS 필드 추가 완료) | **완료** | | eeprom_read_uint32(0x0090, &m_life_cycle) | cmd_parse.c | m_life_cycle = m_config.life_cycle; | **완료** | | eeprom_write/read_uint16_array(0x0480, ...) | cmd_parse.c | AGC gain — HW 제거됨, 명령 비활성화 | **완료** | --- ## 2. 삭제 대상: 미사용 코드 ### 2.1 AES 암호화 (cat_interface.c) 판정 변경: 전체 삭제 | 항목 | 위치 | 판정 | 현재 상태 | |------|------|------|----------| | aes_key[16] 하드코딩 | cat_interface.c | 삭제 | **완료** | | aes_iv[16] (고정 IV = 0) | cat_interface.c | 삭제 | **완료** | | encrypt_data() | cat_interface.c | 삭제 | **완료** | | decrypt_data() | cat_interface.c | 삭제 | **완료** | | eeprom_write_encrypted() | cat_interface.c | 삭제 | **완료** | | eeprom_read_decrypted() | cat_interface.c | 삭제 | **완료** | ### 2.2 Serial Number / Passkey / HW Version 중복 선언 분석 | 데이터 | 전역 변수 (런타임) | FDS (내장 Flash) | EEPROM (외부, 제거됨) | 현재 상태 | |--------|----------------|----------------|-------------------|----------| | Serial Number | SERIAL_NO[12] | m_config.serial_no[12] | ~~addr 0x0030~~ | **EEPROM 경로 삭제 완료** | | Passkey | m_static_passkey[6] | m_config.static_passkey[6] | ~~addr 0x0020~~ | **EEPROM 경로 삭제 완료** | | HW Version | HW_NO[12] | m_config.hw_no[12] | ~~addr 0x0010~~ | **HW_NO 미삭제** | 권장 작업 현황: | # | 작업 | 현재 상태 | |---|------|----------| | 1 | EEPROM 경로 삭제 -> eeprom_init_values_read() 삭제 | **완료** | | 2 | HW_NO[12] 삭제 -> m_config.hw_no 직접 사용 | **미완료** | | 3 | SERIAL_NO, m_static_passkey 유지 (BLE 스택 필요) | 해당없음 | | 4 | 데이터 흐름 단순화: FDS -> 전역변수 -> BLE 스택 | **미완료** | ### 2.3 미사용 전역 변수 | 변수 | 위치 | 판정 | 현재 상태 | |------|------|------|----------| | roles_str[] | main.c:189 | 삭제 | **미완료** | | m_encrypted_text[16] | main.c:194 | 삭제 | **미완료** | | m_encrypted_text2[16] | main.c:195 | 삭제 | **미완료** | | m_decrypted_text[16] | main.c:196 | 삭제 | **미완료** | | DEVICE_NAME | cmd_parse.c | 삭제 | 확인 필요 | | HW_NO[12] | cmd_parse.c | 삭제 | **미완료** | | AES_KEY_SIZE | main.c:154 | 삭제 | **미완료** | | AES_BLOCK_SIZE | main.c:155 | 삭제 | **미완료** | | suppress_unused_warnings() | main.c:239 | 삭제 | **미완료** | | c_addr[6] | main.c:187 | 삭제 | **미완료** | | led_pd_dac_v[LED_NUM] | 참조 다수 | 삭제 | 확인 필요 | ### 2.4 주석 처리된 코드 | 위치 | 내용 | 판정 | 현재 상태 | |------|------|------|----------| | main_timer.c:37-88 | FEATURE_DETAIL_VALUE_FULL 주석 블록 | 삭제 | **미완료** | | cmd_parse.c:282-317 | serial_to_passkey_hash, test_eeprom_page_rw | 삭제 | **미완료** | | cmd_parse.c:87-88 | pd_adc_half/full_a_start extern | 삭제 | 확인 필요 | | battery_saadc.c:22 | //#include "fstorage.h" | 삭제 | **미완료** | --- ## 3. DEBUG_MINIMAL_BOOT 조건부 컴파일 정리 현재 DEBUG_MINIMAL_BOOT=1로 MINIMAL 모드만 사용. Full boot 경로는 실행되지 않음. ### 3.1 제거 대상 #if 블록 | 파일 | 블록 | 판정 | 현재 상태 | |------|------|------|----------| | main.c:280-281 | #if !DEBUG_MINIMAL_BOOT full_gpio_init() | 삭제 (함수 전체) | **미완료** | | main.c:354-355 | #if !DEBUG_MINIMAL_BOOT load_eeprom_config() | 삭제 (함수 전체, EEPROM 제거 완료) | **완료** (함수 삭제됨) | | main.c:1437-1439 | Full boot 경로 (ada2200_init, mcp4725_init 등) | 삭제 | **미완료** | | main.c GPIO init 분기 | GPIO init 분기 | MINIMAL 코드만 유지 | **미완료** | | power_control.c | Full boot power sequence | 삭제 (minimal 경로만 유지) | **미완료** | ### 3.3 DEBUG_MINIMAL_BOOT 제거 시 함께 정리 | 항목 | 현재 상태 | |------|----------| | #define DEBUG_MINIMAL_BOOT 1 삭제 (main.c:96) | **미완료** (여전히 활성) | | 모든 #if 조건 제거, MINIMAL 코드만 유지 | **미완료** | | BLE_DEV_MODE define 유지 | 해당없음 | --- ## 4. Keil 프로젝트 파일 정리 ### 4.1 삭제할 소스 참조 (uvprojx) 현재 상태: **정리 불필요** ble_app_bladder_patch_s140.uvprojx 확인 결과, 아래 삭제 대상 파일들은 이미 프로젝트에 등록되어 있지 않음: - ad5272_i2c.c, ada2200_spi.c, mcp4725_i2c.c, mcp4725_adc.c - ir_i2c.c, LED_Parse.c, measurements.c, measurements_20.c - full_agc.c, meas_pd_voltage_custom.c, cat_interface.c uvprojx 수정 작업 없음. --- ## 5. 버그 및 오류 수정 ### 5.1 심각도 높음 (HIGH) #### B1: BLE TX 큐 풀 시 APP_ERROR_CHECK로 인한 시스템 먹통 현상 파일: main.c (구 binary_tx_handler) 현재 상태: **완료** - `binary_tx_handler()` 함수 본체 삭제 - 모든 호출처를 `dr_binary_tx_safe()`로 교체 완료 - cmd_parse.c (22곳 + 함수 포인터 1곳) - battery_saadc.c (2곳) - app_raw.c (2곳) - tmp235_q1.c (1곳) - parser.c (17곳) - main.h 선언 제거, dr_util.c/dr_adc121s051.c의 옛날 extern 선언 제거 - `dr_binary_tx_safe()`는 NRF_ERROR_RESOURCES 시 최대 100회 재시도 후 패킷 드롭, 연결 에러 시 graceful 리턴 - `data_tx_handler()`의 APP_ERROR_CHECK도 DBG_PRINTF로 교체 — 예상치 못한 에러 시에도 패킷 드롭 후 정상 동작 유지 #### B2: nrf_delay_ms(10) 블로킹 대기 (BLE TX) 파일: main.c:1221-1228 현재 상태: **완료** 조건문 로직이 정상 수정됨. NRF_ERROR_RESOURCES가 아닌 경우에만 delay 실행. #### B3: extern + 초기화 동시 사용 파일: cmd_parse.c 현재 상태: **완료** `extern int8_t pd_adc_counts[4] = {8, 16, 24, 32};` 선언이 제거됨. #### B4: memset/memcpy 버퍼 크기 불일치 및 매직 넘버 파일: main.c config_apply_to_globals() 현재 상태: **완료** - memset 오버런 수정: 하드코딩 `16` → `sizeof(SERIAL_NO)`, `PASSKEY_LENGTH` 사용 - memcpy 매직 넘버 수정: 하드코딩 `12` → `sizeof(m_config.hw_no)`, `sizeof(m_config.serial_no)`, `sizeof(SERIAL_NO)` 등으로 교체 - m_static_passkey memset/memcpy: `PASSKEY_LENGTH` define 활용 스택/힙 오버플로우로 인한 메모리 손상 가능성이 있는 심각한 버그. ### 5.2 심각도 중간 (MEDIUM) #### B6: battery_event_handler에서 floating-point 연산 파일: battery_saadc.c:167 현재 상태: **미완료** 여전히 부동소수점 연산 사용 중: ```c batt_lvl_in_milli_volt_1 = (batt_lvl_in_milli_volt_0) *1.42; ``` 수정 필요: ```c batt_lvl_in_milli_volt_1 = (batt_lvl_in_milli_volt_0 * 142) / 100; ``` #### B7: main_timer 단발 모드 문제 현재 상태: **해당없음** (의도적 설계로 판단) #### B8: processing_start_tick 미사용 파일: cmd_parse.c:57 현재 상태: **완료** (해결됨) 변수가 5초 타임아웃 추적에 활용되고 있음: - cmd_parse.c:483에서 초기값 확인 - cmd_parse.c:489에서 5초 경과 비교 #### B9: config_load() goto 기반 흐름 파일: fstorage.c:157-261 현재 상태: **미완료** `goto cfg_load_start` 패턴이 여전히 존재. 3개의 goto 문과 2개의 레이블로 복잡한 흐름 유지 중. FDS 초기화 실패 시 무한 루프 가능성 여전. ### 5.3 심각도 낮음 (LOW) #### B11: debuf_print.h 파일명 오타 현재 상태: **완료** (파일 삭제) #### B12: 함수 중복 선언 파일: main.h:44-54 현재 상태: **미완료** static 함수 프로토타입 6개가 헤더에 여전히 선언됨: - advertising_start (FEATURE_SECURE_CONNECTION 내) - t_power_off_timeout_handler - power_control_handler - main_s - PM_s - main_routine_handler #### B13: LED_ALLOFF, PD_ALLOFF 매크로 정의 위치 현재 상태: 확인 필요 --- ## 6. 저전력 최적화 ### 6.1 현재 전력 구조 분석 변경 없음. CODE_REVIEW.pdf 6.1절과 동일. ### 6.2 개선 항목 #### P1: UART 비활성화 (가장 큰 절약 -- 예상 ~1mA 절감) 파일: main.c:1427 현재 상태: **미완료** `uart_init()`이 무조건 호출됨. `#if BLE_DEV_MODE` 조건으로 감싸져 있지 않음. 수정 필요: ```c #if BLE_DEV_MODE uart_init(); #endif ``` #### P2: SEGGER RTT 비활성화 (프로덕션) 파일: debug_print.h 현재 상태: **미완료** `ENABLE_PRINTF`가 `1`로 하드코딩되어 있음. `BLE_DEV_MODE`와 연동되지 않음. 수정 필요: ```c #if BLE_DEV_MODE #define ENABLE_PRINTF 1 #else #define ENABLE_PRINTF 0 #endif ``` #### P3: 배터리 타이머 주기 최적화 파일: battery_saadc.c:48 현재 상태: **미완료** `BATTERY_LOOP_INTERVAL = 5000ms` 고정. 동적 조절 로직 없음. #### P4: IMU 타이머 조건부 시작 파일: main.c BLE 이벤트 핸들러 현재 상태: **미완료** BLE_GAP_EVT_CONNECTED/DISCONNECTED 핸들러에 IMU 타이머 start/stop 로직 없음. BLE 미연결 시에도 IMU를 읽을 수 있는 상태. #### P5: main_loop() 타이머 폴링 효율화 현재 상태: **미완료** 플래그 기반 폴링 패턴 그대로 유지 중. #### P6: NRF_LOG 비활성화 고려 현재 상태: **미완료** (확인 필요) ### 6.3 예상 절감 효과 | 최적화 | 예상 절감 | 난이도 | 현재 상태 | |--------|----------|--------|----------| | P1: UART 비활성화 | ~1mA | 쉬움 | **미완료** | | P2: RTT 비활성화 | ~0.1-0.5mA | 쉬움 | **미완료** | | P4: IMU 타이머 조건부 시작 | ~41uA (미연결 시) | 쉬움 | **미완료** | | P3: 배터리 타이머 동적 | ~5uA | 보통 | **미완료** | | P5-A: 단발->직접호출 | 응답 개선 | 쉬움 | **미완료** | | P5-B: app_scheduler | 코드 품질 + 확장성 | 보통 | **미완료** | | P5-C: IMU FIFO+인터럽트 | 연속측정 시 ~50uA | 어려움 | **미완료** | | P6: NRF_LOG 비활성화 | ~10uA | 쉬움 | **미완료** | --- ## 7. 코드 품질 개선 ### 7.1 구조 개선 | # | 항목 | 현재 상태 | |---|------|----------| | Q1 | main.h에서 static 함수 선언 제거 | **미완료** (6개 잔존) | | Q2 | cat_interface.c -> i2c_manager.c로 TWI 통합 | **완료** | | Q3 | extern 변수 과다 사용 | **미완료** (30개 이상) | | Q4 | main_timer.c main_loop() 플래그 기반 폴링 | **미완료** | | Q5 | 매직 넘버 제거 | **미완료** | ### 7.2 코딩 스타일 변경 없음. CODE_REVIEW.pdf 7.2절과 동일. --- ## 8. 작업 우선순위 요약 ### 즉시 수정 (안전/안정성) | # | 항목 | 심각도 | 현재 상태 | |---|------|--------|----------| | 1 | B4: memset/memcpy 버퍼 크기 불일치 및 매직 넘버 | CRITICAL | **완료** | | 2 | B1: BLE TX 큐 풀 시 시스템 먹통 (binary_tx_handler → dr_binary_tx_safe 교체) | HIGH | **완료** | | 3 | B2: BLE TX 에러 핸들링 로직 반전 | HIGH | **완료** | | 4 | B3: extern + 초기화 동시 사용 | HIGH | **완료** | ### 1차 정리 (미사용 코드/EEPROM 삭제) | # | 항목 | 현재 상태 | |---|------|----------| | 5 | 미사용 HW 드라이버 삭제 (1.2절) | **완료** | | 6 | cat_interface.c EEPROM 기능 삭제 + TWI를 i2c_manager.c로 통합 (1.5절) | **완료** | | 7 | cmd_parse.c EEPROM 호출 -> FDS 전환 (1.5.4절) | **완료** | | 8 | 미사용 전역변수 + HW_NO 삭제 (2.2-2.3절) | **미완료** | | 9 | DEBUG_MINIMAL_BOOT 조건 제거 (3절) | **미완료** | | 10 | Keil uvprojx 소스 참조 제거 (4절) | 확인 필요 | | 11 | 주석 처리된 코드 삭제 (2.4절) | **미완료** | ### 2차 정리 (저전력 최적화) | # | 항목 | 예상 절감 | 현재 상태 | |---|------|----------|----------| | 12 | P1: UART 비활성화 | ~1mA | **미완료** | | 13 | P2: RTT 비활성화 | ~0.1-0.5mA | **미완료** | | 14 | P4: IMU 타이머 BLE 연결 시에만 동작 | ~41uA | **미완료** | | 15 | P5-A: main_loop 단발 이벤트 직접 호출로 전환 | 응답 개선 | **미완료** | | 16 | P5-B: app_scheduler 도입 (선택) | 코드 품질 | **미완료** | | 17 | P3: 배터리 타이머 동적 조절 | ~5uA | **미완료** | ### 3차 정리 (코드 품질) | # | 항목 | 현재 상태 | |---|------|----------| | 18 | Q1: main.h static 함수 제거 | **미완료** | | 19 | Q5: 매직 넘버 define화 | **미완료** | | 20 | B9: config_load() goto 제거 | **미완료** |