历史上的今天
返回首页

历史上的今天

今天是:2025年02月22日(星期六)

2020年02月22日 | 一种利用串口51单片机远程升级 OTA

2020-02-22 来源:51hei

回馈网友的心态,发一篇关于OTA的贴,不喜勿喷,随着现在科技的发展,市面上出现很多带wifi,蓝牙等智能产品,为满足人们对产品可以不断完善,诞生了这种远程升级的技术。      


在此之前呢,做过一个stm32远程升级的项目,这种片子的代码地址偏移性很好,load程序和应用程序划分好就可以,后来就想51这种便宜的mcu,能不能也实现这个功能呢,这就有了这次的实验。

废话不多说,先说说原理,OTA主要就三部分,一个是load程序,一个是应用程序,还有带升级的程序,三个分别存储在不同地址,我以flash 32K为例。如下图

 
为什么要这样划分地址呢。主要是因为51单片机的中断地址不能发生偏移(至少我不知道怎么偏移),所以我运行的程序必须在起始地址0x0.吧bootload程序放在了0x6000的位置。

1,bootload程序设计,程序功能主要是判断有没有升级标志,有升级标志把APP2的文件拷贝到APP1,然后跳转到app1位置运行。如果没有升级标志直接跳转到app1.

keil中设置1,BL51 locate 启动文件 ?C_C51STARTUP(0x6100) 需要特殊放置,这样才能保证每次启动后跳转的位置准确;

设置2,target  EProm 0x6000;

 
 


这样编译出来的 hex文件  就是下面这个样子。

 


这个时候bootload程序算设计好了,可以直接烧录到MCU中。

2,应用程序 APP1设计,程序功能主要实现我们自己产品功能,以及接收保存远程发过来的程序。
keil中设置1,BL51 locate 启动文件 ?C_C51STARTUP(0x1000) 需要特殊放置,这样才能保证每次启动后跳转的位置准确;
         设置2,target  EProm 0x0;
 
 

这样就可以确保每次程序跳转正确。关键的在这里,因为每次要先运行bootload 所以需要在0x0 位置 跳转到bootload地址是0x6100,再有boot程序跳转到我们的0x1000 这样成正常运行,看起来很复杂,其中只有两个关键地址,0-->0x6100 -->0x1000 , 就这两步骤。

3,然后再来说说升级文件的打包制作,首先呢需要把 02 10 00  改成 02 61 00.
       在bin文件前面插入256个字节,升级文件信息。
        a,0-3字节 文件版本号
        b 4-7字节 文件长度
        c 8-11字节 文件类型
        d 12-13字节 文件的CRC校验(校验只对程序文件,不包括插入的信息)
        e 10-255  0xff

我这里用C#写了一个小工具和一个模拟云服务器发送的 工具。
 

 


这样就完成了51 远程升级的全部工作。不喜勿喷,附上代码仅供学习参考。

//-------------------------------bootload----------------------------------------
#include "hal_clock.h"
#include "hal_gpio.h"
#include "hal_pwm.h"
#include "hal_timer.h"
#include "hal_interrupt.h"
#include "hal_adc.h"
#include "hal_uart.h"
#include "WIFI_JD780.h"
#include "IR.h"
#include "Buzz.h"
#include "hal_ssp.h"
#include "stdio.h"

#define USAR_APP_ADDR   0x1000

typedef void (*boot_fun)(void) ;//= USAR_APP_ADDR;


int cnt_500ms;
char goto_flag;
int i;
char str[10];

char temp1,temp2;

void main(void)
{
    system_clock_set(0);
    _hal_gpio_init();
    _MCU_TIMER_Init();
    _mcu_uart1_init();

    EA = 0;

    uart1_send("boot run ..                        rn");
    uart1_send("boot addr 0x6000 main addr 0x6100..rn");
    uart1_send(__DATE__);
    uart1_send("rngo to app run addr:0x1000      rn");
    uart1_send("-----------------------------------rn");

//     Ssp_WriteByte(EEPOM_ADDR,0xaa,mFLASH);
        
        
     i = Read_FlashByte(EEPOM_ADDR);//检查是否有升级

     if(i==0xaa)
     {
        uart1_send("Updata......rn");

        for( i=0;i<10;i++)
        {
             Ssp_EraseBlock(APP_ADDR + i*0x400,mFLASH);
        } 


        uart1_send("EraseBlock  OK rn");
        for(i=0;i<0x2800;i++)
        {
            Ssp_WriteByte(i,Read_FlashByte(APP_BACK_ADDR+i),mFLASH);
        }
        uart1_send("WriteBlock  OK rn");
        Ssp_EraseBlock(EEPOM_ADDR,mFLASH);
        Ssp_WriteByte(EEPOM_ADDR,0,mFLASH);

        for(i=0;i<0x2800;i++)
        {
            temp1 = Read_FlashByte(APP_BACK_ADDR+i);
            temp2 = Read_FlashByte(APP_ADDR+i);

            if( temp1 != temp2)//APP_ADDR
            {


                uart1_send("index: ");
                sprintf(str,"%d",i);
                uart1_send(str);
                uart1_send("Updata Error.....rn");
                while(1);
            }
        }
     }


    ((void(code*)(void))USAR_APP_ADDR)();

    while(1);

}




