了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序)。

  从15年12月份以来我的空余时间都在折腾15年底买的PIC32MZ EC Starter kit。并陆续写了十多篇随笔记录我折腾的历程。最近新完成的是用C语言实现了PIC32的UART bootloader, 采用串口通信,适用于Microchip的PIC32MZ EC,稍作对应的修改也可适用于PIC32MX, PIC32MZ EF等。Uart bootloader是用XC32编译的,电脑端的通信软件是用超级终端--HyperTerminal (也可以使用SecureCRT). 和之前我写的HyperBootloader_PIC16/PIC18/dsPIC很类似,算是一个家族系列之一。为保证家族特性,我命其名为HyperBootloader_PIC32

BOOTLOADER PLACEMENT

  HyperBootloader_PIC32 序放在引导闪存存储器中,如下图所示。

  BOOTLOADER LINKER SCRIPT

  由于需要将bootloader放置在特定位置,我们不能使用默认的linker script. 我们需要修改linker script来放置bootloader, 以下是修改后的主要部分。

_RESET_ADDR                    = 0xBFC00000;
_BEV_EXCPT_ADDR = 0xBFC00380;
_DBG_EXCPT_ADDR = 0xBFC00480;
_SIMPLE_TLB_REFILL_EXCPT_ADDR = _ebase_address + 0;
_CACHE_ERR_EXCPT_ADDR = _ebase_address + 0x100;
_GEN_EXCPT_ADDR = _ebase_address + 0x180; /*************************************************************************
* Memory Regions
*
* Memory regions without attributes cannot be used for orphaned sections.
* Only sections specifically assigned to these regions can be allocated
* into these regions.
*
* The Debug exception vector is located at 0x9FC00480.
*
* The config_<address> sections are used to locate the config words at
* their absolute addresses.
*************************************************************************/
MEMORY
{
/* Bootloader user code: Only in the Lower Boot Alias */
kseg0_program_mem (rx) : ORIGIN = 0x9FC02000, LENGTH = 0xDF00
/* Lower Boot Alias last(5th) page: Not used */
kseg0_lba_last_page (rx) : ORIGIN = 0x9FC10000, LENGTH = 0x4000
/* Interrupt Vector table */
kseg0_boot_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
/* Reset and C Startup module */
kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x480
/* Cache TLB Initialization Table */
kseg1_boot_mem_4B0 : ORIGIN = 0xBFC004B0, LENGTH = 0xB50

  BOOTLOADER MAIN CODE

  修改后的linker script加到bootloader的项目中后,接着是bootloader的coding,以下是bootloader code的主要部分

        if (linereceived)
{
for (ix = 0; ix < incrbytes; ix++)
{
Uart_Putc(frameBuffer[ix]);
}
Uart_Putc('\n');
cksum = bcount = GetXbyte(frameBuffer[LEN_NIBBLE1_INDEX],frameBuffer[LEN_NIBBLE2_INDEX]);
SourceAddr.v[1] = GetXbyte(frameBuffer[ADDRH_NIBBLE1_INDEX],frameBuffer[ADDRH_NIBBLE2_INDEX]);
SourceAddr.v[0] = GetXbyte(frameBuffer[ADDRL_NIBBLE1_INDEX],frameBuffer[ADDRL_NIBBLE2_INDEX]);
rectype = GetXbyte(frameBuffer[TYPE_NIBBLE1_INDEX],frameBuffer[TYPE_NIBBLE2_INDEX]);
switch(rectype)
{
case LINEAR_ADDRESS:
SourceAddr.v[3] = GetXbyte(frameBuffer[TYPE_NIBBLE2_INDEX+1],frameBuffer[TYPE_NIBBLE2_INDEX+2]);
SourceAddr.v[2] = GetXbyte(frameBuffer[TYPE_NIBBLE2_INDEX+3],frameBuffer[TYPE_NIBBLE2_INDEX+4]);
Checksum();
break;
case DATA:
if ((SourceAddr.word.HW == 0x1fc0)) break;
if (SourceAddr.Val >= (EraseAddr.Val+ PAGE_SIZE))
{
EraseAddr.Val = (SourceAddr.Val/PAGE_SIZE) * PAGE_SIZE;
NVMErasePage(EraseAddr.Val);
}
linereceived = 0;
for (ix=0; ix < 2*bcount;)
{
pData.byte.LB = GetXbyte(frameBuffer[TYPE_NIBBLE2_INDEX+1+ix+0],frameBuffer[TYPE_NIBBLE2_INDEX+1+ix+1]);
pData.byte.HB = GetXbyte(frameBuffer[TYPE_NIBBLE2_INDEX+1+ix+2],frameBuffer[TYPE_NIBBLE2_INDEX+1+ix+3]);
pData.byte.UB = GetXbyte(frameBuffer[TYPE_NIBBLE2_INDEX+1+ix+4],frameBuffer[TYPE_NIBBLE2_INDEX+1+ix+5]);
pData.byte.MB = GetXbyte(frameBuffer[TYPE_NIBBLE2_INDEX+1+ix+6],frameBuffer[TYPE_NIBBLE2_INDEX+1+ix+7]);
unsigned int error = NVMWriteWord(SourceAddr.Val, pData.Val);
if ((error & 0x3000) > 0) Uart_Putc('N'); // for debug
error = 0;
SourceAddr.Val += 4;
ix += 8;
if (linereceived) Uart_Putc('X'); // for debug
}
Checksum();
//Buf_Init();
break;
case END:
Checksum();
U1MODE = 0x0;
U1STA = 0x0;
TRISCSET = 0x2000; /* RC13 Input */
LATCCLR = 0x6000; /* Clear LATC */
IPC28CLR = 0x1F00; /* Clear IPC28 */
IEC3bits.U1RXIE = 0; /* Clear IEC3 */
(*((void(*)(void))USER_APP_RESET_ADDRESS))();
break;
}
linereceived = 0;
incrbytes = 0;
}

  Bootloader编译成功后,使用programmer烧录到target, 然后拔掉programmer。并且以后再更新application再也不需要programmer了。

  APPLICATION LINKER SCRIPT

  Bootloader和appication同时放置在闪存存储器中,要两者都可以正常工作,就必修确保两者不能有overlap。所以application的放置需要避开bootloader,这样需要需改application 的linker script。 以下是修改后的主要部分。

_RESET_ADDR = 0x9D001000;
_SIMPLE_TLB_REFILL_EXCPT_ADDR = _ebase_address + 0;
_CACHE_ERR_EXCPT_ADDR = _ebase_address + 0x100;
_GEN_EXCPT_ADDR = _ebase_address + 0x180; /*************************************************************************
* Memory Regions
*
* Memory regions without attributes cannot be used for orphaned sections.
* Only sections specifically assigned to these regions can be allocated
* into these regions.
*
* The Debug exception vector is located at 0x9FC00480.
* The config_<address> sections are used to locate the config words at
* their absolute addresses.
*************************************************************************/
MEMORY
{
kseg1_boot_mem : ORIGIN = 0x9D001000, LENGTH = 0x480
kseg0_program_mem (rx) : ORIGIN = 0x9D000000 + 0x1000 + 0x480, LENGTH = 0x200000 - (0x1000 + 0x480) /* All C files will be located here */ kseg0_boot_mem : ORIGIN = 0x9D000000, LENGTH = 0x0
kseg0_data_mem (w!x) : ORIGIN = 0x80000000, LENGTH = 0x80000
sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000
kseg2_ebi_data_mem : ORIGIN = 0xC0000000, LENGTH = 0x4000000
kseg2_sqi_data_mem : ORIGIN = 0xD0000000, LENGTH = 0x4000000
kseg3_ebi_data_mem : ORIGIN = 0xE0000000, LENGTH = 0x4000000
kseg3_sqi_data_mem : ORIGIN = 0xF0000000, LENGTH = 0x4000000
}

  HOW TO USE HYPERBOOTLOADER_PIC32

      1. 使用XC32编译HyperBootloader_PIC32(编译前,需先修改linker script)。

  2. 使用pickit3烧录HyperBootloader_PIC32的Hex文件到目标板中。

  3. 拔除pickit3烧录器,连接目标板与PC的串口,打开超级终端,设置如下:115200-8-None-1-None, Line Delay-20ms

  4. 重启目标板,超级终端会出现Booting... 字样。

  5. 6秒内,打开Send Text File对话框,选择期望烧录的application的hex文件(编译前,需先修改linker script),点击确认, HyperBootloader会将接收到的数据传回到电脑超级终端上,并将数据烧录到目标板程序存储器的正确位置。

  6. 烧录完毕,自动跳转去执行application。

  之后每次更新application,只需重复步骤 4 ~ 6 就可以了。

  NOTE

HyperBootloader不支持configuration bits的烧写,需要application的configuration bits 和HyperBootloader_PIC32的configuration bits保持一致。

自己用C语言写PIC32 serial bootloader的更多相关文章

  1. 自己用C语言写RL78 serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 之前用C实现过多款PI ...

  2. C语言dsPIC / PIC24 serial bootloader和C#语言bootloader PC端串口通信程序

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新dsPIC/PIC2 ...

  3. C语言PIC32 serial bootloader和C#语言bootloader PC端串口通信程序

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 今天介绍下我新完成的为 ...

  4. C语言RH850 F1L serial bootloader和C#语言bootloader PC端串口通信程序

                   了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程 ...

  5. C语言RH850 F1KM serial bootloader和C#语言bootloader PC端串口通信程序

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 今天我要介绍的RH85 ...

  6. 自己用C语言写单片机PIC16 serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 为什么自己写bootl ...

  7. 自己用C语言写NXP S32K116 serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 每次我有了新的EVA ...

  8. 自己用C语言写dsPIC / PIC24 serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). HyperBootlo ...

  9. 自己用C语言写单片机PIC18 serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). HyperBootlo ...

