Exception Handling in Cortex-M 1

Nitroblue 1·2025년 9월 21일
post-thumbnail

ARM Cortex-M RTOS Context switching


그동안 Kernel에서 어플리케이션을 스위칭해줄 때, SP만 저장하는 중이었다...

ARM Cortex-M RTOS Context Switching

Having a foundational knowledge of how the core of an RTOS works can be a valuable skill set for an embedded engineer to have.

About Cortex-M based MC

두 가지 실행 모드 존재.
1. Handler Mode : Interrupt Service Routine (ISR)을 실행할 때 진입.
2. Thread Mode : 일반 애플리케이션 코드 실행시.

두 가지 권한 존재.
1. Unprevileged level
2. Privileged level
-> Handler mode는 항상 privileged, Thread mode는 둘 다 가능.

**Unprivileged level의 Thread Mode가 privileged level로 스위칭하려면 반드시 Handler Mode에서 실행해야 한다.


Registers

Core Registers

모든 Cortex-M MCU는 16개의 32비트 Core registers로 이뤄져 있다.

  • r0, r1, r2, r3 : a1, a2, a3, a4 -> Argument(인자) / scratch register 4-Argument / scratch reg 1
    • 인자 전달, scratch(caller-saved)
  • r4 ~ 48 : v1 ~ v5 -> Variable-register 5 - Variable-reg 1
  • r9 : v6, SB, TR -> Variable-reg 6 or Platform Reg
  • r10, r11 : v7, v8 -> Variable reg 7, 8
    • r4~r8, r10, r11 : callee-saved (함수 진입/리턴 시 보존 필요)
  • r12 : IP -> The Intra-Procedure-call scratch register (Caller-saved)
  • r13 : SP -> The Stack Pointer
  • r14 : LR -> The Link Register (Return Address)
  • r15 : PC -> The Program Counter (Current Instruction)
  • xPSR : 프로그램 상태 reg (Thumb 상태, interrupt mask 등)

r12 : Intra-Procedure-call Scratch Register

ARM Cortex-M devices의 주소 공간은 32bit이다. 이 때, bl(branch and link)instruction은 전체 주소 영역을 뛰어넘을 수 없다. 이러한 상황에서 징검다리 역할을 해주는 함수가 필요한데, 이 함수가 바로 linker가 만들어주는 veneer이다.

Veneer Linker는 임베디드 시스템에서 ARM과 Thumb 명령어 코드 사이의 상호 전환을 돕는 중계 함수 역할을 하며, ARM 아키텍처에서 다른 실행 모드(ARM 모드, Thumb 모드)의 코드를 호출하거나 함수를 복귀할 때, 이 Veneer 코드가 자동으로 삽입되어 두 모드 간의 전환을 처리하고 실행을 연결해준다.
r12는 기존 state를 보존하지 않고 veneer 내부적으로 사용될 수 있는 유일한 reg이다.

r9 : Platform Register (중요)

  • 일반적인 경우 단순한 변수 저장 레지스터.

  • PIC 환경(Position Independent Code)에서는 전역/정적 데이터의 실제 주소를 직접 알 수 없으므로 이 주소들을 모아둔 GOT(Global Offset Table)을 참조해야 한다. 이 때, R9에 GOT의 시작 주소(Static Base, SB)를 저장해 두고, 함수들이 이를 통해 전역/정적 데이터의 주소를 찾아온다.

    ARM Cortex-M에서는 -fpic -msingle-pic-base 옵션으로 컴파일하면 이런 동작이 활성화된다!! 나중에 프로젝트 말미에 보안 체계 확장하면서 아마 쓰일 것 같다.


  • Multithread 환경에서는 R9을 TR(Thread Register)로 쓴다.
  • 이 경우, R9은 현재 스레드의 Thread-Local Storage (TLS) Context Pointer를 가리킨다. 즉, 각 스레드마다 고유한 데이터를 저장하는 공간(TLS)이 있고, 함수들이 R9을 참조해서 해당 스레드의 로컬 데이터를 가져오는 구조가 된다.
    -> 그래서 일부 플랫폼이나 ABI에서는 R9을 반드시 보존해야 하는 callee-saved reg로 취급하기도 한다.

현재 프로젝트 구조상, Tock OS -> 멀티앱 환경 = 쓰레드별 로컬 데이터 보존 필요 -> R9 보존 필요. 따라서 어셈블리 코드 수정 필요.


0개의 댓글