//-----------------------app1---------------------------------------------------

#include "hal_clock.h"
#include "hal_gpio.h"
#include "hal_pwm.h"
#include "hal_timer.h"
#include "hal_interrupt.h"
#include "hal_adc.h"
#include "hal_uart.h"
#include "WIFI_JD780.h"
#include "IR.h"
#include "Buzz.h"
#include "hal_ssp.h"


//0x0000-0x27ff app      main 0x1000      10K
//0x2800-0x4fff app-back                  10K
//0x5000-0x5fff eerom                     2 k
//0x6000-0x7fff boot  main 0x6100         8 k

//?C_C51STARTUP(0x1000)


code unsigned char mcu_sf_ver[5] ="1.09";
code unsigned char mcu_hw_ver[5] ="1.00";

int send_time;

void main(void)
{
    system_clock_set(0);
    _hal_gpio_init(); 
    _MCU_PWM_Init(); 
    _MCU_TIMER_Init();
    _mcu_uart1_init();
    _MCU_IRQ_Init();
    _wifi_init();
    IR_ExtInit();
    _mcu_adc_init();
    BUZ_Init();
    BUZ_PLAY_OFF();

    EA = 0;

    uart1_send("-----------------------------------rn");
    uart1_send("welcome to app world ..............rn");
    uart1_send(__DATE__);
    uart1_send("-----------------------------------rn"); 
    uart1_send("software ver :");
    uart1_send(mcu_sf_ver);
    uart1_send("rn"); 

    EA = 1; 


    while(1)
    {
        _MCU_TIMER_Driver();
        if(F_10ms)
        {
            F_10ms =0;  
                                
            IR_Process();
            _user_wifi_data_drives();
                        
                        
            if(IR_KeyCode.bits.Power)
            {
                IR_KeyCode.bits.Power = 0;
                 BUZ_PLAY_KEY();
                 //SBUF = 'C';
                 SBUF = Read_FlashByte(0x2800);

                 Ssp_EraseBlock(0x2800,mFLASH);

                 SBUF = Read_FlashByte(0x2800);
            }
            if(IR_KeyCode.bits.Auto)
            {
                IR_KeyCode.bits.Auto = 0;
                 BUZ_PLAY_KEY();   

                 SBUF = 'W';
                 //ssp_write_flash_nbyte(APP_BACK_ADDR,"1234567890",10);
                 //ssp_write_flash_nbyte(APP_BACK_ADDR+20,"1234567890",10);
            }
            BUZ_Run();
            //ADC_GetAD_12bit(1);
        }  
    }
}

推荐阅读

史海拾趣

Array Microsystems Inc公司的发展小趣事

Array Microsystems Inc公司自创立之初,便专注于阵列传感器技术的研发。在成立初期,公司面临资金短缺和技术瓶颈的双重挑战。然而,通过不懈的努力和持续的技术创新,Array Microsystems Inc成功研发出了一款高灵敏度、低功耗的阵列传感器。这一突破性的技术不仅填补了市场的空白,还为公司带来了可观的利润。随着产品的推广和应用,Array Microsystems Inc逐渐在电子行业中崭露头角。

Alpha-Micro Electronics公司的发展小趣事

Array Microsystems Inc公司自创立之初,便专注于阵列传感器技术的研发。在成立初期,公司面临资金短缺和技术瓶颈的双重挑战。然而,通过不懈的努力和持续的技术创新,Array Microsystems Inc成功研发出了一款高灵敏度、低功耗的阵列传感器。这一突破性的技术不仅填补了市场的空白,还为公司带来了可观的利润。随着产品的推广和应用,Array Microsystems Inc逐渐在电子行业中崭露头角。

