自己用C語言寫dsPIC / PIC24 serial bootloader


        了解更多關於bootloader 的C語言實現,請加我QQ: 1273623966 (驗證信息請填 bootloader),歡迎咨詢或定制bootloader(在線升級程序)。

  HyperBootloader_dsPIC

  HyperBootloader_dsPIC是我用C語言實現的UART bootloader, 采用串口通信,適用於Microchip的dsPIC30, dsPIC33,同樣適用於PIC24。單片機端bootloader是用XC16編譯的,電腦端的通信軟件是用超級終端--HyperTerminal。

  dsPIC30 和 dsPIC33 程序存儲器

  dsPIC30,dsPIC33, PIC24的程序存儲器架構都一樣,只是大小,和vector位置有所不同。下圖所示的是dsPIC30和dsPIC33程序存儲器的示意圖,以及HyperBootloader的放置位置。HyperBootloader_dsPIC是放置在IVT/AIVT中斷vector所占Page之外,所以IVT/AIVT不需要做任何變動。

  

  如上圖所示,對於dsPIC30, HyperBootloader_dsPIC的ROM Range是0x400~0xBFF, 對於dsPIC33, HyperBootloader_dsPIC的ROM Range是0x100~0x5FF。

  ROM Range 設置

  下面以dsPIC33FJ256GP710A為例,詳細說一下如何設置ROM Range。在編譯HyperBootloader_dsPIC時,需要添加p33FJ256GP710A.gld文件到項目目錄中來,並對其修改以下地方。

  program (xr) : ORIGIN = 0x400, LENGTH = 0x0800 /*2A9FE*/
  __CODE_BASE = 0x400;
  __CODE_LENGTH = 0x0800; /*2AA00;*/

  這樣就完成了對HyerBootloader_dsPIC的ROM Range的設置。

  另外由上圖可知,應用程序需要燒錄到dsPIC33FJ256GP710A ROM的0xC00之后。所以在編譯應用程序時,同樣需要添加p33FJ256GP710A.gld文件到項目目錄中來,並對其修改以下地方來完成ROM Range設置。

  program (xr) : ORIGIN = 0xC00, LENGTH = 0x02A000 /*2A9FE*/
  __CODE_BASE = 0xC00;
  __CODE_LENGTH = 0x02A000; /*2AA00;*/

  主要代碼段

  HyperBootloader_dsPIC采用的是程序字燒錄,具體實現代碼段如下。

        for(;;)
        {
            while (U1RXREG != ':');
            while (!U1STAbits.TRMT);
            U1TXREG=':';

            cksum = bcount = bytecount = GetXbyte();
            //address
            SourceAddr.v[1] = GetXbyte();
            SourceAddr.v[0] = GetXbyte();
            SourceAddr.Val >>= 1;
            rectype = GetXbyte();
            switch(rectype)
            {
            case LINEAR_ADDRESS:
                SourceAddr.v[3] = GetXbyte();
                SourceAddr.v[2] = GetXbyte();
                Checksum();
                break;
            case DATA:
                while (bytecount--)
                {
                    Buffer[incrbyte++] = GetXbyte();
                }
                Checksum();
                if (SourceAddr.Val >= CM_START)
                {
                    //NVMCON = CM_WORD_WRITE;
                    ClearBuffData();
                    break;
                }
                else
                {
                    NVMCON = PM_WORD_WRITE;
                }
                for (ix = 0; ix < bcount; )
                {
                    pData.byte.LB = Buffer[ix+0];
                    pData.byte.HB = Buffer[ix+1];
                    pData.byte.UB = Buffer[ix+2];
                    pData.byte.MB = Buffer[ix+3];

                    TBLPAG = SourceAddr.word.HW;
                    if (SourceAddr.Val == 0)
                    {
                        pData.word.LW = BOOT_START;   // reset vector
                        pData.word.HW = 0x0004;     // goto BOOT_START
                    }
                    __builtin_tblwtl(SourceAddr.word.LW, pData.word.LW);
                    __builtin_tblwth(SourceAddr.word.LW, pData.word.HW);
                    asm("DISI #16");   //Disable interrupts for few instru
                    __builtin_write_NVM();
                    Nop();
                    while (NVMCONbits.WR);

                    rData.word.HW = __builtin_tblrdh(SourceAddr.word.LW);
                    rData.word.LW = __builtin_tblrdl(SourceAddr.word.LW);

                    if ((rData.Val != pData.Val))                   //&&(SourceAddr.Val < CM_START))
                    {
                        putsUART1((unsigned int *)"Error\r\n");
                        RCONbits.SWDTEN=1;   // use WTD to reset device
                        while (1);
                    }
                    ix += 4;
                    SourceAddr.Val += 2;
                }
                ClearBuffData();
                NVMCONbits.WREN = 0;
                break;
            case END:
                Checksum();
                U1MODE = 0x0;
                U1STA = 0x0110;
                (*((void(*)(void))PROG_START))();
                break;
            }
        }    

  如何使用

  1. 使用XC16編譯HyperBootloader_dsPIC(編譯前,需先修改gld文件,詳見"ROM Range設置")。

  2. 使用pickit3燒錄HyperBootloader_dsPIC的Hex文件到目標板中。

  3. 拔除pickit3燒錄器,連接目標板與PC的串口,打開超級終端,設置如下:115200-8-None-1-None, Line Delay-20ms

  4. 重啟目標板,超級終端會出現Booting... 字樣。

  5. 6秒內,在超級終端窗口中按下鍵盤上任何按鍵,會出現">"(6秒內沒按鍵,會自動跳轉到用戶的應用程序中去)。

  6. 打開Send Text File對話框,選擇期望燒錄的應用程序hex文件(編譯前,需先修改gld文件,詳見”ROM Range設置"),點擊確認, HyperBootloader會將接收到的數據傳回到電腦超級終端上,並將數據燒錄到目標板程序存儲器的正確位置。

  7. 燒錄完畢,再次重啟目標板,超級終端顯示完Booting ......,就自動跳到應用程序中,目標板開始正常運行應用程序。

  之后每次更新應用程序,只需重復步驟 4 ~ 7 就可以了。

  主要特性

  HyperBootloader_dsPIC有以下主要特性

  1. C語言寫的,XC16 編譯。

  2. 非常容易移植, 支持dsPIC30, dsPIC33, PIC24。

  3. 支持FLASH燒寫

  4. 可支持EEPROM燒寫。

  5. 支持CONFIG BITS/IDLOC 燒寫。

 

  如果你有什么疑問,或有興趣了解更多關於bootloader 的C語言實現,請加我QQ: 1273623966 驗證信息請填 bootloader 或 cnblogs)。

 

  想了解PIC18 bootloader 請閱讀我的隨筆《自己用C語言寫單片機PIC18 serial bootloader》

  想了解PIC16 bootloader 請閱讀我的隨筆《自己用C語言寫單片機PIC16 serial bootloader》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM