Exception entry and return : EXC_RETURN

ARM-Cortex M 시리즈에서는 컴파일러의 최적화에 따라서 다르지만 서브루틴을 호출하면 원래의 위치로 복귀하기 위해서 LR(Link Register)에 PC의 내용을 저장하게 됩니다. 하지만 Exception(혹은 Interrupt)상황에서는 LR에 아래와 같은 이상한 값들이 저장됩니다.

  • 0xFFFFFFF1
  • 0xFFFFFFF9
  • 0xFFFFFFFD
  • 0xFFFFFFE1
  • 0xFFFFFFE9
  • 0xFFFFFFED

왜 이럴까요? 결론적으로 말씀드리자면 Exception 해제시 Handler/Thread Mode, MSP/PSP를 시스템이 알기 위해서 입니다. 위의 값을 EXC_RETURN 값이라고 하는데 이 값들이 LR에 저장이 되고 Exception 해제시 시스템이 LR을 읽어 진입시의 상태로 되돌릴 수 있게 됩니다. 물론 PC는 Stack에 PUSH/POP됩니다.

아래는 STM32 Cortex®-M4 MCUs and MPUs programming manual에서 발췌한 자세한 내용입니다.

Processor Mode

Thread Mode : 응용 소프트웨어를 실행하는 데 사용됩니다. 프로세서는 Reset 끝나면 Thread Mode로 들어갑니다. CONTROL 레지스터는 소프트웨어 실행에 특권(Privileged)이 있는지 여부를 제어합니다.

Handler Mode : 예외를 처리하는 데 사용됩니다. 프로세서는 예외 처리를 마치면 Thread Mode로 돌아갑니다. 소프트웨어 실행에는 항상 권한(Privileged)이 부여됩니다.

Exception entry and return

예외 처리에 대한 설명은 다음 용어를 사용합니다.

Preemption : 프로세서가 예외(Exception) 처리기를 실행할 때 처리 중인 예외의 우선 순위보다 우선 순위가 높으면 예외가 예외 처리기를 선점할 수 있습니다. 하나의 예외가 다른 예외를 선점하는 경우 이러한 예외를 중첩 예외라고 합니다.

Return : 이것은 예외 처리기가 완료되고 다음을 수행할 때 발생합니다.

  • 우선순위가 충분한 대기 중인 예외가 없을 경우
  • 완료된 예외 처리기가 Late-arriving 예외를 처리하지 않을 경우

프로세서는 스택을 POP하고 프로세서 상태를 인터럽트가 발생하기 전의 상태로 복원합니다.

Tail-chaining : 이 메커니즘은 예외 처리 속도를 높입니다. 예외 처리기 완료 시 예외 항목에 대한 요구 사항을 충족하는 보류 중인 예외가 있는 경우 스택 POP을 건너뛰고 제어가 새 예외 처리기로 전송됩니다.

Late-arriving : 이 메커니즘은 선점 속도를 높입니다. 이전 예외에 대한 상태 저장 중에 우선 순위가 더 높은 예외가 발생하면 프로세서는 우선 순위가 더 높은 예외를 처리하도록 전환하고 해당 예외에 대한 벡터 가져오기를 시작합니다. 저장된 상태는 두 예외 모두에서 동일하므로 상태 저장은 Late-arriving의 영향을 받지 않습니다. 따라서 상태 저장은 중단 없이 계속됩니다. 프로세서는 원래 예외의 예외 처리기의 첫 번째 명령이 프로세서의 실행 단계에 들어갈 때까지 Late-arriving 예외를 수락할 수 있습니다. Late-arriving 예외의 예외 처리기에서 반환되면 일반 Tail-chaining 규칙이 적용됩니다.

Exception entry

우선순위가 충분한 보류 중인 예외가 있고 다음 중 하나가 있는 경우 예외 항목이 발생합니다.

  • 프로세서가 Thread 모드에 있는 경우
  • 새로 발생한 예외는 현재 처리 중인 예외보다 우선 순위가 높아 새 예외가 원래 예외보다 우선할 경우

한 예외가 다른 예외를 선점하면 예외가 중첩됩니다.

우선 순위가 충분하다는 것은 예외가 마스크 레지스터에서 설정한 제한보다 우선 순위가 높다는 것을 의미합니다. 이보다 우선 순위가 낮은 예외는 Pending 상태이지만 프로세서에서 처리되지 않고 보류됩니다.

