diff --git a/Ameba_misc/Ameba_tools/postbuild_tool/postbuild.cpp b/Ameba_misc/Ameba_tools/postbuild_tool/postbuild.cpp index 5ecc62a8..72b5cf3e 100644 --- a/Ameba_misc/Ameba_tools/postbuild_tool/postbuild.cpp +++ b/Ameba_misc/Ameba_tools/postbuild_tool/postbuild.cpp @@ -38,6 +38,8 @@ string isp_file_name_buf[100]; string nn_model_yolotiny_name, nn_model_srcfd_name, nn_model_mobilefacenet_name, nn_model_yamnet_name, nn_model_imgclass_name, nn_header_name1, nn_header_name2, nn_header_name3, nn_header_name4, nn_header_name5, isp_bin_check_name, ota_mode_check_name, fcs_mode_check_name; string ino_name_buf[100]; +string partitiontable_json_name, partition_bin_name; + int isp_selection_check = 0; int nn_model_selection_check = 0; int ota_mode_selection_check = 0; @@ -307,7 +309,7 @@ int main(int argc, char *argv[]) { string string_temp_1 = "cp misc/video_img/"; string string_temp_2 = " ./"; string string_temp_3 = "cp misc/nn_img/"; - string string_temp_4 = "cp "; + string string_temp_4 = "cp -r "; string string_temp_5 = "/*"; string string_temp_6 = "cp image_tool/"; string string_temp_7 = "misc/video_img/"; @@ -580,21 +582,32 @@ int main(int argc, char *argv[]) { system(cmd.c_str()); } + ota_mode_check_name = argv[8]; + ota_mode_check(ota_mode_check_name); + + if (ota_mode_selection_check == 1){ + partitiontable_json_name = "amebapro2_partitiontable_OTA.json"; + partition_bin_name = "partition_ota.bin"; + } else { + partitiontable_json_name = "amebapro2_partitiontable.json"; + partition_bin_name = "partition.bin"; + } + cmdss.clear(); - cmdss << string_temp_1 << "combine amebapro2_partitiontable.json system_files.bin PT_PT=partition.bin,CER_TBL=certable.bin,KEY_CER1=certificate.bin,PT_BL_PRI=boot.bin,PT_FCSDATA=boot_fcs.bin"; + cmdss << string_temp_1 << "combine "<< partitiontable_json_name << " system_files.bin PT_PT=" << partition_bin_name << ",CER_TBL=certable.bin,KEY_CER1=certificate.bin,PT_BL_PRI=boot.bin,PT_FCSDATA=boot_fcs.bin"; getline(cmdss, cmd); cout << cmd << endl; system(cmd.c_str()); if (nn_model_selection_check == 1) { cmdss.clear(); - cmdss << string_temp_1 << "combine amebapro2_partitiontable.json flash_ntz.bin PT_PT=partition.bin,CER_TBL=certable.bin,KEY_CER1=certificate.bin,PT_BL_PRI=boot.bin,PT_FW1=firmware.bin,PT_NN_MDL=nn_model.bin,PT_ISP_IQ=firmware_isp_iq.bin,PT_FCSDATA=boot_fcs.bin"; + cmdss << string_temp_1 << "combine "<< partitiontable_json_name << " flash_ntz.bin PT_PT=" << partition_bin_name << ",CER_TBL=certable.bin,KEY_CER1=certificate.bin,PT_BL_PRI=boot.bin,PT_FW1=firmware.bin,PT_NN_MDL=nn_model.bin,PT_ISP_IQ=firmware_isp_iq.bin,PT_FCSDATA=boot_fcs.bin"; getline(cmdss, cmd); cout << cmd << endl; system(cmd.c_str()); } else { cmdss.clear(); - cmdss << string_temp_1 << "combine amebapro2_partitiontable.json flash_ntz.bin PT_PT=partition.bin,CER_TBL=certable.bin,KEY_CER1=certificate.bin,PT_BL_PRI=boot.bin,PT_FW1=firmware.bin,PT_ISP_IQ=firmware_isp_iq.bin,PT_FCSDATA=boot_fcs.bin"; + cmdss << string_temp_1 << "combine "<< partitiontable_json_name << " flash_ntz.bin PT_PT=" << partition_bin_name << ",CER_TBL=certable.bin,KEY_CER1=certificate.bin,PT_BL_PRI=boot.bin,PT_FW1=firmware.bin,PT_ISP_IQ=firmware_isp_iq.bin,PT_FCSDATA=boot_fcs.bin"; getline(cmdss, cmd); cout << cmd << endl; system(cmd.c_str()); @@ -623,9 +636,6 @@ int main(int argc, char *argv[]) { #error compiler is not supported! #endif - ota_mode_check_name = argv[8]; - ota_mode_check(ota_mode_check_name); - if (ota_mode_selection_check == 1) { cmdss.clear(); cmdss << string_temp_1 << " -E copy "<< string_temp_3 << "firmware.bin "<< string_temp_3 << "ota.bin"; diff --git a/Ameba_misc/Ameba_tools/prebuild_tool/prebuild.cpp b/Ameba_misc/Ameba_tools/prebuild_tool/prebuild.cpp index 297f583c..04910a01 100644 --- a/Ameba_misc/Ameba_tools/prebuild_tool/prebuild.cpp +++ b/Ameba_misc/Ameba_tools/prebuild_tool/prebuild.cpp @@ -39,6 +39,12 @@ int main(int argc, char *argv[]) { // runtime tool path chdir(argv[1]); + + if (strcmp(argv[10], "Enable") == 0 && strcmp(argv[11], "LoadFromFlash") == 0) { + cerr << "OTA is enabled, please select load model from SD card and not load model from flash." << endl; + exit(EXIT_FAILURE); + } + chdir("../.."); isp_camera_option = argv[7]; diff --git a/Arduino_package/ameba_pro2_tools_linux/misc/sys_img/partition_ota.bin b/Arduino_package/ameba_pro2_tools_linux/misc/sys_img/partition_ota.bin new file mode 100755 index 00000000..0208bdd6 Binary files /dev/null and b/Arduino_package/ameba_pro2_tools_linux/misc/sys_img/partition_ota.bin differ diff --git a/Arduino_package/ameba_pro2_tools_linux/postbuild_linux b/Arduino_package/ameba_pro2_tools_linux/postbuild_linux old mode 100644 new mode 100755 index 2b2e85e7..ec3592f7 Binary files a/Arduino_package/ameba_pro2_tools_linux/postbuild_linux and b/Arduino_package/ameba_pro2_tools_linux/postbuild_linux differ diff --git a/Arduino_package/ameba_pro2_tools_linux/prebuild_linux b/Arduino_package/ameba_pro2_tools_linux/prebuild_linux old mode 100644 new mode 100755 index 8d6038e6..839f8ab8 Binary files a/Arduino_package/ameba_pro2_tools_linux/prebuild_linux and b/Arduino_package/ameba_pro2_tools_linux/prebuild_linux differ diff --git a/Arduino_package/ameba_pro2_tools_macos/misc/sys_img/partition_ota.bin b/Arduino_package/ameba_pro2_tools_macos/misc/sys_img/partition_ota.bin new file mode 100755 index 00000000..0208bdd6 Binary files /dev/null and b/Arduino_package/ameba_pro2_tools_macos/misc/sys_img/partition_ota.bin differ diff --git a/Arduino_package/ameba_pro2_tools_macos/postbuild_macos b/Arduino_package/ameba_pro2_tools_macos/postbuild_macos old mode 100644 new mode 100755 index 6e43d32f..36497597 Binary files a/Arduino_package/ameba_pro2_tools_macos/postbuild_macos and b/Arduino_package/ameba_pro2_tools_macos/postbuild_macos differ diff --git a/Arduino_package/ameba_pro2_tools_macos/prebuild_macos b/Arduino_package/ameba_pro2_tools_macos/prebuild_macos old mode 100644 new mode 100755 index 4310e431..6bdb6bfb Binary files a/Arduino_package/ameba_pro2_tools_macos/prebuild_macos and b/Arduino_package/ameba_pro2_tools_macos/prebuild_macos differ diff --git a/Arduino_package/ameba_pro2_tools_windows/misc/sys_img/partition_ota.bin b/Arduino_package/ameba_pro2_tools_windows/misc/sys_img/partition_ota.bin new file mode 100755 index 00000000..0208bdd6 Binary files /dev/null and b/Arduino_package/ameba_pro2_tools_windows/misc/sys_img/partition_ota.bin differ diff --git a/Arduino_package/ameba_pro2_tools_windows/postbuild_windows.exe b/Arduino_package/ameba_pro2_tools_windows/postbuild_windows.exe old mode 100644 new mode 100755 index b653d4ab..5d810b5f Binary files a/Arduino_package/ameba_pro2_tools_windows/postbuild_windows.exe and b/Arduino_package/ameba_pro2_tools_windows/postbuild_windows.exe differ diff --git a/Arduino_package/ameba_pro2_tools_windows/prebuild_windows.exe b/Arduino_package/ameba_pro2_tools_windows/prebuild_windows.exe old mode 100644 new mode 100755 index bb6f58a5..4131cca0 Binary files a/Arduino_package/ameba_pro2_tools_windows/prebuild_windows.exe and b/Arduino_package/ameba_pro2_tools_windows/prebuild_windows.exe differ diff --git a/Arduino_package/hardware/libraries/OTA/examples/OTA/OTA.ino b/Arduino_package/hardware/libraries/OTA/examples/OTA/OTA.ino new file mode 100755 index 00000000..af49078d --- /dev/null +++ b/Arduino_package/hardware/libraries/OTA/examples/OTA/OTA.ino @@ -0,0 +1,28 @@ +#include "ota_thread.h" +#include "WiFi.h" + + +char ssid[] = "Network_SSID"; // your network SSID (name) +char pass[] = "Password"; // your network password +int status = WL_IDLE_STATUS; + +void setup() +{ + Serial.begin(115200); + + // Connection to internet + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to WPA SSID: "); + Serial.println(ssid); + status = WiFi.begin(ssid, pass); + delay(2000); + } + + // Set up the threads + start_OTA_threads(); +} + +void loop() +{ + // Empty or add non-blocking code here +} diff --git a/Arduino_package/hardware/libraries/OTA/keywords.txt b/Arduino_package/hardware/libraries/OTA/keywords.txt new file mode 100755 index 00000000..277846f0 --- /dev/null +++ b/Arduino_package/hardware/libraries/OTA/keywords.txt @@ -0,0 +1,18 @@ +####################################### +# Syntax Coloring Map for OTA +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +start_OTA_threads KEYWORD2 + + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/Arduino_package/hardware/libraries/OTA/library.properties b/Arduino_package/hardware/libraries/OTA/library.properties new file mode 100755 index 00000000..ce3936f3 --- /dev/null +++ b/Arduino_package/hardware/libraries/OTA/library.properties @@ -0,0 +1,9 @@ +name=AmebaOTA +version=1.0.0 +author=Realtek SG +maintainer=Realtek SG +sentence=Ameba OTA API +paragraph=With this you can do over-the-air firmware updates +category=OTA +url= +architectures=AmebaPro2 diff --git a/Arduino_package/hardware/libraries/OTA/src/ota_drv.c b/Arduino_package/hardware/libraries/OTA/src/ota_drv.c new file mode 100644 index 00000000..e88ebe22 --- /dev/null +++ b/Arduino_package/hardware/libraries/OTA/src/ota_drv.c @@ -0,0 +1,47 @@ +#include +#include +#include "wifi_conf.h" +#include "lwip_netconf.h" +#include +#include "ota_drv.h" + +const int PORT = 3000; // MODIFY THIS FOR YOUR HTTP SERVER PORT +const char *server = "192.168.3.4"; // MODIFY THIS FOR YOUR HTTP SERVER IP ADDRESS +const char *resource = "api/uploadfile"; // DO NOT MODIFY + + +// DO NOT MODIFY +const char *OtaState[] = { + "OTA_STATE_IDLE", + "OTA_STATE_RECEIVED_START_SIGNAL", + "OTA_STATE_DOWNLOAD_FIRMWARE_IN_PROGRESS", + "OTA_STATE_DOWNLOAD_FIRMWARE_COMPLETED", + "OTA_STATE_REBOOT"}; + +void http_update_ota_task(void *param) +{ + (void)param; + + int ret = -1; + + g_otaState = OtaState[2]; + + ret = http_update_ota((char *)server, PORT, (char *)resource); + + g_otaState = OtaState[3]; + + // printf("\n\r[%s] Update task exit", __FUNCTION__); + if (!ret) { + // printf("\n\r[%s] Ready to reboot", __FUNCTION__); + g_otaState = OtaState[4]; + ota_platform_reset(); + } + vTaskDelete(NULL); +} + +void ota_http(void) +{ + if (xTaskCreate(http_update_ota_task, (const char *)"http_update_ota_task", 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) { + printf("\n\r[%s] Create update task failed", __FUNCTION__); + } +} diff --git a/Arduino_package/hardware/libraries/OTA/src/ota_drv.h b/Arduino_package/hardware/libraries/OTA/src/ota_drv.h new file mode 100644 index 00000000..ae65f538 --- /dev/null +++ b/Arduino_package/hardware/libraries/OTA/src/ota_drv.h @@ -0,0 +1,10 @@ +#pragma once + +extern const int PORT; +extern const char *server; +extern const char *resource; + +extern const char *OtaState[]; +extern const char *g_otaState; + +void ota_http(void); diff --git a/Arduino_package/hardware/libraries/OTA/src/ota_thread.cpp b/Arduino_package/hardware/libraries/OTA/src/ota_thread.cpp new file mode 100755 index 00000000..d27984c4 --- /dev/null +++ b/Arduino_package/hardware/libraries/OTA/src/ota_thread.cpp @@ -0,0 +1,104 @@ +#define ARDUINOJSON_STRING_LENGTH_SIZE_4 + +#include +#include "ota_thread.h" +#include +#include + +extern "C" { +#include "ota_drv.h" +} + +const char *g_otaState = OtaState[0]; +JsonDocument doc; +String jsonString; +char buffer[1024]; +uint32_t thread1_id, thread2_id, thread3_id, stack_size1, stack_size2; +int priority1; + + +void sendPostRequest() +{ + doc["OTA_state"] = g_otaState; + serializeJson(doc, jsonString); + WiFiClient wifiClient; + + if (wifiClient.connect(server, PORT)) { + // Send POST request + wifiClient.println("POST /api/connectedclients HTTP/1.1"); + wifiClient.println("Host: " + String(server)); + wifiClient.println("Content-Type: application/json"); // Use appropriate content type + wifiClient.println("Content-Length: " + String(jsonString.length())); // Specify the length of the content + wifiClient.println("Connection: keep-alive"); + wifiClient.println(); // Empty line indicates the end of headers + wifiClient.print(jsonString); + } else { + Serial.println("Connection to server failed"); + } + delay(500); + wifiClient.stop(); + delay(3000); +} + +void thread1_task(const void *argument) +{ + while (1) { + sendPostRequest(); + } +} + +void thread2_task(const void *argument) +{ + WiFiServer server(5000); + server.begin(); + while (1) { + WiFiClient client = server.available(); + + while (client.connected()) { + memset(buffer, 0, 1024); + int n = client.read((uint8_t *)(&buffer[0]), sizeof(buffer)); + if (n > 0) { + for (int i = 0; i < n; i++) { + // Serial.print(buffer[i]); + } + n = client.write(buffer, n); + if (n <= 0) { + break; + } + if (strstr(buffer, "start_ota")) { + // Serial.print("\n[OTA] Received start OTA signal from UI."); + if (g_otaState == OtaState[0]) { + ota_http(); + } + } + } + delay(500); + client.stop(); + } + } +} + + +void start_OTA_threads() +{ + priority1 = osPriorityNormal; + stack_size1 = 1024; + thread1_id = os_thread_create_arduino(thread1_task, NULL, priority1, stack_size1); + + // First thread is to do keep alive connectivity check (post requests every 5s) + if (thread1_id) { + Serial.println("[OTA] Keep-alive connectivity thread created successfully."); + } else { + Serial.println("[OTA] Failed to create keep-alive connectivity thread."); + } + + stack_size2 = 2048; + thread2_id = os_thread_create_arduino(thread2_task, NULL, priority1, stack_size2); + + // Second thread is to get the signal to start OTA process. + if (thread2_id) { + Serial.println("[OTA] Start OTA process thread created successfully."); + } else { + Serial.println("[OTA] Failed to create Start OTA process thread."); + } +} diff --git a/Arduino_package/hardware/libraries/OTA/src/ota_thread.h b/Arduino_package/hardware/libraries/OTA/src/ota_thread.h new file mode 100755 index 00000000..02836927 --- /dev/null +++ b/Arduino_package/hardware/libraries/OTA/src/ota_thread.h @@ -0,0 +1,13 @@ +#ifndef OTA_THREAD_H +#define OTA_THREAD_H + +#include +#include + +// Function declarations +void start_OTA_threads(); +void thread1_task(const void *argument); +void thread2_task(const void *argument); + + +#endif // OTA_THREAD_H diff --git a/Arduino_package/hardware/platform.txt b/Arduino_package/hardware/platform.txt index c3207a13..34e0e387 100644 --- a/Arduino_package/hardware/platform.txt +++ b/Arduino_package/hardware/platform.txt @@ -136,9 +136,9 @@ recipe.hooks.prebuild.1.pattern.linux = chmod -R 777 "{ameba.tools_path}" recipe.hooks.prebuild.1.pattern.macosx= chmod -R 777 "{ameba.tools_path}" ## combine toolchain -recipe.hooks.prebuild.2.pattern.windows = "{ameba.tools_path}/prebuild_windows.exe" "{toolchain.path}" "{toolchain_p1_name_path}" "{toolchain_p2_name_path}" {toolchain_p1_name} {toolchain_p2_name} "{hardware.path}" "{build.camera_opt}" "{nn_tool_name_path}" "{nn_tool_name}" -recipe.hooks.prebuild.2.pattern.linux = {ameba.tools_path}/prebuild_linux {toolchain.path} {toolchain_p1_name_path} {toolchain_p2_name_path} {toolchain_p1_name} {toolchain_p2_name} {hardware.path} {build.camera_opt} {nn_tool_name_path} {nn_tool_name} -recipe.hooks.prebuild.2.pattern.macosx = {ameba.tools_path}/prebuild_macos {toolchain.path} {toolchain_p1_name_path} {toolchain_p2_name_path} {toolchain_p1_name} {toolchain_p2_name} {hardware.path} {build.camera_opt} {nn_tool_name_path} {nn_tool_name} +recipe.hooks.prebuild.2.pattern.windows = "{ameba.tools_path}/prebuild_windows.exe" "{toolchain.path}" "{toolchain_p1_name_path}" "{toolchain_p2_name_path}" {toolchain_p1_name} {toolchain_p2_name} "{hardware.path}" "{build.camera_opt}" "{nn_tool_name_path}" "{nn_tool_name}" "{build.ota_mode_val}" "{build.model_src}" +recipe.hooks.prebuild.2.pattern.linux = {ameba.tools_path}/prebuild_linux {toolchain.path} {toolchain_p1_name_path} {toolchain_p2_name_path} {toolchain_p1_name} {toolchain_p2_name} {hardware.path} {build.camera_opt} {nn_tool_name_path} {nn_tool_name} {build.ota_mode_val} {build.model_src} +recipe.hooks.prebuild.2.pattern.macosx = {ameba.tools_path}/prebuild_macos {toolchain.path} {toolchain_p1_name_path} {toolchain_p2_name_path} {toolchain_p1_name} {toolchain_p2_name} {hardware.path} {build.camera_opt} {nn_tool_name_path} {nn_tool_name} {build.ota_mode_val} {build.model_src} recipe.hooks.prebuild.3.pattern.windows = "{ameba.tools_path}/ino_validation_windows.exe" "{build.path}" "{ameba.tools_path}" "{build.model_src}" recipe.hooks.prebuild.3.pattern.linux = {ameba.tools_path}/ino_validation_linux {build.path} {ameba.tools_path} {build.model_src} diff --git a/Arduino_package/package_realtek_amebapro2_early_index.json b/Arduino_package/package_realtek_amebapro2_early_index.json index eab90754..adfe039a 100644 --- a/Arduino_package/package_realtek_amebapro2_early_index.json +++ b/Arduino_package/package_realtek_amebapro2_early_index.json @@ -474,6 +474,33 @@ "size":"77770301" } ] + }, + { + "name": "ameba_pro2_tools", + "version": "1.3.7", + "systems": [ + { + "host": "i686-mingw32", + "archiveFileName": "ameba_pro2_tools_windows-1.3.7.tar.gz", + "url": "https://github.com/ambiot/ambpro2_arduino/raw/dev/Arduino_package/release/ameba_pro2_tools_windows-1.3.7.tar.gz", + "checksum": "SHA-256:220740c069c61fc94db9e086889d4a1b1aee2c2f5d82fb275daef11806c8eec5", + "size": "9426215" + }, + { + "host": "x86_64-pc-linux-gnu", + "archiveFileName": "ameba_pro2_tools_linux-1.3.7.tar.gz", + "url": "https://github.com/ambiot/ambpro2_arduino/raw/dev/Arduino_package/release/ameba_pro2_tools_linux-1.3.7.tar.gz", + "checksum": "SHA-256:985f00a1532d5be0a3250a183e92456565c8628a746962b74188d65c7b8e7def", + "size": "13271103" + }, + { + "host": "x86_64-apple-darwin", + "archiveFileName": "ameba_pro2_tools_macos-1.3.7.tar.gz", + "url": "https://github.com/ambiot/ambpro2_arduino/raw/dev/Arduino_package/release/ameba_pro2_tools_macos-1.3.7.tar.gz", + "checksum": "SHA-256:75696955e08537908c0ad4637e4c5454cb5c6de23ac611fc4fc69a8b64829cfa", + "size": "11471387" + } + ] }, { "name": "ameba_pro2_tools", diff --git a/Arduino_package/release/ameba_pro2_tools_linux-1.3.7.tar.gz b/Arduino_package/release/ameba_pro2_tools_linux-1.3.7.tar.gz new file mode 100644 index 00000000..6729db20 Binary files /dev/null and b/Arduino_package/release/ameba_pro2_tools_linux-1.3.7.tar.gz differ diff --git a/Arduino_package/release/ameba_pro2_tools_macos-1.3.7.tar.gz b/Arduino_package/release/ameba_pro2_tools_macos-1.3.7.tar.gz new file mode 100644 index 00000000..9112d2cc Binary files /dev/null and b/Arduino_package/release/ameba_pro2_tools_macos-1.3.7.tar.gz differ diff --git a/Arduino_package/release/ameba_pro2_tools_windows-1.3.7.tar.gz b/Arduino_package/release/ameba_pro2_tools_windows-1.3.7.tar.gz new file mode 100644 index 00000000..9e6a3d07 Binary files /dev/null and b/Arduino_package/release/ameba_pro2_tools_windows-1.3.7.tar.gz differ