ESP32와 OTA

아직 작성중인 글입니다.

ESP32로 OTA를 할 일이 있어서 글을 남겨본다.

ESP32는 Over-the-air(OTA) 방식으로 원격 펌웨어 다운로드를 할 수 있다.
다만 이를 위해서는 ESP32의 OTA 특징을 먼저 이해해야 한다.
좀 기나긴 여정이 필요하다.

이 글은 다음과 같이 구성된다.

  1. ESP32에서의 OTA 기능
  2. ESP32에서의 OTA 지원 (작성중)
  3. OTA 웹서버 (작성중)
  4. OTA를 통한 펌웨어 업데이트 (작성중)

1. ESP32에서의 OTA 기능

ESP32에서는 OTA 기능을 지원한다. [docs]
docs에 따르면 OTA는 펌웨어가 동작하고 있는 중에 새 펌웨어를 무선으로 다운로드받고 업데이트하는 기술이다.
당연히 몇 가지 의문이 생길 것이다.
펌웨어는 어디에 받아지며 펌웨어를 받는 중 이상이 생기면 어떻게 되는가?
이런 의문들을 해소하기 위해서는 어쩔 수 없이 ESP32의 파티션 구조를 먼저 이해해야 한다.

ESP32는 다양한 기본 파티션 테이블을 지원하며 이 중에는 OTA를 위한 파티션 공간도 존재한다. [docs][pre-defined_table]
예를 들어 다음의 디폴트 파티션(default.csv)을 보자

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x140000,
app1,     app,  ota_1,   0x150000,0x140000,
spiffs,   data, spiffs,  0x290000,0x170000,

이 파티션 정의에 따르면 파티션 테이블은 nvs와 otadata, ota_0, ota_1, spiffs라는 5개의 공간으로 구성된다.
우선 OTA와 상관없는 두 공간을 먼저 살펴보자.

NVS(Non-Volatile Storage)는 ESP32에서 사용하는 키-밸류 형식의 저장공간이다.
ESP32 내부적으로 NVS를 사용하는 라이브러리가 있는 모양이다.
건드리기 상당히 꺼림칙하다는 말이다.
SPIFFS(Serial Peripheral Interface Flash File System)는 ESP32에서 사용하는 경량 파일 시스템이다. [블로그]
이것도 비슷하다.

이제 남은 건 OTA와 관련된 영역들이다.
docs에 따르면 ESP32는 OTA를 위해 최소 두 개 이상의 OTA app 슬롯과 OTA 데이터 파티션이 필요하다고 한다.
위의 디폴트 파티션 테이블은 ota_0와 ota_1, otadata 파티션을 가지고 있는데, 이로써 이 테이블은 docs에서 설명하는 OTA 조건에 부합하는 것을 알 수 있다.
ota_0와 ota_1 파티션은 ROM이 허용하는 내에서 사용자가 지정한 크기대로 사용할 수 있다.
하지만 otadata는 0x2000(8KB)의 고정 크기만큼 사용할 수 있다.
(왜 8KB씩이나 사용하는지는 찾아보지 않아 아직 의문이다.)

그렇다면 otadata 파티션은 어떻게 OTA에 관여할까?
만약 otadata가 0xFF로 초기화되어있는 경우에는 factory app 파티션이 존재한다면 factory app이, 존재하지 않는다면 사용 가능한 OTA 슬롯(보통 ota_0)이 부팅된다.
그리고 첫 OTA 업데이트 이후부터는 otadata는 부팅할 OTA 슬롯을 가르키는 OTA 전용 부트로더가 된다.

한편, otadata는 해당 영역에 대한 (전원 부족 등으로 인한) 기록 이상에 대비해 두 구역으로 나뉘어 운영된다.
OTA를 통해 업데이트를 하게되면 otadata의 두 구역(각 크기 4KB)에 값을 쓴 후 값 비교 과정을 거쳐 정상 기록 여부를 판단한다.
만약 두 구역의 데이터가 일치하지 않으면 각 구역의 카운터 필드(counter field)를 통해 어떤 구역에 값을 먼저 썼는지를 확인하고 해당 구역이 가르키는 OTA app을 다음 부팅에 사용한다.
한편, 이 알고리즘은 otadata가 기록이 끝난 최신 값을 추적하기 위한 것이지 무결성이나 신뢰성을 보장하기 위한 것은 아님에 주의하자.

만약 기록된 최신 값에 위치한 OTA app 이미지가 기록 이상 등으로 인해 잘못되었다면 ESP32는 어떻게 동작할까?
OTA app 이미지에 이상이 발생하면 OTA app은 정상적으로 동작하지 않는다(ESP_OTA_IMG_INVALID).
이 경우, 부트로더는 자동으로 다른 OTA app 슬롯에 있는 구버젼의 펌웨어를 디폴트로 선택하고 로드한다.
이 과정이 ESP32의 롤백 과정(Rollback Process)이다.

롤백 기능을 위해서는 당연히 두 개 이상의 OTA 파티션이 필요하다.
이에 따라 위에서 보았던 디폴트 파티션 테이블은 롤백이 가능한 형태의 파티션임을 알 수 있다.
한편, 롤백은 이미지의 이상 유무를 떠나 사용자가 CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE 옵션을 켜도 동일하게 작동한다.

필자는 OTA app 슬롯 두 개를 두는 대신 factory app 슬롯과 OTA app 슬롯 하나를 두는게 더 낫지 않나 생각하는데
docs에서는 두 개 이상의 OTA app 슬롯을 사용하라고 했으니 우선은 설명서를 그대로 따랐다.
언젠가 시간이 생기면 factory로도 테스트를 해볼 생각이다.

더 자세한 내용은 docs를 참고하길 바란다.

2. ESP32에서의 OTA 지원

3. OTA 웹서버

4. OTA를 통한 펌웨어 업데이트

댓글 남기기