Embedded Recipes(4주차)

박민기·2023년 11월 23일
0

임베디드 레시피

목록 보기
1/2

<목차>
2. Microprocessor 아뜰리에(Atelier) - ARM을 파헤치자
- 2.7 ARM-Thub PCS ; Register 사용법
- 2.8 ARM은 Interrupt 냄새를 어떻게 맡는가
- 2.9 ARM SoC(System On Chip)
- 2.10 SoC 안에서 IP끼리의 Bus 규격
3.Software 데꾸바쥬(Decoupage) - Software의 정체와 만들기
- 3.1 Little Endian과 Big Endian
- 3.2 컴파일에 대한 단상
- 3.3 컴파일 공장 이야기
- 3.4 원하는 컴파일을 해보자
- 3.5 PreProcess(-E option)과 #include

2.7 ARM-Thumb PCS ; Register 사용법

  • PC(Program Counter), LR(Link Register), SP(Stack Pointer)등 특수용법의 Register들이 많이 나왔다. 이외에도 일반 Register들도 쓰이는 쓰임새가 있는데 이에 대한 약속을 APCS(ARM Procedure Call Standard)라고 부른다 이에 맞춰서 Compiler는 기계어를 만들어 낸다.

  • APCS의 약속의 종류는 크게

    • 함수를 부를 때 Register 사용법
    • return 값은 어떻게 돌려주는가
    • Stack은 어떨 때, 어떻게 사용되는가?
    • 이외에도 특수 레지스터는 어떻게 사용되는가?

1. R0~R3

  • 1) Argument
    R0(a1)~R3(a4)의 경우 Argument / Result / Scratch Register.에서 Argument를 넘길때 사용 합니다. 예를들어 Parameter의 개수가 4개의 경우 stack에 저장되는 형태가 아니라 R0~R3에 그리고 R0는 최종적으로 Return 값으로 이해하면 편하다.Parameter가 4개가 넘어갈 경우 Stack backup을 해두는 수고로움을 해줘야 합니다.
  • 2) Result (Return Value)
    R0~R3의 경우 주소값을 참조하여 R0~R3의 값을 변환시킬 수 있으므로 Return값이 여러가지가 나온다.
  • 3) Scratch(연습장)
    Register들을 CPU가 마치 연습장 처럼 임시저장 용도로 마구 사용 가능,

2. R4~R11(v1~v8)

  • variable 용으로서, 함수 호출 후에 바뀌어서는 안되는 값들로서, 호출당한 함수는 stack에 저장 후에 사용하고, 호출당한 함수가 끝나기 전에 복원을 해줘야 합니다.

3. R12~R15(특수 Register)

  • R12(IP)
    주소 할당 시에 임시 보관소로 사용함
  • R13(SP, Stack Pointer)
    Stack을 사용하기 위해 Stack Pointer로 사용합니다.
  • R14(LR, Link Register)
    함수를 호출하거나, 어디론가 jump했을 때 돌아올 주소를 넣는 목적
  • R15(PC, Program Counter)
    현재 실행하고 있는 주소

모든 레지스터는 사용하기 전에 기존에 들어있는 값을 stack에 저장한 뒤 사용해야 하고, 루틴 끝난 후 복귀할 때는 다시 stack에서 꺼내 복구해줘야 한다.

2.8 ARM은 Interrupt 냄새를 어떻게 맡는가?

Exception중에서도 가장 쓸모 있는 건 Interrupt이다. ARM은 Interrupt가 걸리면 어떻게 행동하는가가 바로 Exception처리 중 한가지입니다. 즉, Interrupt가 걸리면 실행 주소가 Exception Vector중에 IRQ나 FIQ Vector로 강제로 바뀌어 지며, 그 Vector에는 실제 Handler로 branch하기 위한 code가 들어 있습니다. IRQ, FIQ Handler는 MCU가 Interrupt에 대한 응답을 말하는 것입니다. Handler 내부에는 Interrupt종류가 다양한데 각각의 Interrupt에 따른 응답을 다릅니다.

