[IDEC] ARM Cortex-M 프로세서 기반의 펌웨어 설계실무 1

2023. 8. 9. 13:23Embedded/ARM Cortex

728x90

IDEC 본센터에서 ARM Cortex-M 프로세서 기반의 펌웨어 설계실무강의를 듣고 왔다. IDEC에서 들은 강의를 내가 이해한 대로 작성할 생각이다. 


  • ARM Cortex-M
  1. ARM Holdings에서 개발한 마이크로프로세서 설계의 일련의 제품군
  2. 주로 임베디드 시스템 및 이동식 장치에서 사용되는 프로세서로, 낮은 전력 소비와 뛰어난 성능을 조화시키는 데 초점을 맞추고 있다.
  3. ARM Cortex 시리즈는 크게 세 가지 주요 계열로 나눌 수 있다.
Cortex-A 시리즈 이 계열의 프로세서는 고성능 컴퓨팅 애플리케이션을 위해 설계되었다. 스마트폰, 태블릿, 네트북 및 서버와 같은 다양한 디바이스에 사용된다. 이 프로세서들은 다중 코어 지원, 대규모 캐시, 고급 부동 소수점 연산 등을 특징으로 하며, 복잡한 작업을 처리하는 데 효율적이다.
Cortex-R 시리즈 이 계열의 프로세서는 실시간 시스템에 주로 사용된다. 자동차 제어 시스템, 의료 기기 및 산업 자동화와 같이 실시간 반응이 필요한 환경에서 운영된다. Cortex-R 프로세서는 신뢰성과 안정성을 강조하며, 실시간 제어와 안전한 작동을 보장하기 위해 설계되었다.
Cortex-M 시리즈  이 계열의 프로세서는 저전력 임베디드 시스템 및 마이크로컨트롤러 애플리케이션을 위해 개발되었다. IoT 디바이스, 센서, 의료 기기 등에서 사용되며, 작은 크기와 낮은 전력 소비, 실시간 기능을 조화시키는 데 중점을 두고 있다. Cortex-M 프로세서는 비교적 간단한 구조를 가지고 있어서 프로세싱 능력과 메모리 요구 사항을 최소화하고, 임베디드 시스템에서 효율적으로 동작할 수 있도록 설계되었다.

 

  • CPU / MCU
  • CPU (Central Processing Unit):

CPU는 주로 범용 컴퓨터 및 서버와 같은 고성능 컴퓨팅 시스템에서 사용된다. 명령어를 해석하고 실행하며, 계산, 데이터 처리, 메모리 관리 등을 수행한다. CPU는 프로그래밍 가능하며, 다양한 응용 프로그램을 실행할 수 있다. 더 높은 성능을 위해 다중 코어 및 고급 기능을 갖춘 CPU도 존재한다.

 

  • MCU (Microcontroller Unit):

MCU는 주로 임베디드 시스템에서 사용되는 작고 저전력 프로세서이다.

주로 단일 칩에 CPU, 메모리, 입출력 포트, 타이머, 통신 인터페이스 등을 통합한 형태로 제공된다.

MCU는 다양한 응용 분야에서 사용되는데, 예를 들어 가전 제품, 자동차 시스템, 의료 기기, 센서 네트워크, IoT 디바이스 등에서 활용된다. MCU의 주요 특징은 낮은 전력 소비와 작은 크기, 실시간 제어 능력이다.

 

CPU와 MCU 두개는 기능적인 차이점이 존재한다.

  1. CPU – 계산목적으로 사용
  2. MCU – 하드웨어를 제어하기위해 사용

 

CPU와 MCU의 차이점

 


  • ARM Cortex - M

ARM Processor와 IP / data bus로 연결되어있다.

STM32보드에선 MCU와 IP가 존재한다.

  1. MCU는 ARM Cortex-M기반의 프로세스가 존재한다. (ARM Processor는 연산만 하는 목적의 블록)
  2. IP(지적재산)는 ARM Procseeor 이외의 프로세스를 IP로 본다. GPIO, UART, ADC, CAN, ROM, RAM 전부 IP이다. 이런 IP들이 버스로 연결되어있다. (버스 또한 IP이다.)

 

우리가 사용할 보드는 STM32-Entry이다. STM32-Entry 보드엔 stm32f103rb(cortex-m3)와 칩제조사의 IP가 존재한다.

