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

      了解bootloader的实现,请加我Q扣: 1273623966 (验证填bootloader);欢迎咨询或定制bootloader; 我的博客主页www.cnblogs.com/geekygeek

       今天是长假的最后一天,明天又要开始上班了,所以我决定今天把在今年国庆前及国庆中完成的bootloader都介绍完,前面的博文已经介绍了3个,现在介绍最后一个--PIC24 HID bootloader。PIC24 HID bootloader 操作简单,速度也快,并且在PIC24FJ256GB106硬件板子上测试多次,稳定可靠。

      开发环境

  1. IDE: MPLABX v4.01

        2. Compiler: XC16, v1.11

        3. Library & Example:  c:/microchip_solutions_v2013-06-15/USB/Device - Bootloaders/HID/Firmware - PIC24FJ256GB110 Family/MPLAB.X

        这个PIC24 HID bootloader 是在MLA_v2013-06-15的Device Bootloader的基础上修改而成的。 bootloader和应用程序的空间分配以及Linker Script的修改是参考以下帖子http://www.microchip.com/forums/m402123.aspx 里面网友“test838"提供的一个非常好的方法,本HID bootloader和应用程序所用的Linker Script都是按照这种方式创建的。按照“test838"的介绍,AN1157的地址分配的方法比AN1094更科学,更安全,而他提供的方法又比AN1157的更好。本HID bootloder 地址是空间是0x400开始,长度=0x1C00. 应用程序地址从0x2000开始到结束。

     下位机

     HID bootloader在例程的基础上,修改了configuration bits, 系统时钟,屏蔽了按键检测的相关代码。例程的是现实方式要有一个按键,按键按下,同时重启板子,就会进入bootloader mode,完成升级。但是我的硬件目标板没有按键。所以我屏蔽了按键检测的相关代码,并在mian函数的开始处做了相应的修改,如下。

    //mInitSwitch2();
    //if((sw2==1) && ((RCON & 0x83) != 0))
    if ((RCON & 0x80) != 0)
    {
        //__asm__("goto 0x1400");
        __asm__("goto 0x2200");
    }

       还有ProcessIO()函数的修改

    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1))
    {
        if (BOOT_required == 0)
        {
            BOOT_wait--;
            if (BOOT_wait == 0)
            {
                
                 //__asm__("goto 0x2200");
                Reset();
                
            }
        }
        else
        {
            BOOT_wait = BOOT_WAIT_TIMEOUT;
        }
        return;
    }
    
    BootApplication();

接着是BootApplication()函数的修改

if(BootState == IdleState)
    {
        //Are we done sending the last response.  We need to be before we 
        //  receive the next command because we clear the PacketToPC buffer
        //  once we receive a command
        if(!USBHandleBusy(USBInHandle))
        {
            if(!USBHandleBusy(USBOutHandle))        //Did we receive a command?
            {
                for(i = 0; i < TotalPacketSize; i++)
                {
                    PacketFromPC.Contents[i] = PacketFromPCBuffer.Contents[i];
                }
                
                USBOutHandle = USBRxOnePacket(HID_EP,(BYTE*)&PacketFromPCBuffer,64);
                BootState = NotIdleState;
                
                //Prepare the next packet we will send to the host, by initializing the entire packet to 0x00.    
                for(i = 0; i < TotalPacketSize; i++)
                {
                    //This saves code space, since we don't have to do it independently in the QUERY_DEVICE and GET_DATA cases.
                    PacketToPC.Contents[i] = 0;    
                }
            }
            else
            {

            }
        }
        else
        {

        }
        if (BOOT_required == 0)
        {
            BOOT_timeout--;
            if (BOOT_timeout == 0)
            {
            //__asm__("goto 0x2200");
                Reset();
            }
        }
    }
    else //(BootState must be in NotIdleState)
    {    
        if ((PacketFromPC.Command != UNLOCK_CONFIG)&&(PacketFromPC.Command != ERASE_DEVICE) && (BOOT_required == 0))
        {
            BOOT_timeout--;
            if (BOOT_timeout == 0)
            {
                //__asm__("goto 0x2200");
                Reset();
            }
        }
        else
        {
            BOOT_required = 1;
        }

编译完成后的HID bootloader,将编译完的HID bootloader通过PICKit3烧入硬件目标板。

        上位机
       本HID bootlodare用的上位机和例程用的上位机是一样的,在“Software Windows Executable"文件夹中,上位机名叫HIDBootloader.exe. 接着就是使用上位机和HID bootloader完成应用程序的升级。

        

        升级步骤如下:

        1. 打开上位机

        2. 重启目标板

        3. 上位机若提示,”Device detected", 则选好要烧写的应用程序hex.

        4. 点击上位机的下载按钮。

        5. 等待烧写完成。

        6. 烧写完成后重启目标板。

posted @ 2017-10-08 22:16  GeekyGeek  阅读(986)  评论(0编辑  收藏  举报