본문 바로가기
임베디드 개발/STM32 (ARM Cortex-M)

STM32 ] HAL_GetTick() 오버플로우에 대한 의문

by eteo 2022. 12. 2.

 

Non Blocking 코드를 작성할 때 아래와 같은 구문을 많이 작성한다. 100ms 간격으로 무언가 실행하는 코드이다.

 

 

이때 의문이 들 수 있다. 오버플로우가되면 어떡하지, 그래도 100ms 간격으로 실행될까?

uint32_t start_tick= HAL_GetTick();

while (1)
{
    if (HAL_GetTick() - start_tick >= 100)
    {
        start_tick = HAL_GetTick();
        // do something
    }
}

 

 

결론은 그렇다이다.

 

다음의 쉬운 예제를 보자.

start_tick(b)이 255이고 current_tick(a)이 오버플로우가 되서 0이 되었다면 차이(c)는 1이어야 맞을 것이다.

 

uint8_t a, b, c;
a = 0;
b = 255;
c = a - b;

 

 

그리고 실제로 c는 1이 나온다.

 

 

컴퓨터는 뺄셈을 2의 보수를 사용한 덧셈으로 처리하므로, c = a + (-b) 와 같고, - 붙은 b는 2의 보수를 취한다.
255를 2의 보수 취해서 비트 반전 후 +1하면, 00000000 + 1 이고, 0+(1)하여 c 는 1이 된다.

 

단, 이게 성립하는 조건은 두 변수가 unsigned 타입의 같은 자료형일 때, 그리고 자료형의 값을 맥시멈까지 쓸 때 성립된다.

 

 

 

 

 

예를 들어, 0에서 9까지 증가했다가 다시 0으로 돌아가는 경우라면 다른 처리가 필요하다.

uint8_t a, b, c;
uint8_t len = 10;

a = 0;
b = 9;
c = ((a+len) - b) % len;


FIFO 버퍼 인덱스 계산할 때 이런방식을 많이 쓴다.

 

 

 

내용 출처 : 유튜브 Baram https://www.youtube.com/watch?v=29bsTyLpKcE&list=PLvFHFPM09alIlp3x4ea_6yG-Di2cTCZ4G