LabHub
배우기 러닝패스 코스

냉장고가 255°C라고 우긴다 · 재시도하다 다음 일을 놓쳤다 · 이론

재시도하다 다음 일을 놓쳤다

LabHub 에서 이어서 보기

한 줄 요약

전송·복구·재시도는 하나의 시간 예산을 나눠 씁니다. 성공 응답도 늦게 왔다면 이번 호출의 성공이 아닙니다.

왜 이게 필요했나

전송에 10ms, 복구에 10ms, 재시도에 다시 10ms를 주면 ‘10ms 안에 끝나는 읽기’가 아닙니다. 제어 루프가 다음 일을 해야 하는데 센서 하나가 실행 흐름을 붙잡을 수 있습니다. timeout은 개별 API의 옵션이기 전에 호출자가 전체 작업에 약속한 기한입니다. 본 실습의 시계는 결정적 모델 시간이고 실제 CPU 실행 지연을 측정하는 것이 아닙니다.

어떻게 동작하나

시작 시각을 한 번 읽고 deadline = start + budget을 구합니다. transfer와 recover에 늘 같은 deadline을 넘깁니다. 첫 전송 3ms, 복구 2ms, 두 번째 전송 3ms라면 합계 8ms입니다. 예산 10ms에서는 성공할 수 있지만 7ms에서는 두 번째 전송이 끝날 수 없습니다. 재시도 때 새 예산을 만드는 것은 시간을 연장한 것입니다.

HAL이 시간 약속을 지킨다는 가정도 시험합니다. 늦은 성공을 반환하는 모델에서는 호출 직후 시계를 다시 읽고 예산 이상 경과했다면 SENSOR_TIMEOUT을 반환해야 합니다. 복구 후에도 같은 검사를 합니다. 정확히 기한에 도착한 결과도 과제에서는 시간 초과입니다. 경계의 포함 여부를 명시하지 않으면 테스트와 구현이 서로 다른 약속을 지키게 됩니다.

시계는 uint32_t 밀리초이고 최댓값 다음에 0으로 돌아갑니다. 따라서 now >= deadline이라는 절대 비교는 래핑 직전·직후에 잘못될 수 있습니다. 이 과제는 예산을 1~INT32_MAX로 제한하고, 관찰 구간에서 래핑이 최대 한 번이라는 전제 아래 unsigned 뺄셈으로 경과 시간을 구합니다. uint32_t의 모듈러 연산을 쓰는 것이지 모든 시계 점프를 해결하는 마법은 아닙니다.

마지막 단계에서는 인자도 경계로 봅니다. bus와 out, 세 콜백이 NULL인지, 주소와 예산이 허용 범위인지 I/O 전에 검사합니다. 잘못된 포인터를 역참조한 뒤 오류를 반환할 수는 없습니다. ctx는 HAL이 정하는 불투명한 값이므로 드라이버가 무조건 NULL을 거부하지 않습니다. 출력 포인터의 두 필드는 성공한 호출에서만 바뀝니다.

현장에서 만나는 모습

센서 표본의 observed_ms는 호스트가 전송 완료를 확인한 시점입니다. ADC가 실제 온도를 변환한 시각이 아니므로 ‘방금 읽었다’만으로 ‘방금 측정했다’고 할 수 없습니다. 상위 프로그램은 마지막 성공 시각과 현재 오류를 함께 보여 줘야 오래된 값이 정상 최신값처럼 보이지 않습니다. 실패 뒤 다음 정상 읽기가 다시 갱신되는지도 시험해야 합니다.

완성 후에도 실물 검증은 남습니다. 풀업·배선·전원·클록·센서 변환 주기·실제 HAL 구현은 이 모델로 검증되지 않습니다. 포트폴리오에는 ‘호스트 C + 결정적 HAL 모델’이라고 적고, 검증한 입력·상태·기한과 검증하지 않은 물리적 항목을 나누세요. 모델 통과는 다음 실물 시험을 준비하는 근거이지 현장 안전 보증이 아닙니다.

다음 실습에서 할 것

7~8단계에서 공유 기한·늦은 성공·래핑·인자 검사를 완성합니다. 전체 채점은 앞 단계까지 다시 확인합니다. 정상→부분 실패→정상 수집에서 마지막 정상 표본이 보존되고 새 표본으로 교체되는지 확인하세요. 세션 종료 시 파일이 사라지므로 소스와 시험 기록을 별도로 보관하세요.