[单片机] fota dfu 升级

发布者:温柔心绪最新更新时间:2022-09-19 来源: csdn关键字:单片机  fota  dfu  升级 手机看文章 扫描二维码
随时随地手机看文章

简易的fota升级方式,仅供参数。


/******************************************************************************************************************************************

 * @file fota.c

 * @author jianqiang.xue

 * @version v1.0.0

 * **************************************************************************/


#include

#include

#include


#include "crc16.h"

#include "errorno.h"

#include "modules.h"

#include "partition.h"


#include "atcmd.h"

#include "comm_box.h"

#include "sys_cmsis.h"


#include "bsp_flash.h"

#include "bsp_uart.h"


#define FOTA_PACK_HEAD_1ST_BYTE                 0xA5

#define FOTA_PACK_OPCODE_DATA                   0x5A

#define FOTA_PACK_OPCODE_ABORT                  0xB6

#define FOTA_GET_PACK_ID(BUFF)                  (BUFF[2])

#define FOTA_GET_DATA_LEN(BUFF)                 (BUFF[3])

#define FOTA_GET_DATA_HEAD_ADDR(BUFF)           (BUFF[4])


#define FOTA_CRC16_INIT_VAL                     0xFFFF

#define FLASH_PAGE_SIZE                         2048

#define RECV_TIMEOUT_MS                         3000

#define BUFF_SIZE                               256

#define PACK_DATA_LEN                           128

#define PACK_MAX_PAGE                           16

#define PACK_HEADER_LEN                         4

#define PACK_CRC_LEN                            2


#define ACTION_CLS_FLAG                         0

#define ACTION_CARRY_TO_APP                     2


#define FOTA_STR_LEN(str)                       strlen(str)

#define FOTA_RX_EVENT                           1


#define ATCMD_RET_CAN_UPGRADED                  "Can Upgradedrn"

#define ATCMD_RET_CANT_UPGRADED                 "Can't Upgradedrn"


static void fota_timer_handle(void const *arg);

static void fota_opcode_abort(void);


sys_timer_id_t fota_timer_id;


SYS_TIMER_DEF(fota_timer, fota_timer_handle);


typedef enum

{

    UPGRADE_FREE = 0,

    UPGRADE_ING,

    UPGRADE_END

} fota_up_stage_t;


typedef enum

{

    RX_DATA_ING = 0,

    RX_DATA_END

} fota_rx_stage_t;


typedef struct

{

    fota_up_stage_t  up_stage;

    fota_rx_stage_t  data_rx_stage;

    uint8_t          pages_num;

    uint16_t         pack_num;

    uint32_t         size_num;

} ota_t;

ota_t g_ota;


static comm_hdr_t hdr;


static uint8_t g_rx_buff[BUFF_SIZE];

static uint8_t g_flash_buf[FLASH_PAGE_SIZE];

static char g_msg_head[] = "UP^";

static char g_msg_tail[] = "rn";


static uint8_t ota_region_erased = 0;

static uint8_t g_pack_id = 0;

static uint8_t g_recv_timeout_flag = 0;


static void fota_jump_carry_mode(uint8_t carry_page_num)

{

    //high 8 page num

    bsp_flash_write_nv((carry_page_num << 8) | ACTION_CARRY_TO_APP);

    sys_reset();

}


static void fota_timer_start(void)

{

    sys_timer_start(fota_timer_id, RECV_TIMEOUT_MS);

}


static void fota_timer_stop(void)

{

    sys_timer_stop(fota_timer_id);

}


static void fota_recv_data_timeout(void)

{

    if (g_ota.up_stage == UPGRADE_ING)

    {

        memset(g_rx_buff, 0, BUFF_SIZE);

        fota_opcode_abort();

    }

}


static void fota_send_ack(char* result, char* err, const char* str, uint16_t len)

