引 言
目前市场上影响力较大的针对S12的集成开发环境CodeWarrior HCS12,功能完善、性能稳定,但是价格昂贵,不利于嵌入式领域的教学和开发。在国内由清华大学开发的S12BDM调试头,目前可支持的目标CPU外部晶振频率不高于19 MHz,它的软件部分由飞思卡尔半导体公司提供。苏州大学2005年研制了针对S12系列MCU的编程调试器,采用MC68HC908JB8(以下简称 JB8)作为编程调试器芯片;但是随着芯片制造技术的更新,S12系列MCU的品种越来越多,性能越来越好,典型的S12系列MCU总线频率为25 MHz,而JB8的总线频率只有3 MHz,可适用目标芯片的型号有限,且JB8只有256字节的RAM空间,可用于接收数据的缓存太小,影响通信速度。因此更加迫切地需要一款功能更加强大并且具有通用性的编程调试器来满足S12系列MCU的需求。
本文在分析了S12系列MCU编程调试器MC68HC908JB8的基础上,设计了基于MC9S08JM60(以下简称JM60)的新型编程调式器,主要解决JB8在通信速率上存在的不足和在通用性方面存在的问题。
1 总体概述
本文所说的编程系统包括编程调试器和PC方的通信,以及编程调试器和目标芯片的通信。图1是编程系统的基本架构。在编程系统中,JM60通过USB2.O和PC方进行交互,接收来自PC方的命令并执行相应的操作,然后通过BDM接口将命令和数据发送到目标芯片,完成对目标芯片的操作。
BDM是飞思卡尔半导体公司推出的一种单线调试方式。图2是BDM接口引脚图,所有命令和参数均通过BKGD专用引脚进行传输,不占用其他任何资源;而且 BDM子模块独立于CPU,有独立的状态机来处理单线接口。与通常的开发手段相比,BDM子模块能利用CPU的空闲周期与CPU打交道,不需要停止处理器即可访问存储器资源。
本编程系统中,作为编程调试器芯片的JM60所拥有的USB2.O全速设备较之串口和USBl.1,它和PC方通信速率非常快。JM60可达24 MHz的总线频率以及充足的RAM空间使得通信流程可以得到进一步改进;同时,JM60的高总线频率也解决了以往采用JB8作为编程调试器芯片但由于 JB8自身总线频率低而限制目标芯片通信频率的瓶颈,使得编程系统的通用性得到提高。
2 通信系统的改进
2.1 通信流程的改进
编程系统的通信由PC机、编程调试器和目标芯片的交互来完成,因而编程系统通信流程的高效与否直接影响着整个编程系统的通信速率。编程系统的通信过程如下:
①PC发送进入BDM命令,目标芯片进入BDM模式;
②PC发送完全擦除命令,擦除目标芯片Flash并进行空白校验,返回校验码;
③PC发送命令将写入子程序的目标代码发送到目标芯片内存中,写入子程序的功能是将存放在目标芯片内存上的用户目标代码写入Flash中;
④PC分析S19文件,提取需要发送的目标代码,以512字节组合成一页,分页发送到目标芯片内存中,然后运行已发送目标芯片中的写入子程序,将用户目标代码写入目标芯片Flash中;
⑤PC判断是否需要发送下一页,并接收校验码判断一页数据发送是否正确。
PC发送一页数据到目标芯片内存之前,先将数据发送到编程调试器内存,和一次向S12系列芯片Flash写入512字节相比较。JB8的RAM只有有限的 256字节,并且堆栈也在RAM区域,可用于接收一页数据的RAM缓存太小,因而每次写入的数据量就会受到限制,要分多次写入。这就增加了PC和编程调试器之间的通信次数以及编程调试器和目标芯片的通信次数,从而影响了编程的速度。图3中,JB8以串行的方式接收和发送数据,先从PC方接收一页128字节用户目标代码(1,3,5,7过程),然后将数据发送到目标芯片内存(2,4,6,8过程)。经过4次的接收之后,目标芯片将RAM空间的512字节数据一次写入Flash空间,返回校验码。
而JM60作为编程调试器则拥有4 KB的RAM,可以直接开辟512字节作为缓冲。在整个编程系统通信流程的设计上,就可以借鉴指令流水线操作的思想,充分考虑可作预取的操作,利用编程调试器和目标芯片之间通信的时间完成PC方单独的操作,以及利用目标芯片自身进行操作的时间来完成PC方和编程调试器之间的操作,提高编程系统的运行速率,尽量减少空等待操作。
在图4所示的以JM60作为编程调试器的编程系统通信流程中,首先PC发送第1页用户目标代码到JM60内存(过程1),然后发送到目标芯片内存(过程 2),目标芯片执行写入子程序将数据写入Flash。写入子程序执行过程中,字写入命令时间t=9×(1÷fNMVOP)+25×(1÷fbus)。 fNMVOP指Flash操作频率,fbus指总线频率。S12系列芯片Flash的操作频率范围限制在150~200 kHz,取fNMVOP=200 kHz,fbus=40 MHz,计算得1个字写入时间在最小情况下为t=0.045 625 ms,写入512字节需要时间为11.68 ms,而PC发送1页数据的时间为512×8÷12Mbps=0.341 ms。因此PC和JM60可以利用目标芯片写入1页数据的时间进行交互,将下一页数据提前发送到JM60,完成从PC→JM60内存,如图5所示。 JM60和目标芯片也可以在PC对前一页数据进行校验的同时,将1页数据从JM60发送到目标芯片,如图6所示。
在实现以上思想的同时也充分考虑了写入过程出错的情况,如图4在JM60内存区域开辟了可存放2页数据的缓冲区用于接收用户目标代码。若前一页数据写入错误,则将这页数据在Flash的块写入首地址传递给块擦除程序,重新进行擦除,等待当前页发送完毕,作为下一页数据参与整个流程进行写入。
2.2 通信子程序的改进
2.2.1 优化通信子程序代码
通信流程的改进提高了整个编程系统的通信速率。进一步分析编程系统,从JM60发送数据到目标芯片,内存需要的时间在整个程序下载过程中占用比例比较大;而在1位发送过程中,如图7所示,从位开始时刻到目标芯片读取时刻的周期间隔是固定的10~13个目标周期,但位与位之间的发送存在时隙。
在原有编程系统的字节发送代码中,发送位1和位0是两个单独的子程序,需要通过判断来分别调用两个子程序。所使用的BCC、JSR、BRA都是周期较长的指令,且每发送1位就调用1次JSR指令,就有一次RTS指令返回,需要周期较多。在改进编程系统的字节发送代码中,将位1和位0的发送代码很好地结合在 1个子程序之内,缩短了位与位之间发送的时隙。
编程系统通过BDM硬件命令WRITE_WORD发送1个字,需要调用5次字节发送程序。发送的5字节分别是1字节的命令操作码、2字节的内存地址、2字节的数据,同时硬件命令WRTE_WORD的完成还需要延迟150个编程调试器时钟周期。所以假如从编程调试器发送100 KB的数据到目标芯片内存,其所需要花费的时间计算如下:
在JB8的编程系统中,发送1个字节的周期为:2+(1+3+5+4+4+4+3+3+4+7)×8+4=310,100 KB的数据需要(100×1024÷2)个字×(5×310+150)个周期÷(3×106)=29.01 s。
在改进的编程系统中,发送1个字节的周期为:2+2+4+3+1+1+2+4+(1+3+6+88)×8+2+4=809,100 KB的数据需要(100×1024÷2)个字×(5×809+150)个周期÷(24×105)=8.95 s。
而JM60缓存中的数据是以连续存放的形式写入目标芯片内存的,因此可以选用BDM固件命令WRITE_NEXT,每次执行命令时寄存器X的值会先自动加 2,然后将1个字写入到X所指向的地址。所以只需要在写入开始时,对寄存器X进行一次地址赋值操作,将目标芯片内存地址减2处的地址值赋给X即可,后续数据可以直接调用WRITE_NEXT命令写入,不需要再发送地址信息。采用WRITE_NEXT写1个字需要发送3个字节(1个字节的命令操作码、2个字节的数据),它的完成需要延迟32个编程调试器时钟周期。因而从编程调试器发送100 KB的数据到目标芯片内存需要花费的时间计算如下:
(100×1024÷2)个字×(3×809+32)个周期÷(24×106)=5.25 s
改进后的编程系统在编程调试器内存与目标芯片内存的数据通信速度上提高了5.5倍,大大提高了编程调试器的工作效率。
2.2.2 编写目标芯片接收程序
优化通信子程序代码之后,从编程调试器内存向目标芯片内存发送数据的时间大大减少,但是使用BDM命令,除了发送2个字节的用户数据之外,还需要发送额外的字节,并且命令的完成都需要较长的延迟时间。由于BDM采用单线引脚串行通信,因此可以自己编写一段模拟BDM串行通信的程序,目标芯片只从编程调试器接收用户目标代码,提高通信速度。
另外将JM60的引脚PTBD.O与目标芯片PTA.0引脚相连来传送数据,以便数据通信过程不影响BKGD引脚。过程如下:
①按照编程调试器发送1位时序,在编程调试器方编写以PTBD.0为发送引脚的字节发送代码;
②按照目标芯片接收1位的过程,编写目标芯片以PTA.0为接收引脚的字节接收代码,进而编写好目标芯片接收程序;
③将自定义的目标芯片接收程序编译成目标代码,通过基本的BDM命令发送到目标芯片内存;
④执行目标芯片中自定义的接收程序,将接收到的字节写入目标芯片指定的内存空间。
由于目标芯片的接收程序是自己定义的,因此编程调试器不需要发送操作码与地址信息,也无需等待命令完成延迟时间。自定义的目标芯片接收程序代码量少于50字节,这部分时间很短。因而假如从编程调试器发送100KB的数据到目标芯片内存,需要花费的时间计算如下:
(100×1024)个字节×809个周期÷(24×106)=3.45 s
使用自定义目标芯片接收程序,在原有系统编程调试器内存与目标芯片内存的数据通信速度上提高了8倍多。
3 编程系统的通用性设计
编程系统的通用性在于两点:一是可以根据不同型号的目标芯片获取相应的MCU参数进行操作;二是可以根据不同型号MCU的总线频率调用相应的发送接收代码。
3.1 MCU信息的存储
S12系列MCU有很多型号,而且未来还会推出更多新型号。表1给出了数据库中MCU的信息。不同型号MCU属性参数不同,包括内部RAM及Flash的大小和起始地址。这些参数在对目标芯片进行擦除、写入及调试操作时极为重要。为了便于通用性方面的设计,在PC方数据库中保存了每款MCU的相关信息,在用户建立工程的时候就可以获取这些字段信息,对目标芯片进行正确的操作。
2.2 通信子程序的改进
2.2.1 优化通信子程序代码
通信流程的改进提高了整个编程系统的通信速率。进一步分析编程系统,从JM60发送数据到目标芯片,内存需要的时间在整个程序下载过程中占用比例比较大;而在1位发送过程中,如图7所示,从位开始时刻到目标芯片读取时刻的周期间隔是固定的10~13个目标周期,但位与位之间的发送存在时隙。
在原有编程系统的字节发送代码中,发送位1和位0是两个单独的子程序,需要通过判断来分别调用两个子程序。所使用的BCC、JSR、BRA都是周期较长的指令,且每发送1位就调用1次JSR指令,就有一次RTS指令返回,需要周期较多。在改进编程系统的字节发送代码中,将位1和位0的发送代码很好地结合在 1个子程序之内,缩短了位与位之间发送的时隙。
编程系统通过BDM硬件命令WRITE_WORD发送1个字,需要调用5次字节发送程序。发送的5字节分别是1字节的命令操作码、2字节的内存地址、2字节的数据,同时硬件命令WRTE_WORD的完成还需要延迟150个编程调试器时钟周期。所以假如从编程调试器发送100 KB的数据到目标芯片内存,其所需要花费的时间计算如下:
在JB8的编程系统中,发送1个字节的周期为:2+(1+3+5+4+4+4+3+3+4+7)×8+4=310,100 KB的数据需要(100×1024÷2)个字×(5×310+150)个周期÷(3×106)=29.01 s。
在改进的编程系统中,发送1个字节的周期为:2+2+4+3+1+1+2+4+(1+3+6+88)×8+2+4=809,100 KB的数据需要(100×1024÷2)个字×(5×809+150)个周期÷(24×105)=8.95 s。
而JM60缓存中的数据是以连续存放的形式写入目标芯片内存的,因此可以选用BDM固件命令WRITE_NEXT,每次执行命令时寄存器X的值会先自动加 2,然后将1个字写入到X所指向的地址。所以只需要在写入开始时,对寄存器X进行一次地址赋值操作,将目标芯片内存地址减2处的地址值赋给X即可,后续数据可以直接调用WRITE_NEXT命令写入,不需要再发送地址信息。采用WRITE_NEXT写1个字需要发送3个字节(1个字节的命令操作码、2个字节的数据),它的完成需要延迟32个编程调试器时钟周期。因而从编程调试器发送100 KB的数据到目标芯片内存需要花费的时间计算如下:
(100×1024÷2)个字×(3×809+32)个周期÷(24×106)=5.25 s
改进后的编程系统在编程调试器内存与目标芯片内存的数据通信速度上提高了5.5倍,大大提高了编程调试器的工作效率。
2.2.2 编写目标芯片接收程序
优化通信子程序代码之后,从编程调试器内存向目标芯片内存发送数据的时间大大减少,但是使用BDM命令,除了发送2个字节的用户数据之外,还需要发送额外的字节,并且命令的完成都需要较长的延迟时间。由于BDM采用单线引脚串行通信,因此可以自己编写一段模拟BDM串行通信的程序,目标芯片只从编程调试器接收用户目标代码,提高通信速度。
另外将JM60的引脚PTBD.O与目标芯片PTA.0引脚相连来传送数据,以便数据通信过程不影响BKGD引脚。过程如下:
①按照编程调试器发送1位时序,在编程调试器方编写以PTBD.0为发送引脚的字节发送代码;
②按照目标芯片接收1位的过程,编写目标芯片以PTA.0为接收引脚的字节接收代码,进而编写好目标芯片接收程序;
③将自定义的目标芯片接收程序编译成目标代码,通过基本的BDM命令发送到目标芯片内存;
④执行目标芯片中自定义的接收程序,将接收到的字节写入目标芯片指定的内存空间。
由于目标芯片的接收程序是自己定义的,因此编程调试器不需要发送操作码与地址信息,也无需等待命令完成延迟时间。自定义的目标芯片接收程序代码量少于50字节,这部分时间很短。因而假如从编程调试器发送100KB的数据到目标芯片内存,需要花费的时间计算如下:
(100×1024)个字节×809个周期÷(24×106)=3.45 s
使用自定义目标芯片接收程序,在原有系统编程调试器内存与目标芯片内存的数据通信速度上提高了8倍多。
3 编程系统的通用性设计
编程系统的通用性在于两点:一是可以根据不同型号的目标芯片获取相应的MCU参数进行操作;二是可以根据不同型号MCU的总线频率调用相应的发送接收代码。
3.1 MCU信息的存储
S12系列MCU有很多型号,而且未来还会推出更多新型号。表1给出了数据库中MCU的信息。不同型号MCU属性参数不同,包括内部RAM及Flash的大小和起始地址。这些参数在对目标芯片进行擦除、写入及调试操作时极为重要。为了便于通用性方面的设计,在PC方数据库中保存了每款MCU的相关信息,在用户建立工程的时候就可以获取这些字段信息,对目标芯片进行正确的操作。
3.2 目标芯片总线频率的测定
不同型号的MCU总线频率不一样,因此编程系统的通用性还在于能使编程调试器自动获取目标MCU的通信频率,使之适应不同型号的MCU。
在HCS12中有一条比较特殊的BDM指令SYNC,它用于探测目标MCU的BDM接口的通信频率。该指令没有具体的操作码,因此不要求知道具体的目标芯片BDM通信频率。表2给出了使用SYNC指令探测目标芯片BDM通信频率的过程。
编程调试器是通过拉低至少128个目标芯片时钟周期来请求SYNC指令的,为了能够测量所有的S12系列芯片BDM通信频率,需要设置一个缺省计时参数。当目标芯片总线频率低于1 MHz的时候,Flash的擦除写入操作不能正常运行,因此可以设置目标芯片的最低BDM接口频率为1 MHz。128个周期时长为128÷1 MHz=128μs。在这个延时时间内,可以向S12系列芯片成功请求SYNC指令。下面给出了测试目标芯片通信频率的代码。
阴影部分是JM60在目标芯片发送128个周期低电平的时间所做的操作,花费的指令周期为count=5+1+6×A(寄存器A的计数次数),目标芯片的通信频率就可以通过公式fBDM=128×fbus÷count计算得到。编程调试器只需要根据计算得到的目标芯片的通信频率,调用在编程调试器方编写的针对不同通信频率段的收发子程序,就可以实现和不同型号目标芯片的正确通信。
结 语
编程系统的通信速率和通用性是衡量编程调试器性能的重要指标。在实际应用中,用户需要不断地修改、调试程序,程序的下载操作会频繁发生,因此减少数据的通信时间,提高用户目标代码的写入速度显得尤为重要。本文针对S12新型编程系统的设计思想已经应用于SD-Pro-grammer For S12 V2中,通信速度提高了5倍多,能适应当前S12系列所有的MCU,对于新款MCU可以实现快速支持。文中给出的编程系统中提高通信速度的设计方法对类似于嵌入式系统的应用开发也有着很好的借鉴作用。
全部0条评论
快来发表一下你的评论吧 !