HAL_Init(); 분석해보기

김지성·2022년 7월 3일
1

Embedded

목록 보기
2/19
HAL_StatusTypeDef HAL_Init(void)
{
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
    defined(STM32F102x6) || defined(STM32F102xB) || \
    defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
    defined(STM32F105xC) || defined(STM32F107xC)
    
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif
#endif /* PREFETCH_ENABLE */

위 코드는 main.c의 HAL_Init();을 따라가보면 나오는 코드이다.

#if (PREFETCH_ENABLE != 0)

A != B는 A와 B가 서로 다를 경우 "TRUE"가 되고, 서로 같은 경우 "FALSE"가 된다.
PREFETCH_ENABLE은 "1U"로 define되어 있기 때문에 if문에서 항상 참이 나올 것이다.

if문을 통과하고 또 다시 if문을 만나게 되는데 나는 "defined(STM32F103xB)"를 만족하기 때문에 "__HAL_FLASH_PREFETCH_BUFFER_ENABLE();" 를 수행하게 된다.



"__HAL_FLASH_PREFETCH_BUFFER_ENABLE();"를 따라가보면 #define된걸 확인할 수 있다.

#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE()	(FLASH->ACR |= FLASH_ACR_PRFTBE)
  • (FLASH->ACR |= FLASH_ACR_PRFTBE)를 해석해보자.

1) FLASH->ACR = (pointer)(0x40022000)
// FLASH->ACR = (*FLASH).ACR
2) FLASH_ACR_PRFTBE = 16
// FLASH_ACR_PRTFBE를 따라가보면 "1<<4"가 나온다.
3) FLASH->ACR |= FLASH_ACR_PRFTBE는 (pointer)(0x40022000) |= 16과 같다.
// (pointer)(0x40022000)가 가르키는 값은 48이다.
// 즉 48 |= 16이다.


FLASH를 따라가보면 #define된걸 확인할 수 있다.

  • #define FLASH ((FLASH_TypeDef *)FLASH_R_BASE)

FLASH_TypeDef를 따라가보면 아래와 같은 코드가 나온다. typedef 예약어를 이용하여 FLASH_TypeDef라고 재선언해준 것이다.

typedef struct
{
__IO uint32_t ACR;			//0x40022000
__IO uint32_t KEYR;			//0x40022004
__IO uint32_t OPTKEYR;		//0x40022008
__IO uint32_t SR;			//0x400220012
__IO uint32_t CR;			//0x400220016
__IO uint32_t AR;			//0x400220020
__IO uint32_t RESERVED;		//0x400220024
__IO uint32_t OBR;			//0x400220028
__IO uint32_t WRPR;			//0x400220032
} FLASH_TypeDef;

FLASH_TypeDef의 구조체를 어떻게 해석할 수 있을까?
FLASH가 가지고 있는 주소값은 0x40022000이다. 구조체는 배열과도 같기 때문에 uint32_t(4byte)만큼 증가하는걸 확인할 수 있다. (*FLASH)에서 4byte씩 증가하게 된다면 16진수로써 표현할 수 있는게 제한이 있다. 16진수를 10진수로 변환시키면 구조체에 적혀있는 변수 그대로 사용이 가능하다.(12=C, 28=1C...)


#define __IO volatile

그렇다면 위의 소스가 뜻하는 의미는 무엇일까?

volatile은 "최적화 취소 + CPU 레지스터 사용 X"으로 무조건 번지수에 넣어서 사용하라는 뜻이다.


Q : FLASH_ACR의 데이터 시트를 찾아보고 뭘 의미하는지 알아볼까?
A :


현재 우리가 해석한 소스는 "(FLASH->ACR |= FLASH_ACR_PRFTBE)"이다.
" *(0x40022000) |= 16" 즉 "48 |= 16"이므로 FLASH_ACR레지스터에 1<<4(=16)를 한걸 알 수 있다. 결국은 "Prefetch"를 활성화시키기 위해 소스를 작성했다고 볼 수 있다.

구조체를 다시 공부해봅시다.

profile
JUST DO IT

0개의 댓글