历史上的今天
返回首页

历史上的今天

今天是:2025年02月03日(星期一)

2020年02月03日 | pic18单片机在BootLoader中的应用

2020-02-03 来源:elecfans

  引 言

  在PIC系列单片机中,只有PIC18系列和PIC16F87X系列的单片机才有IAP功能,才能够使用BootLoader功能。下面只介绍PIC18的BootLoader,PIC16F87X的BootLoader与它类似。


  1 BootLoader程序的工作原理

  BootLoader是一段引导程序,在单片机上电/复位后在用户程序之前先运行。运行后判断当前是否需要进入升级状态。如果不需要升级,就直接运行Flash中原有的程序;如果需要升级,首先擦除旧的程序,然后从串口接收用户程序,同时写入Flash中。接收数据时,需要进行校验,保证接收到的数据是正确的,避免将错误的程序写入到芯片中。

BootLoader是一段引导程序,在单片机上电/复位后在用户程序之前先运行。运行后判断当前是否需要进入升级状态。如果不需要升级,就直接运行Flash中原有的程序;如果需要升级,首先擦除旧的程序,然后从串口接收用户程序,同时写入Flash中。接收数据时,需要进行校验,保证接收到的数据是正确的,避免将错误的程序写入到芯片中。

  PIC18单片机只有一块Flash,可以在Flash的任何位置擦写(甚至可以将BootLoader自身擦除);而51单片机一般都是两块Flash,只能够从一块Flash上擦写另一块Flash,而不能擦写自身。


  BootLoader程序原则上是可以放在整个程序空间中的任何位置的,但是为了简单方便、具有通用性和尽量减少对用户程序的影响,使用了从0x00开始的一段程序空间。


  BootLoader程序可以多种方式获取数据,包括串口、并口、I2C、SPI、USB等;但是从实际使用来看,使用串口无疑是最方便的。


  为了使得用户程序可以获得最大的程序空间,就需要BootLoader程序尽可能的简短。在这里,Microchip和HI-TECH都将BootLoader程序设计为小于200H个字节(100H个字)。使用0x00~0x1FF这个区域还有一个重要原因是,这个地址的空间有特殊的写保护特性。


  PIC18单片机虽然有多个中断源,但只支持两级中断,有两个中断向量,分别位于0x08和0x18;而BootLoader程序占用了0x00~0x1FF的空间,这意味着需要重新定位中断向量,使新的中断向量指向用户的中断程序,这样才能保证正常运行用户程序的中断程序。


  2 程序的使用方法

  (1) HI-TECH的BootLoader程序

  在HI-TECH的PICC18编译器的examples文件夹下,有一个Bootldr子文件夹,里面就是HI-TECH的BootLoader程序。这是一个完整的程序,可以直接进行编译,编译后的HEX可以用编程器下载到芯片中。


  (2) 用户系统的要求

  如果需要使用BootLoader,要求用户系统中有一个RS232串口可以和计算机进行通信。


  (3) 程序的配置

  下面是程序的主要参数,如果它们设置得不正确,会影响程序的使用。

  VERB0:冗余模式,有更多的提示,但是会占用更多的程序空间,建议不用。

  BOOT_TIMEOUT:等待超时的时间,0~9s(再长了也没有意义),默认为5s。

  BAUD:串口通信的波特率,默认是9 600。

  FOSC:用户系统的时钟频率,默认是4 MHz。

  NINE:通信是否使用第9位数据位,默认不使用。

  FILL_BYTE:程序空间擦除时使用的填充数据,默认值是0xFF。

  PROG_START:用户程序的起始位置,默认是0x200。

  其他的参数可以先不用管,在需要时再修改,它们不影响通信和下载。


  (4) 程序的编译

  有两种方法对BootLoader程序进行编译:

  ① 命令行方式。使用命令行时,典型的用法是:

  picc18 -8f452 bootldr.c -o -zg -noerrata

  上面的最后一个参数 -noerrata是PIC18Fxx2系列单片机需要的,若是其他型号,就不用加入;而参数 -18f452是指定单片机的型号,如果是其他型号,就修改为实际使用的型号。

  ② 使用MPLAB IDE。使用MPLAB IDE时,首先按照正常方式建立一个新的工程文件,选择工程文件目录,然后加入HI-TECH的SamplesBootldr目录下文件bootldr.c和bootldr.h。建立工程文件时,选择MCU的型号为实际使用的型号,选择C编译器为HI-TECH的PICC18编译器。

