본문 바로가기

임베디드/ARM

ARM Product 관련 문서 번역(Cortext-M3)

(번역을 시작하게 된 계기)

ARM 아키텍쳐는 높은 시장 선점율에도 불구하고, '여러 요소'들로 추상화 되어 있어 이해에 대한 필요성을 느끼기 쉽지 않다. 여러 요소들의 예로는 펌웨어 엔지니어 입장에는 칩 벤더사 SDK가, 어플리케이션 엔지니어 입장에는 리눅스와 같은 OS가 될 수 있다.

그럼에도 불구하고 ARM 아키텍쳐를 익히는 것은 앞으로 사용 할 Soc SDK의 Learning Curve를 줄여준다는 점에서 의미가 있다고 생각한다. (적어도 ARM 아키텍처를 계속 사용하는 한)

 

목차

Chapter 1 Introduction

Chapter 2 The Cortex-M3 Processor

Chapter 3 The Cortex-M3 Instruction Set

Chapter 4 Cortex-M3 Peripherals

 

※ 본문 중간 중간에 나오는

- 빨간색 글씨는 강조 부분이고,

- 노란색 음영은 강의 및 책을 찾아 보면서 내용을 추가한 것이고,

- 파란색 음영은 개인적인 생각 및 정리한 것입니다.

 

※ ARM 제품 포트폴리오는 다른 포스트에서 다룹니다.


Cortex-M3 Devices Generic User Guide(DUI0552A)

Chapter 1 Introduction

Cortex-M3 구조도

1.1 주요 특징

• outstanding processing performance combined with fast interrupt handling
• enhanced system debug with extensive breakpoint and trace capabilities
• efficient processor core, system and memories
 ultra-low power consumption with integrated sleep mode and an optional deep sleep mode
• platform security robustness, with an optional integrated Memory Protection Unit (MPU).

 

그외

3단계 파이프라인 Harvard 아키텍쳐를 따른다.

전력 효율적인 Instruction Set을 제공.

IEEE754-compliant single-precision floating-point computation.

SIMD multiplication, saturating arithmetic and dedicated hardware division.

 

Cortext-M3 프로세서는 Thumb-2 기술을 기반으로한 Thumb 명령어 셋을 실행한다.

(해당 기술은 high code density하며 프로그램 메모리 사용량을 줄일 수 있다)

 

NVIC는 NMI(Non-maskable interrup)를 포함, 256개의 인터럽트 레벨을 제공.

NVIC는 빠른 ISR 실행을 제공한다(dramatically reducing the interrupt latency)

이는 레지스터의 hardware stacking of register와 다중 로드를 중단하거나 다중 명령을 저장하는 기능으로 인해 가능하다(This is achieved through the hardware stacking of registers, and the ability to suspend load-multiple and store-multiple operations).

Tail-chain 최적화 또한, ISR을 한곳에서 다른 곳으로 옮겨가는(switch) 부하(overhead)를 매우 감소시켰다.

 

저전력 설계를 최적화 하기 위해, NVIC는 Sleep Mode와 통합되었다.

 

1.1.1 System-level interface

Cortex-M3 프로세서는 AMBA® 기술을 사용하는 다중 인터페이스를 제공하여 고속, 저 지연 메모리 액세스를 제공한다.

정렬되지 않은 데이터 액세스를 지원하고 더 빠른 주변 장치 제어, 시스템 스핀 록 및 스레드로부터 안전한 부울 데이터 처리를 가능하게하는 원자(Atomic) 비트 조작을 구현 기능을 제공.

 

Cortex-M3는 또한, MPU(Memory Protection Unit)을 제공하여 메모리의 개별 영역 제어(Control Individual Region)를 가능하게 한다. 이는 어플리케이션으로 하여금 '테스크 별 데이터 혹은 스택 분리 보호' 등 여러 권한을 활용할 수 있게 한다 (MPU로 인하여 테스크 별 Privilege levels을 달리 할 수 있다고 이해하였다).

이러한 기능은 차량에 들어가는 임베디드 어플리케이션에 필수적이다.

 

1.1.2 Optional integrated configurable debug

