본문으로 바로가기

STM32 부트로더는 어떻게 만들어지는가?

category MCU 2021. 12. 8. 23:09
반응형

안녕하세요, 허블입니다.

 

오늘은 부트로더가 어떻게 만들어지는지 알아보겠습니다. 

먼저 시작하기 앞서 부트로더가 무엇인지에 대해부터 알아보겠습니다.

 

 

부트로더란?

부트로더(Bootloader)는 애플리케이션(Application) 영역에서 동작이 되기 전 실행이 되는 부분으로 주로 애플리케이션 영역을 업데이트를 하기 위해서 사용이 됩니다.

 

펌웨어 업데이트를 하기 위해서는 Erase와 Write 하는 동작을 해야 합니다. 애플리케이션 영역만 존재한다고 가정할 경우 펌웨어 업데이트를 하기 위해 자신의 영역을 Erase를 하게 되면 애플리케이션 영역은 지워졌기 때문에 코드를 동작시킬 수 없습니다. 그렇기 때문에 부트로더의 기능이 필요하며 부트로더 영역에서 코드를 실행하여 애플리케이션 영역을 지우고 다운로드하게 됩니다.

 

부트로더(Bootloader)

위에 이미지에서 부트로더의 영역은 0x00000000 ~ 0x00004000입니다.

이것은 고정이 아닙니다. 부트로더의 크기는 상황에 따라서 달라질 수 있습니다. 

 

애플리케이션과 동일한 코드를 부트로더에 넣을 수도 있고 부트로더, 애플리케이션 2가지 영역이 아닌 3가지 영역으로 나누기도 합니다. 이러한 경우는 특별한 경우고 대부분의 부트로더는 OS를 넣지 않고 최소한의 크기로 만들어줍니다. 이유는 다음과 같습니다.

 

STM32 Map파일(좌측 None OS, 우측 OS)

좌측은 None OS이고 우측은 OS를 포함한 코드의 Map 파일입니다.

 

None OS ROM 사이즈(좌측) : 0x32C8(약 13Kbyte)

OS 포함 ROM 사이즈(우측) : 0x6212(약 25Kbyte)

 

OS만 추가했는데 약 12Kbyte가 추가되었습니다. OS를 추가하게 되는 경우 GPIO 초기화 및 코드 추가 시 Flash Size가 쉽게 32Kbyte를 넘게 됩니다. 크기가 커지게 되면 Erase 하는데 많은 시간이 소비가 됩니다.

 

 

 

 

부트로더 동작?

코드는 부트로더부터 순차적으로 실행이 됩니다. 부트로더에서는 Checksum 및 Size 여러 가지 방법으로 애플리케이션의 무결성을 판단합니다. 애플리케이션 영역이 존재가 확인되면 해당 영역의 시작 번지로 Jump를 하게 됩니다.

 

부트로더(Bootloader)

애플리케이션 영역으로 Jump후에는 코드는 애플리케이션 영역에서만 실행이 됩니다. 만약 애플리케이션 영역이 존재하지 않으면 부트로더 영역에서 코드가 수행이 됩니다.

 

 

애플리케이션 영역에서 코드 수행 중 애플리케이션 다운로드 방법?

부트로더(Bootloader)

코드는 부트로더에서 부터 순차적으로 수행이 되고 애플리케이션 영역으로 Jump 하게 되면 코드는 애플리케이션 영역에서 수행을 하게 됩니다. 애플리케이션 영역을 Flash 하기 위해서는 다시 부트로더로 돌아가야 합니다. 따라서 시작 위치로 돌아가기 위해서 Soft Reset을 합니다. 그런데 여기서 문제가 있습니다. 리셋을 하여 부트로더로 돌아갔지만 애플리케이션의 무결성을 판단해보니 이상이 없어 다운로드하지 않고 다시 애플리케이션 영역으로 돌아가게 됩니다. 이런 조건을 구분하기 위해 리셋을 하기 전에 애플리케이션 특정 영역에 Magic Number를 Write 합니다. 무결성을 판단해서 애플리케이션 영역이 존재하여도 Magic Number가 있다면 애플리케이션 영역을 Erase 하면 됩니다.

 

 

애플리케이션 영역에서 부트로더 다운로드?

일반적으로 부트로더는 다운로드할 일이 거의 없습니다. 그럼 부트로더는 어떻게 다운로드해야 할까요? 애플리케이션 영역에서 부트로더를 Erase 하고 Write를 하면 됩니다. 부트로더가 지워진 상태에서 코드를 수행하게 되면 어떻게 될까요? 동작을 하지 않게 됩니다. 프로그램 시작 위치에 있는 부트로더가 없어서 애플리케이션 영역으로 Jump를 할 수 없기 때문입니다.

 

 

 

부트로더 구현?

먼저 부트로더를 구현하기 위해서는 영역을 나누어야 합니다.