프로세서가 예외를 처리하면 예외가 Tail-chaining 또는 Late-arriving 예외가 아닌 한 프로세서는 현재 스택에 정보를 Push합니다. 이 작업을 스태킹이라고 하며 8개의 데이터 Word 구조를 스택 프레임이라고 합니다. 부동 소수점 루틴을 사용할 때 Cortex-M4 프로세서는 자동으로 예외 항목에 구성된 부동 소수점 상태를 쌓습니다.

그림 12는 부동 소수점 상태가 인터럽트 또는 예외의 결과로 스택에 보존될 때 Cortex-M4 스택 프레임 레이아웃을 보여줍니다. 부동 소수점 상태에 대한 스택 공간이 할당되지 않은 경우 스택 프레임은 FPU가 없는 Armv7-M 구현과 동일합니다. 그림 12에서도 이 스택 프레임을 보여줍니다.

그림 12

스태킹 직후 스택 포인터는 스택 프레임에서 가장 낮은 주소를 나타냅니다. 스택 프레임의 정렬은 구성 제어 레지스터(CCR)의 STKALIGN 비트를 통해 제어됩니다.

스택 프레임에는 반환 주소가 포함되며 이것은 중단된 프로그램에서 다음 명령의 주소입니다. 이 값은 예외 반환 시 PC에 복원되어 중단된 프로그램이 다시 시작됩니다.

스태킹 작업과 병행하여 프로세서는 벡터 테이블에서 예외 처리기 시작 주소를 읽는 벡터 가져오기를 수행합니다. 스태킹이 완료되면 프로세서는 예외 처리기 실행을 시작합니다. 동시에 프로세서는 EXC_RETURN 값을 LR에 기록합니다. 이는 스택 프레임에 해당하는 스택 포인터와 항목이 발생하기 전에 프로세서가 있었던 작업 모드를 나타냅니다.

예외 항목 중에 더 높은 우선 순위 예외가 발생하지 않으면 프로세서는 예외 처리기 실행을 시작하고 자동으로 해당 Pending(보류) 중인 인터럽트의 상태를 활성으로 변경합니다.

예외 항목 중에 우선 순위가 더 높은 다른 예외가 발생하면 프로세서는 이 예외에 대한 예외 처리기 실행을 시작하고 이전 예외의 Pending(보류) 상태를 변경하지 않습니다. 이는 Late-arriving 경우입니다.

Exception return

예외 반환은 프로세서가 Handler 모드에 있고 다음 명령 중 하나를 실행하여 EXC_RETURN 값을 PC에 로드할 때 발생합니다.

  • PC를 로드하는 LDM 또는 POP 명령
  • 대상이 PC인 LDR 명령
  • 모든 레지스터를 사용하는 BX 명령어.

EXC_RETURN은 예외 항목에서 LR로 로드되는 값입니다. 예외 메커니즘은 프로세서가 예외 처리기를 완료한 시기를 감지하기 위해 이 값에 의존합니다. 이 값의 하위 5비트는 리턴 스택 및 프로세서 모드에 대한 정보를 제공합니다.

표 18은 예외 반환 동작에 대한 설명과 함께 EXC_RETURN 값을 보여줍니다. 모든 EXC_RETURN 값에는 비트[31:5]가 1로 설정되어 있습니다. 이 값이 PC에 로드되면 예외가 완료되었음을 프로세서에 알리고 프로세서는 적절한 예외 반환 시퀀스를 시작합니다.

EXC_RETURN[31:0]
Description
0xFFFFFFF1
핸들러 모드로 Return, 예외 반환은 MSP의 비부동 소수점 상태를 사용하고 실행은 반환 후 MSP 사용
0xFFFFFFF9
스레드 모드로 Return, 예외 반환은 MSP에서 비부동 소수점 상태를 사용하고 실행은 반환 후 MSP 사용
0xFFFFFFFD
스레드 모드로 Return, 예외 반환은 PSP의 부동 소수점 상태가 아닌 상태를 사용하고 실행은 반환 후 PSP 사용
0xFFFFFFE1
핸들러 모드로 Return, 예외 반환은 MSP에서 부동 소수점 상태를 사용하고 실행은 반환 후 MSP 사용
0xFFFFFFE9
스레드 모드로 Return, 예외 반환은 MSP의 부동 소수점 상태를 사용하고 실행은 반환 후 MSP 사용
0xFFFFFFED
스레드 모드로 Return, 예외 반환은 PSP의 부동 소수점 상태를 사용하고 실행은 반환 후 PSP 사용

표 18. Exception return behavior

참조 : PM0214 Programming manual STM32 Cortex®-M4 MCUs and MPUs programming manual