update to 0.4.1
This commit is contained in:
parent
357cd95693
commit
32a5977fcc
@ -4,7 +4,7 @@
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(PROJECT_VER "0.4.0")
|
||||
set(PROJECT_VER "0.4.1")
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(xiaozhi)
|
||||
|
||||
@ -44,7 +44,6 @@ Application::Application()
|
||||
|
||||
firmware_upgrade_.SetCheckVersionUrl(CONFIG_OTA_VERSION_URL);
|
||||
firmware_upgrade_.SetHeader("Device-Id", SystemInfo::GetMacAddress().c_str());
|
||||
firmware_upgrade_.SetPostData(SystemInfo::GetJsonString());
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
@ -156,8 +155,10 @@ void Application::Start() {
|
||||
ml307_at_modem_.ResetConnections();
|
||||
ml307_at_modem_.WaitForNetworkReady();
|
||||
|
||||
ESP_LOGI(TAG, "ML307 IMEI: %s", ml307_at_modem_.GetImei().c_str());
|
||||
ESP_LOGI(TAG, "ML307 ICCID: %s", ml307_at_modem_.GetIccid().c_str());
|
||||
std::string imei = ml307_at_modem_.GetImei();
|
||||
std::string iccid = ml307_at_modem_.GetIccid();
|
||||
ESP_LOGI(TAG, "ML307 IMEI: %s", imei.c_str());
|
||||
ESP_LOGI(TAG, "ML307 ICCID: %s", iccid.c_str());
|
||||
|
||||
// If low power, the material ready event will be triggered by the modem because of a reset
|
||||
ml307_at_modem_.OnMaterialReady([this]() {
|
||||
@ -166,6 +167,17 @@ void Application::Start() {
|
||||
SetChatState(kChatStateIdle);
|
||||
});
|
||||
});
|
||||
|
||||
// Set the board type for OTA
|
||||
std::string carrier_name = ml307_at_modem_.GetCarrierName();
|
||||
int csq = ml307_at_modem_.GetCsq();
|
||||
std::string board_json = std::string("{\"type\":\"compact.4g\",");
|
||||
board_json += "\"revision\":\"" + module_name + "\",";
|
||||
board_json += "\"carrier\":\"" + carrier_name + "\",";
|
||||
board_json += "\"csq\":\"" + std::to_string(csq) + "\",";
|
||||
board_json += "\"imei\":\"" + imei + "\",";
|
||||
board_json += "\"iccid\":\"" + iccid + "\"}";
|
||||
firmware_upgrade_.SetBoardJson(board_json);
|
||||
#else
|
||||
// Try to connect to WiFi, if failed, launch the WiFi configuration AP
|
||||
auto& wifi_station = WifiStation::GetInstance();
|
||||
@ -186,6 +198,15 @@ void Application::Start() {
|
||||
wifi_ap.Start();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the board type for OTA
|
||||
std::string board_json = std::string("{\"type\":\"compact.wifi\",");
|
||||
board_json += "\"ssid\":\"" + wifi_station.GetSsid() + "\",";
|
||||
board_json += "\"rssi\":" + std::to_string(wifi_station.GetRssi()) + ",";
|
||||
board_json += "\"channel\":" + std::to_string(wifi_station.GetChannel()) + ",";
|
||||
board_json += "\"ip\":\"" + wifi_station.GetIpAddress() + "\",";
|
||||
board_json += "\"mac\":\"" + SystemInfo::GetMacAddress() + "\"}";
|
||||
firmware_upgrade_.SetBoardJson(board_json);
|
||||
#endif
|
||||
|
||||
audio_device_.Initialize();
|
||||
@ -646,8 +667,8 @@ void Application::StartWebSocketClient() {
|
||||
}
|
||||
#endif
|
||||
ws_client_->SetHeader("Authorization", token.c_str());
|
||||
ws_client_->SetHeader("Device-Id", SystemInfo::GetMacAddress().c_str());
|
||||
ws_client_->SetHeader("Protocol-Version", std::to_string(PROTOCOL_VERSION).c_str());
|
||||
ws_client_->SetHeader("Device-Id", SystemInfo::GetMacAddress().c_str());
|
||||
|
||||
ws_client_->OnConnected([this]() {
|
||||
ESP_LOGI(TAG, "Websocket connected");
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <esp_http_client.h>
|
||||
#include <esp_ota_ops.h>
|
||||
#include <esp_app_format.h>
|
||||
#include <esp_chip_info.h>
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
@ -24,10 +25,6 @@ void FirmwareUpgrade::SetCheckVersionUrl(std::string check_version_url) {
|
||||
check_version_url_ = check_version_url;
|
||||
}
|
||||
|
||||
void FirmwareUpgrade::SetPostData(const std::string& post_data) {
|
||||
post_data_ = post_data;
|
||||
}
|
||||
|
||||
void FirmwareUpgrade::SetHeader(const std::string& key, const std::string& value) {
|
||||
headers_[key] = value;
|
||||
}
|
||||
@ -45,13 +42,9 @@ void FirmwareUpgrade::CheckVersion() {
|
||||
http_.SetHeader(header.first, header.second);
|
||||
}
|
||||
|
||||
if (post_data_.empty()) {
|
||||
http_.Open("GET", check_version_url_);
|
||||
} else {
|
||||
http_.SetHeader("Content-Type", "application/json");
|
||||
http_.SetContent(post_data_);
|
||||
http_.Open("POST", check_version_url_);
|
||||
}
|
||||
http_.SetHeader("Content-Type", "application/json");
|
||||
http_.SetContent(GetPostData());
|
||||
http_.Open("POST", check_version_url_);
|
||||
|
||||
auto response = http_.GetBody();
|
||||
http_.Close();
|
||||
@ -257,3 +250,99 @@ bool FirmwareUpgrade::IsNewVersionAvailable(const std::string& currentVersion, c
|
||||
|
||||
return newer.size() > current.size();
|
||||
}
|
||||
|
||||
void FirmwareUpgrade::SetBoardJson(const std::string& board_json) {
|
||||
board_json_ = board_json;
|
||||
}
|
||||
|
||||
std::string FirmwareUpgrade::GetPostData() {
|
||||
/*
|
||||
{
|
||||
"flash_size": 4194304,
|
||||
"psram_size": 0,
|
||||
"minimum_free_heap_size": 123456,
|
||||
"mac_address": "00:00:00:00:00:00",
|
||||
"chip_model_name": "esp32s3",
|
||||
"chip_info": {
|
||||
"model": 1,
|
||||
"cores": 2,
|
||||
"revision": 0,
|
||||
"features": 0
|
||||
},
|
||||
"application": {
|
||||
"name": "my-app",
|
||||
"version": "1.0.0",
|
||||
"compile_time": "2021-01-01T00:00:00Z"
|
||||
"idf_version": "4.2-dev"
|
||||
"elf_sha256": ""
|
||||
},
|
||||
"partition_table": [
|
||||
"app": {
|
||||
"label": "app",
|
||||
"type": 1,
|
||||
"subtype": 2,
|
||||
"address": 0x10000,
|
||||
"size": 0x100000
|
||||
}
|
||||
],
|
||||
"ota": {
|
||||
"label": "ota_0"
|
||||
}
|
||||
}
|
||||
*/
|
||||
std::string json = "{";
|
||||
json += "\"flash_size\":" + std::to_string(SystemInfo::GetFlashSize()) + ",";
|
||||
json += "\"minimum_free_heap_size\":" + std::to_string(SystemInfo::GetMinimumFreeHeapSize()) + ",";
|
||||
json += "\"mac_address\":\"" + SystemInfo::GetMacAddress() + "\",";
|
||||
json += "\"chip_model_name\":\"" + SystemInfo::GetChipModelName() + "\",";
|
||||
json += "\"chip_info\":{";
|
||||
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
json += "\"model\":" + std::to_string(chip_info.model) + ",";
|
||||
json += "\"cores\":" + std::to_string(chip_info.cores) + ",";
|
||||
json += "\"revision\":" + std::to_string(chip_info.revision) + ",";
|
||||
json += "\"features\":" + std::to_string(chip_info.features);
|
||||
json += "},";
|
||||
|
||||
json += "\"application\":{";
|
||||
auto app_desc = esp_app_get_description();
|
||||
json += "\"name\":\"" + std::string(app_desc->project_name) + "\",";
|
||||
json += "\"version\":\"" + std::string(app_desc->version) + "\",";
|
||||
json += "\"compile_time\":\"" + std::string(app_desc->date) + "T" + std::string(app_desc->time) + "Z\",";
|
||||
json += "\"idf_version\":\"" + std::string(app_desc->idf_ver) + "\",";
|
||||
|
||||
char sha256_str[65];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
snprintf(sha256_str + i * 2, sizeof(sha256_str) - i * 2, "%02x", app_desc->app_elf_sha256[i]);
|
||||
}
|
||||
json += "\"elf_sha256\":\"" + std::string(sha256_str) + "\"";
|
||||
json += "},";
|
||||
|
||||
json += "\"partition_table\": [";
|
||||
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL);
|
||||
while (it) {
|
||||
const esp_partition_t *partition = esp_partition_get(it);
|
||||
json += "{";
|
||||
json += "\"label\":\"" + std::string(partition->label) + "\",";
|
||||
json += "\"type\":" + std::to_string(partition->type) + ",";
|
||||
json += "\"subtype\":" + std::to_string(partition->subtype) + ",";
|
||||
json += "\"address\":" + std::to_string(partition->address) + ",";
|
||||
json += "\"size\":" + std::to_string(partition->size);
|
||||
json += "},";
|
||||
it = esp_partition_next(it);
|
||||
}
|
||||
json.pop_back(); // Remove the last comma
|
||||
json += "],";
|
||||
|
||||
json += "\"ota\":{";
|
||||
auto ota_partition = esp_ota_get_running_partition();
|
||||
json += "\"label\":\"" + std::string(ota_partition->label) + "\"";
|
||||
json += "},";
|
||||
|
||||
json += "\"board\":" + board_json_;
|
||||
|
||||
// Close the JSON object
|
||||
json += "}";
|
||||
return json;
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@ public:
|
||||
FirmwareUpgrade(Http& http);
|
||||
~FirmwareUpgrade();
|
||||
|
||||
void SetBoardJson(const std::string& board_json);
|
||||
void SetCheckVersionUrl(std::string check_version_url);
|
||||
void SetPostData(const std::string& post_data);
|
||||
void SetHeader(const std::string& key, const std::string& value);
|
||||
void CheckVersion();
|
||||
bool HasNewVersion() { return has_new_version_; }
|
||||
@ -26,13 +26,14 @@ private:
|
||||
bool has_new_version_ = false;
|
||||
std::string firmware_version_;
|
||||
std::string firmware_url_;
|
||||
std::string post_data_;
|
||||
std::string board_json_;
|
||||
std::map<std::string, std::string> headers_;
|
||||
|
||||
void Upgrade(const std::string& firmware_url);
|
||||
std::function<void(int progress, size_t speed)> upgrade_callback_;
|
||||
std::vector<int> ParseVersion(const std::string& version);
|
||||
bool IsNewVersionAvailable(const std::string& currentVersion, const std::string& newVersion);
|
||||
std::string GetPostData();
|
||||
};
|
||||
|
||||
#endif // _FIRMWARE_UPGRADE_H
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
#include <esp_log.h>
|
||||
#include <esp_flash.h>
|
||||
#include <esp_mac.h>
|
||||
#include <esp_chip_info.h>
|
||||
#include <esp_system.h>
|
||||
#include <esp_partition.h>
|
||||
#include <esp_app_desc.h>
|
||||
@ -41,96 +40,6 @@ std::string SystemInfo::GetChipModelName() {
|
||||
return std::string(CONFIG_IDF_TARGET);
|
||||
}
|
||||
|
||||
std::string SystemInfo::GetJsonString() {
|
||||
/*
|
||||
{
|
||||
"flash_size": 4194304,
|
||||
"psram_size": 0,
|
||||
"minimum_free_heap_size": 123456,
|
||||
"mac_address": "00:00:00:00:00:00",
|
||||
"chip_model_name": "esp32s3",
|
||||
"chip_info": {
|
||||
"model": 1,
|
||||
"cores": 2,
|
||||
"revision": 0,
|
||||
"features": 0
|
||||
},
|
||||
"application": {
|
||||
"name": "my-app",
|
||||
"version": "1.0.0",
|
||||
"compile_time": "2021-01-01T00:00:00Z"
|
||||
"idf_version": "4.2-dev"
|
||||
"elf_sha256": ""
|
||||
},
|
||||
"partition_table": [
|
||||
"app": {
|
||||
"label": "app",
|
||||
"type": 1,
|
||||
"subtype": 2,
|
||||
"address": 0x10000,
|
||||
"size": 0x100000
|
||||
}
|
||||
],
|
||||
"ota": {
|
||||
"label": "ota_0"
|
||||
}
|
||||
}
|
||||
*/
|
||||
std::string json = "{";
|
||||
json += "\"flash_size\":" + std::to_string(GetFlashSize()) + ",";
|
||||
json += "\"minimum_free_heap_size\":" + std::to_string(GetMinimumFreeHeapSize()) + ",";
|
||||
json += "\"mac_address\":\"" + GetMacAddress() + "\",";
|
||||
json += "\"chip_model_name\":\"" + GetChipModelName() + "\",";
|
||||
json += "\"chip_info\":{";
|
||||
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
json += "\"model\":" + std::to_string(chip_info.model) + ",";
|
||||
json += "\"cores\":" + std::to_string(chip_info.cores) + ",";
|
||||
json += "\"revision\":" + std::to_string(chip_info.revision) + ",";
|
||||
json += "\"features\":" + std::to_string(chip_info.features);
|
||||
json += "},";
|
||||
|
||||
json += "\"application\":{";
|
||||
auto app_desc = esp_app_get_description();
|
||||
json += "\"name\":\"" + std::string(app_desc->project_name) + "\",";
|
||||
json += "\"version\":\"" + std::string(app_desc->version) + "\",";
|
||||
json += "\"compile_time\":\"" + std::string(app_desc->date) + "T" + std::string(app_desc->time) + "Z\",";
|
||||
json += "\"idf_version\":\"" + std::string(app_desc->idf_ver) + "\",";
|
||||
|
||||
char sha256_str[65];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
snprintf(sha256_str + i * 2, sizeof(sha256_str) - i * 2, "%02x", app_desc->app_elf_sha256[i]);
|
||||
}
|
||||
json += "\"elf_sha256\":\"" + std::string(sha256_str) + "\"";
|
||||
json += "},";
|
||||
|
||||
json += "\"partition_table\": [";
|
||||
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL);
|
||||
while (it) {
|
||||
const esp_partition_t *partition = esp_partition_get(it);
|
||||
json += "{";
|
||||
json += "\"label\":\"" + std::string(partition->label) + "\",";
|
||||
json += "\"type\":" + std::to_string(partition->type) + ",";
|
||||
json += "\"subtype\":" + std::to_string(partition->subtype) + ",";
|
||||
json += "\"address\":" + std::to_string(partition->address) + ",";
|
||||
json += "\"size\":" + std::to_string(partition->size);
|
||||
json += "},";
|
||||
it = esp_partition_next(it);
|
||||
}
|
||||
json.pop_back(); // Remove the last comma
|
||||
json += "],";
|
||||
|
||||
json += "\"ota\":{";
|
||||
auto ota_partition = esp_ota_get_running_partition();
|
||||
json += "\"label\":\"" + std::string(ota_partition->label) + "\"";
|
||||
json += "}";
|
||||
|
||||
// Close the JSON object
|
||||
json += "}";
|
||||
return json;
|
||||
}
|
||||
|
||||
esp_err_t SystemInfo::PrintRealTimeStats(TickType_t xTicksToWait) {
|
||||
#define ARRAY_SIZE_OFFSET 5
|
||||
TaskStatus_t *start_array = NULL, *end_array = NULL;
|
||||
|
||||
@ -13,7 +13,6 @@ public:
|
||||
static size_t GetFreeHeapSize();
|
||||
static std::string GetMacAddress();
|
||||
static std::string GetChipModelName();
|
||||
static std::string GetJsonString();
|
||||
static esp_err_t PrintRealTimeStats(TickType_t xTicksToWait);
|
||||
};
|
||||
|
||||
|
||||
68
pack.py
68
pack.py
@ -1,68 +0,0 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import csv
|
||||
import os
|
||||
|
||||
# 例如:1000, 0x1000, 1M
|
||||
def read_value(text):
|
||||
text = text.strip()
|
||||
if text.endswith('K'):
|
||||
return int(text[:-1]) * 1024
|
||||
elif text.endswith('M'):
|
||||
return int(text[:-1]) * 1024 * 1024
|
||||
else:
|
||||
if text.startswith('0x'):
|
||||
return int(text, 16)
|
||||
else:
|
||||
return int(text)
|
||||
|
||||
|
||||
def write_bin(image_data, offset, file_path, max_size=None):
|
||||
# Read file_path and write to image_data
|
||||
with open(file_path, 'rb') as f:
|
||||
data = f.read()
|
||||
if max_size is not None:
|
||||
assert len(data) <= max_size, f"Data from {file_path} is too large"
|
||||
image_data[offset:offset+len(data)] = data
|
||||
print(f"Write {os.path.basename(file_path)} to 0x{offset:08X} with size 0x{len(data):08X}")
|
||||
|
||||
|
||||
'''
|
||||
根据 partitions.csv 文件,把 bin 文件打包成一个 4MB 的 image 文件,方便烧录
|
||||
'''
|
||||
def pack_firmware_image():
|
||||
# Create a 4MB image filled with 0xFF
|
||||
image_size = 4 * 1024 * 1024
|
||||
image_data = bytearray([0xFF] * image_size)
|
||||
|
||||
build_dir = os.path.join(os.path.dirname(__file__), 'build')
|
||||
write_bin(image_data, 0, os.path.join(build_dir, 'bootloader', 'bootloader.bin'))
|
||||
write_bin(image_data, 0x8000, os.path.join(build_dir, 'partition_table', 'partition-table.bin'))
|
||||
|
||||
# 读取 partitions.csv 文件
|
||||
with open('partitions.csv', 'r') as f:
|
||||
reader = csv.reader(f)
|
||||
for row in reader:
|
||||
if row[0] == 'model':
|
||||
file_path = os.path.join(build_dir, 'srmodels', 'srmodels.bin')
|
||||
elif row[0] == 'factory':
|
||||
file_path = os.path.join(build_dir, 'xiaozhi.bin')
|
||||
else:
|
||||
continue
|
||||
|
||||
offset = read_value(row[3])
|
||||
size = read_value(row[4])
|
||||
write_bin(image_data, offset, file_path, size)
|
||||
|
||||
# 写入 image 文件
|
||||
output_path = os.path.join(build_dir, 'xiaozhi.img')
|
||||
with open(output_path, 'wb') as f:
|
||||
f.write(image_data)
|
||||
print(f"Image file {output_path} created with size 0x{len(image_data):08X}")
|
||||
|
||||
# Compress image with zip without directory
|
||||
os.system(f"zip -j {output_path}.zip {output_path}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pack_firmware_image()
|
||||
Loading…
Reference in New Issue
Block a user