해당 포스팅은 개인적으로 MCU를 공부하면서 익힌 내용을 기억에 남기기 위한 작업의 일환으로 작성된 글로서
일부 내용에 오류가 있을 수도 있으니 참고하시기 바랍니다.
MCU에서의
중요한 구성요소 중에 하나인
Vector Table에 대하여
어떤 역할을 하는지
알아보자.
내용 요약
Renesas RX66T 마이크로컨트롤러(MCU)는 고성능의 32비트 마이크로컨트롤러로,
주로 산업용 제어 시스템, 로봇, 가전제품 등에서 사용된다.
이 MCU는 다양한 기능과 고속 연산 능력을 제공하며,
특히 모터 제어와 같은 실시간 응용 프로그램에 적합하다.
RX66T의 중요한 구성 요소 중 하나는 벡터 테이블(Vector Table)인데,
이 벡터 테이블은 인터럽트와 예외 처리를 관리하는 데 중요한 역할을 한다.
Vector와 Table의 의미
"벡터 테이블"이라는 이름은 주로 컴퓨터 과학과 전자공학에서 사용되는 용어로,
특정 이벤트나 조건에 따라 실행할 코드의 주소를 저장하는
데이터 구조를 의미합니다.
이 용어는 다음과 같은 이유로 사용됩니다
1. 벡터(Vector)의 의미
"벡터"라는 단어는 여러 가지 의미를 가질 수 있지만, 컴퓨터 과학에서 벡터는 주로 방향과 크기를 가진 수학적 개념에서 유래한 용어로, 특정 방향으로의 이동이나 참조를 나타낸다. 벡터 테이블에서 "벡터"는 특정 이벤트(예: 인터럽트나 예외)가 발생했을 때 참조할 주소를 가리키는 포인터를 의미한다. 즉, 벡터는 특정 이벤트가 발생했을 때 실행할 코드의 시작 주소를 가리키는 역할을 한다.
2. 테이블(Table)의 의미
"테이블"은 데이터를 구조화하여 저장하는 방식 중 하나로, 행과 열로 구성된 데이터 집합을 의미한다. 벡터 테이블은 여러 개의 벡터(주소)를 행렬 형태로 정리한 데이터 구조로, 각 벡터는 특정 이벤트에 대응하는 주소를 저장한다. 이 테이블은 메모리 내의 고정된 위치에 저장되며, 각 엔트리는 특정 이벤트에 대응하는 ISR(Interrupt Service Routine) 또는 예외 처리 루틴의 주소를 포함한다.
Vector Table의 정의
RX66T의 내부에는 2가지 타입의 Vector Table이 있다.
하나는 Exception Vector Table이고,
다른 하나는 Interrupt Vector Table로서 아래와 같다.
벡터 테이블은 MCU의 메모리 내에 위치한 데이터 구조로,
각각의 Vector는 4bytes로 구성되어있으며,
각 인터럽트와 예외에 대한 시작 주소를 저장하고 있다.
이 테이블은 인터럽트가 발생했을 때
해당 인터럽트 서비스 루틴(ISR, Interrupt Service Routine)으로
MCU가 점프할 수 있도록 한다.
벡터 테이블은 일반적으로 고정된 메모리 주소에 위치하며,
각 엔트리는 특정 인터럽트 또는 예외에 대응하는 ISR의 주소를 포함한다.
Vector Table의 내부 구성
Vector Table의 구성
1.리셋 벡터(Reset Vector)
MCU가 리셋될 때 실행을 시작할 주소를 포함합니다. 이 주소는 보통 초기화 코드의 시작 주소입니다.
2.예외 벡터(Exception Vectors)
CPU 예외(예: 불법 명령어 실행, 디버그 이벤트 등)에 대한 ISR 주소를 포함합니다.
3.인터럽트 벡터(Interrupt Vectors)
외부 및 내부 인터럽트 소스에 대한 ISR 주소를 포함합니다.
벡터 테이블의 역할
벡터 테이블의 주요 역할은 다음과 같습니다:
1.인터럽트 처리
인터럽트가 발생하면, MCU는 현재 실행 중인 작업을 중단하고
벡터 테이블을 참조하여 해당 인터럽트에 대한 ISR로 점프한다.
ISR이 실행된 후, MCU는 원래 작업으로 복귀한다.
2.예외 처리
예외가 발생하면, 벡터 테이블을 참조하여
해당 예외에 대한 처리 루틴으로 점프한다.
예외 처리 루틴은 시스템 상태를 점검하고,
필요한 경우 시스템을 복구하거나 재시작한다.
3.시스템 초기화
리셋 벡터는 시스템이 리셋될 때 실행을 시작할 주소를 제공하여,
초기화 코드가 실행되도록 한다.
예제
다음은 RX66T에서 벡터 테이블을 설정하고 사용하는 예제이다.
이 예제는 간단한 타이머 인터럽트를 설정하고,
인터럽트가 발생했을 때 LED를 토글하는 코드이다.
#include <stdint.h>
#include "iodefine.h"
// 인터럽트 서비스 루틴 선언
void Timer_ISR(void);
// 벡터 테이블 설정
__attribute__((section(".vectors"))) void (* const VectorTable[])(void) = {
(void (*)(void))0xFFFFFFFF, // 초기 스택 포인터
Reset_Handler, // 리셋 벡터
NMI_Handler, // NMI 벡터
HardFault_Handler, // 하드 폴트 벡터
// ... (다른 예외 벡터)
Timer_ISR, // 타이머 인터럽트 벡터
// ... (다른 인터럽트 벡터)
};
// 타이머 인터럽트 서비스 루틴
void Timer_ISR(void) {
// 인터럽트 플래그 클리어
CMT0.CMCSR.BIT.CMF = 0;
// LED 토글
PORTA.PODR.BIT.B0 ^= 1;
}
// 메인 함수
int main(void) {
// 시스템 초기화 코드
SystemInit();
// LED 포트 설정
PORTA.PDR.BIT.B0 = 1; // 출력 설정
// 타이머 설정
MSTP(CMT0) = 0; // 타이머 모듈 활성화
CMT0.CMCR.BIT.CKS = 0; // 분주비 설정
CMT0.CMCOR = 31250; // 비교 매치 값 설정
CMT0.CMCSR.BIT.CMIE = 1; // 인터럽트 활성화
IEN(CMT0, CMI0) = 1; // 인터럽트 허용
IR(CMT0, CMI0) = 0; // 인터럽트 플래그 클리어
CMT.CMSTR0.BIT.STR0 = 1; // 타이머 시작
// 메인 루프
while (1) {
// 메인 작업 수행
}
return 0;
}
벡터 테이블 설정
__attribute__((section(".vectors")))를 사용하여
벡터 테이블을 특정 메모리 섹션에 배치한다.
이 테이블은 리셋 벡터, NMI 벡터, 하드 폴트 벡터 등과 함께
타이머 인터럽트 벡터를 포함한다.
인터럽트 서비스 루틴
Timer_ISR 함수는 타이머 인터럽트가 발생했을 때 호출된다.
이 함수는 인터럽트 플래그를 클리어하고, LED를 토글한다.
메인 함수
시스템 초기화 후, LED 포트를 출력으로 설정하고,
타이머를 설정하여 인터럽트를 활성화한다. 메인 루프에서는 주 작업을 수행한다.
결론
벡터 테이블은 RX66T MCU에서 인터럽트와 예외 처리를 관리하는
중요한 데이터 구조이다.
벡터 테이블을 통해 각 인터럽트와 예외에 대한 ISR 주소를 저장하고,
인터럽트가 발생했을 때 해당 ISR로 점프할 수 있도록 한다.
이를 통해 실시간 응용 프로그램에서 신속하고 효율적인 인터럽트 처리가 가능하다.
'프로그래밍 > MCU' 카테고리의 다른 글
MCU 프로그래밍에서 알아두면 좋은 Doxygen 주석 블록(brief, param, retval, 등)에 대하여... (0) | 2024.11.19 |
---|---|
MCU에서 General-purpose Register에 대하여 (2) | 2024.11.16 |