JTAG 포트 또는 2 핀 SWD (Serial Wire Debug) 포트를 통해 프로세서 및 메모리에 대한 높은 시스템 가시성을 제공한다.

그외, ITMInstrumentation Trace Macrocell (ITM), SWVSerial Wire Viewer (SWV), ETMEmbedded Trace Macrocell(ETM)
등의 기능이 있다.

FPB(Flash Patch and Breakpoint Unit)은 8개의 하드웨어 breakpoint comparators를 제공한다.

 

1.1.3 Cortex-M3 프로세서 특징 (원문 그대로 옮겨 놓음)

• tight integration of system peripherals reduces area and development costs.
• Thumb instruction set combines high code density with 32-bit performance.
• code-patch ability for ROM system updates.
Power control optimization of system components.
Integrated sleep modes for low power consumption.
• Fast code execution permits slower processor clock or increases sleep mode time.
• Hardware division and fast digital-signal-processing orientated multiply accumulate.

• Deterministic, high-performance interrupt handling for time-critical applications.
• Optional MPU for safety-critical applications
• Extensive implementation-defined debug and trace capabilities:
— Serial Wire Debug and Serial Wire Trace reduce the number of pins required for debugging, tracing, and code profiling.

 

1.1.4 Cortex-M3 주변기기(Peripherals) 특징

NVIC(Nested Vectored Interrupt Controller) : 저 지연 인터럽트 처리 지원.

SCB(System Control Block) : 프로세서를 위한 프로그래머 모델 인터페이스.

  - CMSIS는 SCB 레지스터를 매핑한 인터페이스를 제공한다.

System Timer : 24bit 카운트 다운 타이머이다. RTOS 혹은 단순 타이머에 사용한다.

MPU(Memory Protection Unit) :  8개의 구별되는 영역을 제공한다. 메모리 영역에 대한 메모리 속성을 제공하여, 시스템 안정성을 높인다.

 

• Memory model on page 2-12
• Exception model on page 2-21
• Fault handling on page 2-28
• Power management on page 2-31.

 

2. The Cortex-M3 Processor

2.1 Programmers model

2.1.1 Processor mode and privilege levels for software execution

▶ 프로세서 모드

- Thread Mode : (default) 어플리케이션을 실행할 때 사용된다. User Mode로도 불린다. 프로세서가 Reset 상태가 되면, 스레드 모드에 들어간다(역자 : 기본 모드라고 생각하면 될 것 같다). 

- Handler Mode : 예외 처리를 위해 사용된다. 끝나면 Thread Mode로 돌아간다.

 

▶ 프로세서 (Access) 레벨

- Unprivileged 

  - SW로 하여금 MSRMRS 명령에 접근하는 것을 막는다. 또한, CPS 명령을 사용할 수 없다.

  - 시스템 timer, NVIC, SCB에 접근할 수 없다.

  - 메모리와 주변기기 접근에 제한이 있다.

- Privileged

  - SW는 모든 자원에 접근이 가능하다.

 

1) Thread 모드 일 때, CONTROL 레지스터는 SW가 Privileged or Unprivileged 레벨로 실행할 지 결정할 수 있다.

2) Handler 모드 일때는 (예외 처리 중이므로) 항상 Privileged 레벨이다.

(다르게 말하면, 예외처리를 수행하는 코드는 모든 자원에 접근이 가능하다)

3) (Thread 모드에서) Privileged 레벨로 실행되는 SW 만이 CONTROL 레지스터에 기록하여 privilege 레벨로 수정할 수 있다. (Thread 모드에서 CONTROL 레지스터가 레벨을 결정 할때 SW는 Privileged 레벨 이어야 한다)

4) Unprivileged 코드는 SVC 명령어를 사용하여 supervisor call 로 하여금 privileged 코드로 컨트롤 하게 할 수 있다.

 

※ 아래는 Udemy 강의를 참고하여 첨부하였다(21.03.02)

When the processor is in 'thread mode', it's possible to move processor to unprivileged.
Once you move out of the privileged to unprivileged in thread mode,
then it's not possible to come back to privileged unless
you change the processor operational mode to 'handler mode'.

