임베디드 시니어가 알려주는 '좋은 코드'의 조건

임베디드 시니어가 알려주는 '좋은 코드'의 조건

"핀맵이 바뀌었다고요? 코드 다 고쳐야 하는데..." 이런 식은 땀 흘려보신 적 있나요? STM32 개발자가 흔히 저지르는 실수 3가지와, 유지보수가 쉬운 펌웨어를 만드는 '방화벽 코딩' 기법을 소개합니다.

10년 차 펌웨어 아키텍트입니다. 하드웨어 팀에서 "미안한데, 아트웍하다가 핀이 꼬여서 UART1UART3으로 바꿔야 할 것 같아"라고 했을 때, 여러분의 반응은 어떤가요?

A: "아... 코드 수십 군데 고쳐야 하는데 며칠 걸려요." 😰
B: "네, `config.h`만 바꾸면 되니까 5분 뒤에 릴리즈할게요." 😎

만약 A라면 오늘 글을 꼭 정독해 주세요. 여러분의 퇴근 시간을 지켜줄 '하드웨어 추상화(HAL)' 꿀팁을 대방출합니다! 😊

1. 당신의 코드가 '스파게티'인 이유 🤔

펌웨어 개발에서 스파게티 코드의 주범은 goto문이 아닙니다. 바로 '비즈니스 로직과 하드웨어 제어 코드의 혼재'입니다.

⚠️ 흔한 실수 Check!
혹시 main.c 파일 안에서 while(1) 루프 안에 HAL_GPIO_WritePin이나 HAL_UART_Transmit 같은 함수가 그대로 들어있지 않나요? 이건 "나 하드웨어랑 결혼했어!"라고 선언하는 것과 같습니다. 이혼(수정)이 아주 힘들어지죠.

우리는 ST가 제공하는 HAL 드라이버를 믿지만, 의존하지는 말아야 합니다. 벤더의 HAL은 하드웨어를 제어하는 도구일 뿐, 우리 애플리케이션의 로직이 되어서는 안 됩니다.

2. 해결책: 나만의 '방화벽' 만들기 📊

해결책은 간단합니다. 벤더 HAL 함수 앞에 나만의 함수(Wrapper)를 하나 더 두는 것입니다. 이것을 저는 '방화벽'이라고 부릅니다.

📌 기억하세요!
`HAL_GPIO_WritePin`은 '어떻게(How)' 제어하는지 말하지만, `Pump_Start`는 '무엇(What)'을 하는지 말합니다. 코드는 '무엇'을 하는지로 작성되어야 합니다.

[방화벽 코딩의 3단계 규칙]

  1. 1단계: 하드웨어 제어 코드는 반드시 별도의 .c / .h 파일(드라이버 파일)로 분리한다.
  2. 2단계: 드라이버 파일의 헤더(.h)에는 HAL_... 관련 타입이나 매크로를 노출하지 않는다.
  3. 3단계: main.c에서는 오직 내가 만든 함수(Led_On(), Motor_Run())만 호출한다.

 

3. 실전 팁: 이렇게 바꾸세요! 🧮

말로만 하면 어렵죠? 나쁜 코드와 좋은 코드의 예시를 비교해 드립니다.

👎 나쁜 예: 하드웨어 종속적

// main.c
if (temp > 50) {
  // 핀 이름이 바뀌면 여기를 수정해야 함
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
}

👍 좋은 예: 의도 중심적

// main.c
if (temp > 50) {
  // 핀이 바뀌어도 여기는 수정 안 함
  Fan_TurnOn();
}

// fan_driver.c (이 파일만 수정하면 됨)
void Fan_TurnOn() {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
}

🔢 내 프로젝트 건강 상태 체크

다음 중 해당되는 항목을 선택해보세요.

항목 선택:

 

4. 마무리: 핵심 내용 요약 📝

기능 구현보다 중요한 것은 '수정하기 쉬운 구조'를 만드는 것입니다.

🛡️

방화벽 코딩 수칙

✨ 원칙 1: 벤더 HAL을 믿되, 의존하지 마라.
📝 원칙 2: 하드웨어 제어는 별도 파일로 격리하라.
🗣️ 원칙 3: '어떻게'가 아니라 '무엇'을 하는지 적어라.

자주 묻는 질문 ❓

Q: STM32 CubeMX가 만들어준 코드는 수정하면 안 되나요?
A: 네, CubeMX가 생성한 `main.c`의 `USER CODE BEGIN` 주석 사이에만 코드를 넣으려고 노력해야 합니다. 하지만 더 좋은 건, 그곳에서조차 별도 드라이버 파일의 함수만 호출하는 것입니다.
Q: LL(Low Layer) 드라이버는 어떤가요?
A: LL은 레지스터 제어에 가깝고 빠르지만, 추상화 수준은 낮습니다. LL을 쓰더라도 오늘 설명한 'Wrapper' 개념은 똑같이 적용해야 안전합니다.

여러분의 코드가 하드웨어로부터 자유로워지는 그날까지! 다음 강의에서 또 만나요. 😊


홈으로 이동


다음 이전