인프런 커뮤니티 질문&답변

chucky2님의 프로필 이미지
chucky2

작성한 질문수

FreeRTOS 프로그래밍

DFI-마무리

[질문/해결완료] deferred interrupt 처리에서 portYIELD_FROM_ISR api의 용도

해결된 질문

작성

·

995

1

deferred interrupt 예제에서, gpio callback 함수내부에 사용된 "portYIELD_FROM_ISR" 함수의 목적을 설명해주세요. 해당 line을 주석 처리하고 수행해도 정상동작합니다.

gpio callback 함수를 수행한 후, gpio isr의 나머지 부분을 수행한 다음 scheduler에 의해서 ulTaskNotifyTake로 다음 수행작업을 기다리던 task1이 수행되는 것으로 보이는데,

portYIELD_FROM_ISR를 사용하면 gpio callback에서 scheduling이 발생하여 바로 (gpio isr 나머지 부분 수행 없이) task1이 수행되는 구조일까요?

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	static portBASE_TYPE xHigherPriorityTaskWoken;

#ifdef FREERTOS_MODULE_TEST
//	vLogicSniffMultiSetLED5(LS_CHANNEL_ALL5, 0); // All Leds Clear
//	vLogicSniffMultiSetLED6(LS_CHANNEL_ALL6, 0); // All Leds Clear
	vLogicSniffSetLED( LS_CHANNEL_7, 1 ); // LED 'ON'
#endif

	//printf("o"); fflush(stdout);
	buttoncounter++;

/* xHigherPriorityTaskWoken은 pdFALSE로 초기화되어야한다 */
	xHigherPriorityTaskWoken = pdFALSE;

#if __MY_ENABLE_DEFERRED_INTERRUPT == 0
	// 시간이 많이 소요되는 함수를 호출
	heavyCopyLoader();
#endif //__MY_ENABLE_DEFERRED_INTERRUPT

	// Semaphore를 'Give' 하여 Blocked Task를 Unblock 상태가 되게 한다.
	vTaskNotifyGiveFromISR(xHandle1, &xHigherPriorityTaskWoken);
	//portYIELD_FROM_ISR(&xHigherPriorityTaskWoken);
}

답변 2

0

chucky2님의 프로필 이미지
chucky2
질문자

답변 감사합니다. 확인차원에서 재 문의 드립니다.

case1: call back에서 portYIELD_FROM_ISR 호출시

  1. isr 진입

  2. isr 내부에서 call back 함수 호출

  3. call back 함수에서 portYIELD_FROM_ISR 호출 (최종 portYIELD 호출되어 portNVIC_INT_CTRL_REG register의 PendSV bit set)

  4. isr 중 call back 이후 부분 수행

  5. isr 완료

  6. xPortPendSVHandler에 의해 context switching 발생

case2: call back에서 portYIELD_FROM_ISR 미호출시

  1. isr 진입

  2. isr 내부에서 call back 함수 호출

  3. call back 함수 수행

  4. isr 중 call back 이후 부분 수행

  5. isr 완료

  6. 선점 당했던 task로 복귀

  7. xPortSysTickHandler에 의해 context switching 발생

 

결국,

Case1은 Case2에서 발생하는 지연 시간 (task로 재 복귀 후, 다음 tick interrupt가 발생하기 까지 시간) 이 발생하지 않는 것으로 이해했습니다. 잘 못 생각하고 있는 부분이 있으면 정정해주세요.

홍영기님의 프로필 이미지
홍영기
지식공유자

맞습니다. ^^
잘 정리해주셨네요. ㅎ~

0

홍영기님의 프로필 이미지
홍영기
지식공유자

안녕하세요. chucky님!

인터럽트 핸들러를 실행하고 있는 상태에서 어떤 HPT(Highest Priority Task)가 Blocked 에서 Ready 로 상태 변경이 되는 경우를 생각해보죠. 인터럽트 핸들러 처리가 끝난 후 이전 태스크(previous task)가 아닌, HPT로 문맥전환을 해준다면 실시간 응답성이 좋아지겠죠?. 이와 관련 영상 1:05초 를 참고해주세요.

portYIELD_FROM_ISR 함수가 바로 이 역할을 수행해줍니다. 이 함수를 사용하지 않더라도 동작은 하겠지만, HPT 는 문맥전환을 위해 systick 인터럽트(xPortSysTickHandler)가 발생될 때까지 기다려야 합니다.

결론. 실시간 처리를 위해서 portYIELD_FROM_ISR 함수를 사용하면 좋다

 

 

 

chucky2님의 프로필 이미지
chucky2

작성한 질문수

질문하기