BootLoader是一段引导程序,在单片机上电/复位后在用户程序之前先运行。运行后判断当前是否需要进入升级状态。如果不需要升级,就直接运行Flash中原有的程序;如果需要升级,首先擦除旧的程序,然后从串口接收用户程序,同时写入Flash中。接收数据时,需要进行校验,保证接收到的数据是正确的,避免将错误的程序写入到芯片中。

  (5) 用户程序的配置

  使用HI-TECH版本的BootLoader,对用户程序的修改是非常少和简单的,只需要修改用户程序的偏移量就可以了,而不需要修改任何程序代码或进行任何特殊的配置。因为BootLoader程序需要占用0~1FFH的空间,所以用户程序需要从200H处开始运行,即设置程序的偏移量为200H。方法是在MPLAB IDE中,从菜单中选择Project→Build OpTIons.。。→Project,在PICC-18 Linker页标下的Specify offset for ROM(ROM代码偏移量)中输入偏移量200(注意这里输入的已经是十六进制了,不用再转换),如图1所示。


  (6) 程序配置字

  对于每个PIC单片机的芯片,都需要设置正确的程序配置字后才能正常运行。虽然在BootLoader中是可以修改配置字的,但是这样并不安全,也不方便。一般情况下,程序配置字设定后是不需要修改的,所以配置字在烧写BootLoader程序时就一起写入单片机芯片,以后就只使用BootLoader来升级(烧写)程序,这样不会破坏芯片的配置字。

  (7) 调试用户程序

  平时,在编写和调试用户程序时,还是和正常方式一样,单片机中不包含BootLoader程序,也不设置偏移量(或者设置为0),以方便使用ICD2等仿真器进行程序仿真。等程序调试好后,再修改程序的偏移量为200H,并重新编译程序,产生最终的用户HEX代码。这样编译好的程序才可以使用BootLoader进行下载。

  (8) 下载用户程序

  使用HI-TECH的BootLoader程序,在下载用户程序到单片机中时,可以不需要特殊的下载程序,只需要使用Windows自带的超级终端程序就可以了。超级终端的通信参数需要设置成和BootLoader程序的一样,包括波特率、校验、数据位、停止位等。


  首先连接好串口线,再启动超级终端程序,然后复位单片机(单片机中应当已经写入了BootLoader程序)。这时,在超级终端的窗口中会显示出一个倒计时的计数器,计数器的初始值就是上面的BOOT_TIMEOUT参数。计数器每秒钟刷新一次。当计数器为0时,就会运行以前的程序。


  如果这期间从超级终端输入任意数据(就是随便按一个键,或者说单片机从串口上接收任意数据),计数器就会停止计数,进入升级状态。这时BootLoader程序会首先擦除旧的程序空间,然后屏幕上会显示出一个冒号“:”,提示等待下载用户程序。这时就可以从超级终端的菜单中选取传送→发送文本文件,选择编译好的HEX文件即可。如果下载成功,超级终端的窗口中会显示出一个小括号“)”,提示下载已经完成,同时用户程序会自动开始运行。使用BootLoader下载时,因为串口的速度相对比较慢(与编程器相比),所以需要等待一会儿。具体时间与用户程序的大小有关。如果下载中出现错误,单片机会自动复位,进入倒计数状态,重复上面的过程。使用超级终端比较简单,不需要特殊的下载软件;但是缺乏交互性,没有进程指示,如果下载过程中出现错误也不能停止下来。


  3 BootLoader程序的改进

  (1) HI-TECH的BootLoader程序中存在的缺陷

  虽然HI-TECH版本的BootLoader程序已经很方便了,具备了所有必需的基本要素;但是程序中存在着一些缺陷,甚至是很重大的隐患,不太适合于直接使用在实际工程中。下面是主要存在的几个问题

  ①BootLoader是以从串口上接收任何数据为标志进入BootLoader状态的。进入BootLoader状态后,BootLoader程序做的第一件事情就是擦除以前程序的空间。如果在实际使用中,单片机因为某种意外原因被复位,而且复位后运行BootLoader时在串口上有任何数据(如干扰信号或者系统正处于串口通信状态),就会造成用户程序的丢失。

  ② BootLoader程序中没有使用看门狗。如果升级失败或者升级过程中程序死机,将不能恢复到初始的升级状态。这对于直接串口连接的方式问题不大,但是需要使用远程升级时是一个致命的问题。

  ③ 在写入用户程序过程中如果出现数据错误,就会复位,而这时用户程序已经被部分写入了。如果复位后运行BootLoader程序没有收到信号时,会启动用户程序。这样残缺的用户程序就可能会造成运行故障和不可预料的结果。如果看门狗是在用户程序中打开的,这时就有可能出现看门狗没有被启动而死机的现象,这是远程升级中一个严重的问题。

  ④ BootLoader程序中允许写EEPROM和芯片配置字。虽然这样增加了灵活性,但是这样是不安全的。如果配置字不小心设置错了,下载后会使整个芯片不能正常运行。这时需要重新用编程器修改配置字才行。

  只有设法克服上面提到的缺陷,才能将BootLoader程序应用到实际系统中。


  (2) 对HI-TECH的BootLoader程序的改进

  针对上面提到的问题,对HI-TECH的BootLoader作了一些修改,删除了部分很少用到的功能和不安全的功能,同时修改了进入BootLoader状态的判断条件。除了使用增强的串口数据识别方式外,还增加了电平检测的方式,用来判断是否进入BootLoader状态。

  ① 针对上面第一项中的问题,修改为识别特定字符串才可以进入BootLoader的升级状态。特定字符串的内容和长度可以由用户自己定义(长度不能超过12字节。在一般情况下,12字节的识别字符串应当足够长了)。可以使用任何数据(包括0)。

  ② 增加了特定引脚电平判断方式,在BootLoader程序运行后,判断某个特定的引脚上的电压是否是预定的电压,由此决定是否需要进入BootLoader升级状态。引脚和预定电压(高/低)可以自由设置。这种方式比较安全,但是不太适合于远程升级。

  ③ 增加了看门狗选项,可以设置使用/不使用看门狗。一般设置看门狗的溢出时间在0.5~2s比较合适。

  ④ 增加了编程响应。在每成功接收到一行HEX数据后,发出一个回应字节,用于编程时的错误检测。PC端的下载程序可以根据这个字节来判断下载过程中是否出错。

  ⑤ 针对上面3(1)中③的问题,可以这样解决。将编译后的HEX文件手工稍作修改,将0x200~0x220(假设用户程序是从0x200开始的)地址段的数据从文件的开头移动到文件的结尾。这样0x200处的代码会在最后才写入单片机中。如果写入过程中出现故障,复位后即使BootLoader启动了用户程序,也会因为这段区域没有代码而重新复位,而不会去运行部分被写入的用户程序。不过这种方法需要对HEX文件的结构有一定的了解才行。


  一个简单判断HEX数据地址的方法是,HEX文件的每一行第一个字符是冒号“:”,冒号后的第3、4、5、6这四个数字就表示这一行数据的地址,是以十六进制表示的。如:“:100200.。。”就表示地址是0x200。在正常情况下,编译后的HEX文件数据是地址从低到高的顺序排列的。


  改进后的程序增加了一部分参数,它们是:

  BOOT_SIGNAL——使用单片机引脚电平触发方式进入BootLoader;

  BOOT_SIGNAL_PORT——定义电平触发启动方式检测用的引脚;

  BOOT_SIGNAL_LEVEL——定义检测电平1=高电平触发,0=低电平触发;

  BOOT_TIME_DELAY——使用超时方式进入BootLoader,这个参数和上面的BOOT_SIGNAL不能同时?使用;??

  USE_EXTEND_HEX——是否接收扩展的HEX代码,不使用可以节省代码,建议不用;

  USEWDT——是否在BootLoader中使用看门狗,建议使用;

  CONFIRM_TIME——联机同步字节数,在超时方式中使用多字节进行同步;

  CONFIRM_DATA——用户可定义的联机数据;

  USE_ECHOBACK——编程时是否回应,使用可以增加下载时的安全性,建议使用。


  使用了BOOT_SIGNAL方式后,与超时方式相关的部分都不再起作用。这时可以定义使用任意引脚来判定是否需要进入BootLoader。在使用BOOT_TIME_DELAY(超时方式)时,增加了一些与之相关的内容,如CONFIRM_DATA,可以使用任何特定的字符串来确认是否需要进入BootLoader状态,增加了BootLoader程序的安全性,避免受到干扰而误进入程序升级状态。


    (3) 其他改进的建议和方法

  ① HI-TECH的BootLoader程序接收的是标准的HEX文件。这在很多时候是不够安全的,不利于程序的加密,容易被反汇编和破解。可以对HEX进行加密处理,变成不能直接查看的数据。

  ② 使用超级终端进行程序下载速度比较慢,同时,如果下载中出现错误,超级终端程序不能及时发现停止下来,而是一直把文件发送完才能停下来。这时BootLoader程序会反复进入BootLoader状态,对单片机有一定的损伤。最好是自行编写一个计算机端的专用下载程序,不但可以提高下载的速度,也可以提高下载的成功率。

  ③ 使用RS422/485方式。有些时候,使用的并不是RS232串口,而是RS422/RS485串口。它们实际是类似的,只是在接口方式上有些区别。RS422/RS485需要控制发送,所以在BootLoader程序中增加一个发送控制就可以了。

  ④ 在BootLoader中,将波特率设置得很高并没有太大的用处,它并不能够提高下载整体的速度,而只能加快数据传输的速度。因为整个下载分为数据通信(数据传输)和Flash写入/擦除(数据等待)两个部分。程序代码Flash空间的擦除和写入速度是比较慢的(典型值是3~?4 ms),太快了反而容易丢失数据,造成下载失败。


  使用9600 bps的波特率时,传输1字节的数据大约是1 ms,接收一个缓冲区8字节大约需要8 ms,大于写入延时,所以不需要延时;当通信速率超过9600 bps时,接收8字节缓冲区的时间可能会小于写入时间,需要在通信中延时。实际使用的测试结果是:使用9600 bps比使用14 400 bps时慢50%,使用57 600 bps比9600 bps快一倍,而使用115 200 bps时与57 600 bps几乎没有任何区别。如果使用超级终端下载,就更没有必要设置高波特率了。因为在使用最常用的三线方式通信时(没有控制信号),超级终端采用了比较保守的方式发送数据,本身就比较慢。

  结语

  一个良好的BootLoader程序应该具有良好的可维护性并可以正确处理异常情况,不会因为意外情况引起系统的损坏和崩溃。

