SysTick timer

시스템 타이머 SysTick timer에 대해서 알아볼까요?

What is SysTick timer?

SysTick 타이머는 모든 Cortex-M3, M4, M7에 포함된 시스템 타이머입니다. 칩 벤더와 관련이 없는 점에서 코어 페리퍼렐임을 유추할 수 있죠!

SysTick 타이머의 동작은 매우 간단합니다. 24 비트 다운 카운터로 카운터값이 0이 되면 그 다음 클럭에 릴로드 레지스터에 프로그램한 릴로드 값으로 카운터값이 바뀝니다. 또 카운터 값이 1에서 0으로 바뀔 때, SysTick 예외 요청(SysTick exception request)이 발생합니다. 사용자가 예외 핸들러를 프로그램을 작성하면, 이 프로그램은 SysTick 예외 요청이 발생할 때마다 주기적으로 실행됩니다.

How to use

먼저 SysTick 타이머의 레지스터를 한번 살펴보죠!

Table 49. SysTick register map and reset values

설정 비트가 몇 개 안되니 이번에는 모두 확인하고 지나가죠.

STK_CTRL

SysTick control and status register 입니다. 제어용 비트 및 플래그 비트가 1개 있습니다.

Field name Description
COUNTFLAG 카운터값이 1에서 0으로 바뀌는 순간 1로 set 됩니다.
STK_CTRL레지스터를 읽으면 자동으로 클리어됩니다.
CLKSOURCE SysTick 타이머의 클럭 소스를 선택합니다.
STM32F1의 경우 0은 8분주된 프로세서 클럭.
1은 분주가 되지 않은 프로세서 클럭을 클럭소스로 설정합니다.
TICK INT SysTick 타이머 예외 요청 허용 여부를 설정합니다.
0 은 비허용, 1은 허용.
ENABLE SysTick 카운터의 동작 여부를 설정합니다.
0으로 설정시 카운터 정지.
1로 설정시 카운터 동작.

STK_LOAD

SysTick reload value register 입니다. 언더플로우시 릴로드할 값이 저장되는 레지스터입니다.

Field name Description
RELOAD[23:0] 24 비트 릴로드 값

STK_VAL

SysTick current value register 입니다. SysTick 타이머의 현재 카운터값이 저장된 레지스터입니다.

Field name Description
CURRENT[23:0] 24 비트 현재 카운터값

STK_CALIB

SysTick calibration value register 입니다.

Field name Description
NOREF 레퍼런스 클럭의 제공여부를 나타냅니다. 0이 제공.
STM32F1의 경우 0으로 읽히여, 8분주된 프로세서 클럭이 레퍼런스 클럭.
SKEW TENMS 에 저장된 값이 정확하게 1 ms 인지 여부를 나타냅니다.
1 이면 정확하게 1 ms가 아님.
0이면 정확하게 1 ms.
TENMS[23:0] 필드 이름은 Ten Milliseconds의 줄임말인데…
STM32F1의 경우에는 1ms로 주기로 동작할 릴로드 값이 들어있습니다.
(72 MHz 동작 기준, 레퍼런스 사용시 값으로 9000)

SysTick Initialization

SysTick 타이머의 초기화 방법은 다음과 같습니다.

The SysTick counter reload and current value are not initialized by hardware. This means the correct initialization sequence for the SysTick counter is:

  1. Program reload value.
  2. Clear current value.
  3. Program Control and Status register.

e.g., 만약 리셋 후 릴로드 값을 99 로 한다면 타이머를 실행하면?

리셋 후 카운터값은 0입니다.

1 클럭이 지나면, 카운터값 0 → 99

98 클럭이 지나면, 카운터값 99 → 1

1 클럭이 지나면 카운터값 1 → 0. SysTick 예외 요청 발생 :lightning:

따라서, 100 클럭마다 SysTick 예외 요청이 발생하겠네요. 보통 SysTick 예외의 주기는 1 ms 또는 10 ms로 설정합니다.

시스템 클럭이 72 ㎒이고, SysTick 에 입력되는 클럭이 8 분주된 시스템 클럭일 때, 1 ms 주기로 사용하기 위해서는 이와 같이 계산합니다.72 ㎒ ÷ 8×1 ms - 1 = 8999, 릴로드 레지스터의 값을 8999로 프로그램하면 됩니다. 어 TENMS 값이랑 1 차이나네요. 왜일까요? 🤔

SysTick 타이머의 초기화 및 설정은 위의 순서를 지켜서 레지스터를 직접 설정해줘도 되지만, CMSIS-CORE에 설정 함수인 SysTick_Config()가 있으니 이걸 사용하는 것이 편합니다. HAL 라이브러리에도 HAL_SYSTICK_Config()라는 설정 함수가 있는데요. 이건 단순한 래퍼 함수라서 결국 SysTick_Config()를 호출합니다.

참고로 SysTick_Config() 은 입력 인수에서 1을 뺀 값을 릴로드 레지스터에 쓰므로 사용자가 미리 1을 빼줄 필요가 없습니다. 만약 TENMS 값을 사용한다면 바로 SysTick_Config(SysTick->CALIB & SysTick_CALIB_TENMS_Msk); 이렇게 사용하면 되겠습니다.

LAB!

HAL 라이브러리에서 제공하는 HAL_Delay() 라는 함수는 타이머를 이용한 딜레이 함수입니다. 소프트웨어 딜레이에 비해 타이머를 이용한 딜레이에는 장점이 하나 있는데요. 딜레이 함수 실행중에 인터럽트가 걸렸을 때 인터럽트 핸들러에서 소요된 시간에 영향을 받지 않는다는 점입니다. 소프트웨어 딜레이는 인터럽트 핸들러에서 소요된 시간의 합만큼 딜레이에 반영됩니다.

HAL_Delay()는 꼭 SysTick 타이머를 이용할 필요는 없지만, OS가 없는 환경이고, 다른 타이머 페리를 사용한다면 그 타이머에서 제공하는 PWM이나 인풋캡쳐, 펄스 생성등의 기능을 사용하지 못하거나 간섭할 수 있어서 작성하는 코드가 복잡해질 수 있습니다. 때문에 보통 단순한 다운카운터 기능 밖에 없는 SysTick 타이머를 사용합니다.

이번 랩에서는 STM32CubeMX가 제공하는 딜레이 함수 HAL_Delay()를 살펴보죠\~

HAL_Delay()stm32f1xx_hal.c에 정의되어 있어요. 소스 코드를 한번 봅시다.

간단한 코드네요. 현재 tick 값을 tickstart에 저장한뒤, while 문에서 tick 값을 폴링해서 폴링한 tick 값이 tickstart 보다 입력인수 Delay 만큼 커지기 전까지 루프를 돌고 있네요.

while문의 조건 구문 (HAL_GetTick() - tickstart) < Delay를 다르게 쓰면, HAL_GetTick() < (tickstart + Delay) 요렇게 됩니다. tick 값은 현재 시각으로 생각하면 이해가 쉬워요. 다시 바꿔쓰면 위 조건 구문은 현재 시각 < (지연 시작 시각 + 지연 시간)이 되고, 지연시작 시각 + 지연 시간 은 결국 탈출 시각이 되므로 현재 시간 < 탈출 시간 과 같은 이야기가 되죠.

E.g., 현재 시각이 오후 11시일 때, 7시간을 잔다면 기상 시각은 오전 6시가 된다.

현재 시각이 오후 11시(지연시작 시각), 7시간을 잔다(지연시간), 기상 시각은 오전 6시(탈출 시각).

HAL_Delay() 함수에서 현재 tick 값을 HAL_GetTick() 을 통해 얻는데요. HAL_GetTick()은 단순히 uwTick라는 전역 변수를 리턴합니다.

그리고 uwTickHAL_IncTick() 라는 함수에 의해 1씩 증가 됩니다.

다시, HAL_IncTick() 는 예외 핸들러인 SysTick_Handler()에서 호출하고 있네요.

마지막으로 SysTick_Handler() 는 SysTick 타이머 하드웨어에 의해서 1ms 마다 한번씩 호출됩니다. 결국 1ms마다 uwTick가 1씩 증가하는 것이죠.

앞에서 본 함수들의 호출 그래프를 그려보면 다음과 같습니다.

HAL_Delay()

References

ARM, Cortex-M3 Devices Generic User Guide

ARM, AN179

ST, PM0056: STM32F10xxx/20xxx/21xxx/L1xxxx Cortex-M3 programming manual

ST, UM1850, Description of STM32F1xx HAL drivers

Leave a Reply

Your email address will not be published. Required fields are marked *