본문 바로가기
Embedded System/소프트웨어 (C,C++)

[F/W] 펌웨어와 부트로더(BootLoader)

by MachineJW 2023. 8. 23.

1. 펌웨어 개념정리

펌웨어(Firmware)는 하드웨어와 밀접하게 관련되어 동작하는 소프트웨어를 의미한다.

펌웨어와 임베디드 소프트웨어는 용어는 혼용되고 있는데

구분하자면 OS가 포팅되어 PC가 아닌 시스템에 여러 프로세스가 동시에 실행 되는 환경의 소프트웨어는 임베디드 소프트웨어로 분류 된다. 펌웨어는 하나의 프로세스로 구성되어 순차적인 동작을 하는 소프트웨어의 종류라고 볼 수 있겠다. (프로세스란 프로그램이 메모리를 할당 받아 실행 되고 있는 것을 의미함)

펌웨어와 임베디드 소프트웨어는 하드웨어에 직접적으로 접근하여 컨트롤한다는 면에서는 동일하다.

하드웨어에 직접 접근하지 않는 웹,엑셀,워드 등의 소프트웨어는 응용 소프트웨어 또는 어플리케이션이라고 한다. 간편하게 OS 없이 하드웨어를 직접 제어하는 프로그램을 펌웨어라고 보면 될 것 같다.

 

2. 펌웨어 빌드과정

 

펌웨어가 만들어지는 과정은 MCU나 개발보드, 개발환경에 달라질 수 있으나 대부분은 비슷하다고 볼 수 있겠다. 어차피 C언어로 프로그램이 만들어지는 과정에는 컴파일러가 있어야하니 여기까지는 뭐 일반 C언어 프로그램을 만드는 것과 동일하다. 한 가지 다른 점이 있다면 MCU를 만드는 제조사에서 편리하게 개발을 할 수 있도록 MCU에 대한 라이브러리를 제공하는 것이다. 당연하게도 펌웨어를 만드는 프로그래머의 입장에서는 제어하는 명령어를 해석해야하는 번거로움을 덜 수 있다. (MCU를 만든 회사에서도 그 정도 까지는 제공해야 많이 팔수 있기 때문에...) 

 

빌드 : 소스파일을 해당 임베디드 MCU에 맞는 명령어 체계로 변환 시키는 동작이 되겠다.

빌드 과정이후에 MCU의 명령어 집합체인 이진(바이너리)파일이 생성되는 데, 이 이진 실행 파일을 메모리에 기록해 놓게 되면, MCU는 이 명령어를 읽고 해석하여 실행하게 된다.

문제는 PC로 작업된 이 이진 파일을 어떻게 MCU에 전달하냐인데, 갖가지 통신방법(UART, SPI 등)을

사용한다.

PC에서 타겟시스템(임베디드MCU)에 이진 파일 전달(교차 컴파일, 크로스 컴파일)할 때 다운로더라는 프로그램이 이를 수행하게 한다.

 

다운로더의 역할은 UART등 통신에 맞추어 MCU에게 데이터를 전달하는 역할을 하며

펌웨어의 일종인 부트로더를 MCU의 플래시 메모리에 Write 하게 된다. (부트로더를 거칠 때는 시리얼통신만)

ISP 방식은 MCU 플래시메모리에 직접적으로 Write하며 부트로더를 사용하지 않는다.

3. 부트로더(Bootloader)

부트로더는 위에서 이야기한 플래시메모리에 이진파일을 쓰는 동작 말고도 매우 중요한 역할을 하는데,

우선 부트로더는 MCU 안에 있는 하나의 프로그램(펌웨어)라고 볼 수 있겠다.

 

- Boot 기능 : 펌웨어를 실행하기위한 초기화 ( 영역마다 메모리를 얼마나 할당할 것인지?)

- Loader 기능 : 펌웨어를 실행할 메모리에 Load 또는 실행

- Update 기능 : 펌웨어를 다양한 방식으로 Update (통신, SD카드.....)

 

부트로더는 프로그램 저장 공간, 지역변수 메모리, 전역변수 메모리의 할당 구역을 나눈다.

부트로더는 MCU 메모리에 특정영역을 차지하고 있다. 대부분의 MCU는 부트로더가 내장되어 있고 샘플 펌웨어 소스도 제공한다. 당연하게도 MCU 임베디드 펌웨어를 개발하기 위해서는 매우 중요하므로 부트로더에 이상이 생길 경우 어떻게서든 복구하여야한다.

4. Arduino의  펌웨어 구현 추상화

Arduino 플랫폼의 경우 위에 설명한 과정을 전부 추상화하여 개발환경을 구축하여 놓았다.

IDE에서는 위의 과정을 전부 생략할 수 있도록 내부에 감추어 놓았다.

MCU가 바뀌어도 간단한 (BSP:보드서포트 패키지)와 드라이버, HAL(하드웨어 추상화 레이어)가 전부 구현 되어 있어 Arduino IDE를 사용하면 이런 펌웨어를 구현할 필요가 없다. 위의 펌웨어 빌드 과정을 업로드 버튼 인터페이스로 전부 끝낼 수 있도록 통합한 것이다.

단점이 있다면 아두이노 API 기본 클래스를 모두 사용해야 하기 때문에 리소스가 많이 걸릴 수 있다.

5. 펌웨어의 설계

펌웨어는 하드웨어 제어 부분과 어플리케이션 소프트웨어를 분리하여 구현함으로써, 하드웨어의 변경 시에도 어플리케이션 소스트웨어는 변경 없이 하드웨어 제어 부분만 변경하면 되도록하는 HAA (Hardware Abstraction Architecture)라는 구조를 사용한다. 위에 언급된 아두이노의 경우 HAA가 이미 구현되어 있다고 보면 되겠다.

 

HIL - 어플리케이션과 HAL 사이의 인터페이스

HAL - HPL 상위계층으로써 좀 더 추상화 된 함수들의 묶음

HPL - 하드웨어 직접 접근하여 제어하는 함수들의 묶음

* HAA 구조라고도 하지만 그냥 통합하여 HAL 이라고 한다.

 

이런 구조를 가짐으로써 하드웨어 변경이 있더라도 어플리케이션의 코드는 수정할 필요가 없이 HAL 레이어의 API 코드만 수정해도 되니 코드의 재활용에 유리하다.

펌웨어에서는 HAL 레이어 구조를 가지도록 설계/구현되는 경우가 많다.