본문 바로가기
임베디드SW/TC275 Lite Kit for 임베디드

스케쥴러 구현하는 방법 - 인터럽트 1ms ISR 사용

by 바이너리 임베디드 2021. 12. 1.

스케쥴러 구현하는 방법

 

현재 TC275 Lite Kit를 사용하여 MCU를 배우는 프로젝트를 진행중에 있으며,

지난편에서는 CCU6 페리페럴을 통해서 1ms ISR을 만드는 이론편이었습니다.

이번 편에서는 직접 1ms ISR을 구현해보고 스케쥴러까지 구현해보는 시간을 가져 보겠습니다.

최종적으로는 스케쥴러에서 1s마다 LED를 깜박 깜빡 동작 시켜보도록 하겠습니다.

 

그럼 지난 글을 아직 보시지 못한 분은 꼭 보고 오시기 바랍니다.

이론편을 알아야 구현이 수월하겠죠?? 아래 링크 달아드리겠습니다.

 

https://cookbook.tistory.com/24

 

인터럽트 1ms ISR 만드는 방법 (MCU TC275 CCU6 모듈)

저번 편에서는 TC275 시스템 클럭을 iLLD를 통해 설정했습니다. 이전 글을 보시지 못한 분은 먼저 이전 글을 이해하시고 오셔야 합니다. https://cookbook.tistory.com/19 인피니언 MCU TC275 iLLD 라이브..

cookbook.tistory.com

 

프로젝트는 어디까지 진행했을까요?

 

아하! Blinking LED iLLD를 우리 프로젝트에 포팅하여 LED를 깜박였었죠?
그리고 이놈의 LED가 1초마다 깜박이지 않아 여기까지 오게 된거였구요.

 

그럼 여기서부터 구현을 시작해보죠.



스케쥴러를 통해 1초마다 깜박일 LED 핀 초기화



Blinky_LED.c 파일과 Blinky_LED.h 파일을 삭제하고 대신에 TC275의 GPIO Pin을 우리가 알아보기 쉽게 초기화해줄수 있는 파일을 만들어보도록 하시죠.

 

스케쥴러 구현하는 방법



우선 제어할 LED에 대한 정보를 찾아봅시다.
이번에는 Lite Kit 레퍼런스 매뉴얼 문서에 있네요.

스케쥴러 구현하는 방법



제가 Control 해볼수 있는 LED는 3개가 있네요. 
그 중 LED1과 LED2를 제어해보도록 하죠. 핀은 P00.5, P00.6을 초기화 해주어야 겠네요.
그리고 동작은 Low-active 라고 하는 것을 보니 Pin 출력을 Low로 해줄시 불이 들어오나 봅니다.

그럼 핀 P00.5 , P00.6은 아래와 같이 Output Mode에 출력의 강도는 speed4로 했습니다.

스케쥴러 구현하는 방법



초기화 이후 Pin 출력을 Low로 해주었습니다. 

LED가 녹색불이 잘 켜져 있네요. 

스케쥴러 구현하는 방법

그럼 스케쥴러를 통해 1초마다 깜박일 LED PIN 초기화는 잘 된것 같습니다.


스케쥴러를 구현을 위한 1ms ISR을 만들어 보자!


지난 편 "인피니언 MCU TC275 iLLD 라이브러리를 포팅하는 방법"에서 iLLD example 코드 중 CCU6_Interrupt_1_KIT_TC275_LK를 참고해서 만들어 보도록 하죠.

우리가 필요로 하는 부분은 CCU6 모듈을 iLLD를 통해 초기화 해주는 부분입니다.
그내용이 initCCU6 함수에 있으며 아래와 같이 찾아가면 됩니다.

CCU6_Interrupt_1_KIT_TC275_LK 폴더 -> CCU6_Interrupt.c 파일 -> initCCU6 함수


스케쥴러 구현하는 방법

 

 

 

스케쥴러 구현하는 방법

 

 

 

스케쥴러 구현하는 방법



initCCU6 함수를 참고하여 우리가 만들고자 하는 1ms ISR을 만들어 보도록합시다.


IfxCcu6_Timer_Config timerConfig;

timerConfig이름을 가진 구조체를 선언합니다. 
이 구조체는 CCU6 모듈을 초기화 하기위한 값들을 셋팅하기 위한 구조체라고 보시면 됩니다.

IfxCcu6_Timer_initModuleConfig(&timerConfig, &MODULE_CCU60);

CCU6에는 0번 1번 2번 Channel을 갖고 있습니다.
CCU6에 0번 채널을 timerConfig라는 구조체에 Default 값으로 셋팅해주는 함수입니다.

timerConfig.base.t12Frequency = 6250000u;

ft12의 클럭 주파수를 6.25MHz로 설정해줍니다. 쉽게 풀어서 1초당 6,250,000번의 클럭이 발생합니다.