{

    uint8_t *p_msg_buf;

    uint16_t msg_len = 0;

    uint16_t offset = 0;


    if (len == 0)

    {

        return;

    }


    msg_len = sizeof(hdr) + strlen(g_msg_head) + strlen(result) +

              strlen(err) + strlen(",") + len + strlen(g_msg_tail);

    p_msg_buf = mem_malloc(msg_len);

    if (!p_msg_buf)

    {

        return;

    }


    memcpy(p_msg_buf, &hdr, sizeof(hdr));

    offset += sizeof(hdr);

    memcpy(p_msg_buf + offset, g_msg_head, strlen(g_msg_head));

    offset += strlen(g_msg_head);

    memcpy(p_msg_buf + offset, result, strlen(result));

    offset += strlen(result);

    memcpy(p_msg_buf + offset, err, strlen(err));

    offset += strlen(err);

    memcpy(p_msg_buf + offset, ",", strlen(","));

    offset += strlen(",");

    memcpy(p_msg_buf + offset, str, len);

    offset += len;

    memcpy(p_msg_buf + offset, g_msg_tail, strlen(g_msg_tail));

    offset += strlen(g_msg_tail);


    comm_box_send_msg(p_msg_buf, msg_len);

    mem_free(p_msg_buf);

}


static void fota_opcode_data(uint8_t pack_len)

{

    memcpy(&g_flash_buf[g_ota.pack_num * PACK_DATA_LEN],

           &FOTA_GET_DATA_HEAD_ADDR(g_rx_buff),

            FOTA_GET_DATA_LEN(g_rx_buff));

    g_ota.size_num += FOTA_GET_DATA_LEN(g_rx_buff);

    g_ota.pack_num ++;

    // After receiving 16 times of 2K, write flash once

    if ((pack_len == (PACK_HEADER_LEN + PACK_CRC_LEN)) &&

        (FOTA_GET_DATA_LEN(g_rx_buff) == 0))

    {

        g_ota.pack_num = 0;

        g_ota.data_rx_stage = RX_DATA_END;

        g_ota.up_stage = UPGRADE_END;

    }

    else if (g_ota.pack_num >= PACK_MAX_PAGE)

    {

        g_ota.pack_num = 0;

        g_ota.data_rx_stage = RX_DATA_END;

        g_ota.up_stage = UPGRADE_ING;

    }

}


static void fota_opcode_abort(void)

{

    memset(&g_ota, 0, sizeof(ota_t));

    g_ota.pages_num = 0;

    ota_region_erased = 0;

    g_pack_id = 0;

    g_recv_timeout_flag = 0;

    fota_recv_data_timeout();

    memset(g_flash_buf, 0, FLASH_PAGE_SIZE);

}


static void fota_verify_data(bsp_uart_t uart, uint8_t *data, uint16_t len)

