Showing Posts From
오후
- 25 Dec, 2025
수요일 오후, 갑자기 '이건 사실 하드웨어 이슈 같은데요?'
수요일 오후, 갑자기 '이건 사실 하드웨어 이슈 같은데요?' 오후 3시, 그 순간 테스트를 돌렸다. 세 번째다. 같은 증상이다. UART 통신이 중간에 끊긴다. 정확히 2.3초 후. 매번 같은 타이밍이다. 소프트웨어 타이밍 이슈는 이렇게 정확하지 않다. 변수가 있다. 인터럽트 우선순위, 태스크 스케줄링, DMA 버퍼 크기... 뭔가 하나라도 달라지면 타이밍이 흔들린다. 근데 이건 딱 2.3초다. 오차 ±10ms. 오실로스코ープ를 켰다. TX 핀에 프로브를 댔다. 파형을 봤다. 2.3초 지점에서 전압이 이상하다. 3.3V로 올라가야 하는데 2.8V에서 멈춘다. 그리고 다시 0V로 떨어진다. "아..." 이건 내 문제가 아니다.HW팀에 연락 슬랙을 열었다. HW팀 채널에 메시지를 썼다. "UART TX 핀 파형 이상한 것 같습니다. 2.3초 후 전압이 2.8V에서 멈춥니다. 회로 확인 부탁드려요." 오실로스코ープ 캡처 이미지를 첨부했다. 빨간 마커로 이상한 부분을 표시했다. 답장이 왔다. 10분 후. "회로도 확인해볼게요. 근데 레이아웃은 이미 나간 상태라..." 레이아웃이 나갔다는 건 PCB 제작이 들어갔다는 뜻이다. 만약 회로 문제면 다시 만들어야 한다. 비용이 수백만원이다. 일정은 2주 늦어진다. "일단 확인 부탁드립니다." 답장을 보내고 자리에서 일어났다. 커피를 마시러 갔다. 내가 할 수 있는 건 기다리는 것뿐이다.목요일, 답이 없다 다음 날 아침. HW팀 김대리가 왔다. "어제 확인해봤는데요." 그는 노트북을 들고 있었다. 회로도를 보여줬다. "UART TX 핀이랑 LED 핀이 같은 풀업 저항을 쓰고 있어요. LED가 켜지면서 전류가 많이 흐르면 전압이 떨어질 수 있겠네요." "아..." LED였다. 우리가 디버깅용으로 달아놓은 LED다. 2.3초마다 깜빡이게 해놨다. 통신 상태를 보려고. "근데 이건 설계 단계에서 검증했어야 하는 거 아닌가요?" 김대리가 어색하게 웃었다. "시뮬레이션에서는 안 나왔어요. 실제로 만들어보니까..." "그럼 어떻게 해야 하나요?" "일단 임시 방편으로 LED 빼고 테스트해보세요. 근본적으로는 회로 수정해야 하는데..." 그는 말을 흐렸다. 레이아웃 다시 나가면 일정이 늦어진다는 걸 알고 있었다. 금요일, 회의 회의가 잡혔다. 오후 2시. 회의실에 HW팀, SW팀, PM이 모였다. PM이 물었다. "정확한 원인이 뭡니까?" HW팀 김대리가 설명했다. 풀업 저항, LED, 전압 강하... 기술적인 이야기를 5분 정도 했다. PM이 고개를 끄덕였다. "그럼 해결 방법은요?" "회로 수정입니다. PCB 다시 제작해야 합니다." "비용이랑 일정은요?" "비용은 300만원 정도. 일정은 2주 추가입니다." PM의 표정이 굳었다. 그는 노트북을 봤다. 간트 차트가 보였다. 일정이 빨간색으로 표시되어 있었다. "2주면... 양산 일정을 못 맞추는데요." 침묵이 흘렀다. 그때 우리 팀장이 말했다. "임시 방편으로 LED를 빼면 되지 않나요? 일단 양산은 LED 없이 나가고, 다음 버전에서 회로 수정하는 걸로." PM이 고개를 끄덕였다. "그게 낫겠네요. 일단 LED 빼고 테스트 진행하세요." 회의가 끝났다. 30분이 걸렸다. 결론은 'LED를 빼자'였다.월요일, 다시 내 일 주말이 지났다. 월요일 아침. 출근했다. HW팀에서 LED를 뺀 보드를 가져왔다. 납땜 자국이 있었다. 수작업으로 제거한 거다. "테스트 부탁드립니다." 보드를 받았다. 내 자리로 돌아왔다. 코드를 올렸다. 테스트를 돌렸다. UART 통신이 정상적으로 동작했다. 2.3초가 지나도 끊기지 않았다. 10분을 돌려봤다. 문제없었다. 슬랙에 메시지를 썼다. "테스트 정상 완료했습니다." 답장이 왔다. "수고하셨습니다." 그게 끝이었다. 일주일이 걸렸다. 실제 작업 시간은 1시간도 안 됐다. 나머지는 기다림이었다. 화요일, 또 다른 문제 다음 날. 새로운 문제가 생겼다. SPI 통신이 안 된다. 센서에서 데이터가 안 온다. 레지스터 설정을 확인했다. 문제없었다. 클럭 주파수를 확인했다. 문제없었다. 오실로스코ープ를 켰다. CLK, MOSI, MISO 핀에 프로브를 댔다. 파형을 봤다. CLK는 정상이다. MOSI도 정상이다. 근데 MISO가 이상하다. 신호가 너무 약하다. 1.2V밖에 안 나온다. 3.3V가 나와야 한다. "또...?" 이것도 하드웨어 문제 같다. 풀업 저항? 아니면 센서 불량? 슬랙을 열었다. HW팀 채널에 메시지를 썼다. "SPI MISO 핀 전압이 1.2V밖에 안 나옵니다. 회로 확인 부탁드려요." 오실로스코프 캡처를 첨부했다. 답장이 왔다. "확인해볼게요." 또 기다림이다. 수요일, 1주일 후 일주일이 지났다. HW팀에서 확인 결과가 왔다. 센서 불량이었다. 다른 센서로 교체했다. 테스트를 돌렸다. 정상 동작했다. "감사합니다." 답장을 보냈다. 결국 2주가 걸렸다. UART 문제 1주일, SPI 문제 1주일. 내가 실제로 작업한 시간은 2시간도 안 됐다. 코드를 올리고, 테스트를 돌리고, 결과를 확인하는 시간. 나머지는 기다림이었다. 이게 펌웨어 개발이다 펌웨어 개발은 소프트웨어만 다루는 게 아니다. 하드웨어도 같이 다룬다. 아니, 정확히는 하드웨어 문제를 찾아내야 한다. 코드가 완벽해도 회로가 잘못되면 안 된다. 레지스터 설정이 맞아도 전압이 이상하면 안 된다. 타이밍이 정확해도 부품이 불량이면 안 된다. 그리고 그걸 판단하는 게 내 일이다. "이건 소프트웨어 문제인가, 하드웨어 문제인가?" 오실로스코ープ를 보고 판단한다. 파형을 보고 판단한다. 전압을 측정하고 판단한다. 그리고 하드웨어 문제면 HW팀에 넘긴다. 기다린다. 확인 결과가 온다. 다시 테스트한다. 이 과정이 며칠씩 걸린다. 때로는 일주일씩 걸린다. 내가 할 수 있는 건 기다리는 것뿐이다. 다음 프로젝트는 다음 프로젝트도 똑같을 거다. 코드를 짠다. 테스트를 돌린다. 문제가 생긴다. 디버깅한다. 하드웨어 문제를 발견한다. HW팀에 넘긴다. 기다린다. 이게 반복된다. 웹 개발자들이 부럽다. 걔네는 하드웨어 걱정이 없다. 서버가 다운되면 재시작하면 된다. 버그가 생기면 패치하면 된다. 나는 보드가 고장 나면 새로 만들어야 한다. 버그가 양산에 들어가면 리콜이다. 비용이 억 단위다. 그래서 더 신중해진다. 더 많이 테스트한다. 더 많이 확인한다. 그리고 하드웨어 문제를 찾아낸다. 오실로스코프를 들고. 금요일 저녁 이번 주도 야근이다. 새로운 보드가 왔다. 이번엔 회로가 수정된 버전이다. LED 문제가 해결됐다. 코드를 올렸다. 테스트를 돌렸다. 정상 동작했다. "드디어..." 2주 만이다. UART 문제가 완전히 해결됐다. 슬랙에 메시지를 썼다. "최종 테스트 완료했습니다. 양산 가능합니다." PM에게서 답장이 왔다. "고생하셨습니다." 그게 끝이다. 퇴근했다. 시계를 봤다. 밤 10시다. 집에 도착했다. 맥주를 꺼냈다. 마셨다. 내일은 토요일이다. 쉴 수 있다. 그리고 월요일이 되면 또 출근한다. 새로운 문제가 기다리고 있을 것이다. "이건 사실 하드웨어 이슈 같은데요?" 또 이 말을 하게 될 것이다.오실로스코프 프로브를 정리하면서 생각했다. 다음엔 HW 검증을 더 빡빡하게 해야겠다고. 근데 또 새로운 문제가 생길 거다. 그게 이 일이니까.
- 03 Dec, 2025
금요일 오후 3시, 라이브 제품에서 버그 리포트가 들어왔다
금요일 오후 3시, 라이브 제품에서 버그 리포트가 들어왔다 금요일 오후 3시 17분 슬랙에 빨간 점이 떴다. CS팀 채널. "펌웨어팀 @김펌웨어 님, 고객사에서 제품 이상 동작 리포트 들어왔습니다. 확인 부탁드립니다." 첨부된 영상을 봤다. 우리 제품이 멈춰있다. 화면에 아무것도 안 뜬다. LED만 깜빡인다. 양산 나간 지 3개월 된 제품이다. 지금까지 문제없었다. 갑자기 왜. "재현되나요?" 물었다. "고객사에서는 자주 발생한다고 합니다. 저희 테스트에서는 재현 안 됩니다." 제일 싫은 유형이다.일단 로그부터 고객사에 요청했다. "디버그 로그 남아있나요?" 30분 후 답장. "로그 기능 꺼져있었습니다." 당연하지. 양산 버전은 로그 비활성화했다. 플래시 용량 아끼려고. "언제부터 발생했나요?" "정확히는 모르겠습니다. 이번 주에 여러 번 발생했다고 합니다." 증상만 봐서는 모른다. 리셋인지, 하드폴트인지, 워치독인지. 우리 테스트 환경에서는 3시간째 돌려도 멀쩡하다. 고객 환경이 뭐가 다른 거지. 팀장한테 보고했다. "양산 제품 이슈 들어왔습니다. 재현은 안 됩니다." "심각한가?" "고객사에서 자주 발생한다고 합니다." "주말에 대응 가능한가?" 알았다는 뜻이다. 환경 차이 고객사 환경을 조사했다. CS팀이 정리해준 내용.24시간 연속 동작 온도: 실내, 에어컨 있음 전원: 5V 어댑터 네트워크: WiFi, 공유기는 TP-Link 펌웨어 버전: v1.2.3 (최신)우리 테스트 환경이랑 똑같다. 뭐가 다르지. HW팀 민수한테 물었다. "하드웨어 이슈 가능성?" "양산 전에 다 검증했는데요. EMC 테스트도 통과했고." "혹시 로트 문제?" "같은 로트 제품 다른 데서는 문제없어요." 소프트웨어 문제다. 그것도 특정 조건에서만.금요일 오후 5시 팀원들 다 퇴근했다. 팀장만 남아있다. "일단 집에 가. 주말에 보자." 나도 가고 싶다. 근데 못 간다. 고객사는 월요일까지 답변 원한다. 일요일 밤까지 원인 찾아야 한다. 회사 냉장고에서 레드불 두 개 꺼냈다. 오늘 밤샐 것 같다. 일단 코드 리뷰부터 시작했다. v1.2.3 릴리즈 이후 변경점. 아무것도 없다. v1.2.3이 최신이고, 그 이후 수정사항 없다. 그럼 v1.2.3 자체에 버그가 있다는 건데. 3개월 동안 왜 안 나왔지. 테스트 시나리오를 다시 봤다. 우리가 놓친 케이스가 있다. 24시간 고객사는 24시간 연속 동작이라고 했다. 우리 테스트는 최대 8시간. 보통 8시간이면 충분하다. 메모리 릭도 잡히고, 타이밍 이슈도 나온다. 근데 24시간 이상 돌려야 나오는 버그도 있다. 타이머 오버플로우 같은 거. 코드에서 타이머 쓰는 부분을 찾았다. 여러 개다. WiFi 재연결 타이머, 센서 폴링 타이머, 워치독 타이머, RTC... 한 개씩 체크했다. 변수 타입, 오버플로우 조건, 래핑 처리. 있다. WiFi 재연결 로직에서 uint32_t 타이머를 밀리초로 쓴다. 49일마다 오버플로우. 근데 비교 로직이 단순 대소비교다. 오버플로우 케이스를 안 본다. if (current_time > reconnect_time + timeout) { wifi_reconnect(); }49일 넘어가면 current_time이 0으로 돌아간다. reconnect_time은 큰 값. 이 조건이 영원히 참이 된다. WiFi 재연결을 무한 반복한다. 찾았다.금요일 밤 11시 재현 시나리오를 짰다. 타이머를 강제로 49일 근처 값으로 세팅. 보드에 올렸다. 돌렸다. 10분 후 멈췄다. 똑같은 증상. LED만 깜빡이고, 응답 없다. 로그 출력도 멈췄다. 원인 확정이다. 수정은 간단하다. 타이머 비교 로직을 래핑 세이프하게. if ((int32_t)(current_time - reconnect_time) > timeout) { wifi_reconnect(); }부호 있는 정수로 캐스팅하면 오버플로우 케이스도 올바르게 동작한다. 수정했다. 다시 테스트. 이번엔 안 멈춘다. 1시간 돌렸다. 문제없다. 패치 버전을 만들었다. v1.2.4. 빌드하고, 테스트 보드에 올리고, 검증했다. 새벽 2시다. 문서 작업 버그 리포트를 썼다. 원인: WiFi 재연결 타이머 오버플로우 처리 누락발생 조건: 연속 동작 49일 경과 시영향: 제품 응답 없음, LED만 동작수정: 타이머 비교 로직 오버플로우 세이프하게 수정패치 버전: v1.2.4 CS팀에 전달할 자료도 만들었다. "고객사에 전달 부탁드립니다. 월요일 오전까지 v1.2.4 펌웨어로 업데이트하면 해결됩니다." 양산 제품 패치 계획도 세웠다. 이미 나간 제품들은 OTA로 업데이트. 다행히 우리 제품은 OTA 지원한다. 안 했으면 리콜이다. 새벽 3시. 집에 갔다. 토요일 오전 11시에 일어났다. 슬랙 확인. 팀장: "고생했다. 월요일은 오후 출근해라." 고맙다. CS팀: "고객사에 전달했습니다. 월요일 업데이트 예정입니다." 됐다. 침대에 누웠다. 천장을 봤다. 49일. 1180시간. 누가 그렇게 오래 테스트하나. 우리 테스트 시나리오는 8시간이 최대다. 비용 때문에. 시간 때문에. 양산 전에 못 잡은 버그다. 고객이 먼저 발견했다. Low 레벨 개발은 이런 거다. 한 줄 실수가 49일 뒤에 터진다. 웹이면 고쳐서 배포하면 된다. 5분이면 된다. 펌웨어는 OTA 있어도 조마조마하다. 업데이트 중에 전원 나가면 브릭이다. 그래도 찾아서 다행이다. 교훈 같은 건 없다 타이머 오버플로우는 기본 중의 기본이다. 알고 있었다. 그런데 놓쳤다. 코드 리뷰 때 못 봤다. 테스트로도 못 잡았다. 완벽한 코드는 없다. 완벽한 테스트도 없다. 고객이 발견하기 전에 찾으면 좋은 거고, 못 찾으면 이렇게 된다. 금요일 오후 3시에 리포트 들어오고, 주말 날리고, 새벽에 고치고. 이게 펌웨어 개발이다. 월요일에 팀 회의 때 공유할 것이다. "타이머 비교 로직 체크리스트에 추가하자." 다들 "아 그거" 할 거다. 알면서 놓친 거니까. 그래도 체크리스트에 넣는다. 다음에 또 놓칠 테니까. Low 레벨은 이렇다. 같은 실수를 반복하지 않으려고 체크리스트 만들고, 그래도 놓친다. 그럼 또 추가한다. 체크리스트가 100개 넘어간다. 읽는 사람은 없다. 너무 길어서. 일요일 푹 잤다. 아무것도 안 했다. 월요일 오후 출근 예정이다. 고객사 업데이트 결과 확인해야 한다. 문제없이 되면 좋겠다. OTA 실패하면 또 야근이다. 침대에 누워서 생각했다. 웹 개발자들은 지금 뭐 하고 있을까. 카페에서 맥북 켜고 코딩하고 있을까. 배포 버튼 누르면 끝일까. 부럽다. 나는 보드 없으면 일 못 한다. 회사 와야 한다. 오실로스코프 봐야 한다. 디버거 연결하고, 플래시 지우고, 펌웨어 올리고, 리셋하고, 로그 보고. 49일 버그는 집에서 못 잡는다. 장비가 없어서. 그래도 찾았다. 그걸로 됐다.금요일 오후의 빨간 알림은 늘 시작이다. 주말이 끝나고 월요일이 온다.