본문 바로가기
임베디드 관련/STM32

HAL과 LL의 차이

by minhyeok.lee 2025. 6. 23.
반응형

HAL (Hardware Abstraction Layer) vs LL (Low Layer)

1. STM32 개발에서 HAL과 LL은 STM32CubeMX로 코드 생성 시 선택할 수 있는 두 가지 주요 API 스타일
2. 둘의 차이를 아래와 같이 핵심적으로 비교 정리


✅ HAL vs LL 요약 비교표

항목 HAL (Hardware Abstraction Layer) LL (Low Layer)
🧠 레벨 상위 레벨 (고수준 추상화) 하위 레벨 (레지스터 가까움)
🔧 API 성격 간편한 함수 제공, 추상화되어 있음 빠르고 직접적인 레지스터 제어
성능 (속도) 느림 (오버헤드 있음) 빠름 (직접 제어)
🧰 구현 난이도 낮음 (사용 쉬움) 높음 (레지스터 이해 필요)
🛠️ 디버깅 난이도 낮음 (구조 명확) 중간~높음 (직접 상태 추적 필요)
🧩 사용 예시 HAL_GPIO_TogglePin() LL_GPIO_TogglePin() 또는 LL_GPIO_SetOutputPin()
🔄 Interrupt 처리 HAL 내부 ISR 처리 → 콜백 함수 실행 직접 인터럽트 핸들러 작성, 빠른 응답 가능
🚀 성능 요구 상황 일반적인 MCU 제어, 코드 가독성 중시 실시간 제어, 속도/자원 최적화 필요
🔍 CubeMX 지원 완전 지원 (자동 생성) 지원되나 HAL보다 자동화 수준 낮음

✅ 실전 코드 예시 비교

1. GPIO 토글 (ex. LED ON/OFF)

 

HAL 방식

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);

 

LL 방식

LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);

 


2. UART 수신 DMA 시작

 

HAL 방식

HAL_UART_Receive_DMA(&huart2, rx_buf, sizeof(rx_buf));

 

LL 방식

LL_USART_EnableDMAReq_RX(USART2);
LL_DMA_ConfigAddresses(DMA1, LL_DMA_STREAM_5,
    LL_USART_DMA_GetRegAddr(USART2, LL_USART_DMA_REG_DATA_RECEIVE),
    (uint32_t)rx_buf,
    LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_5, sizeof(rx_buf));
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5);

✅ HAL vs LL 선택 기준

상황 권장 API
빠르게 개발, 유지보수 용이성 필요 HAL
실시간 성능 최적화, 메모리 절약, 빠른 응답 LL
저사양 MCU (예: STM32G0, STM32F0)에서 성능 한계 발생 시 LL
프로젝트 규모 크고 팀원이 많을 경우 HAL (가독성/유지보수 우수)
드라이버 커스터마이징, ISR 직접 최적화 LL (또는 LL + 직접 레지스터 접근)

✅ HAL + LL 혼용도 가능

STM32CubeMX에서 기본은 HAL이지만, 성능 민감한 일부 루틴만 LL로 직접 작성할 수 있음

 

// 대부분 HAL 사용
HAL_UART_Transmit(&huart1, msg, strlen(msg), 100);

// but, 속도 필요한 곳만 LL 사용
LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_13);

✅ 정리 결론

목적 추천 방식
개발 속도 HAL
최적화 (속도, 메모리) LL
코드 가독성, 유지보수 HAL
커스터마이즈, ISR 빠른 처리 LL 또는 직접 레지스터 접근
혼용 개발 HAL + LL 조합 (현실적인 최적 전략)
반응형

댓글