推荐阅读

史海拾趣

Chiplus Semiconductor Corp公司的发展小趣事

Chiplus深知企业管理对于公司发展的重要性。因此,公司建立了一套完善的管理体系,注重人才培养和团队建设。公司定期举办内部培训和技术交流活动,提升员工的专业技能和综合素质。同时,Chiplus还积极引进外部优秀人才,为公司的持续发展注入新的活力。

Dantona Industries公司的发展小趣事

Dantona Industries非常重视人才的培养和团队建设。他们深知,一个优秀的团队是公司发展的基石。因此,公司投入大量资源用于员工培训、激励机制建设等方面。他们定期组织技术研讨会、团队拓展活动等,提升员工的业务能力和团队凝聚力。同时,公司还建立了完善的晋升机制和薪酬体系,确保员工能够享受到与公司共同成长的成果。这种以人为本的管理理念为公司的持续发展提供了有力保障。

Deutron Electronics Corp公司的发展小趣事

Deutron Electronics Corp深知研发和创新对于公司发展的重要性。因此,公司始终保持着对研发的高投入,不断引进和培养人才。公司建立了完善的研发体系,鼓励员工参与创新活动,并为他们提供了充足的资源和支持。这些措施使得Deutron Electronics Corp在研发方面取得了显著成果,为公司的发展提供了源源不断的动力。