==> (해석) 
프로세서가 thread 모드 일때, unprivileged 로 가는 것이 가능하다.
thread모드 에서 privileged에서 unprivileged로 가는 경우, 'handler' 모드로 변경하지 않는 한,
다시 privileged로 돌아 오는 것은 불가능하다.

==> (설명) 
1)에 의하면 thread 모드에서 unprivileged 레벨로 가능 것이 가능하며(당연),
3)에 의하면 privileged레벨이 아닌 이상 레벨 변경이 불가능 하므로, 다시 unprivileged로 돌아가지 못한다.
다시 privileged 레벨로 돌아가려면, handler 모드에서 레벨을 변경하면 된다.

[21.07.05] 강의 내용 추가

아래 그림처럼 Thread 모드에서 Priviledged --> Unpriviledged 변경이 가능하다. 하지만, 되돌아 가는것은 불가능하다.

일종의 Trap!!

그렇다면, 어떻게 다시 Priviledged 모드로 돌아갈 수 있을까?? 

정답은, Handler 모드로 프로세스 모드를 변경하는 것이다. Handler 모드에서는 항상 Priviledged Level 이므로 이때CONTROL Register를 '0' 으로 변경하면 된다.

 

Privileged IPSR > 0 OR CONTROL.nPRIV = 0 Core 레지스터의 IPSR이 
Thread 모드 아니거나,
CONTROL.nPRIV가 Privileged
Unprivileged IPSR = 0 AND CONTROL.nPRIV = 1 Core 레지스터의 IPSR이
Thread 모드 이면서,
CONTROL.nPRIV가 Unprivileged

- Core레지스터의 IPSR이 0 일때는 Thread 모드이고, 그외에는 Handler 모드이다.

- CONTROL레지스터의 nPRIV 영역이 1 이면 Unprivileged 이고, 0이면 Privileged 이다.

- Unprivileged 레벨 일때는 Thread 모드 이면서(IPSR = 0), CONTROL.nPRIV = 1 이어야 한다.

- Privileged 레벨 일때는 Handler 모드이거나(IPSR > 0), CONTROL.nPRIV = 0 이어야 한다.

- Thread 모드이면서(IPSR = 0), Privileged 레벨(CONTROL.nPRIV = 1) 인것이 가능하다.

- CMSIS를 이용한 모드 변경 예시

 

2.1.2 Stacks

- 프로세서는 main stack(MSP), process stack(PSP) 2개를 사용한다. 각 스택의 포인터 sp는 독립된 레지스터를 가진다.

- Thread 모드에서 CONTROL 레지스터는 프로세서가 main stack 혹은 process stack을 사용할지 결정한다. 

 

2.1.3 Core Registers

 

- R0 ~ R12는 General Purpose Register

- SP는 R13번이다. Thread 모드일 때 CONTROL 레지스터의 bit[1]은 SP를 가리킨다.

- LR은 R14 이다. 링크 레지스터.

  : Subroutines, Function call and Exceptions의 리턴 정보를 저장한다. 

  : 리셋 시 0xFFFFFFFF 값으로 초기화 된다.

- PC는 R15. 

  : Current Program Address를 가지고 있다.

  : 리셋시에 프로그램은 PC를 Reset Vector 값(0x00000004에 저장된)으로 초기화 한다.

  : 값의 Bit[0]은 EPSR T-bit로 (리셋 시에) 저장되며 '1'의 값을 가진다.

 

General-purpose registers

R0-R12 는 General-Purpose 레지스터이다.

 

Stack Pointer

스택 포인터(SP)는 R13이다. Thread Mode에서 CONTROL 레지스터의 bit[1] 값에 따라

Stack Pointer는 두가지로 동작한다.

0 = Main Stack Pointer(MSP) 

1 = Process Stack Pointer(PSP)

 

리셋 시에, 프로세스는 0x0000000 주소에 있는 값을 MSP로 로드 한다.

 

[21.07.02] 강의 내용 추가

더보기

프로세스가 리셋되면, 프로세스는 메모리 주소 0x0000_0000 값을 읽어 MSP에 전달한다.

즉, MSP = value@0x0000_0000

그다음, 프로세스는 메모리 주소 0x0000_0004(리셋 핸들러 주소) 값을 읽어 PC에 전달한다.

