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. 烧写完成后重启目标板。