HTC Korea(TAEJIN Technology )公司的发展小趣事

进入安卓时代,HTC再次展现了其敏锐的市场洞察力和强大的技术实力。2008年,HTC联合电信运营商T-Mobile推出了世界上第一款安卓手机T-Mobile G1,这款手机的成功标志着HTC正式进入了安卓阵营。随后,HTC推出了多款备受好评的安卓手机,如HTC Hero(G3)等,进一步巩固了其在智能手机市场的地位。与谷歌和安卓的合作,为HTC带来了前所未有的发展机遇。

Capital Advanced Technologies公司的发展小趣事

品质管理是CAT发展的重要保障。公司建立了严格的质量管理体系,从原材料采购到产品制造、检验、包装等各个环节都进行严格的品质控制。CAT还注重与客户的沟通与协作,及时了解客户需求,为客户提供个性化的解决方案和优质的售后服务。这些举措使得CAT赢得了客户的广泛信赖和长期合作。

智烽维(CDA)公司的发展小趣事

智烽维(CDA)于2007年成立,专注于超级电容器(法拉电容)的研发和生产。在创立初期,公司面临着资金短缺、技术挑战和市场认知度低等多重困难。然而,凭借对技术的执着追求和对市场的敏锐洞察,智烽维成功推出了卷绕型超级电容器产品,并逐渐在市场上建立起了一定的知名度。

