
1. effective "Differential Upgrade" patch algorithm with high compression rate 2. effective recovery algorithm support recovery firmware in blocks which has low memory consumption and wear-leveling strategies, especially suitable for embeded devices with low RAM. 3. add sample ota bootloader project, see: board\TencentOS_tiny_EVB_MX_Plus\KEIL\ota\ota_bootloader_recovery 4. add sample application project for download firmware through http, see: board\TencentOS_tiny_EVB_MX_Plus\KEIL\ota\ota_application_download_through_http 5. add sample application project for download firmware through qcloud explorer console, see: board\TencentOS_tiny_EVB_MX_Plus\KEIL\ota\ota_application_download_through_qcloud_iot_explorer 6. an OTA markdown document is pending
234 lines
5.7 KiB
C
234 lines
5.7 KiB
C
/*----------------------------------------------------------------------------
|
|
* Tencent is pleased to support the open source community by making TencentOS
|
|
* available.
|
|
*
|
|
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
|
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
|
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
|
*
|
|
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
|
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
|
* License, except for the third-party components listed below which are
|
|
* subject to different license terms. Your integration of TencentOS into your
|
|
* own projects may require compliance with the BSD 3-Clause License, as well
|
|
* as the other licenses applicable to the third-party components included
|
|
* within TencentOS.
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
#include "stdlib.h"
|
|
#include "string.h"
|
|
#include "segment_tree.h"
|
|
|
|
#define ROOT 1
|
|
#define NODES_N(len) (3 * len)
|
|
|
|
static void segtree_build(stree_node_t *nodes, int left, int right, int root)
|
|
{
|
|
stree_node_t *node;
|
|
|
|
node = &nodes[root];
|
|
node->left = left;
|
|
node->right = right;
|
|
node->mid = (left + right) / 2;
|
|
node->is_covered = 0;
|
|
|
|
if (left + 1 != right) {
|
|
segtree_build(nodes, left, node->mid, 2 * root);
|
|
segtree_build(nodes, node->mid, right, 2 * root + 1);
|
|
}
|
|
}
|
|
|
|
int segtree_create(stree_t *stree, int left, int right)
|
|
{
|
|
int length;
|
|
stree_node_t *nodes;
|
|
|
|
if (!stree) {
|
|
return -1;
|
|
}
|
|
|
|
length = right - left;
|
|
if (length <= 0) {
|
|
return -1;
|
|
}
|
|
|
|
memset(stree, 0, sizeof(stree_t));
|
|
|
|
if ((nodes = (stree_node_t *)malloc(NODES_N(length) * sizeof(stree_node_t))) == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
memset(nodes, 0, NODES_N(length) * sizeof(stree_node_t));
|
|
|
|
segtree_build(nodes, left, right, ROOT);
|
|
|
|
stree->nodes = nodes;
|
|
stree->length = length;
|
|
stree->left = left;
|
|
stree->right = right;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int segtree_destroy(stree_t *stree)
|
|
{
|
|
if (!stree || !stree->nodes || !stree->length) {
|
|
return -1;
|
|
}
|
|
|
|
free(stree->nodes);
|
|
return 0;
|
|
}
|
|
|
|
int segtree_reset(stree_t *stree)
|
|
{
|
|
if (!stree || !stree->nodes || !stree->length) {
|
|
return -1;
|
|
}
|
|
|
|
memset(stree->nodes, 0, NODES_N(stree->length) * sizeof(stree_node_t));
|
|
|
|
segtree_build(stree->nodes, stree->left, stree->right, ROOT);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void segtree_do_insert(stree_node_t *nodes, int left, int right, int root)
|
|
{
|
|
stree_node_t *node;
|
|
|
|
node = &nodes[root];
|
|
|
|
if (node->left == left && node->right == right) {
|
|
node->is_covered = 1;
|
|
return;
|
|
}
|
|
|
|
if (right <= node->mid) {
|
|
segtree_do_insert(nodes, left, right, 2 * root);
|
|
} else if (left >= node->mid) {
|
|
segtree_do_insert(nodes, left, right, 2 * root + 1);
|
|
} else {
|
|
segtree_do_insert(nodes, left, node->mid, 2 * root);
|
|
segtree_do_insert(nodes, node->mid, right, 2 * root + 1);
|
|
}
|
|
}
|
|
|
|
int segtree_insert(stree_t *stree, int left, int right)
|
|
{
|
|
if (!stree || !stree->nodes) {
|
|
return -1;
|
|
}
|
|
|
|
if (right - left < 0) {
|
|
return -1;
|
|
}
|
|
|
|
segtree_do_insert(stree->nodes, left, right, ROOT);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int segtree_do_delete(stree_node_t *nodes, int left, int right, int root)
|
|
{
|
|
int is_covered = 0;
|
|
stree_node_t *node;
|
|
|
|
node = &nodes[root];
|
|
|
|
if (node->left + 1 == node->right) {
|
|
is_covered = node->is_covered;
|
|
node->is_covered = 0;
|
|
return is_covered;
|
|
}
|
|
|
|
if (node->is_covered) {
|
|
node->is_covered = 0;
|
|
nodes[2 * root].is_covered = 1;
|
|
nodes[2 * root + 1].is_covered = 1;
|
|
}
|
|
|
|
if (right <= node->mid) {
|
|
return segtree_do_delete(nodes, left, right, 2 * root);
|
|
} else if (left >= node->mid) {
|
|
return segtree_do_delete(nodes, left, right, 2 * root + 1);
|
|
} else {
|
|
return segtree_do_delete(nodes, left, node->mid, 2 * root) &&
|
|
segtree_do_delete(nodes, node->mid, right, 2 * root + 1);
|
|
}
|
|
}
|
|
|
|
int segtree_delete(stree_t *stree, int left, int right)
|
|
{
|
|
if (!stree || !stree->nodes) {
|
|
return -1;
|
|
}
|
|
|
|
if (right - left < 0) {
|
|
return -1;
|
|
}
|
|
|
|
return segtree_do_delete(stree->nodes, left, right, ROOT);
|
|
}
|
|
|
|
static int segtree_do_query(stree_node_t *nodes, int left, int right, int root)
|
|
{
|
|
stree_node_t *node;
|
|
|
|
node = &nodes[root];
|
|
|
|
if (node->left + 1 == node->right) {
|
|
return node->is_covered;
|
|
}
|
|
|
|
if (right <= node->mid) {
|
|
return segtree_do_query(nodes, left, right, 2 * root);
|
|
} else if (left >= node->mid) {
|
|
return segtree_do_query(nodes, left, right, 2 * root + 1);
|
|
} else {
|
|
return segtree_do_query(nodes, left, node->mid, 2 * root) &&
|
|
segtree_do_query(nodes, node->mid, right, 2 * root + 1);
|
|
}
|
|
|
|
}
|
|
|
|
int segtree_query(stree_t *stree, int left, int right)
|
|
{
|
|
if (!stree || !stree->nodes) {
|
|
return -1;
|
|
}
|
|
|
|
if (right - left < 0) {
|
|
return -1;
|
|
}
|
|
|
|
return segtree_do_query(stree->nodes, left, right, ROOT);
|
|
}
|
|
|
|
static int segtree_do_cal(stree_node_t *nodes, int root)
|
|
{
|
|
stree_node_t *node;
|
|
|
|
node = &nodes[root];
|
|
|
|
if (node->is_covered) {
|
|
return node->right - node->left;
|
|
}
|
|
|
|
if (node->left + 1 == node->right) {
|
|
return 0;
|
|
}
|
|
|
|
return segtree_do_cal(nodes, 2 * root ) + segtree_do_cal(nodes, 2 * root + 1);
|
|
}
|
|
|
|
int segtree_cal(stree_t *stree)
|
|
{
|
|
if (!stree || !stree->nodes) {
|
|
return -1;
|
|
}
|
|
|
|
return segtree_do_cal(stree->nodes, ROOT);
|
|
}
|
|
|