칩제조사 IP는 MCU이외의 GPIO, UART, ADC, CAN, ROM, RAM 등이 칩제조사에서 설계한 IP이다.

그래서 ARM에서 설계한 IP(레지스터, ALU)와 칩제조사기 설계한 IP(GPIO, UART, ADC, CAN, ROM, RAM)는 다른 IP이다. 이 IP들은 DATA BUS를 통해 연결된다. 

 

ARM Processor내부에는 core가 존재한다. (ARM프로세스이고 “cpu”가 아니다.)

펌웨어 관점에서 중요하게 봐야 할 것은 core이다.

 

core내부의 핵심적인 요소는 2가지 존재한다

  1. 레지스터
  2. ALU(산술연산장치)

레지스터는 표기를 R0, R1... R15로 표기한다. (MCU가 32BIT기준에서 R0 ~ R15까지 존재한다.)

레지스터와 ALU의 관계에서 코드적으로 ALU의 연산은 상수와 레지스터만 가능하다

 

Int gvar;
void main(){
	gvar = gvar+1; 
	// 더하기연산은 ALU에서 이루어진다 (ALU는 상수와 레지스터만 연산가능), core가 해석할 수 있는 코드(머신코드)로 컴파일러가 변환한다, 이런 머신코드(2진 데이터)는 ROM에 저장된다. 
	//1. RAM에서 ARM processor의 core로 load한다. (데이터 읽어온다)
	//2. core에서 레지스터로 값을 집어넣는다. (LDR R0, [R1] -> ADD R0 R0 #1 -> STR R0 [R1]) 
	//3. Core의 ALU에서 연산을 한 후 다시 ram으로 데이터를 전송한다.
	//cisc는 메모리(ram)자체가 연산의 대상이 될 수 있다. 
	//CORE와 프로세스 사이에 존재하는 캐쉬, MMU, 멀티미디어 프로세스, FPU(실수연산을 담당하는 프로세스)등등이 존재.
	//Coretex 시리즈(A, M등등)는 레지스터가 R0 ~ R15까지만 존재
}

 


  •  MEMORY MAP

Memory Map

 

ROM은 Flash메모리를 많이 사용한다. Flash 메모리는  NAND Flash와 NOR Flash가 존재한다. (ex. NAND FALSH : USB, NOR FALSH : ARM)

ROM은 머신코드(어셈블리어)가 들어가 있다. NAND Flash는 코드가 내부에 있다면 실행되지 않는다.(코드실행 불가능한 공간)

RAMSRAM(s : STATIC)이 존재, SDRAM(s : 동기)

 

NOR Flash를 임베디드에서 사용하는 이유:

  1. 부트 로더: NOR Flash는 부트 로더(부팅 프로그램) 및 초기화 코드를 저장하기에 적합한 빠른 읽기 속도를 제공한다. 이로 인해 장치 부팅 시간을 단축하고 안정성을 향상시킬 수 있다.

  2. 펌웨어 업데이트: 임베디드 시스템에서는 펌웨어 업데이트가 중요한 역할을 한다. NOR Flash는 랜덤 액세스가 가능한 특성으로 인해 펌웨어 업데이트를 용이하게 만든다.

  3. 소형 데이터 저장: 코드 및 작은 데이터 저장에 적합한 NOR Flash는 프로그램 및 설정 데이터를 보다 효율적으로 저장할 수 있게 해준다.

  4. 안정성: NAND Flash보다 내구성이 높고, 더 적은 데이터 손실이 발생하는 NOR Flash는 임베디드 시스템에서 안정적인 작동을 지원한다.

    종합적으로, NOR Flash는 임베디드 시스템에서 빠른 읽기 속도와 높은 내구성이 필요한 경우에 주로 사용되며, 부트 로딩 및 프로그램 코드 저장에 적합하다.

 

데이터를 송수신할 때, 동기와 비동기가 존재한다.

동기 : 반드시 클럭이 존재한다. 데이터를 주고받을 때 클럭을 바인딩해서 데이터 주고받는다. (동기방식 : SPI, I2C)

비동기 : 클럭이 존재하지 않는다. 모듈간의 통신 속도를 정해 통신한다. (비동기 방식 : UART)

 

칩제조사에서 만든 GPIO, UART, ADC등등은 내부에 레지스터가 존재. 해당 레지스터를 SFR(Special Function Register)라 한다.

칩관점에서 보면 ARM core의 레지스터와 칩제조사에서 만든 레지스터(IP의 레지스터)가 존재하게 된다.