问答坊 | AI 解惑

开放源码硬件简史

开放源码硬件史前时代早在60,70 年代,电子爱好者就开始互相交流电路设计,PCB版图, 形成了开放源码硬件的雏形。在中国,这个时期,出现了很多以业余无线电和电子设计为主题的书刊、杂志。集成电路出现后,越来越多的功能集成在一个芯片中, 电路 ...…

查看全部问答>

飞思卡尔单片机开发环境

飞思卡尔单片机开发环境,先分享了…

查看全部问答>

IR2110烫的要命,急!!!!!!!!

本帖最后由 paulhyde 于 2014-9-15 09:35 编辑 A题,线接的没问题,有散热,可是IR2110接上没2秒就烫的要命  …

查看全部问答>

第9/15原创:事无巨细,无源蜂鸣器

事无巨细,无源蜂鸣器     CEPARK AVR学习板上,最简单的内容也许就是蜂鸣器了。当然如果你硬要用它来唱歌的话,那还是有点难度的。所以我们还是让它先发出“滴滴“声好了。      先来拓展拓展我们的知识吧(内容部 ...…

查看全部问答>

【Labview】labview下载地址

也许菜鸟们还不知道在哪可以下到labview,那么这个贴子应该可以帮助你们。 labview8.6完整官方下载地址 http://www.ni.com/labview/family/zhs/ ftp://evalftp86:LabV13w86@ftp.ni.com/ 附件中为labview2009官方下载地址 大家可以先用试用 ...…

查看全部问答>

有关VGA图像显示

我在做一个VGA图像显示的设计,然后采用的是定制ROM的方式。现在问题出在像素点的采集上,即定制ROM时那个.MIF或者.HEX文件里面的像素点怎么得到啊,希望知道的大侠们能指点指点···谢谢!…

查看全部问答>

evc socket有windows通信问题

小弟定义了一个结构体,然后想用来进行windows和wince通信,内容是文件的一些信息。然后把文件从windows传到wince上去。不过每次传都收不到真确的东西。请问我哪里有问题,是wince的Unicode的问题吗?…

查看全部问答>

调试运行不了,报错:管道的另一端上无任何进程

一个DLL,一个exe工程,加载dll使用#pragma comment lib形式,在EVC下可以运行的; 但现在要移植到ce6下,使用vs2005编译通过,部署也成功,但运行不起来,调试发现连APP的构造函数也没运行,就报错提示:管道的另一端上无任何进程。网上搜索没有 ...…

查看全部问答>

TFT液晶驱动

最近在用一种叫WXCAT35-TG3#001的TFT彩色屏,原想用HDL程序来驱动它,不过资料很少,没看懂它的工作原理。希望大侠们能够给予点帮助 如果哪位写过有关程序的话希望也教我一下,谢谢啦~ PS:我找到的数据手册…

查看全部问答>

STR911SPI做主收不到数据

  GPIO_StructInit(&GPIO_InitStruct);        GPIO_InitStruct.GPIO_Direction = GPIO_PinInput;  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;  GP ...…

查看全部问答>