MCU 내부에는 IP(Interrupt Controller)가 달려 있고 외부 pin,내부에 있는 선을 확인하여 그 선을 통해서 신호를 주면 Interrupt Controller가 Interrupt여부를 인지하여 IRQ mode로 바뀌어 줍니다.

CPU로의 Interface는 CU부분에서 여기에 몇 번 Interrupt가 들어 왔는지 확인후 그에 맞는 ISR만들어서 응답한다.

Nesting

Interrupt가 걸려서 ISR을 처리하는 동안 Interrupt가 또 걸리는게 Nesting
??? Interrupt vecotr
대부분의 MCU MPU에 대부분 없음

2.9 ARM SoC(System On Chip)

  • ARM은 processor를 만들어서 파는 회사가 아니라 CPU architecture를 파는회사
  • ARM이 design한 architecture를 가져다 쓰는 회사로부터 로열티를 받음
  • 퀄컴, 삼성, 인텔 등의 ARM의 라이센스를 구매해 자신들의 MCU 및 MPU에 맞게 재 design
  • ARM의 core를 기반으로 여러 기능을 덧붙혀 하나의 chip으로 만들어 판매하는 SoC(System On Chip) 시장이 생겨남

2.10 AMBA - SoC 안에서 IP끼리의 Bus규격

  • SoC내부에서 ARM core와 서로 다른 IP끼리 어떻게 연결돼야 할까?
  • ARM은 내부 IP들끼리 잘 통신하면서 ARM core를 가장 효율적으로 활용할 수 있는 방법을 적용한 Bus 프로토콜을 제안 -> AMBA프로토콜!!!
  • Bus 프로토콜은 bus 위로 data를 어떻게 송수신 할 것인지에 대한 약속
  • AMBA는 AHB, ASB, APB로 나뉜다
    • AHB(Advanced High Performance Bus)
      이름대로 'burst mode'를 지원해 data의 빠른 전송이 가능
    • ASB(Advanced System Bus)
    • APB(Advanced Peripheral Bus)
      저속인 peripheral IP가 중간에 끼면 전체속도가 느려지므로 저속의 IP들을 묶어서 사용하기 위한 bus 인터페이스(MUX 기반 bus)

Software 데꾸바쮸(Decoupage)

3.1 Little Endian과 Big Endian

  • 0x12345678이라는 dword 데이터를 저장할 경우
    • Little Endian은 MSB가 상위주소에 저장된다. [0] = 0x78, [1] = 0x56 [2] = 0x34, [3] = 0x12
    • Big Endian은 MSB가 하위 주소에 저장된다. [0] = 0x12, [1] = 0x34, [2] = 0x56, [3] = 0x78
  • Big endian은 사람이 읽기 쉬운 형태 little endian은 ARM processor가 읽기 쉬운 형태.
  • ARM processor는 default로 little endian을 사용하지만 CR 레지스터를 설정하여 big endian가능

3.2 컴파일에 대한 단상

  • 기계를 다루기 위해서는 bit pattern을 저장ㅇ하고 Data Bus를 통하여 processor에게 던져주면 Prcoessor는 그일을 합니다. 즉 프로그램이란 일련의 기계어 명령의 순차적인 집합이며, 예전에는 이런 기계어 명령을 사람이 직접 Processor에게 입력시켰습니다. 그 이후 -Assembly라는 개념을 도입하게 되었는데, Native Code와 1:1 matching이 되는 그나마 사람이 보기 쉬운 표기 체계를 만들어냈습니다.

  • Native, Assember라는 것이 특정 Processor에만 통하고, Processor의 경우 특정한 약속된 Bit Pattern에 반응한다는 사실 때문에, 특정 Processor에서만 동작함

    • Compatibilty 호환성에 한계를 들어냄
    • 서로 다른 Processor에 맞는 Assembly를 만들어내는 Compiler가 있었으면 좋겠다는 생각으로 entity를 만들어냄
  • C, C++같은 High Level Language compiler의경우 C compilerㄹ를 이용해서 그 Processor에서 동작 가능한 Assembly를 generation하는 형태임

