Computer Science
탄탄한 기반 실력을 위한
전공과 이론 지식 모음
Today I Learned!
배웠으면 기록을 해야지
TIL 사진
Flutter 사진
Flutter로 모바일까지
거꾸로캠퍼스 코딩랩 Flutter 앱개발 강사
스파르타코딩클럽 즉문즉답 튜터
카카오테크캠퍼스 3기 학습코치
프로필 사진
박성민
임베디드 세계에
발을 들인 박치기 공룡
임베디드 사진
EMBEDDED SYSTEM
임베디드 SW와 HW, 이론부터 실전까지
ALGORITHM
알고리즘 해결 전략 기록
🎓
중앙대학교 소프트웨어학부
텔레칩스 차량용 임베디드 스쿨 3기
애플 개발자 아카데미 1기
깃허브 사진
GitHub
프로젝트 모아보기
Instagram
인스타그램 사진

Embedded System/MCU

[STM32] HAL 드라이버란?

sm_amoled 2025. 10. 19. 20:07

이번에 STM32 개발 실습을 진행하면서 계속해서 HAL 이라는 키워드가 나왔다. 약간 namespace 같은건가? 싶었는데, 이게 라이브러리였다. 코드 작성하면서 눈치껏 이해했더니 이게 직접 레지스터를 건드리는 작업들이 복잡하고 실수가 많이 나올 수 있으니, 이 구조를 미리 묶어서 함수로 제공하는 형태인 것 같았다. 그래서 HAL 라이브러리가 무엇인지, 그래서 HAL을 써야하는지 말아야 하는지에 대해서 한 번 정리해보려고 한다.

 

HAL이 뭐냐면

<< HAL User Manual 공식 DOCS로부터 발췌 >>

The HAL drivers are designed to offer a rich set of APIs and to interact easily with the application upper layers. Each driver consists of a set of functions covering the most common peripheral features. The development of each driver is driven by a common API which standardizes the driver structure, the functions and the parameter names. The HAL drivers include a set of driver modules, each module being linked to a standalone peripheral. However, in some cases, the module is linked to a peripheral functional mode. As an example, several modules exist for the USART peripheral: UART driver module, USART driver module, SMARTCARD driver module and IRDA drive module.

 

HAL은 Hardware Abstraction Layer, 하드웨어 레지스터를 직접 제어하는 드라이버 코드로, 개발자가 작성하는 코드가 HW를 쉽게 제어할 수 있도록 풍부한 API를 제공해둔 것이다. HAL 드라이버는 여러 주변 장치에 대한 개별적인 모듈들로 구성되고 있으며, 각 모듈은 함수명, 파라미터명 등을 표준에 따라 작성해두어 개발 시 쉽게 활용할 수 있다.

 

레지스터를 조금 더 직접 제어하는 방식인 Low Layer 방식 (이하 LL)도 있다.

 

드라이버?

사실 나는 드라이버라는 단어도 잘 모르고 있었다. 막상 뭐냐고 말하라고 하니 못하겠더라.

 

드라이버는 HW와 SW를 연결하는 중간 계층의 코드이다. 드라이버의 함수 또는 API를 호출했을 때 레지스터에 대한 RW 작업을 대신 수행해준다면 이건 드라이버라고 볼 수 있다. HAL을 사용할 때 HAL_GPIO_WritePin 같은 코드들이 내 대신 Memory 상 GPIO의 특정 위치에 bit set 하는 작업을 해주는데, 이게 드라이버의 역할이라고 보면 된다.

 

HAL을 사용했을 때의 장점

우선 ‘Abstraction’ 이라는 이름에서부터 써야 할 것 같은 느낌이 팍팍 든다 ㅋㅋㅋ. 공식문서에 작성되어 있는 장점들을 한 번 살펴보자.

  • 공통 Peripheral의 API가 동일하기 때문에, 코드를 한 번 작성하면 다른 STM32 시리즈의 보드에서도 동작할 수 있다.
    • 낮은 성능의 CPU가 붙은 보드로 개발하다가 문제가 생겼을 때 더 좋은 성능의 보드로 옮겨서 그대로 이어 개발할 수 있음.
  • 3가지 API의 프로그래밍 모델을 제공한다.
    • Polling : 작업 완료할 때까지 CPU가 대기
    • Interrupt : 특정한 이벤트가 발생하면 HW가 CPU에게 알림
    • DMA : CPU의 개입 없이 HW가 메모리 전송을 수행
  • RTOS 호환
    • Reentrance API 지원 →
  • 동일한 Peripheral이 여러개 있어도 괜찮음 (USART1, USART2, … 서로 간섭 X)
  • 모든 HAL API에서 사용자 정의 함수를 호출할 수 있다.
  • 공유자원에 대한 보호 매커니즘 지원 (세마포어 같은 거인듯 → 통신 중에 다른 Peripheral의 간섭 방지)
  • 타임아웃 설정을 통해 무한루프에 빠지는 것 방지 가능

 

