해결된 질문
작성
·
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
답변 감사합니다. 확인차원에서 재 문의 드립니다.
case1: call back에서 portYIELD_FROM_ISR 호출시
isr 진입
isr 내부에서 call back 함수 호출
call back 함수에서 portYIELD_FROM_ISR 호출 (최종 portYIELD 호출되어 portNVIC_INT_CTRL_REG register의 PendSV bit set)
isr 중 call back 이후 부분 수행
isr 완료
xPortPendSVHandler에 의해 context switching 발생
case2: call back에서 portYIELD_FROM_ISR 미호출시
isr 진입
isr 내부에서 call back 함수 호출
call back 함수 수행
isr 중 call back 이후 부분 수행
isr 완료
선점 당했던 task로 복귀
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 함수를 사용하면 좋다
맞습니다. ^^
잘 정리해주셨네요. ㅎ~