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"를 활성화시키기 위해 소스를 작성했다고 볼 수 있다.
구조체를 다시 공부해봅시다.