그래서 HAL을 써야하나?

에 대해서는 여전히 많은 갑론을박이 있는 것 같다.

HAL을 쓰면 안된다.

  • 여전히 버그가 있다.
  • HAL을 쓰면 성능이 별로다 (느리다)
  • 내부 동작을 이미 이해하고 있으면 굳이 HAL을 써야하나?
  • HAL 자체가 어떻게 동작하고 있는지를 추가로 공부해야한다. (버그가 아니라 기능이예요)
  • 내부 구현이 좀 더럽고 불필요한게 많다. (그래서 HAL에 몇 줄 주석처리해도 동작함)
  • HW의 동작방식을 알지 못한다면 형편없는 개발자이다.

HAL을 써야한다.

  • 사람들은 내가 직접 작성한 코드보다 HAL 을 신뢰한다.
  • 다음 사람이 유지보수 할 것도 생각해야 한다.
  • 단순히 GPIO 정도 할거면 Register 건드리는걸로 개발해도 되는데, ETHERNET이나 File System으로 가면 복잡성이 너무 증가한다.
  • 코드를 작성해서 돈을 받는게 아니라, 문제를 해결해서 돈을 받는거다. 비즈니스 로직에 집중할 수 있는 HAL을 사용하는게 좋다.
  • 그렇다면 OS나 컴파일러는 왜 직접 만들어서 안쓰냐? 남들이 잘 만들어둔 것을 활용할 줄 아는 것이 부적절한게 아니다.

 

몇 가지 추가적인 인사이트

  • SPI 기능의 경우에는 HAL 의 코드 부피가 커서 LL 방식을 사용하는게 더 효율적이다.
  • 둘 다 할 줄 알아야 하는건 맞음 (HAL에서 문제 발생했을 때 원인을 찾고 해결할 줄 알아야 하니깐)
  • HAL 같은 드라이버는 프로세서를 위한 제품이지, 프로젝트를 위한 제품이 아니다.
  • LL 드라이버를 사용하는 곳도 종종 있다.
  • 최적화가 필요할 때에는 레지스터로 구현이 필요하다.
  • 의존성을 한 번 더 꺾어서 [ HAL → 프로젝트 자체 HAL → 프로젝트 코드 ] 으로 자체 HAL을 추가하는 곳도 있다.
  • 필요한 부분에만 HAL 쓰면 되는거 아니냐?

 

공부하는 사람은 HAL을 써야하나?

라는 주제의 레딧 글도 있었다. https://www.reddit.com/r/embedded/comments/113geyh/make_an_argument_for_whether_a_beginner_should_or/?tl=ko

  • 초보자는 둘 다 해야한다.
    • HAL을 활용한 추상화와 코드 재사용에 대해서도 연습해야한다.
    • 직접 레지스터를 제어하는 방식에 대해서도 연습해야한다.
  • 그렇다면 레지스터를 사용하는 방법을 배우기 전에 추상화를 먼저 배워도 돼냐?
    • 결과물을 만들어내면서 HW 까지 점차 내려가는게 더 좋다. (Top Down)
    • 레지스터부터 다루면서 추상화 단계로 올라오는게 더 좋다. (Bottom Up)

 

그렇다면 나는 어떻게 할 것인가?

우선 HAL 없이 코드를 작성해보자.

  • 데이터시트를 보고 레지스터를 조작하면서 코드를 작성할 줄 알아야 한다.
  • 결국 나는 내부가 어떻게 동작하는지 알아야 한다.
  • 90%는 HAL을 쓰고 10%만 직접 구현하게 된다는데, 이게 90%는 이미 어떻게 구현할 지 다 알고있고 10%는 최적화를 위해 구현 방법 + 개선 방법도 알고있어야 한다는 의미로 이해된다.

(혹시 다음에는 LL 드라이버를 활용하는 방법도 한 번 시도를 해봐야할까? 시간이 남는다면 요건 고려해봐야겠다.)

 

 

참고 문서

HAL 공식 유저 매뉴얼

https://www.st.com/resource/en/user_manual/um1725-description-of-stm32f4-hal-and-lowlayer-drivers-stmicroelectronics.pdf

 

320x100