AntennaHome公司的发展小趣事

为了进一步提升品牌影响力和市场知名度,AntennaHome公司积极参与国际电子行业的各大展会。在展会上,公司展示了最新的天线技术和产品,吸引了众多国内外客户的关注。通过与客户的深入交流,公司不仅收获了宝贵的市场信息和合作机会,还进一步提升了品牌在行业内的地位。

Chip Quik公司的发展小趣事

为了进一步拓展业务,Chip Quik公司积极寻求与电子制造商、维修中心和分销商等合作伙伴建立合作关系。通过与这些合作伙伴的紧密合作,公司能够更好地了解市场需求,优化产品供应链,提高市场覆盖率。

国盛科技(BOCHEN)公司的发展小趣事

国盛科技在发展过程中获得了多项认证与荣誉。例如,公司获得了知识产权管理体系认证证书,荣登《人民代表报》全国两会特刊,成为“中国质量万里行促进会”会员并获得“收录企业”荣誉称号等。这些认证与荣誉的获得,充分证明了国盛科技在电子行业的领先地位和企业实力的不断提升。

FOSLINK公司的发展小趣事

面对全球气候变化的严峻挑战,FOSLINK公司积极响应国家关于绿色发展的号召,将绿色转型作为企业发展的重要方向。公司致力于研发和生产低能耗、环保型的电子产品,并不断优化生产工艺流程,减少资源消耗和环境污染。同时,FOSLINK还积极推广绿色供应链管理,与供应商和客户共同构建绿色、低碳的产业链生态。这一系列的绿色转型举措,不仅彰显了FOSLINK的社会责任感,也为其赢得了更多消费者的青睐和支持。

问答坊 | AI 解惑

TMS320F2812外部接口分析与存储器扩展

TMS320F2812外部接口分析与存储器扩展…

查看全部问答>

关于量子计算机的一个问题

谁能简单解释一下量子计算机是什么啊?…

查看全部问答>

Speech Recognizer:sapi能够在wince中使用吗?

Licensing Model for Windows CE  中  Professional版本中包含sapi5.0和 Speech Recognizer 但是Microsoft English (US) Windows CE Speech Recognizer (available in 4.2 only) 是说只能在4.2下使用是什么意思?还是4.2以 ...…

查看全部问答>

ARM 指令 关于DCD和SPACE的一个问题

语句如下: FiqStackSpace SPACE FIQ_Stack_Legth FiqStack      DCD   FiqStackSpace + FIQ_Stack_Legth 最后一条语句,DCD的后面跟FiqStackSpace + FIQ_Stack_Legth, DCD后面的FiqStackSpace,表示一串空字符 ...…

查看全部问答>

顺利着陆,来散个分,即散即结

坐的居然也是A330,还好一路无事,飞了12个小时,超累人。顺利抵达西雅图。…

查看全部问答>

关于 CSP_BITFMASK,CSP_BITFVAL的疑问

在csparm_macros.h中有这样两个函数定义: #define CSP_BITFMASK(bit) (((1U …

查看全部问答>

wm中wifi与BT兼容性的问题

wifi与BT用的模式都是spi的。两者共用一clk,但是不同的天线。BT与wifi之间相连接的是BT_STATE,WL_ACTIVE,BT_PRIORITY,如果把这三线去掉,单独当其中任何一个都是可以工作的,但是如果连接起来,我的wifi是可以找到无线网络,并且能连接上,但是就 ...…

查看全部问答>

广告灯自动控制电路图(

城市广告灯大多数只在夜晚12点钟以前起到较好的宣传作用,子夜一过,行人稀少,也就失去了广告的意义。该广告灯自动控制电路能在傍晚天渐黑时自动接通广告灯牌的电源,同时开始计时,待4~6小时后于子夜自动切断电源,从而实现全自动控制和节电的目 ...…

查看全部问答>

ARM Cortex-M4 处理器竞争白热化

ARM Cortex-M4 处理器竞争白热化近几年ARM 独领风骚,2010 年,ARM 在32/64 bit MCU 及MPU 架构中的市场占有率最多,达23.5%,据Semicast 统计,2010 年基于ARM 的市场规模已达到200 亿美元,而Cortex-M 架构更是引领了微控制器市场的新风尚,今年 ...…

查看全部问答>