즉, PC = @Reset Handler

 

PC는 Reset Handler의 명령어를 실행한다.

Reset Handler는 C or Asm으로 작성된 초기화 코드이다. main() 함수를 호출한다.

 

<동작 프로세스>

프로세스 리셋--> Data Section 초기화 --> BSS Section 초기화 --> 'C' std 라이브러리 초기화--> main() 진입

 

이하 Special Register

프로그램 상태 레지스터(PSR)

- PSR(Program Status Register)은 아래 레지스터의 조합이다.

    • Application Program Status Register (APSR)
    • Interrupt Program Status Register (IPSR)
    • Execution Program Status Register (EPSR).

 

3개의 레지스터에 개별적으로 접근하거나, 조합으로 사용한다.

레지스터는 MSR, MRS 명령어 사용시에 인자로 들어간다.  

   - e.g. PSR, MRS 명령어로 위의 3개 레지스터를 읽어 들인다.

   - e.g. APSR_nzcvq, MSR 명령어로 APSR N, Z, C, V, Q 비트에 쓴다.

 

32bit PSR 레지스터
PSR 레지스터 조합

 

어플리케이션 프로그램 상태 레지스터(APSR)

이전의 명령어로 인해 변한 현재 상태의 Condition을 표현한다(N, Z, C, V, Q)

인터럽트 프로그램 상태 레지스터(IPSR)

- 인터럽트 넘버 정보를 가진다.

- IPSR이 0 일때는 Thread 모드이고, 그외에는 Handler 모드이다.

 

실행 프로그램 상태 레지스터(EPSR)

- Thumb 상태 정보를 저장한다. 

- 아래의 2가지 중 하나에 대한 실행 상태 비트를 포함한다.

  - If-Then(IT) instruction

  - Interruptible-Continuable Instruction(ICI) field for an interrupted load multiple or store multiple

    instruction

- MSR 명령어를 이용해 EPSR를 바로 읽어 들이면 항상 '0'을 반환한다.

- MSR 명령어를 이용해 EPSR에 쓰는 행위도 무시 된다.

 

ESPR 레지스터

※ 아래는 Udemy 강의를 참고하여 첨부하였다(21.03.02)

더보기
If 'T' bit of the EPSR is set '1', processor thinks that
the next instruction which it is about to execute is from Thumb ISA

If 'T' bit of the EPSR is reset '0', processor thinks that
the next instruction which it is about to execute is from ARM ISA

==> (해석)
만약 EPSR의 'T' 비트가 '1'로 설정된다면, 프로세스는 다음 명령어가 Thumb ISA로 부터 
실행됨으로 간주한다.
만약 EPSR의 'T' 비트가 '0'로 설정된다면, 프로세스는 다음 명령어가 ARM ISA로 부터 
실행됨으로 간주한다.

==> (참고)
ARM Cortex Mx 프로세서는 Thumb state 만 지원하므로 EPSR 레지스터의 'T' 비트는
'1'로 유지되어야만 한다.
'T' 비트가 0인 상태에서 명령어 실행은 프로세서 Usage fault를 유발한다.

PC의 lsb는 'T' bit와 링크되어 있다.

PC가 참조하는 주소는 0번째 비트가 항상 '1'이어야 한다.

컴파일러가 신경써주는 문제라서, C언어를 작성하는 입장에서는 신경쓰지 않아도 된다.

 

ex) 함수 포인터가 함수 주소를 받을 때 함수 주소가 '짝수'라면, 컴파일러가 '홀수'로 바꾼다.

 

PRIMASK

Priority Mask Register

 

FAULTMASK

Fault Mask Register

 

BASEPRI

Base Priority Mask Register

 

CONTROL Register(CONTROL)

- Control 레지스터는 (프로세서가 Thread 모드 일때) 사용되는 스택과 SW가 실행되는(Privilege or Unprivilege) 레벨을 컨트롤 한다. 

- SPSEL : 현재 활성화된 sp를 정의. Handler 모드일 때는 '0'. 쓰기를 않는다.

    - 0 : MSP가 현재 sp이다.

    - 1 : PSP가 현재 sp이다. 

- nPRIV : 현재 Thread 모드의 privilege 레벨을 결정한다.

    - 0 : Privileged

    - 1 : Unprivileged

 

※ Handler 모드는 항상 MSP를 사용하므로, 프로세서는 Handler 모드에서 CONTROL 레지스터의 Active SP 비트에 쓰는 것을 무시한다.

 

※ OS 환경에서 ARM은 스레드 모드에서 실행되는 Thread가 프로세스 스택을 사용하고, 커널 및 예외 처리기가 메인 스택을 사용하도록 권장.

즉, Thread는 PSP 사용하기를 권장, 커널 및 예외처리기는 MSP 사용하기를 권장.

 

(자세한건 2-10 참조)

정리하면,

Privileged IPSR > 0 OR CONTROL.nPRIV = 0 Core 레지스터의 IPSR이 
Thread 모드 아니거나,
CONTROL.nPRIV가 Privileged
Unprivileged IPSR = 0 AND CONTROL.nPRIV = 1 Core 레지스터의 IPSR이
Thread 모드 이면서,
CONTROL.nPRIV가 Unprivileged

- Core레지스터의 IPSR이 0 일때는 Thread 모드이고, 그외에는 Handler 모드이다.

- CONTROL레지스터의 nPRIV 영역이 1 이면 Unprivileged 이고, 0이면 Privileged 이다.

- Unprivileged 일때는 Thread 모드 이면서, CONTROL.nPRIV = 1 이어야 한다.

- Privileged 일때는 Handler 모드이거나, CONTROL.nPRIV = 0 이어야 한다.

- Thread 모드이면서, Privileged 레벨 인것이 가능하다.

- CMSIS를 이용한 모드 변경 예시

 

 

2.1.6 The Cortex Microcontroller Software Interface Standard(CMSIS)

- CMSIS는 Cortex-M3 프로세서의 Peripherals 에 대한 주소 정의 및 데이터 구조가 포함. 

 


2.2 Memory Model

- 4GB 메모리 예시

- SRAM 및 Peripheral 영역에는 선택전 비트 밴드(Optional bit-band)를 포함. 비트 밴드는 데이터에 Atmoic 연산을 제공한다.

 

AMBA는 ARM의 Bus Interface Specification

- AHB : High-Speed Communication에 사용

- APH: Low-Speed Communication에 사용

 

2.2.5 Optional bit-banding

(Peripheral, SRAM에 한해서) 비트 대역 영역(Bit band region)의 각 비트는 비트 대역 별칭(Bit band alias)에 즉, 32bit에 매핑할 수 있다. 

Peripheral, SRAM에 한해서 최초의 1MB 비트-밴드 영역에 매핑되는, 각각의 32MB Alias(별칭) 영역을 가지고 있다

Bit-Banding은 비트 데이터에 대해 아토믹(Atomic) 연산을 제공한다. 즉, Bit-Band Region을 Bit-Band Alias(별칭)을 이용하여 읽거나 수정할 때 다른 인터럽트나 예외에 의해 중단될 수 없다.

 

Memory Map의 Bit-Banding 영역

 

정리하면 Bit-Bending은 각 개개 비트를 단일 주소화 할 수 있다(Bit addressable feature or Bit-bending) 따라서, 단일 비트 만을 수정하려고 할때, 일반적인 방법으로는 (LDRB, ORR, STRB) 명령어가 사용되지만, 비트-밴딩을 이용하면 LDRB 명령어만 사용하면 된다. 

 

Alias Address = Alias_base + (32 * (Bit_band_memory_addr - Bit_band_base)) + Bit * 4

 

2.5.5 Power management programming hints

- ISO/IEC C 는 WFI, WFE 명령을 직접적으로 생성하지 못한다. 따라서, CMSIS는 다음과 같은 함수 형태로 제공한다.

void __WFE(void) // Wait For Event
void __WFI(void) // Wait For Interrupt

 


2.3 Exception model

2.3.1 Exception states

각각의 Exception은 아래의 상태 중 하나이다.

- Inactive 

- Pending : 프로세서로 부터 자원을 받기를 기다리는 상태

