
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
149 lines
3.9 KiB
C
149 lines
3.9 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 "assert.h"
|
|
#include "string.h"
|
|
#include "topo_sorting.h"
|
|
|
|
int topo_sorting_create(topo_sorting_t *topo_sorting, graph_t *graph)
|
|
{
|
|
int i = 0;
|
|
|
|
if (!topo_sorting || !graph) {
|
|
return -1;
|
|
}
|
|
|
|
memset(topo_sorting, 0, sizeof(topo_sorting_t));
|
|
|
|
if (stack_create(&topo_sorting->stack, graph_vertex_max(graph)) != 0) {
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i < graph_vertex_max(graph); ++i) {
|
|
if (graph_indegree_get(graph, i) == 0 &&
|
|
graph_tag_get(graph, i) != TOPO_VISITED) {
|
|
stack_push(&topo_sorting->stack, i);
|
|
graph_tag_set(graph, i, TOPO_VISITED);
|
|
}
|
|
}
|
|
|
|
topo_sorting->graph = graph;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int topo_sorting_destroy(topo_sorting_t *topo_sorting)
|
|
{
|
|
int i = 0;
|
|
|
|
if (!topo_sorting || !topo_sorting->graph) {
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < graph_vertex_max(topo_sorting->graph); ++i) {
|
|
graph_tag_reset(topo_sorting->graph, i);
|
|
}
|
|
|
|
stack_destroy(&topo_sorting->stack);
|
|
|
|
topo_sorting->graph = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int topo_sorting_has_next(topo_sorting_t *topo_sorting)
|
|
{
|
|
if (!topo_sorting || !topo_sorting->graph) {
|
|
return 0;
|
|
}
|
|
|
|
return !stack_is_empty(&topo_sorting->stack);
|
|
}
|
|
|
|
static void push2stack(int tail_vertex, int head_vertex, void *arg)
|
|
{
|
|
topo_sorting_t *topo_sorting = (topo_sorting_t *)arg;
|
|
|
|
if (graph_indegree_get(topo_sorting->graph, head_vertex) == 0) {
|
|
stack_push(&topo_sorting->stack, head_vertex);
|
|
graph_tag_set(topo_sorting->graph, head_vertex, TOPO_VISITED);
|
|
}
|
|
}
|
|
|
|
int topo_sorting_next(topo_sorting_t *topo_sorting)
|
|
{
|
|
int vertex;
|
|
|
|
assert(sizeof(e_type_t) == sizeof(int));
|
|
|
|
if (!topo_sorting || !topo_sorting->graph) {
|
|
return -1;
|
|
}
|
|
|
|
if (stack_is_empty(&topo_sorting->stack)) {
|
|
return -1;
|
|
}
|
|
|
|
vertex = stack_pop(&topo_sorting->stack);
|
|
|
|
graph_edge_rmv_by_tail(topo_sorting->graph, vertex, push2stack, (void *)topo_sorting);
|
|
|
|
return vertex;
|
|
}
|
|
|
|
int topo_has_ring(topo_sorting_t *topo_sorting)
|
|
{
|
|
if (!topo_sorting || !topo_sorting->graph) {
|
|
return -1;
|
|
}
|
|
|
|
return graph_edgesn_get(topo_sorting->graph) != 0;
|
|
}
|
|
|
|
int topo_ring_break(topo_sorting_t *topo_sorting)
|
|
{
|
|
int i = 0;
|
|
graph_t *graph;
|
|
|
|
if (!topo_sorting || !topo_sorting->graph) {
|
|
return -1;
|
|
}
|
|
|
|
graph = topo_sorting->graph;
|
|
|
|
for (i = 0; i < graph_vertex_max(graph); ++i) {
|
|
if (graph_indegree_get(graph, i) != 0 &&
|
|
graph_outdegree_get(graph, i) != 0 &&
|
|
graph_tag_get(graph, i) != TOPO_VISITED) {
|
|
/* remove one edge from the graph */
|
|
graph_edge_rmv_one_by_head(graph, i);
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < graph_vertex_max(graph); ++i) {
|
|
if (graph_indegree_get(graph, i) == 0 &&
|
|
graph_tag_get(graph, i) != TOPO_VISITED) {
|
|
stack_push(&topo_sorting->stack, i);
|
|
graph_tag_set(graph, i, TOPO_VISITED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|