Cross compiler란?

  • 실제 target에서 돌아갈 binary image를 PC 상에서 compile 할 수 있게 해주는 환경
  • 다른 플렛폼에서(windows, Mac) 다른 플렛폼의(Android, IOS, Embedded) 실행 파일을 만들어 주는 컴파일러를 가르킴
    • 예를 들어 Android의 .apk파일(어플리캐이션)을 만들고자 할 때 흔히 사용하는 소프트웨어가 있습니다.
      바로 Android studio 입니다. 이 소프트웨어를 실행시킨 후 컴파일하면 실행파일이 만들어 집니다.
      이 실행 파일은 windows에서 실행이 불가능 하죠. windows는 .exe파일만 실행 가능하기 때문입니다.
      하지만 windows에서 스마트폰을 가상으로 띄우거나 직접 스마트폰에 apk파일을 넣은 후 직접 스마트폰으로 실행하면
      어플리케이션은 실행이 잘 됩니다. 즉, 다른 플렛폼인 windows에서 다른 플렛폼에서 작동되는 .apk파일을 만들어 냈죠. 이를 가르켜 '크로스 컴파일' 이라고 합니다. 다시말해서 다른 플렛폼에서 작동되는 실행파일을 만들 때 사용하는 녀석입니다.

3.3 컴파일 공장 이야기

  • 컴파일공장의 목적은 바로 우리가 흔히 말하는 Native code의 집합인 Binary Image를 만들어 내는 것이 목적입니다. Binary의 정체는 바로 Processor만이 알아들을 수 있는 Native Code(기계어)의 집합입니다. 인간의 눈으로는 도저히 무슨 말인지 알아낼 수가 없는 뭐 그런 세상의 것입니다. 컴파일의 단상에서 불쑥 튀어나온 그 녀석입니다.

  • Binary를 만들어 내기 위해서 원료가 필요합니다. 그 원료는 하하 바로 .c나 .h, 그리고 .s 등의 파일들입니다. (.c, .h는 C code와 header 그리고 .s는 ARM assembly file입니다. ) .s의 경우에는 .c를 컴파일하고 나면 Assembly로 만들어 줄 수 있지만, 여러 가지 성능 측면에서 사람이 직접 Assembly로 짠 파일입니다. 뭐 별거 아니지요.

  • link 개념의 등장

    • .c file을 Assembly로 만든 후 Assembler를 이용하여 Object라는 새로운 기계어이긴 하지만 혼자서 완성된 형태는 아니며, 각기 다른 .c를 컴파일 한 object와 연결할 수도 있는 정보와, 디버깅이 가능한 symbol정보를 담고 있습니다. 이 형태는 요즘 흔히들 말하는 elf형태를 말하는 것이며, elf 형태를 따른 object들은 linker를 이용하여 서로 link할 수 있게 되는 것
    • 즉, 컴파일은 Source file들을 C compiler (armcc, tcc)를 이용하여, Assembly로 만들고, 또 이를 Assembler(armasm)을 이용하여 object file로 만든다. 이 때 object file은 나중에 linker (armlink)를 이용하여 모두 엮이게 되며, elf확장자가 output된다.

3.4 원하는 컴파일을 해보자

spaghetti.h

#define EQUAL=
typeef struct {
bool memberBool;
int memberInt;
word memberWord;
}structure

spaghetti.c

#include "spaghetti.h"
int zi EQUAL 0;
int rw EQUAL 3;
extern int relocate EQUAL 3;
extern structure recipes [3];
int add(int a, int b);

main()
{
int stack;
volatile int local, local1, local3;

local EQUAL 3;
local EQUAL 4;

local3 EQUAL add (local, local2);
stack +EQUAL local3;
return stack;
}

int add(int a, int b)
{
return(a+b);
}
profile
세상을 놀라게할 임베디드 SW 개발자

0개의 댓글