diff --git a/docs/Application_guide/en/firmware-upgrade/firmware-ota-delta-package-making.md b/docs/Application_guide/en/firmware-upgrade/firmware-ota-delta-package-making.md index 759f5847a280e1051150a5f01d5e8cf8ee81ffce..7d9d8afcf5dab2358b8e0a4f1b163f1de6f98976 100644 --- a/docs/Application_guide/en/firmware-upgrade/firmware-ota-delta-package-making.md +++ b/docs/Application_guide/en/firmware-upgrade/firmware-ota-delta-package-making.md @@ -18,7 +18,7 @@ This document introduces the method of making QuecPython FOTA upgrade packages. 6. Click "**OK**" to generate the upgrade package. -![](../media/firmware-upgrade/firmware-ota/OTA9.png) +![](../media/firmware-upgrade/firmware-ota/ota_package_make_1.png) ## EC200A Series @@ -34,7 +34,7 @@ This document introduces the method of making QuecPython FOTA upgrade packages. 5. Click "**OK**" to generate the upgrade package. -![](../media/firmware-upgrade/firmware-ota/OTA10.png) +![](../media/firmware-upgrade/firmware-ota/ota_package_make_2.png) ## EC200U Series @@ -49,7 +49,7 @@ This document introduces the method of making QuecPython FOTA upgrade packages. 5. Click "**OK**" to generate the upgrade package. -![](../media/firmware-upgrade/firmware-ota/OTA8.png) +![](../media/firmware-upgrade/firmware-ota/ota_package_make_3.png) ## BG95&BG600L Series diff --git a/docs/Application_guide/en/firmware-upgrade/firmware-ota.md b/docs/Application_guide/en/firmware-upgrade/firmware-ota.md index d39cc3f7c57b368bf0146cc3232982936ce222fc..9655656f66c0f93f6737cfab9b25c7f6f4e2f1d1 100644 --- a/docs/Application_guide/en/firmware-upgrade/firmware-ota.md +++ b/docs/Application_guide/en/firmware-upgrade/firmware-ota.md @@ -55,7 +55,7 @@ QuecPython分区表构成细节可以参见[QuecPython存储设备介绍](../sys 固件程序镜像占用的存储空间较大,而设备的存储空间有限,因此固件采用的是差分升级方案。而文件系统分区在设备启动后内容会发生变动无法作差分升级,因此用户应用脚本只能作全量升级。进而导致固件和应用脚本无法同时升级。所以,QuecPython OTA升级也分为固件升级和APP升级。实际使用过程中,为了实现远程控制设备自动进行OTA升级,通常都要结合云平台实现设备端加云端的一整套OTA方案,如下框图。 -![](../media/firmware-upgrade/firmware-ota/OTA_cloud.jpg) +![](../media/firmware-upgrade/firmware-ota/aws_ota_flow_chart.png) ### 固件升级步骤 @@ -81,11 +81,11 @@ OTA云平台的作用是: 3.升级状态管理,如升级成功或者失败。 -借助于OTA云平台可实现网页控制OTA自动升级。使用前需要先初始化云平台相关的功能。API细节参考[QuecPython IoT 平台](https://python.quectel.com/doc/API_reference/zh/cloudlib/index.html)。 +借助于OTA云平台可实现网页控制OTA自动升级。使用前需要先初始化云平台相关的功能,如证书填写和连接云平台。 ###### 2.接收云平台升级消息 -用户在云平台网页触发OTA升级,设备会收到消息通知,从消息中获取到升级包URL。在前述初始化云平台功能后,订阅OTA升级相关的主题即可接收到云平台发送的消息通知。 +用户在云平台网页创建OTA任务并部署,设备通过定期轮询获取消息通知,从消息中获取到升级包URL。在前述初始化云平台功能后,订阅OTA任务相关的主题并定期发布特定主题可接收到云平台发送的消息通知。 ###### 3.下载升级包 @@ -93,43 +93,82 @@ OTA云平台的作用是: ###### 4.重启 -升级包校验成功后,需重启模块(自动重启或手动重启),系统在设备重启之后自动进行OTA升级。 +升级包校验成功后,需重启模块(自动重启或手动重启),系统在设备重启之后自动进行升级。 ###### 5.运行新固件 -升级完成后自动运行新固件,将当前版本号上报到云平台,云平台判断是否升级成功。 +升级完成后自动运行新固件,将当前版本号和云平台上OTA任务文档中的版本号进行比对,如果一致则发布特定主题,上报OTA成功的状态到云平台。 #### 云端准备 -##### 阿里云 +##### 亚马逊云 -如果使用阿里云平台的OTA功能,首先需要接入阿里云,设备如何接入阿里云可以参考[aLiYun - 阿里 IoT 平台](https://python.quectel.com/doc/API_reference/zh/cloudlib/aLiYun.html)。接入阿里云之后如何使用云平台OTA功能可以参见[阿里云物联网平台OTA升级操作相关文档](https://help.aliyun.com/document_detail/130990.html?spm=a2c4g.130990.0.0.28722110xYe5Td)。 +如果使用亚马逊云平台的OTA功能,首先需要接入亚马逊云,设备如何接入亚马逊云可以参考[亚马逊云应用指导文档]()。 -这里以阿里云为例展示OTA平台使用操作步骤: +这里以亚马逊云为例展示OTA平台使用操作步骤: -1.创建OTA模块,以设备平台名称命名,如: `EC600N-CNLC` +1.创建S3存储桶,下图中的qpyota即为最终创建的存储桶。 -![](../media/firmware-upgrade/firmware-ota/aliyun_ota_fota_module.png) +![](../media/firmware-upgrade/firmware-ota/aws_s3.png) -2.创建OTA升级包 +![](../media/firmware-upgrade/firmware-ota/aws_s3_create.png) -![](../media/firmware-upgrade/firmware-ota/aliyun_ota_fota_upgrade_package.png) +2.上传升级包文件和OTA任务描述文档到S3存储桶,点击下图中的upload按钮进行上传,下图中的EG915UEUAB_V0002-V0003.pack为FOTA升级的差分包,fota.json为FOTA升级任务的描述文档。 -3.选择批量升级, 创建升级计划 +![](../media/firmware-upgrade/firmware-ota/aws_s3_fota_upload.png) -![](../media/firmware-upgrade/firmware-ota/aliyun_ota_fota_plain.png) +其中升级任务的描述文档格式参照下述内容: -4.等待设备升级,查看升级结果 +```json +[ + { + "operation":"FOTA", + "files":[ + { + "fileName":"EG915UEUAB_V0002-V0003.pack", + "fileVersion": "EG915UEUABR03A21M08_OCPU_QPY", + "fileSource":{ + "url":"${aws:iot:s3-presigned-url:https://qpyota.s3.us-west-2.amazonaws.com/EG915UEUAB_V0002-V0003.pack}" + } + } + ] + } +] +``` + +3.创建OTA升级任务 + +找到AWS IOT版块,选择管理->远程操作->任务,点击create job按钮。 + +![](../media/firmware-upgrade/firmware-ota/aws_ota_jobs_create.png) + +在第1步填入任务名称和任务描述后,进入第2步进行文件配置,选择任务作用的目标物品,可以选择特定的物品如QuecPython_OTA,也可以选择物品组,物品组中包含多个设备。这里的物品是事先创建好的,具体创建方法可以参考[亚马逊云应用指导文档]()中的描述。接下来再选择任务描述文档,即前面已经上传到S3存储桶的fota.json文件。再接下来需要为预前面的URL创建一个IAM角色,这里的预签名URL的作用是为了生成一个有期限的升级包文件URL给设备下载时使用,因为安全限制,设备无法直接下载S3存储桶上的升级包文件。这里设定URL的有效时长为60分钟。 + +![](../media/firmware-upgrade/firmware-ota/aws_ota_jobs_create1.png) + +![](../media/firmware-upgrade/firmware-ota/aws_ota_jobs_create2.png) + +上述完成后进入第3步任务配置,选择部署方式后点击submit完成任务创建,jobfota即为已创建的任务。 + +![](../media/firmware-upgrade/firmware-ota/aws_ota_jobs_create3.png) + +![](../media/firmware-upgrade/firmware-ota/aws_ota_jobs_create4.png) -![](../media/firmware-upgrade/firmware-ota/aliyun_ota_fota_upgrade_process.png) +点击任务jobfota可以查看任务细节,如下任务执行页面展示升级任务的执行情况,当前有一个物品QuecPython_OTA在排队等待执行升级任务。任务文档页面展示当前升级任务的细节,如升级模式为"FOTA",升级包的名称为"EG915UEUAB_V0002-V0003.pack",升级到的目标版本号"EG915UEUABR03A21M08_OCPU_QPY",以及升级包文件的URL。 -##### 腾讯云 +![](../media/firmware-upgrade/firmware-ota/aws_ota_jobs_create5.png) -如果使用腾讯云平台的OTA功能,首先需要接入腾讯云,设备如何接入腾讯云可以参考[TenCentYun- 腾讯 IoT 平台](https://python.quectel.com/doc/API_reference/zh/cloudlib/TenCentYun.html)。接入腾讯云之后如何使用云平台OTA功能可以参见[腾讯云物联网开发平台固件升级协议](https://cloud.tencent.com/document/product/1081/39359)。[腾讯云物联网开发平台固件升级操作](https://cloud.tencent.com/document/product/1081/40296)。 +![](../media/firmware-upgrade/firmware-ota/aws_ota_jobs_create6.png) -##### 移远云 +4.设备端运行升级程序,等待设备升级,查看升级结果 -如果使用移远云平台的OTA功能,首先需要接入移远云,设备如何接入移远云可以参见QuecPython接入移远云操作文档(待补充)。接入移远云之后如何使用云平台OTA功能可以参见[移远云OTA升级操作文档](https://iot-cloud-docs.quectelcn.com/guide/deviceManage/ota/page-02.html)。 +下载阶段完成上报进度。 + +![](../media/firmware-upgrade/firmware-ota/aws_ota_result.png) + +升级完成重启后上报升级成功。 + +![](../media/firmware-upgrade/firmware-ota/aws_ota_result1.png) ### APP升级使用步骤 @@ -145,11 +184,11 @@ OTA云平台的作用是: ###### 1.初始化云平台功能 -借助于OTA云平台可实现网页控制OTA自动升级。使用前需要先初始化云平台相关的功能。API细节参考wiki API [QuecPython云平台](https://python.quectel.com/doc/API_reference/zh/cloudlib/index.html)。 +借助于OTA云平台可实现网页控制OTA自动升级。使用前需要先初始化云平台相关的功能,如证书填写和连接云平台。 ###### 2.接收云平台升级消息 -用户在云平台网页触发OTA升级,设备会收到消息通知,从消息中获取到升级包url。在前述初始化云平台功能后,订阅OTA升级相关的主题即可接收到云平台发送的消息通知。 +用户在云平台网页创建OTA任务并部署,设备通过定期轮询获取消息通知,从消息中获取到升级包URL。在前述初始化云平台功能后,订阅OTA任务相关的主题并定期发布特定主题可接收到云平台发送的消息通知。 ###### 3.下载升级包 @@ -165,209 +204,294 @@ OTA云平台的作用是: ###### 6.运行新固件 -升级完成后会清除升级标志,进入新的应用程序。将当前版本号上报到云平台,云平台判断是否升级成功。 +升级完成后会清除升级标志,进入新的应用程序。将当前版本号和云平台上OTA任务文档中的版本号进行比对,如果一致则发布特定主题,上报OTA成功的状态到云平台。 #### 云端准备 -##### 阿里云 - -参考固件升级配置方法。 - -以阿里云为例展示OTA平台使用操作步骤: - -1.创建OTA模块,以`PROJECT_NAME`命名,如: `QuecPython-Tracker` +##### 亚马逊云 + +以亚马逊云为例展示OTA平台使用操作步骤: + +1.上传升级包文件和OTA任务描述文档到S3存储桶,点击下图中的upload按钮进行上传,下图中的a.py和b.py分别为app_fota升级的目标python脚本文件,app_fota.json为app_fota升级任务的描述文档。 + +![](../media/firmware-upgrade/firmware-ota/aws_s3_upload.png) + +其中升级任务的描述文档格式参照下述内容: + +```json +[ + { + "operation":"app_fota", + "files":[ + { + "fileName":"/usr/a.py", + "fileVersion": "2.0", + "fileSource":{ + "url":"${aws:iot:s3-presigned-url:https://qpyota.s3.us-west-2.amazonaws.com/a.py}" + } + }, + { + "fileName":"/usr/b.py", + "fileVersion": "2.0", + "fileSource":{ + "url":"${aws:iot:s3-presigned-url:https://qpyota.s3.us-west-2.amazonaws.com/b.py}" + } + } + ] + } +] +``` -![](../media/firmware-upgrade/firmware-ota/aliyun_ota_sota_module.png) +3.创建OTA升级任务 -2.创建OTA升级包,将需要升级的项目文件后缀名修改为`.bin`。此处需要在**推送给设备的自定义信息**中编写升级文件名对应的设备全路径文件名, 如: `{"files":{"common.bin":"/usr/modules/common.py","settings.bin":"/usr/settings.py","test_tracker.bin":"/usr/test_tracker.py"}}`。 +具体方法和固件升级任务创建一致,区别是选择的任务描述文档不一样,选择前面上传的app_fota.json文件。 -![](../media/firmware-upgrade/firmware-ota/aliyun_ota_sota_upgrade_package.png) +![](../media/firmware-upgrade/firmware-ota/aws_appota_jobs_create.png) -3.选择批量升级, 创建升级计划 +4.设备端运行升级程序,等待设备升级,查看升级结果 -![](../media/firmware-upgrade/firmware-ota/aliyun_ota_sota_plain.png) +下载阶段完成上报进度。 -4.等待设备升级,查看升级结果 +![](../media/firmware-upgrade/firmware-ota/aws_appota_result.png) -![](../media/firmware-upgrade/firmware-ota/aliyun_ota_sota_upgrade_process.png) +升级完成重启后上报升级成功。 -##### 腾讯云 +![](../media/firmware-upgrade/firmware-ota/aws_appota_result1.png) -参考固件升级配置方法。 +## 示例代码 -##### 移远云 +### 亚马逊云 -参考固件升级配置方法。 +aws.py -## 示例代码 +```python +from umqtt import MQTTClient +import ujson +import utime as time +import _thread +import log + +class Aws(object): + """ + Azure client + """ + def __init__(self, client_id, username, password, server, port, keep_alive=60, ssl=False, ssl_params=None): + self.client_id = client_id + self.username = username + self.password = password + self.server = server + self.port = port + self.ssl = ssl + self.ssl_params = ssl_params + self.client = None + self.connected = False + self.keep_alive = keep_alive + self.callback = None + self.logging = log.getLogger("AWS") + + def _connect(self): + try: + self.client = MQTTClient(self.client_id, + self.server, + port=self.port, + user=self.username, + password=self.password, + keepalive=self.keep_alive, + ssl=self.ssl, + ssl_params=self.ssl_params) + self.client.connect() + self.connected = True + if self.callback: + self.client.set_callback(self.callback) + self.logging.info("Connected to Aws IoT Hub") + return True + except Exception as e: + self.logging.error("Failed to connect to Aws IoT Hub: %s", e) + return False + + def set_callback(self, callback): + self.callback = callback + + def connect(self): + if not self.check_connection(): + self._connect() + + def check_connection(self): + return self.connected + + def disconnect(self): + try: + if self.client: + self.client.disconnect() + self.client = None + self.connected = False + self.logging.info("Disconnected from Aws IoT Hub") + return True + except Exception as e: + self.logging.error("Failed to disconnect from Aws IoT Hub: %s", e) + return False + + def subscribe(self, topic): + try: + if self.client: + self.client.subscribe(topic) + self.logging.info("subscribe success") + return True + except Exception as e: + self.logging.error("Failed to subscribe to Aws IoT Hub: %s", e) + return False + + def publish(self, topic, payload): + try: + if self.client: + self.client.publish(topic, ujson.dumps(payload)) + self.logging.info("publish success") + except Exception as e: + self.logging.error("Failed to publish message: %s", e) + + def loop(self): + try: + while True: + if self.client: + self.client.wait_msg() + else: + time.sleep_ms(100) + except Exception as e: + self.logging.error("Error in MQTT loop: %s", e) + + def loop_forever(self): + _thread.start_new_thread(self.loop, ()) +``` -### 阿里云 +aws_ota_test.py ```python +from usr.aws import Aws +import modem +import ujson import uos import fota import app_fota -import modem -import ujson from misc import Power -from aliYun import aLiYun - -# 定义软件名称 -PROJECT_NAME = "QuecPython-XXX" -# 定义软件版本 -PROJECT_VERSION = "1.0.0" -# 获取固件型号 -FIRMWARE_NAME = uos.uname()[0].split("=")[1] -# 获取固件版本号 +import utime + +# certificate.crt +certificate_content = """ +# (content of certificate.pem.crt) +""" +# private.pem +private_content = """ +# (content of private.pem.key) +""" + +# device name +client_id = 'QuecPython_OTA' +# server address +server = 'ambzd54j67b7h-ats.iot.us-west-2.amazonaws.com' +# port +port = 8883 +# user +user = None +# pwd +pwd = None + +# get firmware version FIRMWARE_VERSION = modem.getDevFwVersion() -# 初始化aLiYun功能 -ProductKey = "xxx" -ProductSecret = "xxx" -DeviceName = "xxx" -DeviceSecret = "xxx" -MqttServer = "xxx" -cloud = aLiYun(ProductKey, ProductSecret, DeviceName, DeviceSecret, MqttServer) - -# 初始化OTA相关Topic -# 设备模块版本信息上报topic -ota_topic_device_inform = "/ota/device/inform/%s/%s" % (ProductKey, DeviceName) -# 设备OTA升级计划下发topic -ota_topic_device_upgrade = "/ota/device/upgrade/%s/%s" % (ProductKey, DeviceName) -# 设备升级进度上报topic -ota_topic_device_progress = "/ota/device/progress/%s/%s" % (ProductKey, DeviceName) -# 设备OTA升级计划查询topic -ota_topic_firmware_get = "/sys/%s/%s/thing/ota/firmware/get" % (ProductKey, DeviceName) -# 设备OTA升级计划查询应答topic -ota_topic_firmware_get_reply = "/sys/%s/%s/thing/ota/firmware/get_reply" % (ProductKey, DeviceName) - -# 设置MQTT连接 -client_id = modem.getDevImei() -clean_session = True -cloud.setMqtt(client_id, clean_session) - - -ota_module = None -# 订阅Topic回调函数 -def sub_cb(topic, data): - if topic in (ota_topic_device_upgrade, ota_topic_firmware_get_reply): - # OTA升级 - global ota_module - data = ujson.loads(data) - ota_module = data["module"] - ota_version = data["version"] - if ota_module == FIRMWARE_NAME: - # FOTA升级 +import usr.a as a +APP_VERSION = a.getversion() + +def fota_callback(args): + print("Download status: %s, Download process: %s" % tuple(args)) + status = "IN_PROGRESS" + progress = args[1] + process_data = {"status": status,"statusDetails":{"progress":progress, "step":"downloading"}} + aws_obj.publish("$aws/things/QuecPython_OTA/jobs/jobfota/update", process_data) + +def event_callback(topic, data): + """ + aws callback + """ + import ujson + global operation + receive_data = ujson.loads(data.decode()) + # print("Subscribe Recv: Topic={},Msg={}".format(topic.decode(), data.decode())) + operation = receive_data["execution"]["jobDocument"][0]["operation"] + version = receive_data["execution"]["jobDocument"][0]["files"][0]["fileVersion"] + + if operation == "FOTA": + # FOTA + if version == FIRMWARE_VERSION: + print("fota SUCCEEDED") + process_data = {"status": "SUCCEEDED","statusDetails":{"operation": 'install', "state": 'package installed and started'}} + aws_obj.publish("$aws/things/QuecPython_OTA/jobs/jobfota/update", process_data) + else: + print("start fota") _fota = fota() - _fota.httpDownload(url1=data.get("url"), callback=fota_callback) - elif ota_module == PROJECT_NAME: - # SOTA升级 - ota_data = [{"url": i["fileUrl"], "filename": "/usr/" + i["fileName"].replace(".bin", ".py")} for i in data.get("files", [])] + ret = _fota.httpDownload(url1=receive_data["execution"]["jobDocument"][0]["files"][0]["fileSource"]["url"], callback=fota_callback) + if ret == 0: + print("fota download completely", ret) + else: + status = "FAILED" + print("fota FAILED", ret) + process_data = {"status": status,"statusDetails":{"progress":100}} + aws_obj.publish("$aws/things/QuecPython_OTA/jobs/jobfota/update", process_data) + elif operation == "app_fota": + # app_fota + if version == APP_VERSION: + print("app_fota SUCCEEDED") + process_data = {"status": "SUCCEEDED","statusDetails":{"operation": 'install', "state": 'package installed and started'}} + aws_obj.publish("$aws/things/QuecPython_OTA/jobs/jobappota/update", process_data) + else: + print("start app_fota") _app_fota = app_fota.new() + ota_data = [{"url": i["fileSource"]["url"], "file_name": i["fileName"]} for i in receive_data["execution"]["jobDocument"][0]["files"]] res = _app_fota.bulk_download(ota_data) - # SOTA上报升级结果 ota_process = 100 if not res else -1 if ota_process == 100: _app_fota.set_update_flag() - process_data = { - "id": 5, - "params": { - "step": ota_process, - "desc": "desc", - "module": ota_module, - } - } - cloud.publish(ota_topic_device_progress, ujson.dumps(process_data), qos=1) - # 升级完成之后需要重启设备 - Power.powerRestart() - - - -# FOTA升级进度回调函数 -def fota_callback(args): - print("Download status: %s, Download process: %s" % tuple(args)) - ota_process = None - if args[0] in (0, 1, 2) and args[1] == 100: - ota_process = 100 - else: - ota_process = -1 - if ota_process is not None: - # FOTA上报升级结果 - process_data = { - "id": 5, - "params": { - "step": ota_process, - "desc": "success", - "module": ota_module, - } - } - cloud.publish(ota_topic_device_progress, ujson.dumps(process_data), qos=1) - # 升级成功后会自动重启, 此处无需手动重启 - #Power.powerRestart() - - -# 设置订阅Topic回调函数 -cloud.setCallBack(sub_cb) - -# 订阅Topic -qos = 1 -cloud.subscribe(ota_topic_device_upgrade, qos) -cloud.subscribe(ota_topic_firmware_get_reply￿, qos) - -# 阿里云功能启动 -cloud.start() - -# 上报软件版本信息 -sota_data = { - "id": 1, - "params": { - "version": PROJECT_VERSION, - "module": PROJECT_NAME, - } -} -cloud.publish(ota_topic_device_inform, ujson.dumps(sota_data), qos=1) - -# 上报固件版本信息 -fota_data = { - "id": 2, - "params": { - "version": FIRMWARE_VERSION, - "module": FIRMWARE_NAME, - } -} -cloud.publish(ota_topic_device_inform, ujson.dumps(fota_data), qos=1) - -# 查询软件升级计划 -sota_query = { - "id": 3, - "version": "1.0", - "params": { - "module": PROJECT_NAME, - }, - "method": "thing.ota.firmware.get" -} -cloud.publish(ota_topic_firmware_get, ujson.dumps(sota_query), qos=1) - -# 查询固件升级计划 -sota_query = { - "id": 4, - "version": "1.0", - "params": { - "module": FIRMWARE_NAME, - }, - "method": "thing.ota.firmware.get" -} -cloud.publish(ota_topic_firmware_get, ujson.dumps(sota_query), qos=1) + print("app_fota download completely") + process_data = {"status": "IN_PROGRESS","statusDetails":{"progress":ota_process, "step":"downloading"}} + aws_obj.publish("$aws/things/QuecPython_OTA/jobs/jobappota/update", process_data) + utime.sleep(5) + # restart device + Power.powerRestart() + else: + status = "FAILED" + print("app_fota FAILED", res) + process_data = {"status": status,"statusDetails":{"progress":100}} + aws_obj.publish("$aws/things/QuecPython_OTA/jobs/jobappota/update", process_data) + +# create aws obj +aws_obj = Aws(client_id, user, pwd, server, port, keep_alive=60,ssl=True,ssl_params={"cert": certificate_content,"key": private_content}) +print("create aws obj") +# register callback +aws_obj.set_callback(event_callback) +print("aws set callback") + +# connect mqtt server +print("aws connect start") +aws_obj.connect() +print("aws connect end") + +# subscribe jobs topic +aws_obj.subscribe("$aws/things/QuecPython_OTA/jobs/notify") +aws_obj.subscribe("$aws/things/QuecPython_OTA/jobs/get/accepted") + +# start +aws_obj.loop_forever() +print("aws loop_forever") + +# get ota jobs +utime.sleep(5) +a = {"key":0} +aws_obj.publish("$aws/things/QuecPython_OTA/jobs/get", a) +utime.sleep(5) +aws_obj.publish("$aws/things/QuecPython_OTA/jobs/jobfota/get", a) +utime.sleep(5) +aws_obj.publish("$aws/things/QuecPython_OTA/jobs/jobappota/get", a) ``` -### 腾讯云 - -程序架构同阿里云示例代码一致,只需修改云平台功能部分代码为腾讯云平台。 - -### 移远云 - -程序架构同阿里云示例代码一致,只需修改云平台功能部分代码为移远云平台。 - ## 各型号支持情况 | 型号 | 差分升级 | 最小系统升级 | diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_jobs_create.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_jobs_create.png new file mode 100644 index 0000000000000000000000000000000000000000..b80d6188a5efcc89305f2262b4099c8e462b49f8 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_jobs_create.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_result.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_result.png new file mode 100644 index 0000000000000000000000000000000000000000..f98c5b1707f490a267ab99c3885bbb2e0128d1bf Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_result.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_result1.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_result1.png new file mode 100644 index 0000000000000000000000000000000000000000..7fe3cc009e5649274072cf6a6f562a3b197cf108 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_appota_result1.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_flow_chart.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_flow_chart.png new file mode 100644 index 0000000000000000000000000000000000000000..53179e0164dd7dc31ed951ed717e0c980e0a76c6 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_flow_chart.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create.png new file mode 100644 index 0000000000000000000000000000000000000000..7137208b9bf9f0af66738ffbf746e500b0b36763 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create1.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create1.png new file mode 100644 index 0000000000000000000000000000000000000000..a84df2d68e50cee38c6495cc7ceff1edec809271 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create1.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create2.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create2.png new file mode 100644 index 0000000000000000000000000000000000000000..38ccd119f67fe656aa0b579bec8e38c156c552dd Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create2.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create3.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create3.png new file mode 100644 index 0000000000000000000000000000000000000000..e885fdd4fb756f7c747a3e6f61d4f9dfb707c9cd Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create3.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create4.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create4.png new file mode 100644 index 0000000000000000000000000000000000000000..8f381a949779e8049825879fd0adb4c818e31412 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create4.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create5.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create5.png new file mode 100644 index 0000000000000000000000000000000000000000..4228770cb25a0088ce879f7f9a9bd905a312b199 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create5.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create6.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create6.png new file mode 100644 index 0000000000000000000000000000000000000000..bc109c3f55a606ab815218cf884bb279a807f9bb Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_jobs_create6.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_result.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_result.png new file mode 100644 index 0000000000000000000000000000000000000000..9d96138df94c120c2774ad619cd4ff4909f3bc71 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_result.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_result1.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_result1.png new file mode 100644 index 0000000000000000000000000000000000000000..8afa29777536152c451deeb2a434edc94ce64800 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_ota_result1.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3.png new file mode 100644 index 0000000000000000000000000000000000000000..902868de26d0577c5c796384f01badae2bc5be07 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_create.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_create.png new file mode 100644 index 0000000000000000000000000000000000000000..9e7befafcf1fdad78a733c413b66359d4e220274 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_create.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_fota_upload.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_fota_upload.png new file mode 100644 index 0000000000000000000000000000000000000000..44690e7e0d1642539ddcfb09fd96e9795b5cbca5 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_fota_upload.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_upload.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_upload.png new file mode 100644 index 0000000000000000000000000000000000000000..b89921451cef2d82e4c7dcfd750fd05d1599f040 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/aws_s3_upload.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_1.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_1.png new file mode 100644 index 0000000000000000000000000000000000000000..e47248e051acff2c2046b0c2035c980af4abf6a1 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_1.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_2.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ba7769462b3699a249aff7fcd79e600bb4031245 Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_2.png differ diff --git a/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_3.png b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_3.png new file mode 100644 index 0000000000000000000000000000000000000000..2066a474fe431704d596a97686c64e86d5078b6c Binary files /dev/null and b/docs/Application_guide/en/media/firmware-upgrade/firmware-ota/ota_package_make_3.png differ diff --git a/docs/Application_guide/en/media/system/fs/backup_restore.png b/docs/Application_guide/en/media/system/fs/backup_restore.png new file mode 100644 index 0000000000000000000000000000000000000000..b859efd84d391bd492bfc605496a5682fb6a0f06 Binary files /dev/null and b/docs/Application_guide/en/media/system/fs/backup_restore.png differ diff --git a/docs/Application_guide/en/media/system/memory-management/memory_layout.png b/docs/Application_guide/en/media/system/memory-management/memory_layout.png index b3b5e438c63247654981245f69e73a9b7e43e561..98ec0033b9ad2b2cb77098e0e5be408206db9b6a 100644 Binary files a/docs/Application_guide/en/media/system/memory-management/memory_layout.png and b/docs/Application_guide/en/media/system/memory-management/memory_layout.png differ diff --git a/docs/Application_guide/zh/media/system/fs/backup_restore.png b/docs/Application_guide/zh/media/system/fs/backup_restore.png new file mode 100644 index 0000000000000000000000000000000000000000..ecf9ba426fbcf7b87cde6eb3c94a0118b8e864a2 Binary files /dev/null and b/docs/Application_guide/zh/media/system/fs/backup_restore.png differ diff --git a/docs/Application_guide/zh/system/fs.md b/docs/Application_guide/zh/system/fs.md index b0c325d7c5c1e3682f645bb7e605ebd8bbd1404d..1deb44605224eba3b6d4c9c4854b8d4446de09a8 100644 --- a/docs/Application_guide/zh/system/fs.md +++ b/docs/Application_guide/zh/system/fs.md @@ -357,20 +357,38 @@ path of the file:/usr/a/b ### 概述 -QuecPython设备软件由固件和用户应用脚本2部分组成。其中固件存放在系统程序分区,而用户应用脚本存放在设备文件系统分区。为了确保系统稳定性,设计了文件系统备份还原机制。当前设备划分了2个文件系统分区,分别是:用户文件系统usr和备份文件系统bak。用户文件系统存放用户正常运行需要的py脚本和数据文件,可读写。备份文件系统用来备份用户文件系统中的出厂原始文件,只读。如果开启了备份还原功能,当用户文件系统中的文件被误删除或意外被修改时,会自动从备份文件系统还原原始的文件到用户文件系统。NOR flash空间分布如下图: +QuecPython设备软件由固件和用户应用脚本2部分组成。其中固件存放在系统程序分区包括kernel和QuecPython VM,而用户应用脚本存放在设备文件系统分区。为了确保系统稳定性,设计了文件系统备份还原机制。当前设备划分了2个文件系统分区,分别是:用户文件系统usr和备份文件系统bak。用户文件系统存放用户正常运行需要的py脚本和数据文件,可读写。备份文件系统用来备份用户文件系统中的出厂原始文件,只读。如果开启了备份还原功能,当用户文件系统中的文件被误删除或意外被修改时,会自动从备份文件系统还原原始的文件到用户文件系统。NOR flash空间分布如下图: ![](../media/system/fs/FS_2.png) ### 实现原理 -1. 用户通过使用QPYcom工具合并固件时,勾选【备份】,文件将自动导入“**备份文件系统分区**”,会在“**备份文件系统分区**”生成两个名称分别为checksum.json和backup_restore.json的文件。checksum.json记录了备份区文件的CRC校验值。backup_restore.json记录是否开启备份还原功能的标志。 -2. 开机启动阶段检测到开启了备份还原功能,系统会检测“**用户文件系统分区**”是否存在checksum.json文件。若不存在,则将”**备份文件系统分区**“的checksum.json拷贝到“**用户文件系统分区**”。然后使用"**用户文件系统分区**"的checksum.json文件中的CRC校验值,和利用“**用户文件系统分区**”中用户文件计算出来的CRC校验值进行比对。如果文件不存在或者校验值不相等,则将“**备份文件系统分区**”对应的文件拷贝到“**用户文件系统分区**”,并重新计算CRC校验值并更新到“**用户文件系统分区**”的checksum.json文件中。 -3. 当参与备份还原的用户文件需要OTA升级时,在升级过程的最后一步,会将更新后的用户文件的CRC校验值更新到“**用户文件系统分区**”的checksum.json文件中。 +![](../media/system/fs/backup_restore.png) -综上,触发还原动作有以下几种情况: +#### 备份 -1. 用户文件系统分区的checksum.json文件被意外删除。 -2. 用户文件系统分区中文件的数据发生变化,或者文件丢失。 +对用户文件系统的文件进行备份,具体流程是: + +1.将用户文件系统下的源文件拷贝一份到备份文件系统。 + +2.在用户文件系统和备份文件系统各生成一个checksum.json文件。该文件存放的内容是每一个源文件的文件名和其对应的checksum值,checksum值是根据每一个源文件的内容通过CRC32算法计算出来的,所以每一个源文件都有唯一对应的一个checksum值。 + +3.在备份文件系统生成一个备份还原标志文件backup_restore.json,记录是否开启备份还原功能。 + +#### 还原 + +当用户文件系统的文件发生损坏时,从备份文件系统中拷贝对应的文件到用户文件系统。具体流程是: +1.开机检测到备份文件系统中备份还原的标志使能,且用户文件系统下的checksum.json文件存在,这时如果用户文件系统下的某个源文件被删除,则会将备份文件系统中对应源文件拷贝到用户文件系统下,并更新该文件对应的checksum值到用户文件系统下的checksum.json文件中。 + +2.开机检测到备份文件系统中备份还原的标志使能,且用户文件系统下的checksum.json文件存在,这时如果用户文件系统下的某个源文件被破坏,则会将备份文件系统中对应源文件拷贝到用户文件系统下,并更新该文件对应的checksum值到用户文件系统下的checksum.json文件中。 + +3.开机检测到备份文件系统中备份还原的标志使能,这时如果用户文件系统下的checksum.json文件不存在,则会将备份文件系统中checksum.json文件拷贝一份到用户文件系统,然后再走上述1、2步的检测流程。 + +#### OTA更新 + +当用户文件系统的文件需要OTA升级时,在升级成功后,会将升级后的用户文件的checksum值更新到用户文件系统下的checksum.json文件中。 + +> 注意:不会更新备份文件系统下的checksum文件和源文件。 ### 工具操作