UART통신은 UART내부의 ID에서 존재하는 레지스터에 UART의 통신관련 데이터들이 들어있다. (해당 레지스터를 보고 UART통신을 진행)

 

고유의 주소가 MAPING되어있다.

실제 BUS에 붙어있는 것이 SFR이다. / 그래서 RAM에서 CORE에 데이터를 주고 값을 받듯이(SDRAM의 연산과정) IP에서의 연산과정도 방금 과정과 동일하다.

(BUS : 주소를 이용해 데이터 제어)

 

IPSFR안의 주소는 공장에서 제조될 때 정해진다.(그래서 SFR을 사용할 때는 절대주소를 사용)

그러나 RAM의 레지스터는 주소가 정해져 있지 않다.

 

Memory MAP, Nested Vectored Interrupt Controller, System Timer, Bit banding등이 아키텍쳐의 주요 기능

 

core내부의 레지스터는 주소로 접근하는 방식이 아닌 어셈블리어 관점으로 접근한다.

칩을 설계할 때는 ip의 주소를 arm에서 제공하는 메모리 맵에 맞춰 주소를 설정해줘야 한다.

 

ALU의 기본대상은 레지스터 / 레지스터의 길이가 8비트 = 8비트 CPU / 32비트 = 32비트 CPU

 

ROM - code space, sram space, peripheral space등이 존재. flash메모리의 시작주소는 800만 주소이다.

SRAM -  주소가 2천만번지부터 시작된다.

SFR - 4천만번지부터 사용(Pheripheral)

 

일본의 르네사스사의 coretex m4sram의 주소 번지가 조금씩 다르다.

 


  • 시스템 타이머

펌웨어에선 시간정보가 중요하다.

IP(칩제조사에서 만든 IP, Cortex-M 내부의 System Timer와는 별개이다.)에선 TIMER라는 IP존재한다. Cortex-M은 CoreProcessor사이에 System Timer가 존재. (밖의 타이머는 PWM, COUNTER등의 기능을 하지만 내부 타이머는 카운터로만 동작)

 

  • 비트 밴딩

Bit bamd영역이 sramperipheral2가지 존재. Flash = 128kb, sram = 20kb – 비트 밴딩 영역의  메모리 주소에 존재한다. Bit band regionbit band alias사이에 공간이 존재. Alias – 물리적으로 없지만, 마치 존재하는 것과 같이 사용한다. (가상적으로 존재)

 

Bit band 영역

  1. 물리적으로 존재
  2. Bit band는 0x20000000 (2천만번지부터 시작된다.)

Bit band alias

  1. 가상적으로 존재
  2. 시작주소가 0x22000000 (2천2백만이다. 4bit로 데이터 저장)
  3. 0x22000004 -> 0x22000008 등으로 메모리 사용
  4. char gvar가 2천만이라 가정한다면, 메모리에 상위 7비트는 남겨두고 하위 1비트는 1을 더하고 싶다면, gvar = 0x1; (이렇게 한다면 안된다. -> 해당 연산 수행하면 상위 7비트는 0이 된다 -> 논리연산으로 1만 증가시켜 줘야함)
  5. bit band영역의 각 비트들이 bit band alias의 4bit로 쓰여진다. (상위 32비트는 값이 쓰여지지 않고 0으로 인식)
    1. gvar – gvar | 0x01 – 메모리에서 값을 읽고 연산한 후 쓰는 구조
    2. bvar = 0x01 - 메모리에서 연산하는 구조X, 내부적으론 하드웨어적으로 연산하지만 소프트웨어적으론 연산하지 X – 만든 목적은 Octionic Operation.
      1. 1)는 LOAD, OPERATION, STOP의 구조 생성.
  6. -      2)는
  7. -      인터럽트 서비스함수가 존재한다면
  8. -      1)은 LOAD->OPERATION -> IST -> STORE의 과정을 거친다 / 2)는 바로 메모리에 할당
  9. -      Atomic – 인터럽트가 내부적인 영향을 받지 않고 동작하는 코드

 

Processor내부의 레지스터는 R0 ~ R15까지 존재한다.

R13(SP), R14(LR), R15(PC)는 특수한 목적으로 사용

리셋되면 R13R15에 특정한 값이 부여된다. 부여되는 값은 SP = mem[0X00, 4B]

PC = MEM[0X4, 4B]