timerConfig.base.t12Period = 6250u;

Period Register의 값을 6250으로 설정해줍니다.
그러면 ft12가 1s당 6,250,000번 클럭이 발생하므로 1ms 동안에는 6250번 클럭이 발생하게 됩니다.
따라서 Period Register의 값과 Match가 되는 시간은 1ms마다입니다.

timerConfig.timer = IfxCcu6_TimerId_t12;

T12모듈의 timer를 사용하겠다는 셋팅입니다.

timerConfig.interrupt1.source = IfxCcu6_InterruptSource_t12PeriodMatch;

인터럽트 리퀘스트 소스를 설정해주는 부분이며 Period Match가 발생시 인터럽트 리퀘스트를 할수 있습니다.

timerConfig.interrupt1.serviceRequest = IfxCcu6_ServiceRequest_0;

CCU6 모듈의 인터럽트 리퀘스트를 연결해주는 통로를 셋팅해 준다고 보시면 되고 0~3번까지중 하나라를 선택하시면 됩니다. 현재는 0번으로 셋팅했습니다.    

timerConfig.interrupt1.priority = ISR_PRIORITY_CCU60_T12_TIMER; 

인터럽트의 우선순위를 결정해줍니다. 인터럽트 간의 실행 순서를 따질때 필요한 부분이나 현재 우리는 인터럽트를 하나 사용하고 있으니 어떤것으로 해주어도 상관 없습니다.

timerConfig.interrupt1.typeOfService = IfxSrc_Tos_cpu0;                     

인터럽트를 어떤 코어에서 명령을 내릴것인가를 정해주는 것입니다. 저희는 현재 코어 0만 사용하므로 코어 0으로 설정해주었습니다.

bsp_isr_RegisterHandler(UC_CORE_MAIN_0, (BspIsrHandler)Isr_Ccu60T12, ISR_PRIORITY_CCU60_T12_TIMER);

이 부분은 ISR 함수를 등록해주는 부분이라고 생각하시면 됩니다.
Isr_Ccu60T12가 인터럽트 서비스 루틴의 함수명이 됩니다.

timerConfig.trigger.t13InSyncWithT12 = FALSE;

Timer13을 Timer12에 맞추어 Sync를 맞출지에 대한 셋팅인데, 현재 우리는 T12만 사용하므로 False로 설정하겠습니다.

IfxCcu6_Timer_initModule(&g_timer, &timerConfig);

지금까지 timerConfig구조체에 우리가 원하는 값으로 설정하여 초기화를 다시 진행합니다.

IfxCcu6_Timer_start(&g_timer);

그리고 CCU60을 스타트합니다.

 

 

스케쥴러 구현하는 방법

 

 



이와 같이 설정해주면 ISR은 Period Match가 1ms 마다  수행되게됩니다.


1ms ISR로 스케쥴러를 만들어 보자!

 

그럼 Main함수의 무한루프와 1ms ISR을 통해 10ms Task와 1000ms Task를 간단하게 구현한 스케쥴러 코드를 보여 드리도록 하겠습니다.

스케쥴러 구현하는 방법



1ms ISR에서 1ms 마다 1씩 증가하는 카운터 변수를 이용하여 원하는 시간에 맞추어 Flag가 Set이 되도록 설정합니다.
무한루프문에서 Scheduler를 수행하고 지속적으로 수행하게 합니다.
그리고 Scheduler 안에서 조건문으로 Flag가 Set이되면 Task를 수행하게 하여 구현합니다.
다양한 Task를 만들고 싶을때는 ISR에서 다양한 Flag를 만들어 주면 됩니다.

스케쥴러 구현하는 방법


이것은 500ms Task를 구현한 함수이며 LED1과 LED2를 번갈아 가며 500ms 후 On 500ms 후 Off로 동작시킨 예제 코드입니다.

와우! 드디어 LED를 내가 원하는 시간에 맞추어 정확하게 동작시키는 것을 구현해보았습니다.
LED 하나를 깜박이기 위해서 많은 시간을 들였네요.
그래도 중요한 건 정말 많은 것을 배워왔습니다.

보드를 구입하고, 환경을 셋팅하고, iLLD 라이브러리를 포팅하고, CCU6 페리페럴을 이해하고, 스케쥴러의 기본개념을 구현해야 LED를 제어할수 있는 것입니다.

여기 까지 아는것도 절대 쉬운일이 아닙니다.
정말 잘하셨다고 칭찬드리고 싶습니다^^


여기까지 진행하시면서 생기는 모든 질문과 답변은 아래 카페에서 해드립니다.

많이 많이 방문하셔서 실력을 업그레이드 하세요.

 

https://cafe.naver.com/binaryembedded



댓글