Exception Handling in Cortex-M 3

Nitroblue 1·2025년 9월 22일

Context State Stacking

  • AAPCS 규약에 따르면, 호출된 함수(Callee)가 호출한 함수로 돌아가기 전에 원래값으로 복구해야 하는 reg set이 있다.

    r4-r8, r10, r11 and SP(r13) (and r9 in PCS variants that designate r9 as v6)
    이 reg들은 호출된 함수가 원래 상태로 돌려놔야 한다.
    PendSV같은 context switching routine이 이 부분을 저장/복구하는 이유.

    반대로, r0-r3, r12, LR(r14), PC(r15), xPSR : 총 8개는 호출한 함수(Caller)가 보존해야하는 레지스터들이다. 이를 HW conetxt frame이라고 부른다.

  • 또한, [C]PSR은 전역 reg라서, flag[4:0](N, Z, C, V, Q) in [31:27] bits와 GE[3:0] bits in [19:16] bits는 함수 진입이나 복귀 시 정의되지 않는다. (이 비트들은 최근 비교 등에 대한 상태를 전달함) 이는 곧, 해당 reg에 필요한 상태를 보존하는 책임 역시 Caller에게 있음을 의미한다.

  • Stack은 double-word aligned이어야 한다. 이는 곧 함수에 진입할 때 스택이 항상 8바이트 정렬로 시작해야 한다는 뜻이다.


Summary

Interrupt에서의 실행이 Abstract Binary Interface에 부합하려면, ARM Architecture는 stack을 항상 8바이트로 정렬하고, caller가 r0-r3, r12, r14 상태를 저장해야 한다. 이를 수행하기 위해 ARM Cortex-M Core는 이 Context를 스택에 자동으로 push한다.

Note

  • 예외 처리하기 전에 사용 중이던 스택에 데이터가 푸시된다. 예를 들어, 시스템이 Thread 모드에서 psp를 사용중일 때 예외가 발생하면, 데이터는 psp에 푸시된다. 만약 다른 예외 처리를 하는 도중에 더 높은 우선순위의 예외에 의해 선점되었다면 데이터는 msp에 푸시된다.
r0~e3 : 함수 인자 전달용
r12 : 임시용
LR : 리턴 주소
PC : 복귀할 명령어
xPSR : 프로그램 상태 레지스터, 실행 상태 플래그 포함

Exception Return

  • exception에서 exit할 때, 하드웨어에게 어떤 state를 복구할 지 설명해줘야 한다.
    이 때 EXC_RETURN이 link register(lr)로 로드되어야 한다.

  • 보통은 exception 진입시에 lr에 있던 값을 그대로 보여준다. 하지만, Thread mode sp를 바꾸기 위해서 다르게 저장할 수도 있다.

EXC_RETURN V | Mode to Return to | Stack to use
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
  0xFFFFFFF1 | 	  Handler mode   |     MSP
  0xFFFFFFF9 |     Thread mode   |     MSP
  0xFFFFFFFD |     Thread mode   |     PSP
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

더 있는데, FP는 아직 서비스에 포함하지 않을 예정이므로 스킵.


RTOS Context Switching

  • Schedular capable of context switching between different tasks. (yield : 양보)
  • Very basic Operating System primitives such as mutexes/semaphores and a way to pass messages between tasks
  • Configuration operations for sandboxing different code from one another by leveraging the privilege and access control features the hardware offers.

Schedulars usually come in two main varieties

  1. Preemptive : 어떤 태스크가 실행중이어도 더 중요한 일이 생기면 스위칭.
  2. Cooperative : 한 태스크가 실행중일 때는 강제 스위칭 불가. 해당 태스크가 명시적으로 yield(양보)해야 다른 태스크 실행.

스위칭이 발생할 때, 현재 태스크의 state를 저장해야 한다. 이 때 저장 항목으로는 태스크의 실행 상태와 현재 사용 중인 하드웨어 레지스터값들이 포함된다.

0개의 댓글