随机推荐

  1. Torch 网络层 参数的初始化问题

    Torch 网络层 参数的初始化问题 参考链接: https://github.com/Kaixhin/nninit 从 Torch 中自带的包,可以看到:https://github.com/tor ...

  2. 水池进水与放水问题:有一个水池,水池的容量是固定 的500L,一边为进水口,一边为出水口.........(多线程应用)

    package demo2; class Pooll {    /**1:有一个水池,水池的容量是固定 的500L,一边为进水口,一边为出水口.     * 要求,进水与放水不能同时进行.     水 ...

  3. Ionic页面加载前 ionic页面加载完成 ionic页面销毁执行的事件

    ionic 中$ionicView.beforeEnter(页面刚加载前)  $ionicView.afterEnter  (页面加载完成) $destroy(页面销毁) 广播事件 //ionic c ...

  4. .NET设计规范————类型设计规范

    类型设计规范 从CLR的角度看,只有值类型和引用类型两种类型,但是从框架设计的角度我们把类型从逻辑上分了更多的组.如下所示: 类是引用类型的一般情况,占了框架中的大多情况,类的流行归于它支持面向对象的 ...

  5. ios 写项目的时候遇到的问题及解决方案(3)

    22.看了苹果的文档,里面有这一句话:All launch images must be PNG files and must reside in the top level of your appl ...

  6. 【转】JSch - Java实现的SFTP(文件下载详解篇)

    上一篇讲述了使用JSch实现文件上传的功能,这一篇主要讲述一下JSch实现文件下载的功能.并介绍一些SFTP的辅助方法,如cd,ls等.   同样,JSch的文件下载也支持三种传输模式:OVERWRI ...

  7. 【java】之3种方式实现Object和Map之间的转换

    利用commons.BeanUtils实现Obj和Map之间转换,这种是最简单,也是最经常用的 public static Object mapToObject(Map<String, Obje ...

  8. R语言-数据高级管理

    数学函数 abs() 绝对值 sqrt() 平方 ceiling() 向上取整 floor() 向下取整 trunc() 截取整数部分 round(x,digits = n) 保留几位小数 统计函数 ...

  9. 键盘键与虚拟键码对照表+delphi虚拟键码对应关键

    键盘键与虚拟键码对照表 字母和数字键 数字小键盘的键 功能键 其它键 键 键码 键 键码 键 键码 键 键码 A 65 0 96 F1 112 Backspace 8 B 66 1 97 F2 113 ...

  10. C#开发分享:如何改变系统鼠标样式

    开发过程中发现需要用到改变鼠标样式(就是光标的样子),但是在网上找了很多资料,都是介绍在程序中使用,我需要的效果时在系统级使用.现在找到了,分享给大家. [DllImport("user32 ...