【TI 学习】Boot_serial 中的命令分析
[复制链接]
个人认为 LM Flash Program 这个软件是eflash和sflash的集合体。要想深入地分析以太网升级和串口升级就首先要分析一下eflash.c 和sflash.c。
COMMAND_PING:被用来接收从bootloader发送的连接已建立的ACK。它用来简单的ping一下bootloader,看update application是否可以与bootloader通信了。只有一个字节。
COMMAND_DOWNLOAD:发往bootloader的,告诉bootloader存储数据的地址和大小。这个命令也会触发擦除整个flash或者是程序区,取决于它的地址。此命令还会等待一个ACK或者NCK。此命令必须在COMMAN_GET_STATUS后边,已确认bootloader已分配了适当的地址和大小给即将到来的数据。
COMMAND_RUN:发送一个执行控制和地址。
COMMAN_GET_STATUS:这个命令返回上一个命令处理的状态。典型地,这个命令应该被接收以确保上一个命令处理的状态,该命令只有一个字节。
COMMAN_SEND_DATA:这个命令一般在COMMAND_DOWNLOAD或者如果还有数据要发送的话就在另一个COMMAND_SEND_DATA后面,在连续发送数据的时候会自动增加地址,传输数据的大小有bootloader中的接收缓冲区限制,一旦发送的字节数达到了COMMAN_DOWNLOAD所接收到的数就终止发送。并且每次该命令被调用后都应该紧跟一个COMMAND_GET_STATUS命令,确保上次编程成功,否则就不增加地址,而重发上一次数据。
COMMAND_RESET:这个命令用来告诉bootloader复位,通常是一个新的应用程序镜像被下载到bootloader里边或者新的bootloader被写入之后。但是这里有个问题就是,新的bootloader应该写入到0x0,但是如果地址不是0x1000是写不进去的,所以,这个理主要是用bootloader升级应用程序时用的,如果是用bootloader升级bootloader,好像是不行的,尽管理论上bootloader会被复制到RAM里边运行,可以对整个flash去进行操作。这个命令可以被用来当与bootloader的通信发生了严重错误或者想重新开始的时候,当复位开始之前会先发送回一个ACK到updater application。
用bootloader升级bootloader不是不可以,而是这样做非常的不安全。
通过以太网的时候不能升级bootloader还有另一个原因:
今天看到了sflash,就简单说以下它的用法,它可以同时把bootloader和application下载到device里。
接下来简单分析一下bootloader升级的流程:
串口升级不像以太网升级那样分一个客户端或服务器端,虽不这么说,但是也可以这么理解。
首先在PC上指定好串口的端口,波特率,然后打开两个文件,可以把bootloader和application同时烧进去(也就是说同时升级bootloader和application),也可以先暂时只烧写application。
然后调用UpdateFlash函数,该函数会把要烧写的数据发送给bootloader,由bootloader调用flash相关函数完成烧写工作。
UpdateFlash(),(在这里我们先不通过bootloader升级bootloader,这样分析起来符合目前的实际情况,也比较简单。)。
首先LM Flash Programer会根据要升级的文件的大小调用内存块分配函数malloc()分配相应大小的内存块,在调用fread()把文件读到文件缓冲区当中,一切准备好之后,先发送COMMAND_DOWNLOAD命令,通知device上的bootloader即将下载的文件的被烧写的地址和大小,bootloader收到这个命令后首先会检查这个地址是否符合相应规则,然后会擦写相应地址和相应大小的flash,然后发送一个ACK。
如果LM Flash Programer收到了这个ACK,就准备发送一个指定数目字节大小 +1的数据包,其中这个1就是1个字节的命令COMMAND_SEND_DATA,在这里我们可以认为他是每一次把文件分为76个字节的数据块来发送的,这样做是不至于让device在program flash的时候产生错误。但实际发送的时候,是每次都发送77个字节,如果这个Transfer Size设置为<4||>255,才会如下所说每次发送8个字节,否则按照我们设置的来。
如此多次发送,直到所有的数据都发送完毕为止。
如果在sflash中指定了application的起始地址,接下来就发送COMMAND_RUN命令,开发板上的bootloader接受到该命令后先等待UART TX FIFO中的ACK发送完毕,然后检查即将跳转执行的地址,也就是应用程序的起始地址,是否合法,如果合法,然后复位并禁能所使用的外设,跳转到相应的位置执行,不再返回,RAM中复制的bootloader仍留在里边。
如果没有指定application的起始地址,就会发送一个COMMAND_RESET命令,让device重新运行。
所有的命令在服务器端都是通过SendCommand函数发送出去的,它首先把命令发送出去,再用SendPacket发送一个COMMAND_GET_STATUS发送一个包,再用GetPacket获取bootloader发送的命令执行状态包,注意这里不是AckPacket,一定要严格区分开来:
AckPacket:是表示接收到这个命令了,至于这个命令是否执行成功它并不负责。每一次发送包都要求接受方给予一个回应。只要接受包时的校验和是正确的,我们就发送一个AckPacket,否则NakPacket。
COMMAND_GET_STATUS:当bootloader收到该命令后,它首先发送一个AckPacket,然后再发送一个命令执行状态的包。
[ 本帖最后由 Study_Stellaris 于 2011-9-22 23:17 编辑 ]
|