打印

Boot_serial 中的命令分析

[复制链接]
2170|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
GONGHCU|  楼主 | 2011-9-26 19:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
个人认为 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,然后再发送一个命令执行状态的包。

相关帖子

沙发
FVJFIFE| | 2011-9-27 14:15 | 只看该作者
好难记啊!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

298

帖子

2

粉丝