PC가 창을 닫아버리면 프로그램 카운터가 곧 실행할 명령어의 주소이다.

 

0x00 : 0x2000, 1000

0x04 : 리셋 되었을 때 최초 실행되는 명령어

 

NVIC – Nested(중첩) -> 인터럽트 처리 중 다시 인터럽트를 처리해야 한다면 인터럽트 처리하던 도중에

Coreprocessor사이에 NVIC가 존재.

기본적으로 인터럽트는 IP들이 processor에게 요청 / processorip들에게 인터럽트 요청을 받는다.

arm에선 외부에서 들어오는 인터럽트를 irq라 한다(processor밖의 인터럽트)

irq-0부터 최대 240개까지 사용가능 (irq – 0 ~ irq – 239) – 해당 내용은 칩마다 다르다.

 

물리적인 인터럽트가 중요한 것이 아니라 몇번의 irq가 요청하는지가 중요하다.

벡터 테이블 인터럽트 벡터 테이블 테이블이 있는 위치는 0번지 / 0번지에 있는 벡터 값들을 벡터 테이블이라 한다.

 

Index Addr 4b (sp)
0 0x00 4b (pc)
1 0x04 4b
2 0x08 4b
4b
15 0x3c 4b
16 0x40 4b
17 0x44 4b

메모리 – flash rom(벡터 테이블)

Sp – 0x00

Pc – 0x04 최초 실행되는 명령어의 주소값

 

15 16을 나누는 기준 – 0~15internal ( = system ) / 16 ~ external( = user)

Irq – 0에 물리적인 연결은 칩마다 다르다. (irq0에 무엇이 연결되어있든 그것은 중요하지 않다.)

만약 우리가 사용하는 mcuirq 0 uart가 있다 가정한다면.

 

만약 irq0의 요청이 들어온다면 cortex0x40번지(16, 16부턴 external)에 들어있는 4바이트 값이 읽혀져서 요청된다(pc에 들어간다)

Irq1의 요청 들어오면 0x44의 값이 읽혀진다(pc에 들어간다)

ð  cortex에선 이런 과정이 설계되어 동작된다.

함수이름을 프로그램에 넣는다는 것은 함수를 실행하겠다는 것.

 

시스템 카운터가 Internalnvic(인터럽트)를 사용하게 되면 15번지(0x3c)에서의 값을 pc에 넣는다.

 

ARM7 -> ARM9 -> ARM11

Cortex – A(Application)

Cortex – R(Real time)

Cortex – M(Microcontroller)

MMU - mmu가 있어야만 os를 포팅할 수 있다.

è  Cortex Rcortex Mmmu가 존재하지 않는다.

 

빌드 결과물 만들 수 있다

빌드과정 – 1~4까지가 존재

1.     *.c, *.s -> 컴파일

2.     Assemble

3.     Link

4.     결과물 1,2,3이 생성된다.(Bin, hex, axf(elf)파일등이 생성된다.)

 

빌드결과물은 3가지

Axfdefault파일 무조건 만들어야 한다.

주소 - 머신코드로 작성되어 있고 우리가 실행하는 것은 위의 머신코드를 해석한 것을 나타낸 것이다.

 

Gpio 제어에 있어 가장 먼저 수행되어야 할 것이 방향설정

Gpio가 제어되는 순서 -> ARM Processro내부의 GPIO IP의 SFR을 이용해 GPIO를 제어

sfr에 접근하기 위해 해당 sfr의 주소를 알아야한다. -> 주소를 알아야 해당 sfa파일 사용가능

 

GPIOA_CRL을 컨트롤해야 한다. (LED1을 제어하기 위해)

DefaultGPIO가 동작하지 않게 되어있기 때문에 활성화시켜줘야한다.

 

RCC_APB2ENR를 이용해야한다.

 

하위 2비트 : MODE (현재 수업에선 11사용)

상위 2비트 : CNF ( 현재 푸쉬풀 사용 : 00 )

 

나머지비트는 유지 20~23번비트까지 해당 내용 설정

 

ODR – OUTPUT DATA REGISTER

 

Gpio를 활성화시키기 위해 해야하는 것들

1.     클럭 공급

2.     방향 출력 -> 0 0 1 1 (23 22 21 20) 설정해줘야함

회로의 default방향은 in으로 하는게 맞다.

 

비트연산에서 해당 비트를 없애고 싶으면 AND 연산 / 1을 추가하고 싶으면 OR연산하도록 한다.