STM32 HAL & Project Architecture

Pages List
List view
Home
Portfolio
HW
FW
SW
FPGA / Adaptive SoC
Daily
Photo
Etc
 
STM32 Peripheral

STM32 HAL & Project Architecture


notion image
💡
Embedded Systems Programming on ARM Cortex-M3/M4 Processor by Kiran

STM32 Cube 프로젝트 아키텍쳐의 개요


notion image
HAL layer는 다양한 peripheral들에 대한 APIs를 제공한다.
CMSIS-Core layer는 Processor 내부의 peripheral register에 접근할 수 있는 APIs를 제공한다. (NVIC, SysTick, MPU, SCB)
 
 

HAL driver를 사용하는 경우의 프로젝트 생성 방법


notion image
 
notion image
 
notion image
 
notion image
HAL Layer로 program을 develop할 예정이므로 Project Type은 ‘STM32Cube’로 선택한다.
 
notion image
CMSIS Layer는 ARM이 제공하는데, 다양한 Micro-controller에 Portable한 Application을 개발할 수 있게 도와준다.
 
cmsis_cm0.h : cortex-m0
cmsis_cm3.h : cortex-m3
cmsis_cm4.h : cortex-m4
우리는 STM32F407을 사용하고 있기 때문에, cmsis_cm0, 3, 7은 제거해도 무방하다.
 
다음은 MCU Initialization에서 반드시 수행해야 할 것들과 선택적으로 수행할 것들을 정리한 것이다.
notion image
 
 

STM32 Cube Framework Program Flow


notion image
HAL Layer로 Program을 develop할 때, main 함수에서 가장 먼저 호출하는 함수가 “HAL_Init”이다.
HAL_Init은 Device의 HAL Layer를 Initialization하는 기능을 한다.
 
HAL_Init 함수에 이어서 호출되는 함수는 “SystemClock_Config”함수이다.
이 함수는 MCU의 System Clock을 설정하는 함수인데, User Application에 따라 호출 여부가 결정된다.
요구되는 Clock 속도가 느린 Peripheral들만 사용한다면, 굳이 설정할 필요없이 16MHz의 RC 내부 Clock으로 충분하다.
하지만 USB, Ethernet, SDIO와 같은 빠른 Clock 속도가 요구되는 Peripheral들을 사용한다면,
“SystemClock_Config”함수에서 알맞은 Clock source와 PLL을 설정해야 한다.
 
“SystemClock_Config”함수는 HAL_Layer가 제공하지 않으므로 User가 본인의 ‘main.c’에 작성해야 한다.
 
 

Processor Specific High Level Initialization (by HAL_Init)


notion image
notion image

① Flash Interface Init

Flash Interface를 Initialization하는 부분
 

② SysTick Timer Init

SysTick Timer가 1ms마다 Interrupt를 generation해야 하므로 Initialization한다.
(HAL APIs는 SysTick Timer를 기반으로 동작한다.)
 

③ Other Processor Specific Low level Init

User Application에 따라 Processor의 Low level을 설정해야 하는데, 이와 관련된 내용들이 ‘HAL_MspInit’에 작성된다.
(HAL_MspInit은 User Application layer에 implement되어야 한다.)
 
 

Processor Specific Low Level Initialization (by HAL_MspInit)


< HAL_MspInit >
< HAL_MspInit >
 
< HAL_MspInit >
< HAL_MspInit >
 
HAL_MspInit에서는 완전히 Application specific한 Processor Specific Low Level Initialization을 수행해야 한다.
① 필요한 System Exception을 Enable
② System Exception의 Priority를 Configuring 한다.
③ MPU, FPU 등의 필요한 Processor features를 Enable하고 Configuring 한다.
 
 

Understanding ‘main.c’, ‘msp.c’, ‘it.c’


notion image
notion image
① UART를 사용하기 위해서는 UART Peripheral을 Initialization해야 한다.
Initialization에는 High-level Initialization과 Low Level Initialization의 두 가지가 있다.
 
notion image
② User Application이 High-level Initialization인 Uart_Init 함수를 call하면, Cube layer는 Low-level Initialization을 수행하기 위해 Uart_Msp_Init()을 다시 call한다.
(Uart_Msp_Init은 msp.c에 implementation되어 있다.)
③ User Application은 Uart_transmit_it함수로 UART Peripheral를 사용해, data를 외부로 송신한다.
④ Transmission이 성공적으로 이루어지면, UART Peripheral은 Processor에 Interrupt를 발생시킨다.
그러면, it.c에 User가 작성한 Interrupt Handler가 수행된다.
⑤ Interrupt Handler는 STM32 HAL layer에 있는 Interrupt Processing API를 call하고, UART Interrupt가 발생한 원인을 찾는다.
⑥ Interrupt Processing API는 main.c의 알맞은 Callback 함수를 call한다.
(Transmission complete Callback, Reception complete Callback, Error Callback, etc..)
 
 

Peripheral Handle Structure


notion image
MCU의 Peripheral들을 쉽고 효율적으로 다루기 위해 Handle Structure를 사용한다.
 
< UART Handle Structure >
< UART Handle Structure >
Peripheral 마다 Handle Structure의 member element는 서로 다르지만, 가장 처음의 두 가지는 거의 동일하다.
(Peripheral의 TypeDef, InitTypeDef)
 
notion image
TypeDef는 Peripheral의 Register Base Address를 가리킨다.
InitTypeDef는 Peripheral의 Configurable parameter들을 가진다.
(UART를 예로 들면, Baud rate, data bit의 수, stop bit의 수, parity control, hardware flow control 등)
 
다음 그림은 각 Peripheral들에 대한 Handle Structure이다.
notion image
 
notion image
RCC와 GPIO는 Handle Structure가 굳이 필요 없기 때문에 정의하지 않았다고 한다.
 
notion image
TypeDef Structure는 Device Specific Headerfile에 정의되어 있다.
이 Structure는 어떤 Peripheral의 register detail을 memory map의 순서대로 describe한다.
 
notion image
 
 

Linking Handler Structure and Peripheral


notion image
Peripheral의 Address를 통해서 Handler Structure와 Peripheral을 연결한다.
Peripheral Handler Structure의 TypeDef 포인터에 User가 사용하고자 하는 Peripheral의 Base address를 입력한다.
(즉, Peripheral의 Address를 통해서 Handler Structure와 Peripheral이 연결된다.)
이렇게 Handler Structure가 Peripheral의 Base address를 가지고 있으면, TypeDef 포인터를 de-reference하는 방식으로 Peripheral의 모든 register에 접근할 수 있다.
 
Peripheral의 Address는 다음의 그림처럼 0x4000_0000~0x5000_0000 사이에서 찾으면 된다.
notion image
 
notion image
 
UART4의 Base address를 찾아보자.
notion image
 
notion image
UART4는 APB1에 hanging하고, APB1의 Base address는 0x4000_0000이다.
그리고 UART4의 Address offset은 0x4C00이므로, UART4의 Base address는 ‘0x4000_4C00’이다.
 
notion image
Peripheral의 register의 address는 Peripheral의 Base address에 offset를 더한 값이다.
 
 

STM32 Cube Header File Hierarchy


notion image