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

  HyperBootloader_PIC18_J 和 HyperBootloader_PIC18_None_J

  完成PIC16 bootloader (详细情况请阅读我的上一篇随笔《自己用C语言写单片机PIC16 serial bootloader》) 后,接着就开始写PIC18的UART bootloader。事实上我写了HyperBootloader_PIC18_J 和 HyperBootloader_PIC18_None_J 两种bootloader。 一种给PIC18F, 另一种给PIC18FJ。两种bootloader除了在实现上有一点不同,大小也不同外,其他都差不多。都是模仿HI-TECH PICC bootloader实现的, 都是放置在程序存储器的头部,电脑端的程序都是用超级终端传送应用程序的Hex文件。在继续之前,先讲讲PIC18F和PIC18FJ的区别。

  PIC18F和PIC18FJ的区别

  PIC18F和PIC18FJ一个不同点是CONFIG BITS的烧写位置。对于PIC18F, CONFIG BITS被映射到程序存储器300000h (虚拟地址)开始的单元中。对于PIC18FJ,CONFIG BITS被烧写到程序存储器的底部(真实地址),每次上电自动会被映射到程序存储器300000h (虚拟地址)开始的单元中,所以对于PIC18FJ, 更新了CONFIG BITS,reset后才生效。

  

Interrupt Vector Remap

  由于bootloader 位于程序存储器的头部,需要对Interrupt Vector进行remap. 代码如下。

  #asm
    PSECT intcode
    goto APP_START + 0x8
    PSECT intcodelo
    goto APP_START + 0x18
  #endasm

  HyperBootloader_PIC18_None_J 主要代码段

  HyperBootloader_PIC18_None_J 每接收一行的超级终端发过来的Hex数据,一个一个程序字地烧录。具体实现的主要代码段如下。

    for(;;)        // loop until end of file
{
while (RCREG!=':'); // wait for start of hex file line while(!TXSTAbits.TRMT);
TXREG=':'; // the prompt to download a new program cksum = bcount = g2x(); // get the byte count
#if _EEPROMSIZE > 256
EEADRH = TBLPTRH = g2x(); // get the address
#else
TBLPTRH = g2x();
#endif
TBLPTRL = EEADR = g2x(); DO_NOT_INCREMENT = 1;
rectype = g2x(); // get the record type
switch(rectype)
{
case DATA: // ldata record
#if (PROG_START > 0x200) || defined(__PIC18FX520)
// to protect bootloader from being overwritten
if( (FLASH) && (TBLPTRU==0) && (TBLPTRH < (unsigned char)(PROG_START>>8)) )
// to protect bootloader from being overwritten
break; // if bootloader is threatened, skip this
#endif
clear_buffer();
while(bcount--)
{
TABLAT = EEDATA = buff[(EEADR&(_FLASH_WRITE_SIZE-1))] = g2x(); // get the data if((CONFIG)||(EEPROM))
{
if(CONFIG) // EEPROM/config. write byte at a time
{
table_write();
}
//zap();
}
else
{
if((EEADR & (_FLASH_WRITE_SIZE-1)) == (_FLASH_WRITE_SIZE-1)) //program/IDLOCs flash bytes at a time
{
flash8();
clear_buffer();
}
}
EEADR++;
}
if(((EEADR&(_FLASH_WRITE_SIZE-1))!=0)&&(FLASH)&&(!CONFIG))
flash8();
checksum();
break;
case END: // end of hex file
checksum();
TXSTA = 0x02; //reset USART before jump to application
RCSTA = 0x00;
(*((void(*)(void))PROG_START))(); // jump to new program
break;
case EXTEND_ADDRESS: // extended address record
while(bcount--)
{
EEADR=g2x(); // determines whether EE, Config or ID
}
EEPGD=1;
if(EEADR==0xF0)
EEPGD=0; // select for EEPROM
CFGS=0;
if((EEADR&0xF0)==0x30)
CFGS=1; // select for config write
TBLPTRU=EEADR;
checksum();
break;
}
}

  HyperBootloader_PIC18_J 主要代码段

  HyperBootloader_PIC18_J 每接收一行的超级终端发过来的Hex数据,在存到block数组中,block满了,再整个block地烧录。具体实现的主要代码段如下。

