[单片机] 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-20 09:01

28-基于51单片机的智能窗帘设计
具体实现功能 系统由STC89C51+1602液晶+步进电机+光敏电阻+按键模块+DS1302时钟模块+ADC0832模块+电源构成。 1、LCD1602显示日期和时间、当前控制模式及光照强度; 2、可通过按键切换:手动模式、定时模式、光控模式; 3、手动模式:通过开窗帘和关窗帘键对窗帘进行控制; 4、定时模式:通过按键设置开窗帘和关窗帘的时间; 5、光控模式:光照强度大于设置值时开启窗帘,否则关闭; 6、步进电机正转半圈,模拟开窗,红色LED灯点亮;电机反转半圈,模拟关窗,红色LED灯熄灭。 按键说明: 按键1:切换模式(在手动模式、定时模式、光控模式循环切换) 按键2:进入当前时间的设置(年
[单片机]
28-基于51<font color='red'>单片机</font>的智能窗帘设计
飞利浦51LPC系列单片机用于控制交流电机
    摘要: 飞利浦公司研制的51LPC系列单片机是采用两倍速80C51内核,具有低成本、低功耗、低电磁干扰(EMI)、高抗干扰性及内建电源Brownout侦测、模拟功能、UART、I2C和片内RC振荡器的新一代单片机。本文介绍51LPC系列单片机控制交流电机的原理电路和源程序。     关键词: P87LPC761 Brownout侦侧 模拟比较器 EMI 电流过零检测 半波整流 双向可控硅 1 概述 PHILIPS 51LPC系列单片机目前已包括P87LPC760/1/2/4/7/8/9共七个型号。51LPC提供高速和低速的晶振和RC振荡方式,可编程选择;具有较宽的操作电压范围2.7~6.
[应用]
atmega48单片机特性 atmega48的低功耗设计
本文主要介绍了atmega48单片机的特性,提出了其低功耗设计的一般方法,并以定时控制系统的设计为例,具体说明atmega48的低功耗设计方案。 随着微电子技术和计算机技术的发展,尤其是微机在各个领域的普遍应用,功耗、成本、体积以及可靠性等指标均成为设计者所关注的重要问题。尤其是在由电池供电的设备中,如何降低设备功耗成为设计的首要任务。本文中以atmel公司的atmega48单片机为例,介绍了单片机低功耗设计的一般方法。 atmega48单片机低功耗系统设计首要是选择合适的单片机。atmega48单片机是一款8位微控制器,具有高性能、低功耗的显著特点。由于采用risc精简指令集结构,其指令集大多为单周期指令,具有高速运行的
[单片机]
atmega48<font color='red'>单片机</font>特性 atmega48的低功耗设计
富士通推出适合汽车应用的新型微控制器
    富士通半导体(上海)有限公司今日宣布,推出适合汽车应用的新型32位微控制器-MB91F552,该芯片最适合用于混合动力汽车(HEV)的电池的电源系统及电力传输电路。已于2013年5月13日起提供新产品样片。 图1.MB91F552     除在单一微控制器芯片上集成了控制数字电源系统(如200MHz PWM模块)的优化功能,MB91F552还支持峰值电流模式控制,大大促进了电源的稳定性并降低系统成本。     近年来随着混合动力汽车及其它电动汽车的普及,已经需要将行驶过程中产生的电力存储在车载电池中。通过这种方式储存的电力,除了对车载辅助电池进行充电,还可以向汽车上的电机、音响系统、灯光和其它板上电气元件供
[汽车电子]
动力电池“军备竞赛”升级,电池企业第二季度密集扩产
动力电池新一轮扩产竞赛仍在继续。 据盖世汽车不完全统计,2021年二季度,以宁德时代、国轩高科、中航锂电、蜂巢能源等为代表的动力电池企业相继在二季度进行了签约、开工、投产等新投建举措,其中以中航锂电的动作最为密集,仅在5月份,其就先后与福建厦门、四川成都、湖北武汉三地达成合作协议。 动力电池企业二季度继续加码扩产能 5月9日,中航锂电与厦门火炬高技术产业开发区签署项目合作框架协议,双方就中航锂电厦门基地30GWh动力电池扩产项目达成合作共识。该扩建项目建成后,中航锂电厦门基地将形成年产能50GWh的国际领先智能化工厂。其实,早在2019年6月,中航锂电厦门项目就已正式落户厦门火炬高新区,彼时该基地规划产能20GWh,
[嵌入式]
动力电池“军备竞赛”<font color='red'>升级</font>,电池企业第二季度密集扩产
世界智能化进程加速,MCU市场潜力无限
如同每台电脑都有一个作为大脑的CPU在其中运行,我们每天接触到的各种家电、数码产品、办公设备、汽车电子以及各种仪器仪表之中,也都有一个或者数个MCU(微控制器)默默运行,担负着控制、运算、信号转换及处理、通信等多项工作。而且随着越来越多电子产品向着智能化方向迈出脚步,MCU功能、性能及应用技术的发展也越来越快。为让更多电子工程师了解MCU最新发展状况,在今年的高交会电子展(ELEXCON)期间,创意时代将在深圳首次举办MCU技术创新与应用大会(MCU!MCU!2009),与业界精英分享MCU最新技术、热门应用及市场趋势。 MCU市场逐步扩大,32位市场百家争鸣 作为嵌入式系统的重要组成部分,MCU是推动对象系统实现
[单片机]
【蓝桥杯单片机组】(4)Timer0/1 定时器
需要使用的寄存器:TMOD(工作方式寄存器) TCON(控制寄存器)THx TLx TMOD TMOD D7 D6 D5 D4 D3 D2 D1 D0 GATE C/T M1 M0 GATE C/T M1 M0 T1 T1 T1 T1 T0 T0 T0 T0 GATE: GATE = 0:定时器开始或结束仅由TCON^TRx控制 GATE = 1:定时器开始或结束仅由TCON^TRx与外部中断引脚的电平共同控制(INTx = 1 && TRx = 1 时开始计数) C/T: C/T = 0:定时器模式 C/T = 1:计数器模式 M1 M0 工作方式 0 0 13 bit Timer&Counter 0 1
[单片机]
PIC单片机与MCS-51系列单片机的区别
应该说有三个主要特点: (1)总线结构:MCS-51单片机的总线结构是冯-诺依曼型,计算机在同一个存储空间取指令和数据,两者不能同时进行;而PIC单片机的总线结构是哈佛结构,指令和数据空间是完全分开的,一个用于指令,一个用于数据,由于可以对程序和数据同时进行访问,所以提高了数据吞吐率。正因为在PIC单片机中采用了哈佛双总线结构,所以与常见的微控制器不同的一点是:程序和数据总线可以采用不同的宽度。数据总线都是8位的,但指令总线位数分别位12、14、16位。 (2)流水线结构:MCS-51单片机的取指和执行采用单指令流水线结构,即取一条指令,执行完后再取下一条指令;而PIC的取指和执行采用双指令流水线结构,当一条指令被执行时,允许下一条
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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