关于启动的详细信息请参阅:Using the TMS320C6748/C746/C6742 Bootloader
介绍开发板启动流程和不同的烧写方式。
AIS是TI的一种二进制镜像文件的格式,在后面会详细讲解到它的组成和作用。
下面对DSP启动的主要模式,也就是AIS模式。这是非常重要的模式,DSP C6748的大部分启动模式都必须使用AIS。AIS是一种二进制文件的镜像,对于这些启动模式,用户程序必须转换成.ais格式才能使用。我们使用CCS编译出来的.out文件是不能直接启动的,我们转换的时候可以使用TI提供的AISgen这样一个工具来生成相应的.ais文件。对于AISgen工具来说,它不仅可以生成二进制文件,也可以生成文本文件,在生成的时候如果将扩展名设置为.c或.h的话,生成的是一些16进制的ASCII码字符文件,而选择其他的扩展名的话,都会按二进制方式处理。不管选择扩展名是.ais还是.bin都是一样的内容。AIS模式启动的主要好处,就是可以通过一些指令可以调用存储在ROM BootLoader中的一些初始化函数,我们就可以通过这种方式在我们使用万事之前,首先先初始化DDR2、EMIF之类的设备,这样的话我们的程序就可以使用更多的资源,比较方便,它的功能比较类似于GEL文件。我们在Debug时可以通过GEL文件做一些初始化的操作,在真正把程序烧写到目标开发板运行的时候可以通过AIS将一种镜像格式来完成跟GEL文件类似的初始化操作。当然,这里需要说的是,这种功能只是初始化的功能跟GEL文件一样,但并不能实现GEL文件的一些调试和交互功能。
对于AIS启动方式,就比较多了,首先,EMIF NOR FLASH和EMIF NAND FLASH启动。这里需要注意的是,如果要是NOR FLASH和NAND FLASH启动的话,NOR FLASH必须要接在EMIF接口的片选2信号(也就是CS2接口),它是一个异步的接口。对于NAND FLASH,必须接到CS3接口,如果设备不是这样连接的话是没有办法启动的。这里先说一下EMIF NOR FLASH启动,使用这种启动方式,同样需要一个字的配置信息,这个配置信息主要功能就是选择连接EMIF接口的NOR FLASH的三种启动方式,如果相应的启动位被配置为AIS启动方式的话,使用AIS镜像启动,入口地址被固定为0x60000004,而使用AIS NOR FLASH相比非AIS模式下的两种NOR FLASH启动方式的最大区别是使用AIS镜像可以做一些设备的初始化的操作,这样的话我们就可以把程序加载到DDR2中来运行。
AIS主模式下,从EMIF NAND FLASH启动,这是我们最常用的启动方式,因为在各种各样的程序存储器或大容量存储器中,NAND FLASH是一种价格低廉、读写速度快、擦写速度快,使用最广泛的一种存储器,在核心板上有一块128MB\256MB\512MB的NAND FLASH存储空间。而对于C6748来说,从NAND FLASH中启动是怎样的一种过程呢?首先,在上电以后RBL(Rom BootLoader)读取管脚配置来确定我们要从NAND FLASH启动;然后,RBL对相应的接口初始化,比如说使用PSC来使能EMIF接口,然后配置相应的管脚复用为NAND FLASH方式,这里需要注意的是,NAND FLASH同时支持8位和16位的NAND FLASH,而且来支持ECC校验。这里需要注意的是,不是所有的NAND FLASH都被支持,在我们的数据手册中有一张表格列出了C6748所支持的所有NAND FLASH型号。在配置完相应的接口后,RBL会根据它储存的一张表格(列出了所有支持的NAND FLASH厂家、设备型号、参数(页大小、块大小、扇区大小、扇区块数目等等信息)),通过这些信息找到合适的参数,然后通过相应的读写操作时序来从NAND FLASH中读写我们的用户程序。这里需要注意的是,不管我们使用任何设备来启动,在程序中一定有不能影响这种启动方式的操作,而且在AISgen工具配置生成.ais文件的时候,也不能有相应的操作影响启动,比如说在AISgen工具中选择的是从EMIF NAND FLASH启动,但是我们在TSC模块把EMIF接口禁用了(不使能这个接口),这样的话我们就没有办法完成整个启动的操作。这里还需要注意的一点,默认情况下只支持从NAND FLASH block1启动,当然我们也可以配置为从NAND FLASH block0来启动,一般情况下我们都从NAND FLASH block1来启动,这样的话,要求在烧写的时候必须将我们的AIS格式的DSP应用程序烧写到block1为起始地址的空间内。如果我们在程序中所位于的NAND FLASH空间中有坏块的话,RBL会自动跳过并标记为这个空间为坏块来继续执行程序。
I2C EEPROM,I2C也叫IIC接口,如果要从I2C接口接的EEPROM启动的话,有两个要求,一是I2C从设备地址必须固定为0x50,然后我们的程序必须从EEPROM的零地址开始写才能够启动。同样的,如果我们的BOOT管脚配置成这种启动模式,RBL也会自动初始化时钟管脚复用以及时序配置信息。
SPI EEPROM/Flash,不过对于SPI接口这两种设备也是有一定要求的,同样这个启动镜像必须从这个内存空间的零地址开始写,而且对于SPI的EEPROM来说,必须使用16位的地址线,而Flash必须使用24位的地址。所以对我们选用的这些器件的型号具有一定的要求。
MMC/eMMC/SD,它们都是接在同样的接口上的三种设备。硬件版本必须是2.1及以上的版本才支持。CPU版本是456M的话一定是2.1以上版本的,能够支持。这里需要注意的是,对eMMC设备最高版本是支持到4.2,而对于SD卡是2.0版本的SD卡。使用这种方式启动的好处,如果要批量测试一批的设备的话,把程序烧写到SD卡来说比较方便。这里还需要注意一点是,如果使用这种启动方式,只支持从SD卡0接口来启动,对于C6748来说虽然有两个SD卡的控制器,但只能从0启动。启动的时候,是通过检测SD卡或MMC、eMMC设备的内存当中的一个模数,如果找到模数的话就从这个数字启动,如果没有找到,RBL会自动从2MB的空间内来持续寻找。而且对于这种启动方式来说,RBL会默认检测接到总线上的设备是不是SD卡,如果是的话就从SD卡启动,如果不是的话,就检测它是不是MMC或eMMC设备,当然,我们也可以通过BOOT管脚的3位配置选项来强制它只检测SD卡来加快启动速度。对于这几种启动方式都是AIS主模式,所谓的主模式就是这种启动方式DSP C6748是作为Host(主设备),而NOR FLASH、NAND FLASH、EEPROM等都是作为接在这个主设备的一种从设备来启动的。
对于AIS从模式的三种启动模式(I2C、SPI、UART),DSP C6748的角色就变了,它是作为从设备来连接到外部的主设备来启动的,当然外部的主设备的类型就可以没有任何限制,可以是ARM、DSP、FPGA、PC等,只要符合I2C、SPI、UART三种接口的时序就可以。但是这种启动模式相对来说比较复杂,需要一定的应答机制。TI为我们提供了UART启动的案例,在上位机有一个使用C#写的上位机程序来通过UART接口直接加载程序到DSP C6748上启动。从AIS从模式启动比较复杂,因为有一定的协议,而且要求上位机(Host)上的程序必须能够解析ais格式的文件,也就是通过AISgen工具来生成ais文件的各个段的信息,通过后续的解析将相应段加载到不同的内存地址,所以说相对复杂一些。通过串口加载运行程序那一部分简单介绍了程序加载的流程。
DSP C6748支持这么多启动模式,目的是让程序的加载和运行更为灵活,以满足我们在实际项目中的不同要求。最典型的一种可能就是我们在一个项目中要使用不同类型的CPU芯片,但是我们要在主CPU(host)上一般来说会跑一个操作系统,这样的话对于DSP来说就可以通过系统上、或者说系统上文件系统的一个文件来储存DSP的程序,当我们需要用到DSP的时候将相应的程序加载到DSP中运行就可以,这样的好处是省去了烧写的问题,另外比较灵活,如果想要更新程序,或者比如说在DSP上运行的程序本来就是不同的,有各种各样的程序都要运行,这样对于不同的启动模式来说比较方便。TI的设备用HPI比较多,用UART的方式比较方便,串口用起来比较简单。在RBL经过对于启动设备的判断和初始化以后,就开始加载我们的自己的DSP应用程序,在加载应用程序当中,我们也可以写一个中间的用户引导程序(UBL(User BootLoader))。当然这个不是必须的,它可以做哪些操作?首先,不管是非AIS模式还是AIS模式来说,都可以通过用户的BootLoader来对设备进行一些初始化信息。还有一个功能,通过这种方式可以支持一个更高级的启动方式,比如说对于C6748来说还支持USB和网络接口,在实际应用中可能网络接口用的比较多,但是启动模式默认并不支持从网络启动,我们就可以在C6748的存储空间烧一个我们自己写的用户引导程序(二级引导程序),在这个引导程序我们可以完成一些对网络的初始化操作。然后我们可以通过一些协议(比如说TFTP协议),来从远程服务器加载相应的程序数据,然后再讲程序数据加载到DSP的内存中进行运行。当然,UBL也不是必须的,如果我们不需要一些复杂的功能,目前的启动模式就能满足我们的需求的话,我们可以直接只烧写我们自己的应用程序就可以了,RBL就将我们CPU的权限(启动过程)就移交给我们自己写的应用程序或引导程序。当然,使用自己的引导程序灵活性会更高一些,比如说可以通过网络来远程烧写。
讲解AIS格式文件,为什么要讲解这种文件呢?是因为对DSP C6748来说,除了4中启动方式不要求是AIS格式的镜像,其他的启动方式都必须要求DSP可执行文件的二进制镜像为AIS的格式。
AIS格式文件实际上是一种脚本。功能主要是调用储存在ROM BootLoader中的相关函数来执行一些初始化的命令。
一个典型的AIS文件的结构如Figure 4所示(来自Using the TMS320C6748C6746C6742 Bootloader.pdf),
最开始是一个Magic Word,什么是Magic Word呢?Magic Word是一个固定的字符串,在这里所具有的意思是,标识我们整个AIS文件的起始位置,这样RBL在找我们的可启动镜像的时候就通过这一个固定的数字来判断,只要找到这个数字就认为这是一个AIS格式文件的起始部分。
紧接着这个Magic Word的是一连串的命令。这个命令是可选的,可以有也可以没有,可以有一条也可以有多条,在所有的命令执行完是一个跳转并关闭的命令,执行这条命令的主要功能就是跳转到我们自己的应用程序入口地址,从这个地址开始执行我们的应用程序。
而中间的命令的格式如Figure 5所示,首先是一个头部的代码,然后一些参数,最后是一些数据。
然后看几个命令。
需要注意的命令都是有一定的固定的字符串,0x58535901。
第一个命令是段加载命令(Section Load Command),在CMD文件那一部分讲过段的概念,段就是连续内存存储的最小单元,也就是说在一个段内,它所占用的内存是连续存储的,但是不同的段它所占用的内存空间可以是不连续的,所以这个段加载命令就是把一个连续的存储空间的段的全部内容加载到内存空间中。
还有一个是段填充命令,把一个段填充为一个固定的值。
CRC校验命令
跳转并关闭命令,意思是用BootLoader执行完后,要跳转到用户可执行程序的时候,它将会在它启动的时候将启动的外设关闭。如果在我们的程序要使用这个外设的话,还得在程序中重新进行初始化。
跳转命令。跟上边跳转并关闭命令的区别是并不关闭这个外设,一般这个命令只在RBL的内部执行一些功能时使用。
连续读取使能命令,这个命令就是从SPI或者IIC外设连续读取一些数据,使用这个命令可以提高速度。
一个非常重要的命令,函数执行命令,它的主要功能就是通过这个命令来调用一些特定的函数来执行一些初始化操作,比如说PLL、EMIF等等,而这些函数就是储存在ROM中的。
这个函数执行命令也是包含函数的头部(标识符,标识这个命令的字0x5853590D),然后是函数的序号和参数的数目,之后就是紧跟的一些参数。
启动表命令,一共就这这么多命令,可以通过一个实际的文件来讲解。
使用AISgen工具来生成文件,
提示:AISgen_d800k008和HexAIS_OMAP-L138都可以产生AIS脚本文件而且均支持命令行方式自动生成。
生成.ais或者.bin格式的文件,对于AISgen工具来说,如果扩展名不是.h或.c的话,其他的文件都是按二进制格式来处理的,如果扩展名写的是.h或.c的话,会默认生成一个c语言的数组,每个数组每一行,或者说每个数组中每个元素都包含有一个相应的执行命令,它的主要作用就是方便我们了解AIS文件结构,当然也可以用在一些其他的用途,比如说我们要通过其他的主设备(host设备)来加载DSP程序的时候也可以用到。
使用AISgen工具生成GPIO_LED.c和GPIO_LED.h两个文件,然后使用文本编辑器打开,可以看到每一行都代表一行代码
根据刚才的了解,每个AIS文件的头部是一个Magic Word,即一个固定的数字:0x41504954,然后下面跟着一系列的命令,这里使用的程序是GPIO_LED程序,因为这个程序比较简单,可以让我们比较清楚的了解整个文件的结构。
对于使用AIS工具来说,转换成的.h、.c格式文件和.bin、.ais格式文件的内容是一样的,我们也可以通过十六进制编辑器来查看这个文件,
从这个文件中还可以看出这个文件的存储格式是小端存储的,也就是说数据的低位存储在内存的低字节,比如说:0x41504954,54这个字节是位于低位,它储存在文件的地址上也是低位地址,也就是偏移为0的地址。而49比54高1位,所以它在文件中存储的也是比它高1位,也就是偏移了1个地址。50和41的情况也是类似的。因为二进制.ais格式文件内容跟生成的.h数组的内容是一样的,为了查看方便,在这里以.h文件来进行介绍。
可以看到紧跟着Magic Word后面是一个段加载命令(0x58535901),段加载命令后面是跟随段加载地址(0x00800020)。这个地址是哪里的地址呢?看一下C6748的内存映射,0x00800020位于DSP的L2 RAM中(参考:TMS320C6748™ Fixed- and Floating-Point datasheet DSP (Rev. G).pdf)
所以就像开头讲启动顺序时说过,如果用户DSP程序要全部放在L2 RAM中执行的话,一定要把程序的起始地址做一个偏移,否则就与储存在DSP C6748 ROM中的ROM BootLoader的启动时候所占用的内存空间冲突,这样就会导致RBL也不能正常执行,用户所编译的DSP程序也不能DSP C6748上正确的执行。
第三个参数是加载的这一段程序,或者是这一个段的大小,这一段相当于初始化之前先通过ROM BootLoader命令加载了默认的一段初始化代码,这里就不研究代码的具体作用,看一下其他的函数。因为通过这一篇文档我们知道函数有一个固定的头部(0x585359),检索一下这个头部,下一个命令是0x58535901,仍然是一个段加载命令,在这次所加载的地址是:0x008002E0,起始地址仍然在DSP的L2 RAM中。再看下一条命令,同样又加载了一段程序,而且这段程序也依然在DSP的L2 RAM中。通过前面的段加载命令后加载了一个不同的命令(0x58535905),这个命令是跳转命令,跳转但不关闭外设。从这里我们大概也可以知道前面加载一段程序的主要功能,就是在我们的ROM BootLoader要执行一些初始化操作之前需要预先加载一段很小的一段初始化程序,现在使用这个跳转命令就跳转到刚才加载这段程序的地址来执行,0x00800220
执行完以后我们的程序要执行:0x5853590D,这个函数是实际做一些初始化命令的函数
可以看到0x5853590D是函数执行命令,从这里开始,ROM BootLoader开始调用一些固定的函数来进行初始化。在这个命令后面首先是函数的索引(序号)和函数参数数目,低16位是函数的索引,高16位是函数参数数目,可以看到是哪些具体的函数。
首先,第一个跟随它的值是0x00020000,它代表的是执行了序号为0个函数,带有2个参数。索引为0的函数是:PLL0 Configuration,带有了2个参数
可以看到2个参数功能主要是配置分频系数,我们可以具体看一下。
参数1:BIT31-24:CLKMODE,配置时钟模式,可以选择晶体和晶振,然后是BIT23-16:PLLM:倍频,BIT15-8:PLLDIV:分频,BIT7-0:POSTDIV:后分频,与AISgen比较一下
参数1值是:0x00120000
BIT31-24:0x00,对应的时钟源为:Crystal(晶体)
BIT23-16:0x12,倍频系数,转换为十进制为:18,这里需要注意的一点是:在AIS工具默认情况下为我们计算的数字是实际的数值,而实际上我们不仅仅配置寄存器,在我们对PLL初始化时需要对寄存器赋的值是它的分母的一个系数,实际我们需要赋的是这样一个值(1/(n+1)),是n的值,AIS工具默认将我们分母上整个值都做了显示(19,即默认做了加1运算),所以这里应该是19,实际赋值是18。
BIT15- 8 :0x00,预分频系数,因为分频设置的都是1,所以这里的值是0。
BIT7 - 0 :0x00,后分频系数,因为分频设置的都是1,所以这里的值是0。
然后紧跟的参数2(0x00000309),代表这三个分频系数,这里需要说明的一点是:之前在讲时钟模块时也讲过,在时钟配置的时候有一些外设的分频系数是固定的,比如说DSP的大部分外设都是使用CPU2分频,这是一个固定值,不可以配的,可以配置的值就是这几个分频系数。
可以看到这3个系数占用了0到23位也就是24位数字,每一个系数占有8位的值,这里赋的值是16进制的0x309(视频教程内是0x209),可以看一下,分别按每8位转换成10进制,结果是:0、3、9,所以分频系数分别为1、4、10。
同样对于下边的函数也是一样的,(0x00080003)它执行的是索引为3的函数,带有8个参数。
索引为3的函数是mDDR/DDR2 Controller Configuration,mDDR/DDR2控制器配置,带有8个参数,
前2个参数是对PLL1的配置,主要也是配置PLL1的分频系数,与PLL0的配置类似的。而下面就是指定一些时序,仍然通过AIS工具来看一下,可以看到,第3个参数DRPYC1R是DDR的一个时序,这个参数和我们所配置的值相同。
从这里大家可能也比较清楚了,在AIS文件中,最重要的一部分就是对各个外设进行初始化,而初始化就是通过调用储存在DSP的1MB大的ROM中的ROM BootLoader来执行的。而这些相当于一些固定的命令,可以认为是我们的程序在跟ROM BootLoader进行交互的时候所使用的协议,我给你传递这样的命令,你就给我执行相应的配置。当然从这里可以看到后面还有好多函数执行的命令,这里就不详细的说了,大家可以参考这篇文档(Using the TMS320C6748C6746C6742 Bootloader.pdf)详细的理解一下。
在初始化命令之后,我们可以看到有一个比较重要的就是在后面还有一个段加载命令,它的主要功能就是来加载我们的应用程序了。
可以看到这一次段加载命令的起始地址是:0xC0000000,这个地址是DDR内存的起始地址,它加载的长度是0x00000080,那加载的这一段内容是什么呢?我们可以通过跟.out文件同时生成的.map文件来看一下,打开.map文件,其中有关于内存段的部分。
可以看到,位于地址:0xC0000000,长度为:0x00000080这个段是.text段,而且是.text段的_c_int00函数。查找下一个段加载命令,可以看到这一次加载的地址是:0xC0001000,长度是:0x000010E0。
看一下.map文件,这是加载.text段的其他部分,起始地址是:0xC0001000,长度是:0x000010E0。
这里的段加载命令主要是把已经初始化的段,像.text段、.text:_c_int00段加载到我们的内存中。
同样这个加载的地址是:0xC00028E0,可以看一下,这是.switch段,是一个跳转表所在地址,下一个是0xC00028FC,是.cinit段。
这些都是我们在DSP二进制可执行文件当中的已初始化的段,什么叫已初始化的段呢?已初始化的段就是我们这个程序在我们编译好以后,它的内容一定是固定不变的,只要这个程序被确定的编译出来,我们就可以非常肯定知道在这些段究竟是什么内容,但是对于未初始化的段来说,在程序运行的任何时候它的值可能都是不同的,我们就没有办法断定它的值是什么。同样的话,已初始化段和未初始化段还有个区别是:已初始化段既可以把它全部复制到内存(RAM)中运行,也可以直接在程序存储器中执行,比如说挂载在EMIF接口上片选2信号上的NOR FLASH。在前面我们也说过,DSP的ROM BootLoader有一种启动模式支持从NOR FLASH直接加载代码来运行,这种启动方式跟我们非常熟悉的或者跟我们大家都熟悉的作为入门的51单片机就很类似,它的执行过程就是PC指针直接指向它的ROM存储空间,或者说内部FLASH存储空间来执行程序。而DSP一般情况下是要将程序中所有的代码都复制到内存执行,这样的好处是因为内存的执行速度要远远快于我们的程序存储器,比如说ROM、FLASH这样的存储器。
在所有段加载完以后,我们在AIS文件之前也看过要执行一条跳转并关闭的命令来开始执行我们的应用程序。执行这条命令就跳转到我们自己编写的DSP二进制可执行程序的入口地址。
对于C语言编写的应用程序来说,它的入口地址就是它的C语言环境的初始化函数所在的地址,在我们的这个例程中,它的地址就是:0xC0000000。可以看到AIS文件的最后一个命令就是跳转到这个地址来开始执行应用程序。
通过理解这个DSP二进制文件的格式,方便我们自己开发一些BootLoader程序有好处,比如说如果我们觉得每一次编译出来的.out文件都需要转换可能比较麻烦,就可以自己写一个BootLoader,让它直接按段加载我们所生成的不管是coff格式还是elf格式的.out文件,其实原理很简单,就是将各个段加载到cmd文件所分配的内存空间,如果我们对各个段所分配的内存空间都是连续的,直接将整个文件中初始化的段复制到相应的内存就可以了。然后我们指定一个入口地址,或者说直接由BootLoader直接跳转到相应的地址来执行程序就可以了。
在前面讲解DSP C6748的启动方式讲过DSP C6748支持3种AIS从模式启动,也就是DSP C6748在启动过程中它是作为从设备来启动的,这三种启动模式分别为IIC、SPI和串口UART。它们的启动流程大概类似,在这里以用的比较广泛的串口来给大家讲解。
整个的加载过程主要分为3个部分,这3个部分就相当于HOST与DSP C6748通讯的一个协议,首先要有一个握手过程,也就是起始字的同步,HOST发一个固定的字符给C6748,然后C6748再返回一个固定字符来达成一个握手的信号,之后要测试连接的可靠性,连续发一串字符并准确的收到字符代表这个连接是可靠的,然后就是开始由HOST向C6748传输功能操作码,每传输一个段的操作码或每执行一个函数都要执行一下OS操作码同步的这个步骤。
下面来简单看一下这3个步骤的具体流程。
首先是起始的握手信号(SWS),从这张图可以明显的看出在开始的时候,由HOST主机向DSP发送一个XMT_START信号。对于串口加载来说,因为发送的数据是8位的,所以它的值是0x58,也就是说先由HOST向C6748发送一个固定的0x58,C6748的RBL(ROM BootLoader)将会返回一个固定的数字,在正确的情况下,它会返回0x52这个数字,然后HOST再会判断接受到的数字是不是0x52,如果不是的话就会持续发送0x58,如果是的话就会接受SWS(start-word synchronization消息同步)这样一个过程。从这个HOST和DSP交互这张图可以看到,如果HOST接受不到正确的RECV_START信号的话,就会一直发送XMT_START信号,如果接收到以后,整个SWS过程就结束了。这里还需要注意一点,串口加载比较特殊,在执行SWS同步之前,C6748会通过串口向HOST发送一个BOOTME的可见ASCII码字符信息,在整个串口加载过程中,只会在最开始的时候发送这一串BOOTME的可见的ASCII字符,其他的都是通过16进制形式发送的。
POS(ping op-code synchronization),POS的过程主要是为了验证HOST与C6748之间建立的连接是否是可靠的。
与SWS类似,POS是先发送一个固定的信号:0x5853590B,如果正常情况下,C6748的RBL会返回0x5253590B这样一个数字,如果不正确的情况下,HOST应当持续发送0x5853590B这个数,如果正确的话执行下一个步骤,发送一个32位的数字,这个数字从n开始,首先发送n这个值,这里需要注意的是,对于SPI和IIC来说,它是16位模式的,所以发送是按16位发送,对于串口UART来说它是8位的,发送数字是按8位发送,而且是以小端模式发送,就拿刚才这个数字0x5853590B来说,发送的时候先发送0B,然后是59,然后是53,最后是58,接收的时候也是一样的,先接收低位再接收高位。发送的这个数据n可以是任意值,但是一般情况下n会取2,发送完n以后,如果不正常的话,没有接收到正确的数据会执行上一个步骤SWS,如果正确的话,HOST应该再发送1这个数据,也就是0x00000001,如果不正确同样返回到SWS这个步骤,如果正确就将2到n-1之间所有的数都执行一下这个过程,也就是说我发什么数,C6748的RBL就会返回什么数,如果这一个系列的操作全部正确的话,整个POS过程就执行完毕。
OS(op-code synchronization),在OS这一步就正式执行一些我们的AIS文件中的一些命令了。O的缩写是op-code,也就是操作码,S是同步的意思,也就是说这一步骤的意思是操作码同步。跟前面类似,首先由HOST向C6748发送一个操作码,然后再接收一个相应的操作码,这个操作码就是0x585359##,最后两位是函数执行的序号,我们在上一部分也讲过,执行的函数有不同的类型,比如说有PLL初始化、EMIF初始化、DDR初始化等等,所以最后两位是可变的。而接收回来的这个数据,应当除了最高位的值由58变成52以外,其他值按照原样返回。而且在每执行一个命令之前都要执行一个OS过程,执行完OS过程以后,HOST应当将该功能底下的所有代码发送到DSP C6748,执行完毕以后再执行下一个功能码。
下面就以GPIO_LED这个例程来为大家讲解一下通过串口加载的实际执行过程,这里需要用到一个工具就是串口监视精灵
它的主要作用是监视在串口通过的数据,包括接收、发送以及IO控制的一些数据,这样我们就能很清晰的看到我们的上位机UART HOST程序跟我们的DSP C6748程序交互的完全过程,首先我们需要知道我们的串口号,打开设备管理器可以看到端口下面的COM号,如果电脑连接多个串口设备的话要查看一下串口名称。
首先在软件中选择要监视的串口,然后使它处于监视状态,然后打开监视,在目前的情况下就处于监控状态。在这里还需要两个软件,首先就是AISgen工具。首先打开这个工具生成我们需要的代码,配置依然使用的是TI C6748默认的配置,这里需要注意的是在启动模式(Boot Mode)选择UART2,然后选择DSP程序GPIO_LED.out,同样也要生成一个.h文件来方便我们分析,然后再生成一个我们要加载的.ais文件。
然后就是我们的HOST程序UART HOST,在这里需要设置AIS文件,选择刚刚生成的.ais文件,然后选择串口号,波特率115200,Wait for BOOTME表示如果接收到BOOTME的信息就开始执行整个过程。
后面讲解了一下通过串口监视软件和OMAP-L138 UART Boot Host进行串口启动监视。
在这一部分给大家讲解程序的几种烧写方式,一种是通过CCS加载相应的.out烧写程序来烧写,一种是通过串口来烧写,还有一种是将程序烧写到SD卡当中来启动。对于前两种方式来说,对于我们的比较小的程序还比较合适,如果使用的是100系列的仿真器,速度比较慢大概每秒只有10几KB左右,所以在烧写比较大的程序会很费时间,串口也有同样的问题,但是如果没有更快的仿真器而又想测试比较大的程序,可以使用SD卡启动的方式。我们将程序烧写到SD卡当中,然后使用开发板从SD卡启动,这样的话就可以通过SD卡来简单的测试一下相对比较大的程序在目标开发板上独立运行的效果。下面就讲解一下怎么烧写,在讲烧写之前,先要准备好我们的AIS文件,在这里详细介绍一下AISgen工具的使用。
首先需要知道DSP的固件版本(Device Type),这个可以通过CCS仿真器连接到目标开发板查看ROM的起始地址的字符,以字符串查看的话会显示d800k008,对于456M的CPU来说它一定是最新的版本。
然后是启动模式的选择(Boot Mode),C6748支持多种启动模式,可以根据需要来选择,这里需要注意的是,选择不同的启动模式,然后也需要一些配置,比如选择NAND FLASH就会多一个flash的标签页来让我们配置相关参数。
下面是时钟源(Clock Source),一个是晶体,一个是晶振
再下边是一些复选框,可以勾选我们所需要进行的一些配置,比如说PLL0,PLL1的配置在我们勾选DDR的时候一定要配置,以为DDR的时钟来源是来源于PLL1,如果在EMIF接口上挂载了SD RAM也可以勾选Configure SDRAM,如果需要配置PSC电源与睡眠管理控制,如果是想要在启动的时候就默认使能一些外设,就可以勾选Configure PSC复选框,这个功能(Configure Pinmux)是配置管脚复用,通过这个方式就可以手动制定一些管脚复用情况。这里需要注意的是,如果现在将NAND FLASH作为启动设备,但是在管脚复用又把管脚配置为其他功能,这样可能会导致启动失败,因为在选择相应的启动模式时,RBL BootLoader会自动将相应的外设使能并配置管脚复用情况,所以我们不需要手动在这里进行操作,这个是由RBL自动完成的。
最后还有一个使能CRC校验(Enable CRC),还有一个指定入口点(Specify Entrypoint),一般情况下我们不需要指定入口点,因为AISgen工具会自动从它所支持的coff格式或elf格式的文件当中读取相应的入口点。
在下边是DSP应用程序文件(DSP Application File),这就是我们通过CCS编译出来的.out文件,这里需要注意的是,它同时支持coff、elf两种.out文件。还有一个需要注意的是DSP应用程序文件可以不止一个,可以指定多个.out文件,文件之间用;来间隔。如果有多个.out文件可能需要指定入口点,如果不指定入口点,AIS工具默认从第一个.out文件读取入口点作为默认的入口点,如果指定的话,比如说启动的时候想优先加载第二个.out文件,就可以将第二个或其他的.out文件的程序入口点进行指定,在DSP C6748在启动时就会自动加载其它的程序。
同时也可以加载一些其他的数据文件,比如说bmp图像,这里需要注意的是,如果加载的是一个数据文件,不是应用程序的话,AISgen工具是没有办法读取到入口点的,所以需要后面加一个@,加一个32位的地址来指定它的加载地址,比如说:@0x80000000,这个地址是片上的128KB的RAM,当然也可以修改为其他地址,如果是在AISgen工具里初始化了DDR,我们就可以将它加载到DDR的地址,比如:@0xC1000000,这个很方便的地方就是比如说一些固定的数据,像在LCD中显示一个固定的图片,就可以将它预先通过RBL加载到内存,这样的话我们的程序只需要在相应的地址将这些数据读取出来就可以了。文件可以有多个,可以将任意多个文件将它们融合在一起,当然也可以有多个.out程序,当有多个.out程序时,默认情况下只能执行1个程序,如果需要在程序中切换的话,需要手工编写一些代码让我们的程序执行跳转到相应的入口点。
下面是生成的AIS输出文件(AIS Output File),输出文件只能有1个,它的扩展名如果是.h或.c,就会生成c语言数组,除此以外的任何文件都按二进制进行处理,也就是AIS文件,当然一般情况下为了方便区分扩展名,都使用.ais。
现在以NAND FLASH为例看一下标签页怎么设置。
这里需要配置FLASH宽度,包括8位和16位,这里使用的是8位的NAND FLASH,下面是CS3 SETUP,这是EMIF接口的CS3寄存器配置的值,这里需要注意的是,这个值的多少只会影响EMIF接口读取NAND FLASH的时序,也就是说速度的快慢,默认会使用一个最大值:0x3FFFFFFF,这里使用的这个值是通过查阅EMIF接口以及相应的NAND FLASH芯片的数据手册来得到的一个相对优化的值。
下面是PLL0的配置,PLL0主要是给一些主要的外设以及CPU提供时钟,首先是预分频、倍频、后分频以及3个分频系数。在时钟那一部分讲过有一些外设的分频系数是固定的,比如说GPIO这些外设,它默认是CPU的二分频,所以我们并不能改它的频率,这里我们可以根据需要来修改它的值,可以看到AISgen工具可以自动为我们计算出来主要的几个频率。这里需要注意一下,如果EMIF接口连接的是SD RAM的话,理论来讲它的最高时钟是不能超过100M的,如果在EMIF接口连接的是异步设备的话,可以达到148M。在时钟里面也讲过,对于PLL来说,它所能输出的最大频率是600M,最小频率是300M,在这里就可以根据实际情况来修改频率,当然这个频率值是RBL初始化时候频率,如果想在初始化中动态修改频率,就可以参考相应的代码来修改时钟频率。
下面是PLL1,PLL1的时钟主要是给DDR2提供时钟,而DDR的最大时钟频率是312M。
再看一下DDR的标签,这里主要是配置一下DDR的时序参数,这些参数可以通过查阅DDR接口以及相应的DDR数据手册来计算得到,当然TI也有一个帮助我们计算的EXCEL文件来协助计算DDR的时序。这里还可以选择DDR的类型:mDDR或DDR2,这里有一个使用PLL1的直接时钟来源(Use direct clock from PLL1),这个的意思是,我们在时钟讲过PLL1和PLL0一样都会经过一个后分频,而使用这一项的目的就是使DDR的时钟直接来源于倍频后的时钟而不经过这个后分频,这样的话DDR2的频率就跟其他的外设所使用的时钟频率就分开了,也就是说如果勾选这一项的话DDR的频率可以稳定在312M,但是对于其他连接在PLL1的其他外设来说,可以根据PLL1的DIV1\2\3分频系数来调整相应的频率。
PSC可以配置我们使能的外设,这里是一些序号,关于这个序号是多少我们可以参见DSP C6748的数据手册
在数据手册6.8.1节,这里有LPSC Number的序号,LPSC是Local PSC的意思,这里可以看到PSC0的一些序号和PSC1的一些序号
可以根据需要来使能我们响应的外设,这里还需要注意的是,如果外设作为启动设备的时候不要在AISgen工具的PSC标签页禁用那些外设,否则的话会导致启动不正常,这里还需要注意一点是在PSC1模块有一个SATA,SATA的使能是需要被强制使能的,目前来说AISgen工具所调用的RBL函数是不能使能这个模块的,如果在PSC选项页的PSC1部分添加上8可能会导致启动不正常。
在这里建议大家根据实际情况来使能相应的外设,这样的话可以降低功耗。
下面是管脚复用的配置,可以选择是哪一个管脚,后面跟一个32位16进制的值,这个值怎么计算可以使用TI提供的管脚复用配置工具,
管脚复用配置,
除了使用图形界面的AISgen工具来生成,还可以支持从命令行生成
首先打开一个终端,Windows下有cmd和powershell两种,Powershell相比cmd的功能更加强大,首先需要进到目录,
AISgen工具只支持一条命令,这条命令就是自动加载我们所保存的cfg文件当中的配置来生成相应的文件
AISgen_d800k008.exe -cfg="LED.cfg
支持命令行的好处是可以实现一些自动化的操作
打开CCS工具,工程名右键打开Properties
在每一个工程后都在自动调用
实际使用的命令:
${HexAIS_DIR}\HexAIS_OMAP-L138.exe -ini ${HexAIS_DIR}\NandFlash.ini -o ${ProjName}.ais ${ProjName}.out
使用CCS加载烧写程序烧写NandFlash
使用串口加载烧写程序烧写NandFlash
串口烧写是基于C#编写的,烧写前需要安装.net框架,.net 2.0版本、3.5版本
该程序需要.Net框架才可以正常运行,Windows下需要安装.Net框架3.5(Windows7系统自带,Windows XP、Windows 8需要额外安装),Linux下需要安装Mono开发环境。
[]参数是可选参数,<>是必要参数(注意区分大小写)
Windows:
sfh_OMAP-L138 [-targetType ] [-flashType ] [] []
Linux(.exe扩展名不能省略)
sudo mono ./sfh_OMAP-L138.exe [-targetType ] [-flashType ] [] []
Command主要包括有擦写FLASH命令、烧写命令。烧写命令包括烧写UBL和应用程序、只烧写用户应用程序两种。
targetType指定设备类型,如果不指定设备类型,默认为OMAP-L138,必须指定设备类型为C6748。
flashType指定flash类型,可以指定NOR FLASH、NAND FLASH、EEPROM,但是因为TL-6748的核心板上只有NAND FLASH,所以这个烧写只支持NAND FLASH,如果需要其他格式的话可以尝试编译这个烧写工具,在编译这个烧写工具的时候需要注意,由于程序比较多,必须安装ARM的编译器、DSP的编译器、C#的编译器。
Options可选的选项
InputFiles输出的文件,可以是一个也可以是多个。
在Linux下和在Windows下一样,注意需要使用root权限,即:sudo命令。调用mono这个程序,而且执行的这个程序不能把.exe的扩展名省略。
Windows:
sfh_OMAP-L138 -flash_noubl -targetType C6748 -flashType NAND -p COM3 C:\User\E\Desktop\LED.bin
Linux:
sudo mono sfh_OMAP-L138.exe -flash_noubl -targetType C6748 -flashType NAND -p /dev/ttyUSB0 /home/f/LED.bin
-flash_noubl参数表示直接烧写用户应用程序,没有UBL程序(User BootLoader)这个二级引导程序。
-targetType设备类型:C6748
-flashType指定FLASH类型:NAND FLASH
-p指定我们要使用的串口:COM16,必须是电脑上实际的串口,而且这个串口当前只能被这个烧写程序来访问。如果之前开了串口调试助手,Secure CRT这样的串口程序,需要先关闭。
最后指定输出的文件目录及文件名。
以下是TMS320C6748开发例程使用手册P39页写的命令
Windows:
sfh_OMAP-L138 -flash_noubl -targetType C6748 -flashType NAND -p COM16
GPIO_LED.ais
参数列表
参数 | 说明 | |
---|---|---|
< Command > | -erase | 擦除Flash |
-flash_noubl | 烧写 用户应用程序AIS镜像文件 | |
-flash | 烧写 用户引导程序(user boot loader,UBL)以及用户应用程序二进制文件(第一个输入文件是UBL,第二个输入文件是用户应用程序二进制文件) | |
-flash_dsp | 烧写 DSP 用户引导程序(user boot loader,UBL),ARM用户引导程序(user boot loader,UBL)以及用户应用程序二进制文件(第一个用户输入文件是DSP UBL,第二个输入文件是用户应用程序二进制文件)仅支持OMAPL137 | |
-targetType < target > | OMAPL138 AM1808 C6748 | |
-flashType < flash > | NAND | 创龙的核心板只有NandFlash 仅支持这一个选项 |
-h | 显示帮助 | |
-v | 显示详细输出信息 | |
-p | 指定串口名称 Windows下是COM1、COM2等 Linux下是/dev/ttyS1或者/dev/ttyUSB1等 | |
-baud | 指定波特率,默认115200 | |
-appStartAddr | 应用程序入口地址 默认0xC1080000 | |
-appLoadAddr | 应用镜像加载地址 默认0xC1080000 | |
-appFlashBlock | 烧写镜像位置 |
范例:(Windows环境)
1、启动模式开关拨到UART2模式00101,确认计算机可以从串口接收到BOOTME消息。
2、使用HexAIS_OMAP-L138或者AISgen工具将.out文件转换成AIS二进制文件
3、打开命令行提示符
4、执行烧写命令
在cmd中
sfh_OMAP-L138 -flash_noubl -targetType C6748 -flashType NAND -p COM3 C:\User\E\Desktop\1.bin
在powershell中
./sfh_OMAP-L138 -flash_noubl -targetType C6748 -flashType NAND -p COM3 C:\User\E\Desktop\1.bin
在cmd下:
5、复位或者上电开发板,这样软件就会接收到DSP通过串口发送的BOOTME
根据程序大小不同可能需要不同时间
串口只能使用串口2,因为在编译烧写工具的时候指定了串口2
在传输我们的程序之前会先将一个叫sft的程序传输到我们的内存中并执行,这些命令是段加载命令。烧写过程是:先将一个在目标板上执行的烧写程序加载到DSP C6748的内存中,执行这个烧写程序,再通过串口将我们需要烧写的程序加载到目标开发板上,然后再由C6748内存中运行的本地烧写程序将接收到的烧写程序烧写到NAND FLASH中,这样就烧写完成了。
6、将启动模式更改为Nand Flash,复位开发板,就可以正常运行程序。
同时烧写一个UBL和一个DSP可执行程序
在cmd中
sfh_OMAP-L138 -flash -targetType C6748 -flashType NAND -p COM9 ubl_C6748_NAND.ais GPIO_LED.bin
1、首先将SD卡插入读卡器,并将读卡器连接到电脑,需要对SD卡做一些处理,比如分区和格式化处理,这样做的目的是为了防止之前使用SD卡烧写的程序对将要烧写的程序产生影响,这一步不是必须的。
格式化为FAT32,4096扇区对齐
执行硬盘菜单下的重建主引导记录和清除保留扇区,清除MBR
2、BOOTICE
打开AISgen工具,生成SD卡用的.ais文件
3、点击扇区编辑后,显示分区表的一些信息,点击从文件恢复扇区,选择刚才生成的.asi文件
恢复位置,起始扇区号,为了SD卡插在电脑上还能够正确被识别,需要在这里偏移64个扇区保证我们的程序不会将我们的主引导记录以及分区表覆盖,然后点击恢复。这样我们的SD卡就可以启动了。
4、取出SD卡插到开发板上,将启动模式调整为SD卡的启动方式,复位开发板,程序就可以启动了。
也可以使用WinHex这样的工具来将我们的.ais文件写到我们的磁盘中,首先打开.ais文件
然后打开磁盘
复制ais文件中所有内容,点击编辑菜单中,复制选块,标准
点击可移动磁盘2
偏移一定的地址
点击编辑菜单,剪切板数据,写入,确定,这样就将文件的内容写入到SD卡中。
对于C6748的SD卡启动模式来说,可以将值写入到0地址和2MB字节内的地址。RBL找不到起始字符会在2MB字节持续寻找这个起始字符,直到找到才开始启动。
点击保存扇区。
生产工具是生产力发展水平的标志。这句话体现了生产工具对生产力发展水平的推动作用,
在这一期的视频教程中将要介绍几种在DSP程序烧写方面提高生产效率的方式。对于DSP C674x系列或OMAP-L系列CPU来说,在CPU内部有一个1MB大小的ROM,在ROM中对于作为通用目的的DSP或CPU来说,它的主要功能是存放一些内置的BootLoader,BootLoader能解析我们存储器中的程序并把它加载到内存中,还可以进行一些外设的初始化操作,但是这个BootLoader有一个要求,就是要求我们的存储镜像(对于大多数的启动方式)必须是.ais格式的。那么就有一个问题,每次使用CCS或直接使用DSP的编译工具链,编译出来的文件都是.out的文件,这样的话我们每一次将它烧写之前都需要将这个.out文件转换为.ais格式文件,这里需要说明的是,.ais文件和.bin文件实际上是一样的,只是扩展名的不同,对于DSP C6748来说他们没有什么不同,因为DSP C6748或者说这一系列的CPU的ROM BootLoader只支持.ais格式的二进制文件。
如果我们每一次编译完都进行一次转换操作,然后再把程序烧写,这样会比较麻烦,有没有一种自动化的方式呢?当然有,这里介绍一种自动化的方式,在我们每一次编译完生成.out文件的同时就将这个.out文件转化成相应的.ais文件,这样的话,我们每一次编译完这个工程都可以直接烧写.ais文件就可以了。
在开始之前,首先要准备相应的工具软件:HexAIS_OMAP-L138.exe。这里之所以写OMAP-L138的意思是这一系列的CPU统称为OMAP-L138系列,包括DSP C6748、OMAP-L138、AM1808这些CPU。还有一个文件就是相应的配置文件:NandFlash.ini。最后一个文件是创龙写的一个说明文件:ReadMe.txt。
先打开NandFlash.ini这个配置文件,这个配置文件跟我们使用AISgen工具是一致的,都是填写一些配置信息。比如说
[General]
busWidth=8 // NAND FLASH的位宽
BootMode=NAND // 启动模式
crcCheckType=NO_CRC // 不使用CRC校验
[PLL0CONFIG]
PLL0CFG0 = 0x00120000 // 锁相环控制器的配置
PLL0CFG1 = 0x00000309 // 锁相环控制器的配置
[EMIF25ASYNC] // EMIF的配置
A1CR = 0x00000000
A2CR = 0x08224114
A3CR = 0x00000000
A4CR = 0x00000000
NANDFCR = 0x00000002
[EMIF3DDR] // DDR的配置
PLL1CFG0 = 0x0D000001
PLL1CFG1 = 0x00000002
DDRPHYC1R = 0x000000C3
SDCR = 0x00134632
SDTIMR = 0x264A2A09
SDTIMR2 = 0x4412C722
SDRCR = 0x40000260
CLK2XSRC = 0x00000000
// 在这里跟AISgen的配置一样,默认将所有的外设都使能了,这样方便我们的调试
[PSCCONFIG] // PSC的配置 对某些外设使能和禁用的配置
LPSCCFG=0x00000003
[PSCCONFIG]
LPSCCFG=0x00010003
[PSCCONFIG]
LPSCCFG=0x00020003
[PSCCONFIG]
LPSCCFG=0x00030003
[PSCCONFIG]
LPSCCFG=0x00040003
[PSCCONFIG]
LPSCCFG=0x00050003
[PSCCONFIG]
LPSCCFG=0x00060003
[PSCCONFIG]
LPSCCFG=0x000B0003
[PSCCONFIG]
LPSCCFG=0x000C0003
[PSCCONFIG]
LPSCCFG=0x000D0003
[PSCCONFIG]
LPSCCFG=0x000F0003
[PSCCONFIG]
LPSCCFG=0x01000003
[PSCCONFIG]
LPSCCFG=0x01010003
[PSCCONFIG]
LPSCCFG=0x01030003
[PSCCONFIG]
LPSCCFG=0x01040003
[PSCCONFIG]
LPSCCFG=0x01050003
[PSCCONFIG]
LPSCCFG=0x01060003
[PSCCONFIG]
LPSCCFG=0x01070003
[PSCCONFIG]
LPSCCFG=0x01090003
[PSCCONFIG]
LPSCCFG=0x010A0003
[PSCCONFIG]
LPSCCFG=0x010B0003
[PSCCONFIG]
LPSCCFG=0x010C0003
[PSCCONFIG]
LPSCCFG=0x010D0003
[PSCCONFIG]
LPSCCFG=0x010E0003
[PSCCONFIG]
LPSCCFG=0x010F0003
[PSCCONFIG]
LPSCCFG=0x01100003
[PSCCONFIG]
LPSCCFG=0x01110003
[PSCCONFIG]
LPSCCFG=0x01120003
[PSCCONFIG]
LPSCCFG=0x01130003
[PSCCONFIG]
LPSCCFG=0x01140003
[PSCCONFIG]
LPSCCFG=0x01150003
[PSCCONFIG]
LPSCCFG=0x01180003
[PSCCONFIG]
LPSCCFG=0x01190003
[PSCCONFIG]
LPSCCFG=0x011A0003
[PSCCONFIG]
LPSCCFG=0x011B0003
[PSCCONFIG]
LPSCCFG=0x011C0003
[PSCCONFIG]
LPSCCFG=0x011D0003
[PSCCONFIG]
LPSCCFG=0x011E0003
[PSCCONFIG]
LPSCCFG=0x011F0003
// 注释掉的内容是我们的.ais文件对这个NAND FLASH ECC校验的一个补丁,在这里不需要这个文件
;[INPUTFILE]
;FILENAME=DSP_nand_ecc_patch_OMAP-L138.out
;[AIS_Jump]
;LOCATION=_NAND_ECC_patchApply
这里的配置跟之前使用的AISgen工具的配置是一致的,所以这两个工具生成的AIS内容是相同的。这里需要说明的一点,通过WinHex或者类似的16进制查看工具可以看到,这两个文件在生成内容上实际上是不同的,这个不同只是在生成各个数据段的排列不同,但实际上的内容是完全一致的,因为我们对它的配置都是一致的,在这里跟AISgen的配置一样,默认将所有的外设都使能了,这样方便我们的调试,但是从严谨的角度来说,推荐对外设的使能写在程序代码中,这样的情况下在不需要这些外设的时候就可以关闭它来降低功耗。最后是两个注释掉的内容,注释掉的内容是我们的.ais文件对这个NAND FLASH ECC校验的一个补丁,在这里不需要这个文件,所以将这两行代码注释掉。可以根据自己的需要来修改代码的内容。
打开ReadMe.txt文件,这两句话就是我们要对我们的某一个工程需要进行的配置操作,在这里因为我们需要在CCS编译完工程后自动生成相应的.ais文件,所以需要在它的post build命令中添加以下命令
${HexAIS_DIR}\HexAIS_OMAP-L138.exe -ini ${HexAIS_DIR}\NandFlash.ini -o ${ProjName}.ais ${ProjName}.out
HexAIS_DIR
HexAIS的路径 C:\HexAIS
打开工程属性,然后找到编译step相关的选项卡,在post build step中添加命令。
还有一个需要注意的是,这个命令使用了一个环境变量,就是:HexAIS_DIR,这个变量的意思是我们刚刚所说的这个工具在电脑上的路径,因为不同的电脑的配置不一样,所以这里同时需要添加一个变量,点击变量这个选项卡,点击Add,输入变量的名字,在自己电脑上可以通过存放这个工具的路径不同而设置不同的路径。然后点击OK。
最后一步,重新编译这个工程,点击Rebuild。
可以看到在Console窗口中生成了一些信息。双击标签最大化,可以看到在完成链接步骤,生成.out文件后又执行了刚才的命令,生成.ais文件
C:\HexAIS\HexAIS_OMAP-L138.exe -ini C:\HexAIS\NandFlash.ini -o DEMO.ais DEMO.out
同时将这个命令的执行过程捕获到窗口中,可以看到同样打印了一些配置信息,比如说:
Begining the AIS file generation.
AIS file being generated for bootmode: NAND. // 启动模式NAND FLASH
Parsing the input object file, DEMO.out. // 输入文件DEMO.out
AIS file generation was successful.
Wrote 612616 bytes to file DEMO.ais. // 输出文件DEMO.ais
Conversion is complete. // 成功标志
这样的话,通过这种方式,每一次我们编译完工程都会自动生成相应的.out文件和相应的.ais文件,这样以后我们只需要直接将.ais文件烧写到存储设备中就可以了,这样就减少我们烧写时候执行的步骤。
在DEBUG模式下,打开debug目录,就可以找到DEMO.ais文件,这样就方便了很多。
改进的使用CCS加载烧写程序烧写NAND FLASH方法,这种烧写方式比之前使用的版本要快很多。然后我们加载一个仿真器配置文件,如果工具栏中没有Target Configuration这个工具栏,可以通过View菜单来打开它。
然后选中仿真器配置文件,右键点击加载配置(Launch Slected Configuration),这样的话CCS就进入了DEBUG模式,但是还没有连接我们的目标开发板,右键Texas Instruments XDS100v2 USB Emulator,点击连接(Connect Target),可以看到CCS自动连接到开发板,当然在连接之前需要确定硬件连接正常,并且电源也连接正常。可以看到CCS自动为我们执行了GEL文件初始化操作,然后我们需要加载我们的烧写程序,点击工具栏上的烧写按钮,然后加载我们的烧写程序:NANDWriter_DSPv2.out(视频内),实际为:C6748_NandWrite v2.out,这样的话CCS就把我们的烧写程序加载到开发板,然后点击绿色的按钮或按F8键,运行我们的烧写程序,可以看到在Console中显示我们的烧写程序已经运行。
运行程序以后,跟我们前面的版本一样,首先会提示你是否进行全局擦除,这个擦除是将NAND FLASH的所有块进行擦除并标记为0xFF,在一般情况下我们并不需要执行这样的操作,因为在烧写的过程中,烧写的程序会自动将所需要的块进行擦除操作,然后按回车后提示我们输入要烧写程序的大小,注意这个烧写大小是以字节为单位的,所以打开文件管理器,在我们烧写的文件上按右键打开属性菜单,可以看到后面具体这个文件的大小,精确到了字节。需要将这个字节数输入到Console窗口下,然后按回车键,这时烧写程序提醒我们:Load the binary AIS file into Memory(@0xC4000000)(加载二进制文件到内存),这里加载的地址是0xC4000000,然后打开加载内存的工具栏。如果在CCS中没有看到Memory Broswer窗口,可以通过View菜单来打开。打开这个窗口以后,将鼠标点击Texas Instruments XDS100v2 USB Emulator,然后就可以看到Memory Broswer窗口有一个Save Memory的图标被点亮,在它的右边有一个下拉箭头,点击下拉箭头,选择:Load Memory,然后选择我们要加载的文件,这里就是上述的EDMO.ais文件,然后点击下一步,然后内存地址不能填错,为:0xC4000000,Type-size: 32bits即可。最后点击finish就可以了,程序就开始将我们的程序数据加载到内存。
在这里我们直接再点击绿色的按钮就可以开始烧写操作了,不过,在这个时候可以看一下加载的数据是不是我们文件的数据,可以在Memory Broswer窗口输入我们的内存地址,这里需要注意的是,这个窗口不仅可以输入我们16进制的内存地址,还可以输入我们的变量名,可以看到起始地址是一个Magic Word(魔词),可以证明我们的程序加载到内存加载成功了,最后点击绿色的按钮就开始了烧写操作,可以看到这个烧写操作,我们烧写的是一个1.25MB的文件,可以看到烧写的是非常快的,很快就烧写完成了。
DSP C6748主要有两种烧写方式,一个是通过CCS加载烧写程序来烧写NAND FLASH,还有一种就是通过串口来烧写,串口烧写可能相对来说更方便一些,但是这两种烧写方式都有一个很大的弊端,就是不能完全脱离我们的计算机,就是不同脱离我们的电脑进行,这样的话如果更新程序,比如说在现场来更新的话就必须拿出电脑再连接硬件,这样的话就麻烦很多,而且如果需要批量生产,批量来固话某一程序的话,这种方式的弊端就更大了,在这里就给大家来介绍一种方式,这种方式就是通过SD卡来烧写我们的NAND FLASH,这样的话只要拿着这张SD卡,在任何有SD卡的设备上就能轻松将程序进行更新或烧写,这样对于大批量生产会方便很多。在使用SD卡来烧写NAND FLASH之前,首先需要一张可以进行烧写的SD卡。还需要注意一个问题,如果这张SD卡没有使用过,或者说之前没有作为启动SD卡来使用的话,没有关系,可以直接来用,如果之前把它烧写过其他的启动文件,就需要先执行一步额外的操作,这个操作需要清除SD卡之前的数据以保证我们的SD卡不会有问题,在这里使用一个DiskGenius的工具,这是一个非常著名的国产免费的分区软件,根据系统选择32位或64位,打开这个软件。这里需要注意的是,我们使用这个工具不一定非要对这个SD卡进行格式化,我们需要做的是清除这个SD卡中之前残留的其他启动镜像。
主要执行的两步操作是,在硬盘菜单下,有一个重建主引导记录(MBR)的操作,这个主要是担心我们之前写镜像的时候写到这块区域自我影响,还有一个操作是在硬盘菜单下,清除暴露扇区,执行了这两个操作以后如果你的SD卡之前烧写过其他镜像就会被清除,当然最稳妥的办法还可以将分区进行格式化操作,但是一般情况下不需要这样做。执行了前面这两步操作就可以了,因为它是实时生效的,不需要保存,然后关闭这个软件。
第二步操作就是制作一个可启动的SD卡镜像,这个方式已经在上一集视频讲过,在这里使用一个叫BOOTICE的工具来帮助我们将启动镜像写到SD卡中,这里我们需要的这个启动镜像是SD2NandFlashWriter.ais(视频中),SD2NandFlashWriterv2.ais(实际资料内的文件)。
打开这个BOOTICE工具后,选择目标磁盘,一定不要选错,否则会将电脑其他磁盘数据进行损坏,尤其是如果你将这段数据写到起始扇区中,一般情况下载起始扇区都是MBR或者是其他引导程序,很可能会导致你的电脑无法启动,所以需要注意的是这个磁盘一定要选到SD卡,可以通过容量和名称来标识出来,然后点击扇区编辑,点击从文件恢复扇区,在这里选择刚刚的文件,起始扇区号填64,之所以填64是为了跳过前面的MBR主引导记录以及分区表一些信息,如果从0开始恢复的话程序将这些输入覆盖以后,你的SD卡插到电脑上会提示未识别,这样会比较麻烦,所以偏移64个扇区从这里开始恢复,这样的话就不会将我们的一些信息进行覆盖,点击恢复,可以看到文件成功恢复到我们的SD卡中,这样的话我们将SD可启动包含SD卡烧写程序的可启动SD卡就制作完成了。
下一步操作是准备我们的启动镜像,这一步就很简单了,将我们通过AISgen工具转换的,或者是通过本期视频教程第一部分内容使用的工具、方法生成的.ais文件复制到我们的SD卡就可以了,打开SD卡的文件分区,这里需要注意的是SD卡的文件系统必须格式化为FAT32,对于大于2GB的SD卡在Windows下格式化都默认为FAT32系统,小于2GB的可能是FAT16的文件系统,格式化的时候需要注意必须为FAT32。文件复制到SD卡的Tronlong/C6748文件夹下,更名为Boot.ais,这个文件就是刚刚我们使用的综合演示程序,注意这个文件名一定是Boot.ais这个名字,文件大小无所谓,不过一般情况下DSP程序都不会很大。这样启动SD卡就完成了,以后需要修改程序,打开文件夹Tronlong/C6748,更换Boot.ais文件就可以了。以后只需要更换那一个文件就可以,不用重新执行上述的制作可启动SD卡的步骤了,这样的话就很方便的更换我们要烧写的程序。