for (;;)
{
while (RCREG != ':');
while(!TXSTAbits.TRMT);
TXREG=':'; // the prompt to download a new program cksum = bcount = g2x();
data_buffer[LEN_INDEX] = bcount;
data_buffer[ADDRH_INDEX] = g2x();
data_buffer[ADDRL_INDEX] = g2x();
rectype = g2x();
switch(rectype)
{
case DATA:
while (bcount--)
{
data_buffer[LEN_INDEX + data_index + 1] = g2x();
data_index++;
}
checksum();
EECON1 = PGM_WRITE;
WriteMem();
break;
case END:
checksum();
if (block_start)
{
WriteStart();
resetBlockBuffer();
block_start = 0;
}
TXSTA = 0x02; //reset USART before jump to application
RCSTA = 0x00;
asm("goto "___mkstr(APP_START));
break;
case EXTEND_ADDRESS:
g2x();
data_buffer[ADDRU_INDEX] = g2x();
checksum();
break;
}
data_index = 0;
}

  如何使用

  1. 使用XC8编译HyperBootloader_PIC18_J 或HyperBootloader_PIC18_None_J。

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

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

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

  5. 6秒内,在超级终端窗口中按下键盘上任何按键,会出现">"(6秒内没按键,会自动跳转到用户的应用程序中去)。

  6. 打开Send Text File对话框,选择期望烧录的应用程序hex文件(由于bootloader在程序存储器的头部,所以应用程序需要在编译前设置XC8的Code offset, 如果是使用HyperBootloader_PIC18_J,设置为400, 如果是使用HyperBootloader_PIC18_None_J, 设置为300),点击确认, HyperBootloader会将接收到的数据传回到电脑超级终端上,并将数据烧录到目标板程序存储器的正确位置。

  7. 烧录完毕,再次重启目标板,超级终端显示完Booting ......,就自动跳到应用程序中,目标板开始正常运行应用程序。

  之后每次更新应用程序,只需重复步骤 4 ~ 7 就可以了。

  主要特性

  HyperBootloader_PIC18_J 和 HyperBootloader_PIC18_None_J 有以下主要特性

  1. C语言写的,XC8 编译。

  2. 非常容易移植。

  3. 支持FLASH烧写

  4. 可支持EEPROM烧写。

  5. 支持CONFIG BITS/IDLOC 烧写。

  如果你有什么疑问,或有兴趣了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader 或 cnblogs)。

  

  想了解dsPIC bootloader 请阅读我的随笔《自己用C语言写dsPIC / PIC24 serial bootloader》

  想了解PIC16 bootloader 请阅读我的随笔《自己用C语言写单片机PIC16 serial bootloader》

自己用C语言写单片机PIC18 serial bootloader的更多相关文章

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

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

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

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

  3. 自己用C语言写NXP S32K144 serial bootloader

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

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

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

  5. 自己用C语言写RH850 F1KM serial bootloader

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

  6. 自己用C语言写RH850 F1L serial bootloader

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

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

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

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

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

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

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

随机推荐

  1. openjudge 螺旋加密

    /*======================================================================== 25:螺旋加密 总时间限制: 1000ms 内存限 ...

  2. pm2使用

    简单教程 首先需要安装pm2: npm install -g pm2 运行: pm2 start app.js 初次安装并运行,会有一个高大上的界面: 高大上的界面 直接我们介绍过forever,那么 ...

  3. Weblogic是瓦特?和JVM是瓦特关系?

    所谓固定内存60M是瓦特? 以下内容是个瓦特? “总内存大小=堆内存+非堆内存1200m:为堆内存大小,如果不指定后者参数则有最大数限制,网上很多文章认为这就是JVM内存,-Xmx为设置最大堆内存60 ...

  4. vim没有颜色

    vim /etc/vim/vimrc   #查找到syntax on 启用,去掉前面的" (引号).

  5. web.xml文件详解

      web.xml文件详解 Table of Contents 1 listener. filter.servlet 加载顺序 2 web.xml文件详解 3 相应元素配置 1 listener. f ...

  6. springmvc配置servlet的拦截形式/*和/的区别

    今天复制一个现有的spring-mvc的项目修改配置作为新的项目,结果悲剧了!遇到了一个小问题困扰了半天,找同事找总监都没有搞定,纠结了半天终于发现了问题所在,随笔记一下,所谓好记性不如烂博客嘛! 问 ...

  7. <<软技能,代码之外的生存技能>>读书笔记

    管理 1. 制定大目标,再分解成小目标,定时反思自己的长期和短期的成果 2. 人都希望自己很重要, 要让下属有存在感,让他们做事有成就感 3. 奖励积极比惩罚消极更有用 4. 学会换位思考,不要用&q ...

  8. OAF_开发系列25_实现OAF中Java类型并发程式开发oracle.apps.fnd.cp.request(概念)

    20150719 Created By BaoXinjian

  9. Angular进度-1207

    https://www.angular.cn/docs/ts/latest/tutorial/toh-pt1.html

  10. Python 之 for循环中的lambda

    第一种 f = [lambda x: x*i for i in range(4)]  (如果将x换成i,调用时候就不用传参数,结果都为3) 对于上面的表达式,调用结果: >>> f ...