-
ESP32 IDF HTTP OTADEVICE 2023. 11. 9. 14:02
OTA 펌웨어 업데이트 기능 구현을 위한 과정을 정리한다.
1.파티션 정의
파티션에 대한 예시테이블은 IDF폴더 안에 파티션 관련 예시파일이 몇 개 있었다.
4M 기준으로 수정은 다음과 같이 하였으며, 이를 컴파일할 폴더에 복사해놨다.

nvs(2)는 NVS(Non-Volatile Storage) API 용입니다 .
NVS는 장치별 PHY 교정 데이터(초기화 데이터와 다름)를 저장하는 데 사용됩니다.
프로젝트에 최소 0x3000바이트의 NVS 파티션을 포함하는 것이 좋습니다.phy(1)은 PHY 초기화 데이터를 저장하기 위한 것입니다.
이를 통해 PHY를 펌웨어가 아닌 장치별로 구성할 수 있습니다.
기본 구성에서는 phy 파티션이 사용되지 않으며 PHY 초기화 데이터가 앱 자체에 컴파일됩니다.따라서 이 파티션을 파티션 테이블에서 제거하여 공간을 절약할 수 있습니다.
factory(0x00)은 기본 앱 파티션입니다.부트로더는 data/ota 유형의 파티션이 없는 한 팩토리 앱을 실행합니다.
이 경우 이 파티션을 읽어 부팅할 OTA 이미지를 결정합니다.
"otadata" OTA 업데이트용 데이터를 보관하는 새로운 슬롯도 있습니다.
부트로더는 실행할 앱을 파악하기 위해 이 데이터를 참조합니다.
“ota data”가 비어 있으면 팩토리 앱이 실행됩니다
ota_0(0x10) … ota_15(0x1F)는 OTA 앱 슬롯입니다.
nvs_keys(4)는 NVS 키 파티션용입니다.NVS 암호화 기능이 활성화된 경우 NVS 암호화 키를 저장하는 데 사용됩니다 .
이 파티션의 크기는 4096바이트(최소 파티션 크기)여야 합니다.파티션에 대한 정보는 아래의 링크 내용을 보면 나온다.
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html
Partition Tables - ESP32 - — ESP-IDF Programming Guide latest documentation
Note Using C file I/O API to open a file (fopen`) in any write mode (w, w+, a, a+, r+) will fail and return NULL. Using open with any other flag than O_RDONLY will fail and return -1 while errno global variable will be set to EROFS. This is also true for a
docs.espressif.com

OTA관련 파티션에 대해 정리하면,
1) otadata는 최초 데이터가 없을 경우 factory 내용을 부팅한다.
2) 이 후, 업데이트시마다 otadata의 내용을 참조하여 ota_0이나 ota_1로 부팅한다.
3) factory는 업데이트 대상이 아니다.
4) 용량이 부족할 경우 factory를 삭제하고 ota_0과 ota_1로 확장하여 사용하면 된다.
2. 서버 소스
node.js로 작성하는 소스의 일부는 다음과 같다.
http서버의 /uploads/app.bin이라고 요청하면 해당 폴더의 app.bin파일이 다운받아지는 구조다.
브라우저에서 직접 주소를 치고 app.bin파일이 다운받아지는지 확인하면 끝이다.
//펌웨어 다운로드 app.get('/uploads/*', function (req, res) { var uri = url.parse(req.url, true); var pathname = uri.pathname; var fileurl = pathname.replace('/uploads/', ''); const file = `${__dirname}/uploads/` + fileurl; console.log('firwmware download : ', uri.pathname); res.download(file); });2. 예시 소스 참조
IDF의 example>system>ota>simple_ota_example을 참조한다.
단 여기에는 HTTPS로 업데이트 하게 되어있다(기본이 HTTPS다)
따라서 아래와 같이 기존 내용을 수정한다.
주석을 친 부분이 기존 소스에서 주로 수정한 부분들이다.
void simple_ota_example_task(void *pvParameter) { char url_temp[100]; sprintf(url_temp, "http://%s:%s/%s", otaserver, otaport, "uploads/app.bin"); ESP_LOGI(OTA_TAG, "Starting OTA example task"); // #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF // esp_netif_t *netif = get_example_netif_from_desc(bind_interface_name); // if (netif == NULL) { // ESP_LOGE(OTA_TAG, "Can't find netif from interface description"); // abort(); // } // struct ifreq ifr; // esp_netif_get_netif_impl_name(netif, ifr.ifr_name); // ESP_LOGI(OTA_TAG, "Bind interface name is %s", ifr.ifr_name); // #endif esp_http_client_config_t config = { .url = url_temp, // #ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE // .crt_bundle_attach = esp_crt_bundle_attach, // #else // .cert_pem = (char *)server_cert_pem_start, // #endif /* CONFIG_EXAMPLE_USE_CERT_BUNDLE */ .event_handler = _http_event_handler, .keep_alive_enable = true, // #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF // .if_name = &ifr, // #endif }; // #ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK // config.skip_cert_common_name_check = true; // #endif esp_https_ota_config_t ota_config = { .http_config = &config, }; ESP_LOGI(OTA_TAG, "Attempting to download update from %s", config.url); esp_err_t ret = esp_https_ota(&ota_config); if (ret == ESP_OK) { ESP_LOGI(OTA_TAG, "OTA Succeed, Rebooting..."); esp_restart(); } else { ESP_LOGE(OTA_TAG, "Firmware upgrade failed"); } while (1) { vTaskDelay(1000 / portTICK_PERIOD_MS); } }그러나 다음과 같은 에러 메시지가 나온다.
ESP32에서는 기본이 HTTPS OTA 다운로드이기 때문에 인증서 사용을 안한다고 나오는 에러이다.

이를 위한 테스트용옵션으로 변경해야 한다.
idf.py menuconfig > Component config > ESP HTTPS OTA에서 아래 내용을 체크해준다.

이후 실행을 하면 한참동안 로그가 발생되지 않다가 아래와 같이 한번에 나오며

아래와 같이 V1.01에서 V1.0으로 된 것을 확인할 수 있다.

프로그램 상 OTA TASK는 로드가 걸리는 부분이므로 프로그램에 주의를 하여 와치독에 걸리지 않도록 주의해야 한다.
'DEVICE' 카테고리의 다른 글
STM32CubeIDE에서 ST-Link V2 인식 안될 때 (0) 2024.08.07 ESP32 IDF환경에서 JSON활성화시키기 (0) 2023.11.02 ESP32 Flash Download Tools (0) 2023.10.13 ESP-IDF 윈도우즈 설치 (1) 2023.10.12 STM32 TIMER PWM NEGATIVE 동작 안할때 (0) 2023.02.24