임의로 부트로더 사이즈를 0x4000, 애플리케이션 사이즈를 0x8000이라고 가정해보겠습니다.

 

IAR Linker 설정, 부트로더

부트로더의 경우 처음 코드가 수행되기 때문에 Vector의 시작 번지는 0x08000000입니다.

 

 

부트로더 ROM 설정

부트로더의 ROM의 Start는 0x08000000, END 0x08004000이 됩니다. 영역 설정이 끝났다면 애플리케이션 영역을 다운로드하기 위한 코드를 추가해줍니다. 추가해야 할 코드는 다음과 같습니다.

 

1. 애플리케이션 무결성 확인 및 애플리케이션을 다운할지 여부 확인

2. 애플리케이션 영역 Erase

3. 애플리케이션 영역 Write

4. 다시 애플리케이션 무결성을 확인, 애플리케이션 시작 영역으로 Jump

 

여기서 주의해야 할 점은 Flash를 동작하는 동안 Global Interrupt는 모두 정지하게 됩니다. 즉, 인터럽트를 Flash 하는 동안 사용할 수 없습니다. 따라서 WDG을 사용하게 된다면 Deinit을 하고 Flash 동작을 수행해야 합니다. 

 

STM32 메모리 테이블

STM32 계열의 메모리 테이블입니다. Sector에 따라서 메모리 사이즈가 다릅니다. 큰 메모리의 경우 128Kbyte 입니다. 작은 메모리의 경우엔 Erase가 금방 끝나지만 큰 메모리의 경우엔 Erase시 몇 초가 걸립니다. WDG을 Deinit을 하지 않고 Erase를 하게 되면 Flash 하는 동안 인터럽트는 동작하지 않기 때문에 Reset이 되게 됩니다. 영역이 16Kbyte로 작은 경우는 Erase시간이 매우 짧기 때문에 상황에 따라서 WDG을 Deinit 하지 않고 사용할 수도 있습니다.

 

 

 

 

애플리케이션 구현?

부트로더와 같이 Linker 옵션을 설정합니다. 코드 시작 번지가 다르기 때문에 부트로더와는 설정이 많이 다릅니다.

 

애플리케이션 Linker 설정

부트로더의 Size는 0x4000이었습니다. 애플리케이션의 Vector 시작 번지는 부트로더 영역 다음인 0x08004000이 됩니다. 만약 애플리케이션의 Vertor가 부트의 시작 번지가 0x08000000이면? 애플리케이션 코드가 수행되지 않습니다.

 

애플리케이션 ROM 설정

애플리케이션의 시작 번지는 0x08004000이고 Size는 0x8000이었기 때문에 End는 0x0800BFFF가 됩니다.

 

Vect offset 설정

마지막으로 System 코드에 VECT_TAB_OFFSET을 설정해야 Vect 시작 주소가 0x08004000으로 변경됩니다.

 

애플리케이션 영역에서 애플리케이션 다운로드

1. 애플리케이션 다운로드하기 위해서 Flash의 특정 영역에 Magic Number를 Write 하고 Soft Reset을 합니다.

2. 부트로더에서 Magic Number를 확인하고 애플리케이션 영역 Erase후 코드를 Write 합니다.

 

애플리케이션 영역에서 부트로더 다운로드

1. 부트로더의 영역을 Erase 하고 부트코드를 Write 합니다. 이때 부트로더 다운로드를 실패하는 경우 다시 Write를 하면 되지만 Reset을 하게 되는 경우 애플리케이션은 동작할 수 없습니다. 부트로더가 없기 때문에 애플리케이션으로 Jump를 할 수 없기 때문입니다.

 

이상으로 마치겠습니다.

 

 

 

2021.05.30 - [프로그래밍/MFC] - [MFC]CStdioFile 클래스를 이용해 유니코드 텍스트 저장, 불러오기

 

[MFC]CStdioFile 클래스를 이용해 유니코드 텍스트 저장, 불러오기

오늘 포스팅할 내용은 MFC에서 CStdioFile 클래스를 이용해 유니코드 텍스트 저장, 불러오기입니다. 유니코드 텍스트가 어떤 인코딩 방식으로 저장되었는지 나타내기 위해 데이터 맨 앞에는 BOM(Byte

hubbleconstant.tistory.com

2021.08.12 - [프로그래밍/C#] - C# winform Chart 사용 방법, 간단한 예제

 

C# winform Chart 사용 방법, 간단한 예제

안녕하세요, 허블입니다. 오늘은 C# winform에서 제공해주는 Chart 클래스에 대해서 알아보려고 합니다. Chart를 이용하면 별도의 라이브러리 설치 없이 그래프를 렌더링 할 수 있습니다. Chart 클래스

hubbleconstant.tistory.com

 

반응형

'MCU' 카테고리의 다른 글

[ST CubeMX] FreeRTOS 메시지큐(Message Queue) 예제 코드 사용법  (2) 2021.11.14