- Active : 프로세서로 부터 자원을 할당 받아 동작 중인 상태

- Active and Pending : Exception이 프로세서의 자원을 할당받고 있고, 같은 자원에 의해서 Pending 중인 Exception이 있는 상태

 

※ Exception handler가 다른 Exception handler에 의해 인터럽트를 받으면, 두 Exception이 모두 Active 상태에 놓일 수 있다.

 

Active and Pending은 하나의 코어를 쓰면서 Active 상태 일때, 다른 예외가 발생해서 현재 Exception이 Pending 상태에 놓이는 상황을 말하는가?

 

 

2.3.2 Exception types

Reset : reset이 asserted 되면, 명령의 어느 지점이든 중지되고, deasserted되면 reset vector 테이블에서 제공한 주소에서 스레드 모드로 실행된다.

NMI : NonMaskable Interrupt 는 주변기기로 부터 시그널 받거나, SW로 부터 트리거 될 수 있다. Reset 다음으로 우선순위가 높다. '-2'는 고정. Reset을 제외하곤 Preempted 될 수 없다. 

HardFault : '-1' 고정.

 

[21.07.05] 강의 내용 추가

Previledged 권한으로 접근 가능한 레지스터에 Unpreviledge 권한으로 접근하려 하면 HardFault로 빠졌었다.

 

 

2.3.3 Exception handlers

프로세서는 예외를 다음의 핸들러로 처리한다.

Interrupt Service Routines (ISRs) : Interrupt(IRQ)를 처리한다.

Fault handlers : HardFault, MemManage fault, Usage Fault, Bus Fault 등의 fault exceptions을 처리한다.

System handlers : NMI, PendSV, SVCall SysTick 등의 system exception을 처리한다.

 

2.3.4 Vector Table

- LSB는 '1'이다

- Exception Handler는 Thumb Code 이다.

- 시스템 리셋이 되면, 벡터 테이블은 0x0000_0000으로 고정된다. 

 

[21.07.02] 책 내용 추가

더보기

전원이 켜지면, ARM은 Exception Vector Table의 Reset Vector를 읽는다.

ARM은 Exception Vector Table에 정의된 상황이 발생하면, PC를 테이블의 Offset 주소로 강제 변환한다.

그리고, 해당 주소에 잇는 32bit 명령 1개를 실행한다.

 

Offset 주소에 저장된 명령은 브랜치 명령으로 시스템 마다 각기 다른 예외 처리 방식에 대응하기 위함이다.

(즉, 분기 명령을 두어서 각기 다른 예외 코드 길이를 신경 쓰지 않게 한다)

브랜치 명령을 따라 점프하여 Exception Handler를 실행한다.


3. The Cortex-M3 Instruction Set

 

3.2 CMCIS functions

- ISO/IEC C 코드는 몇몇 Cortex-M3 명령어에 직접 접근할 수 없다.

- 이러한 명령어 들은 CMSIS에서 혹은 컴파일러에서 함수 형태로 제공하게 된다.

- 만약, C 컴파일러가 적절한 내장 함수를 지원하지 않는 경우, 일부 명령어에 액세스하려면 인라인 어셈블러를

  사용해야 할 수도 있다.

Cortex-M3 명령어 역할을 하는 함수들

 

- CMSIS 또한 MRS, MSR 명령어를 이용해 특수 레지스터에 접근 하게 하는 함수를 제공한다.

 

(역자 : Core Register와 CMSIS의 자세한 용법은 link 를 참조한다)

 


4. Cortex-M3 Peripherals

 

 


(참고) 

Cortext-M3는 대표적인 Armv7-M 계열의 제품이다

※ Armv7-M 계열 특징

Armv7-M Profile benefits

 

 

반응형

'임베디드 > ARM' 카테고리의 다른 글

Cortex-M3/M4 Utils  (0) 2021.03.20
Core Register & CMSIS  (0) 2021.03.09
ARM 교육 받을 수 있는 곳  (0) 2021.02.13
ARM ToolChain 관련 문서  (0) 2020.10.06
[Book Review] 원리부터 실무까지 쉽고 명확한 ARM프로그래밍  (0) 2020.08.22