{

    int32_t ret = RETVAL(E_OK);

    uint16_t calc_crc;

    uint16_t recv_crc;

    uint8_t pdu_len = 0; // Protocol Data Unit

    uint8_t pack_len = 0;

    char pack_id_s[5];

    char err_s[5];


    (void)uart;


    g_recv_timeout_flag = 1;


    memcpy(g_rx_buff, data, len);


    // Calculate the current packet length

    if (len > 4)

    {

        pdu_len = FOTA_GET_DATA_LEN(g_rx_buff) + PACK_HEADER_LEN;

    }

    else

    {

        pdu_len = 0;

        return;

    }


    pack_len = pdu_len + PACK_CRC_LEN;

    if (len != pack_len)

    {

        ret = RETVAL(E_INVAL_LEN);

    }

    if ((ret == RETVAL(E_OK)) && g_rx_buff[0] == FOTA_PACK_HEAD_1ST_BYTE)

    {

        calc_crc = crc16(FOTA_CRC16_INIT_VAL, g_rx_buff, pdu_len);

        recv_crc = (g_rx_buff[pack_len - 2] << 8) | g_rx_buff[pack_len - 1];


        if (calc_crc == recv_crc)

        {

            if (g_rx_buff[1] == FOTA_PACK_OPCODE_DATA &&

                (g_ota.data_rx_stage == RX_DATA_ING))

            {

                // Verify that the packet ID is correct

                if ((FOTA_GET_PACK_ID(g_rx_buff) - g_pack_id == 1) ||

                    (g_pack_id - FOTA_GET_PACK_ID(g_rx_buff) == 255))

                {

                    fota_opcode_data(pack_len);

                }

                // Resend the acknowledge signal

                else if (FOTA_GET_PACK_ID(g_rx_buff) == g_pack_id)

                {

                    ret = RETVAL(E_OK);

                }

                else

                {

                    ret = RETVAL(E_MSG);

                }

            }

            else if (g_rx_buff[1] == FOTA_PACK_OPCODE_ABORT)

[1] [2]
关键字:单片机  fota  dfu  升级 引用地址:[单片机] fota dfu 升级

上一篇:[keil][python][单片机] keil 集成bin文件生成 boot+app合并 dfu生成
下一篇:[单片机] x_strtok,安全分割函数

推荐阅读最新更新时间:2024-11-12 11:18

MCU、车用动能续强,欣铨营运审慎乐观
半导体测试厂欣铨(3264)去年受惠IDM厂扩大释出委外代工订单,加上并购全智科后扩大在射频(RF)测试市场占有率,去年归属母公司税后净利达12.77亿元,为7年来获利新高。欣铨总经理张季明昨(9)日在法人说明会中表示,产业市况延续去年荣景,对今年营运审慎乐观。 欣铨公告去年财报。 去年第四季合并营收21.05亿元,归属母公司税后净利约达3.90亿元,每股净利0.83元。 去年合并营收年增25.6%达78.60亿元,创下历史新高纪录,归属母公司税后净利12.77亿元,较前年大幅成长43.0%,为7年来年度获利新高,每股净利2.73元。 欣铨董事会决议今年每普通股拟配发1.65元现金股利,股息配发率约6成,以欣铨昨日股价收盘价37.
[半导体设计/制造]
单片机驱动数码管电路的制做
把七或八只发光二极管组合在一个模件上组成了个8字和小数点,用以显示数字。为了减少管脚,把各个发光管的其中同一个极接在一起作为共用点,因此就产生了共阳极和共阴极数码之说。共阳管就是把各个发光管的正极接在一起,而共阴管就刚好相反。见下图: 大部分的逻辑IC的吸收电流要强于输出电流。因此,大家都爱使用共阴极的数码管,因为可选的IC多些。很可惜,我的这组数码管是共阳的,因此公共端我打算用三级管来驱动。最常用的S9012,首先我得计划好电路方式,就采用最常用的动态扫描显示。先搭建最简电路,调试出需采用元件的参数。 先不接上图的R2和74HC244,将数码管一个段直接接地。调节R1,测得S9012基极电流为0.21mA时集电极也
[单片机]
<font color='red'>单片机</font>驱动数码管电路的制做
通过ESP8266和RP2040 MCU实现无线树莓派HAT控制的PiSquare
原文链接:PiSquare enables wireless Raspberry Pi HAT control though ESP8266 and RP2040 MCUs (Crowdfunding) 由Jean-Luc Aufranc撰写。 SB Components PiSquare 是一款外形尺寸与树莓派HAT一样的板子,它是基于树莓派RP2040微控制器和ESP-12E的无线模块,可以方便无线控制多个树莓派 HAT,而且无需将那些HAT堆叠在树莓派上。 PiSquare使用socket编程的方式来无线控制多个树莓派HAT,例如,你们可以通过SPI或UART连接多个HAT,而其扩展板不会相互冲突,因为这里的物理接口
[工业控制]
通过ESP8266和RP2040 <font color='red'>MCU</font>实现无线树莓派HAT控制的PiSquare
基于AT89C2051单片机制作的电子万年历的原理及设计
很多用AT89C205l制作电子万年历的文章,介绍的都是采用单片机内部定时计数器作定时计时,难免受到停电的影响而需要经常调整,为此,笔者设计制作了AT89C20Sl+DSl302的电子万年历。 该万年历的特点是;动态显示、遥控操作;能按多位数码管或多点输出I采用DSl302时钟模块,走时准确、停电能继续计时(精度±5秒/日左右若采用有源晶报,如DS32Hz,走时精度甚至可达到年误差小于2分钟)。 一、功能 显示年、月、日、星期、时、分。遥控操作、整点报时、定时报时及定时显示、停电自动计时等。 二、硬件电路设计 AT89C2051作为数据处理,DSl302作为计时处理及停电继续走时,用13只LED数码管显示年、月、日、星
[单片机]
基于AT89C2051<font color='red'>单片机</font>制作的电子万年历的原理及设计
基于单片机的通信电源监控系统设计与实现
  通信电源是通信网络的"心脏",通信电源系统稳定、可靠的运行直接关系到通信的稳定性及可靠性。目前大型通信电源的供电方式多采用集中供电的方式,一旦发生供电故障,将直接引起整个通信系统的瘫痪。   通信电源的传统维护方式主要依靠人工看守,工作量大,效率低下,造成设备发生故障而没有及时进行处理而产生的重大通信阻断时有发生。因此对在网运行通信电源设备实现远程实时监测,有利于及时发现电源故障,减少人为因素,对保证供电系统稳定、可靠运行显得十分重要。\'   目前,通信电源系统广泛使用高频开关电源系统设备,其智能化程度高。在运行过程中,电源系统的具体运行要求很多,例如:若电源系统不能输出规定电流和电压或输出的电流、电压超出允许波动范围,
[单片机]
基于<font color='red'>单片机</font>的通信电源监控系统设计与实现
用PROTEUS仿真单片机与LCD接口项目
设计要求: 在上一个项目中,介绍了如何使用8051微控制器进行串行通信,这是一个非常基础的项目,不需要太多的硬件。接下来将实现LCD与8051微控制器的接口。经常将LCD作为硬件工程项目的调试工具。使用LCD来显示不同的值。例如, ATM机,手机也都配有LCD。该项目将使用通常称为1602 的LCD。因此,我们使用8051单片机同LCD的连接。 还是放一下图和代码吧 #include reg51.h #define uchar unsigned char #define uint unsigned int sbit RS = P1^0; sbit RW = P1^2; sbit EN = P1^1; voi
[单片机]
用PROTEUS仿真<font color='red'>单片机</font>与LCD接口项目
MCU之MSP430和MSP432对比
MSP430 MCU世界里的一则神话,全球16位MCU最低功耗的标杆,过去20年来从未被超越,是工程师眼中当之无愧的低功耗之王。而早年TI隆重推出了基于ARM Cortex-M4F内核的32位低功耗MCU产品——MSP432。而这两者之间最显著的差异在哪里,下面跟小编一起来了解一下吧~ 这一功耗更低、性能更佳的MCU产品家族的诞生,是否会打破MSP430低功耗之王的神话?答案揭晓前,让我们先对二者进行一下比较。
[单片机]
<font color='red'>MCU</font>之MSP430和MSP432对比
【GD32 MCU 入门教程】GD32 MCU 常见外设介绍 (6) ADC 模块介绍
6.1.ADC 基础知识 12 位逐次逼近式模数转换器模块(ADC),可以采样来自于外部输入通道、内部输入通道的模拟信号,采样转换后,转换结果可以按照最低有效位对齐或最高有效位对齐的方式保存在相应的数据寄存器中。 6.2.GD32 ADC 外设原理 GD32 ADC 主要特性 ◼ 高性能: – ADC采样分辨率: 12位、 10位、 8位、或者6位分辨率; – 前置校准功能; – 可编程采样时间; – 数据存储模式:最高有效位对齐和最低有效位对齐; – 支持规则数据转换的DMA请求。 ◼ 模拟输入通道: – 16个外部模拟输入通道; – 1个内部温度传感器输入通道(VSENSE); – 1个内部参考电压输入通道(VREFINT
[单片机]
【GD32 <font color='red'>MCU</font> 入门教程】GD32 <font color='red'>MCU</font> 常见外设介绍 (6) ADC 模块介绍
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved