×
单片机 > 单片机程序设计 > 详情

PIC24 通过USB在线升级 -- USB CDC bootloader

发布时间:2020-06-17 发布时间:
|

今年国庆完成了4个bootloader,前面介绍了2个,都是PIC32MZ的USB bootloader, 接着介绍2个PIC24 的USB bootloader, 首先是PIC24 USB CDC bootloader。PIC24 USB CDC bootloader 是我开发给我的PIC24FJ256GB106硬件板子的。


开发环境


1. IDE: MPLABX v4.01


2. Compiler: XC16, v1.11


3. Library&Example: c:/microchip_solutions_v2013-06-15/USB/Device-CDC-Basic Demo


这个PIC24 CDC bootloader 是在MLA_v2013-06-15的USB CDC basic demo的基础上修改而成。bootloader 占用空间从0x400开始, 长度= 0x1C00。 CDC bootloader模拟UART通信,一行一行接收串口发送过来的hex原文,然后对每行的hex原文进行解析,将里面的bin数据烧写到对应的地址上。整个的逻辑实现都在我写的Boot_DoProcess()函数中,函数代码如下。


uint8_t BOOT_DoProcess(uint8_t *buffer, uint16_t byteCount)

{

    uint8_t i;

     

    uint8_t bcount, recType;

    DWORD_VAL pData;

    uint8_t retVal = 0;

    if (byteCount == 64)

    {

        return 1;

    }

    bcount = GetXbyte(buffer[LEN_NIBBLE1_INDEX],buffer[LEN_NIBBLE2_INDEX]);

 

    if (!Checksum(buffer, bcount))

    {

        retVal = 2;

        return retVal;

    }

     

    srcAddress.v[1] = GetXbyte(buffer[ADDRH_NIBBLE1_INDEX],buffer[ADDRH_NIBBLE2_INDEX]);

    srcAddress.v[0] = GetXbyte(buffer[ADDRL_NIBBLE1_INDEX],buffer[ADDRL_NIBBLE2_INDEX]);

    srcAddress.Val >>= 1;

    recType = GetXbyte(buffer[TYPE_NIBBLE1_INDEX],buffer[TYPE_NIBBLE2_INDEX]);

    switch(recType)

    {

    case LINEAR_ADDRESS:

        srcAddress.v[3] = GetXbyte(buffer[TYPE_NIBBLE2_INDEX+1],buffer[TYPE_NIBBLE2_INDEX+2]);

        srcAddress.v[2] = GetXbyte(buffer[TYPE_NIBBLE2_INDEX+3],buffer[TYPE_NIBBLE2_INDEX+4]);

        retVal = 3;

        break;

    case DATA:

        if ((srcAddress.Val >= BOOT_START_ADDRESS) && (srcAddress.Val < APPL_RESET_ADDRESS))  // boot protection, avoid to overlap

        {

            retVal = 4;

            return retVal;

        }

        eraseAddress.Val = srcAddress.Val;

        if ((srcAddress.Val % ERASE_BLOCK) == 0)

        {

            NVM_EraseBlock(eraseAddress.Val);

        }

        for (i=0; i < 2*bcount;)

        {

            pData.byte.LB = GetXbyte(buffer[TYPE_NIBBLE2_INDEX+1+i+0],buffer[TYPE_NIBBLE2_INDEX+1+i+1]);

            pData.byte.HB = GetXbyte(buffer[TYPE_NIBBLE2_INDEX+1+i+2],buffer[TYPE_NIBBLE2_INDEX+1+i+3]);

            pData.byte.UB = GetXbyte(buffer[TYPE_NIBBLE2_INDEX+1+i+4],buffer[TYPE_NIBBLE2_INDEX+1+i+5]);

            pData.byte.MB = GetXbyte(buffer[TYPE_NIBBLE2_INDEX+1+i+6],buffer[TYPE_NIBBLE2_INDEX+1+i+7]);

            unsigned int error = NVM_WriteWord(srcAddress.Val, pData.Val);

            if ((error & 0x2000) > 0)

            {

                retVal = 5;

                return retVal;

            }

            error = 0;

            srcAddress.Val += 2;

            i += 8;

        }

        //retVal = 1;

        break;

    case END:

        retVal = 6;

        break;

    }

    return retVal;

}


在main.c中ProcessIO()函数中调用Boot_DoProcess(). ProcessIO改动很大,代码如下。


void ProcessIO(void)

{   

    BYTE numBytesRead;

    WORD status;

    //Blink the LEDs according to the USB device status

    BlinkUSBStatus();

    // User Application USB tasks

    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;


    if(buttonPressed)

    {

        if(stringPrinted == FALSE)

        {

            if(mUSBUSARTIsTxTrfReady())

            {

                putrsUSBUSART("Button Pressed -- rn");

                stringPrinted = TRUE;

            }

        }

    }

    else

    {

        stringPrinted = FALSE;

    }


    if(USBUSARTIsTxTrfReady())

    {

        numBytesRead = getsUSBUSART(USB_Out_Buffer,64);

        if(numBytesRead != 0)

        {

            BYTE i;

            BYTE j;

            for(i=0;i

            {

                switch(USB_Out_Buffer[i])

                {

                    case 0x0A:

                    case 0x0D:

                        USB_In_Buffer[i] = USB_Out_Buffer[i];

                        if (!BOOT_Handshake)

                        {

                            BOOT_Handshake = 1;

                        }

                        else

                        {

                            if ((BOOT_RecordSOF == 1) && (BOOT_RecordEOF == 0))

                            {

                                BOOT_RecordBuffer[BOOT_RecordCounter++] = USB_Out_Buffer[i];

                                BOOT_RecordEOF = 1;

                                for (j=0; j

                                {

                                    BOOT_OperationBuffer[j] = BOOT_RecordBuffer[j];

                                }

                                BOOT_OperationCounter = BOOT_RecordCounter;

                                BOOT_RecordLineFlag = 1;

                                BOOT_RecordSOF = 0;

                                BOOT_RecordEOF = 0;

                                BOOT_RecordCounter = 0;

                            }

                        }

                        break;

                    case ':':

                        USB_In_Buffer[i] = USB_Out_Buffer[i];

                        if (BOOT_Handshake)

                        {

                            if (!BOOT_RecordSOF)

                            {

                                BOOT_RecordBuffer[BOOT_RecordCounter++] = USB_Out_Buffer[i];

                                BOOT_RecordSOF = 1;

                            }

                        }

                        break;

                    default:

USB_In_Buffer[i] = USB_Out_


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多