久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標(biāo)題: 一種利用串口51單片機(jī)遠(yuǎn)程升級(jí) OTA [打印本頁(yè)]

作者: boboxuexi    時(shí)間: 2020-2-15 18:29
標(biāo)題: 一種利用串口51單片機(jī)遠(yuǎn)程升級(jí) OTA
      想想來(lái)這個(gè)論壇挺久了,也在這學(xué)了不少東西,本著回饋論壇,回饋網(wǎng)友的心態(tài),發(fā)一篇關(guān)于OTA的貼,不喜勿噴,隨著現(xiàn)在科技的發(fā)展,市面上出現(xiàn)很多帶wifi,藍(lán)牙等智能產(chǎn)品,為滿足人們對(duì)產(chǎn)品可以不斷完善,誕生了這種遠(yuǎn)程升級(jí)的技術(shù)。      在此之前呢,做過(guò)一個(gè)stm32遠(yuǎn)程升級(jí)的項(xiàng)目,這種片子的代碼地址偏移性很好,load程序和應(yīng)用程序劃分好就可以,后來(lái)就想51這種便宜的mcu,能不能也實(shí)現(xiàn)這個(gè)功能呢,這就有了這次的實(shí)驗(yàn)。
       廢話不多說(shuō),先說(shuō)說(shuō)原理,OTA主要就三部分,一個(gè)是load程序,一個(gè)是應(yīng)用程序,還有帶升級(jí)的程序,三個(gè)分別存儲(chǔ)在不同地址,我以flash 32K為例。如下圖


為什么要這樣劃分地址呢。主要是因?yàn)?1單片機(jī)的中斷地址不能發(fā)生偏移(至少我不知道怎么偏移),所以我運(yùn)行的程序必須在起始地址0x0.吧bootload程序放在了0x6000的位置。

     1,bootload程序設(shè)計(jì),程序功能主要是判斷有沒(méi)有升級(jí)標(biāo)志,有升級(jí)標(biāo)志把APP2的文件拷貝到APP1,然后跳轉(zhuǎn)到app1位置運(yùn)行。如果沒(méi)有升級(jí)標(biāo)志直接跳轉(zhuǎn)到app1.
    keil中設(shè)置1,BL51 locate 啟動(dòng)文件 ?C_C51STARTUP(0x6100) 需要特殊放置,這樣才能保證每次啟動(dòng)后跳轉(zhuǎn)的位置準(zhǔn)確;
            設(shè)置2,target  EProm 0x6000;





這樣編譯出來(lái)的 hex文件  就是下面這個(gè)樣子。




這個(gè)時(shí)候bootload程序算設(shè)計(jì)好了,可以直接燒錄到MCU中。

2,應(yīng)用程序 APP1設(shè)計(jì),程序功能主要實(shí)現(xiàn)我們自己產(chǎn)品功能,以及接收保存遠(yuǎn)程發(fā)過(guò)來(lái)的程序。
keil中設(shè)置1,BL51 locate 啟動(dòng)文件 ?C_C51STARTUP(0x1000) 需要特殊放置,這樣才能保證每次啟動(dòng)后跳轉(zhuǎn)的位置準(zhǔn)確;
         設(shè)置2,target  EProm 0x0;







這樣就可以確保每次程序跳轉(zhuǎn)正確。關(guān)鍵的在這里,因?yàn)槊看我冗\(yùn)行bootload 所以需要在0x0 位置 跳轉(zhuǎn)到bootload地址是0x6100,再有boot程序跳轉(zhuǎn)到我們的0x1000 這樣成正常運(yùn)行,看起來(lái)很復(fù)雜,其中只有兩個(gè)關(guān)鍵地址,0-->0x6100 -->0x1000 , 就這兩步驟。

3,然后再來(lái)說(shuō)說(shuō)升級(jí)文件的打包制作,首先呢需要把 02 10 00  改成 02 61 00.
       在bin文件前面插入256個(gè)字節(jié),升級(jí)文件信息。
        a,0-3字節(jié) 文件版本號(hào)
        b 4-7字節(jié) 文件長(zhǎng)度
        c 8-11字節(jié) 文件類型
        d 12-13字節(jié) 文件的CRC校驗(yàn)(校驗(yàn)只對(duì)程序文件,不包括插入的信息)
        e 10-255  0xff

我這里用C#寫(xiě)了一個(gè)小工具和一個(gè)模擬云服務(wù)器發(fā)送的 工具。





這樣就完成了51 遠(yuǎn)程升級(jí)的全部工作。不喜勿噴,附上代碼僅供學(xué)習(xí)參考。

//-------------------------------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 ..                        \r\n");
    uart1_send("boot addr 0x6000 main addr 0x6100..\r\n");
    uart1_send(__DATE__);
    uart1_send("\r\ngo to app run addr:0x1000      \r\n");
    uart1_send("-----------------------------------\r\n");

//     Ssp_WriteByte(EEPOM_ADDR,0xaa,mFLASH);
        
        
     i = Read_FlashByte(EEPOM_ADDR);//檢查是否有升級(jí)

     if(i==0xaa)
     {
        uart1_send("Updata......\r\n");

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


        uart1_send("EraseBlock  OK \r\n");
        for(i=0;i<0x2800;i++)
        {
            Ssp_WriteByte(i,Read_FlashByte(APP_BACK_ADDR+i),mFLASH);
        }
        uart1_send("WriteBlock  OK \r\n");
        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.....\r\n");
                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("-----------------------------------\r\n");
    uart1_send("welcome to app world ..............\r\n");
    uart1_send(__DATE__);
    uart1_send("-----------------------------------\r\n");
    uart1_send("software ver :");
    uart1_send(mcu_sf_ver);
    uart1_send("\r\n");

    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);
        }  
    }
}



全部資料51hei下載地址:

bin+fifo.zip (50.72 KB, 下載次數(shù): 144)

tool.zip (14.3 KB, 下載次數(shù): 111)


作者: york_feng    時(shí)間: 2020-2-20 11:34
不錯(cuò),會(huì)玩!
作者: boboxuexi    時(shí)間: 2020-2-21 08:09
york_feng 發(fā)表于 2020-2-20 11:34
不錯(cuò),會(huì)玩!

過(guò)獎(jiǎng)了
作者: xyz_123    時(shí)間: 2020-2-22 10:29
編譯bootload時(shí),
Memory Model選Large: variables in XDATA有何講究,用Small可以嗎?
不勾選Use On-chip ROM有何講究?

編譯App1時(shí),
App1的起點(diǎn)放在0x1000有何講究?可以放在其它處,例如0x100嗎?

作者: boboxuexi    時(shí)間: 2020-2-23 09:37
xyz_123 發(fā)表于 2020-2-22 10:29
編譯bootload時(shí),
Memory Model選Large: variables in XDATA有何講究,用Small可以嗎?
不勾選Use On-chi ...

Small:變量存儲(chǔ)在內(nèi)部ram里;
Large:變量存儲(chǔ)在外部Ram里,使用16位間接尋址;所以程序大我們一般選 large
app1可以放置再0x100,這個(gè)地址避開(kāi)中斷向量就可以,個(gè)人愚見(jiàn)。
作者: chinayanhui    時(shí)間: 2020-2-23 13:38
一直有一個(gè)疑問(wèn)想問(wèn)一下樓主

就是51單片機(jī)在運(yùn)行的過(guò)程中可以讀寫(xiě)程序區(qū)的flash嗎?
作者: boboxuexi    時(shí)間: 2020-2-23 17:04
chinayanhui 發(fā)表于 2020-2-23 13:38
一直有一個(gè)疑問(wèn)想問(wèn)一下樓主

就是51單片機(jī)在運(yùn)行的過(guò)程中可以讀寫(xiě)程序區(qū)的flash嗎?

51系列有很多品牌,具體要看規(guī)格書(shū)
作者: fpauly    時(shí)間: 2020-2-23 18:53
這個(gè)有意思
作者: abcdefbcdef    時(shí)間: 2020-2-23 22:13
正好需要!!!
作者: boboxuexi    時(shí)間: 2020-2-28 00:02
百度 “51 OTA”,竟然發(fā)現(xiàn)有被復(fù)制到別人的論壇。
作者: yoghourt    時(shí)間: 2020-2-28 15:58
樓主真的很用心呀
作者: 這是我    時(shí)間: 2020-2-28 21:51
不錯(cuò)資料,學(xué)習(xí)下。
作者: hei51com    時(shí)間: 2020-5-12 23:07
51也能串口升級(jí),會(huì)玩
作者: boboxuexi    時(shí)間: 2020-7-24 20:41
hei51com 發(fā)表于 2020-5-12 23:07
51也能串口升級(jí),會(huì)玩

多謝夸獎(jiǎng)
作者: shenyuqiu    時(shí)間: 2020-7-25 18:32
高手,這是高手
作者: dsfpp    時(shí)間: 2020-12-3 19:20
高手啊,啟動(dòng)跳轉(zhuǎn)改.A51好像可以跳吧
作者: zhaobolove    時(shí)間: 2020-12-5 10:11
C51  代碼不全, 無(wú)法實(shí)現(xiàn)樓主 說(shuō)的 功能,   不信 , 你們 試一試 ,
樓主 ,也就是 一個(gè) 方向 ,  方案,  想專研的人 可以考慮 安裝這個(gè)思路去實(shí)現(xiàn),  但是不一定會(huì)成功,  說(shuō)了
這只是方案!
作者: dsfpp    時(shí)間: 2020-12-27 02:20
樓上試,代碼不全嘛,我沒(méi)有51單片機(jī),有的話我也來(lái)試了
作者: yuanyijie    時(shí)間: 2021-6-30 10:21
存在風(fēng)險(xiǎn)哦
作者: boboxuexi    時(shí)間: 2021-7-1 09:10
yuanyijie 發(fā)表于 2021-6-30 10:21
存在風(fēng)險(xiǎn)哦

什么風(fēng)險(xiǎn)呢?
作者: yuanyijie    時(shí)間: 2021-7-3 09:13
boboxuexi 發(fā)表于 2021-7-1 09:10
什么風(fēng)險(xiǎn)呢?

從APP2拷貝數(shù)據(jù)到APP1的時(shí)候,剛好擦除了扇區(qū)0而還沒(méi)寫(xiě)入時(shí),突然掉電了,怎么能跳轉(zhuǎn)到BOOTLOAD(0X6000)程序呢位置呢?
作者: yuanyijie    時(shí)間: 2021-7-3 09:18
                INTERRUPT_OFFSET EQU 0X0600 ;中斷偏移量


                CSEG    AT      0X0000;絕對(duì)地址
                               
?C_STARTUP:     LJMP    STARTUP1

                                ;中斷向量地址
                                ORG      0X0003;相對(duì)地址(偏移地址)
                                LJMP     INTERRUPT_OFFSET + $    ;INT0中斷
                               
                                ORG      0X000B       
                                LJMP     INTERRUPT_OFFSET + $         ;T0中斷
                               
                                ORG      0X0013  
                                LJMP     INTERRUPT_OFFSET + $    ;INT1中斷
                               
                                ORG      0X001B  
                                LJMP     INTERRUPT_OFFSET + $    ;T1中斷
                               
                                ORG      0X0023          
                                LJMP     INTERRUPT_OFFSET + $         ;UART1中斷
                               
                                ORG      0X002B
                                LJMP     INTERRUPT_OFFSET + $    ;WDT中斷
                               
                                ORG      0X0033
                                LJMP     INTERRUPT_OFFSET + $    ;LVD中斷
                               
                                ORG      0X003B
                                LJMP     INTERRUPT_OFFSET + $    ;UART2中斷
                               
                                ORG      0X0043
                                LJMP     INTERRUPT_OFFSET + $         ;SPI中斷
                               
                                ORG      0X004B
                                LJMP     INTERRUPT_OFFSET + $    ;IIC中斷
                               
                                ORG      0X0053
                                LJMP     INTERRUPT_OFFSET + $    ;T3中斷
                               
                                ORG      0X005B
                                LJMP     INTERRUPT_OFFSET + $    ;T4中斷
                               
                                ORG      0X0063
                                LJMP     INTERRUPT_OFFSET + $    ;PWM中斷
                               
                                ORG      0X006B
                                LJMP     INTERRUPT_OFFSET + $    ;T5中斷
                               
                                ORG      0X0073
                                LJMP     INTERRUPT_OFFSET + $    ;CTK中斷
                               
                                ORG      0X007B
                                LJMP     INTERRUPT_OFFSET + $    ;ADC中斷
                               
                                ORG      0X0083
                                LJMP     INTERRUPT_OFFSET + $    ;INT2-INT7中斷
                               
                                ORG      0X008B
                                LJMP     INTERRUPT_OFFSET + $    ;INT8-17中斷

                                ORG      0X0093
                                LJMP     INTERRUPT_OFFSET + $    ;P2INT中斷
                               
                                RSEG    ?C_C51STARTUP;自動(dòng)分配地址
               
                                ;CSEG    AT      0X0700;指定APP起始地址


我做的是把BOOTLOAD程序放在0X0000-0X0600處的,使用XMODEM協(xié)議進(jìn)行下載
作者: boboxuexi    時(shí)間: 2021-7-3 16:47
yuanyijie 發(fā)表于 2021-7-3 09:13
從APP2拷貝數(shù)據(jù)到APP1的時(shí)候,剛好擦除了扇區(qū)0而還沒(méi)寫(xiě)入時(shí),突然掉電了,怎么能跳轉(zhuǎn)到BOOTLOAD(0X6000)程序 ...

有道理
作者: boboxuexi    時(shí)間: 2021-7-3 16:47
yuanyijie 發(fā)表于 2021-7-3 09:18
INTERRUPT_OFFSET EQU 0X0600 ;中斷偏移量



有道理,受教了
作者: cell    時(shí)間: 2021-10-25 13:03
請(qǐng)問(wèn)怎么read和write單片機(jī)flash
作者: jxgzht    時(shí)間: 2021-11-15 19:45
yuanyijie 發(fā)表于 2021-7-3 09:18
INTERRUPT_OFFSET EQU 0X0600 ;中斷偏移量

你好!我正在自學(xué)做一個(gè)51單片機(jī)用1K xmodem升級(jí)的項(xiàng)目,請(qǐng)問(wèn)可以請(qǐng)教源碼嗎?謝謝!
作者: hongshi123    時(shí)間: 2022-10-10 14:19
你好 遠(yuǎn)程升級(jí)那部分有完整的代碼嗎  能分享下嗎
作者: iampxj    時(shí)間: 2022-10-10 14:31
have a look

作者: 624353765    時(shí)間: 2022-10-10 20:54
我也做過(guò)IAP51單片機(jī)在線升級(jí)功能,大致國(guó)過(guò)程和你的差不多,但比你的簡(jiǎn)單
我的項(xiàng)目比較大,需要用到64KROM,所以外置EEPROM,有更新先下載到EEPROM并驗(yàn)證一次
ROM劃分兩部分APP區(qū)(地址從0x0000開(kāi)始)和UPDATE區(qū),UPDATE只負(fù)責(zé)把EEPROM中的新APP程序?qū)懭雴纹瑱C(jī)APP區(qū),驗(yàn)證升級(jí)和程序下載命令等都在APP中,這樣就能隨時(shí)更新下載驗(yàn)證指令了。
UPDATE區(qū)程序需要偏置到單片機(jī)FLASH末尾處,同時(shí)APP區(qū)也備份UPDATE程序,用來(lái)驗(yàn)證是否正確。需要升級(jí)時(shí)使用指針函數(shù)跳轉(zhuǎn)到UPDATE區(qū),升級(jí)完單片機(jī)復(fù)位即可。
作者: hongshi123    時(shí)間: 2022-10-27 09:33
yuanyijie 發(fā)表于 2021-7-3 09:18
INTERRUPT_OFFSET EQU 0X0600 ;中斷偏移量

你好 能否請(qǐng)教下怎么做 最近在做51單片機(jī)升級(jí)
作者: STC莊偉    時(shí)間: 2022-10-27 10:30
hongshi123 發(fā)表于 2022-10-27 09:33
你好 能否請(qǐng)教下怎么做 最近在做51單片機(jī)升級(jí)

新站STCAI
還是從 STC-ISP V6.90T 以上版本的 ISP燒錄/輔助開(kāi)發(fā)工具包一體化軟件的//資料下載// 專欄 中下載 開(kāi)源的 C語(yǔ)言代碼, 開(kāi)源的原理圖

51hei截圖20221027102901.jpg (164.21 KB, 下載次數(shù): 112)

51hei截圖20221027102901.jpg

作者: linlin1    時(shí)間: 2025-2-6 13:35
厲害,試一試




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 亚洲最大黄色 | 依人久久 | 欧美超碰在线 | 国产精品入口 | 毛片网站大全 | 国产蜜臀av | 日韩精品免费观看 | 日韩高清在线播放 | 97超碰免费 | 91看片看淫黄大片 | 欧美亚洲国产日韩 | 99在线免费观看 | 午夜影院在线观看视频 | 欧美午夜精品一区二区 | www.久久久久| 欧洲一区二区三区 | 国产视频在线观看视频 | 欧美性爽 | 深夜福利网 | 久久九九免费视频 | 色婷婷免费视频 | 午夜精品视频 | 国产午夜在线观看 | 日韩中文字幕视频 | 小镇姑娘国语版在线观看免费 | 免费在线小视频 | 欧美国产在线观看 | 99福利视频| 成人在线视频免费观看 | 亚洲高清在线视频 | 日本天堂在线 | 99超碰在线观看 | 精品一区二区国产 | 日韩一区二区三区精品 | 视频一区在线播放 | a级毛毛片| 精品国产乱码久久久久久影片 | 天天干天天舔 | 亚洲精品自拍视频 | 亚洲久热 | 国产一区二区三区免费 |