TM4CBootLoader3(Serial更新)

当通过串行端口(UART、SSI或I2C)执行更新时,使用ConfigureDevice()配置选定的串行端口,使其准备好用于更新固件。然后,Updater()处于一个无限循环中,接受命令并在请求时更新固件。这个主例程的所有传输都使用包处理函数(SendPacket()、ReceivePacket()、AckPacket()和NakPacket())。更新完成后,可以通过向引导加载程序发出reset命令来重置引导加载程序。

当更新应用程序的请求通过并定义了FLASH_CODE_PROTECTION时,引导加载程序首先清除整个应用程序区域,然后再接受新应用程序的二进制文件。这可以防止flash的部分擦除在新二进制文件下载到微控制器之前暴露任何代码。引导加载程序本身被保留,这样它就不会引导一个被部分删除的程序。一旦所有应用程序flash区域都被成功擦除,引导加载程序将继续下载新的二进制文件。当没有定义FLASH_CODE_PROTECTION时,引导加载程序只擦去足够的空间以适应正在下载的新应用程序。

在引导加载程序本身需要更新的情况下,引导加载程序必须在flash中替换自己。通过执行地址为0x0000.0000的下载,可以识别引导加载程序的更新。同样,引导加载程序根据FLASH_CODE_PROTECTION的设置进行不同的操作。当FLASH_CODE_PROTECTION被定义并且下载地址表示一个引导加载程序更新时,引导加载程序通过在清除和替换自身之前清除整个应用程序区域来保护微控制器上已经存在的任何应用程序代码。如果进程在任何时候被中断,要么旧的引导加载程序仍然存在于flash中并且不引导部分应用程序,要么应用程序代码已经被擦除。当没有定义FLASH_CODE_PROTECTION时,引导加载程序只擦去足够的空间以适合它自己的代码,并保持应用程序完好无损。

包处理

引导加载程序使用定义良好的包来确保与更新程序的可靠通信。数据包总是被通信设备确认或不确认。数据包使用相同的格式来接收和发送数据包。这包括用于确认成功或不成功接收数据包的方法。虽然串行端口上的实际信令是不同的,但数据包格式仍然独立于传输数据的方法。

引导加载程序使用SendPacket()函数将数据包发送到另一个设备。此函数封装了将有效数据包发送到另一个设备所需的所有步骤,包括等待来自另一个设备的应答或不应答。要成功发送数据包,必须执行以下步骤:

1. 发送将被发送到设备的数据包的大小。大小总是数据的大小+ 2。2. 发送数据缓冲区的校验和,以帮助确保正确传输命令。校验和算法是在提供的checksum()函数中实现的,它只是数据字节的和。3.发送实际的数据字节。4. 等待一个单个字节的确认,从设备,它要么正确地接收到数据,要么它检测到一个传输错误。

接收的信息包使用与发送的信息包相同的格式。引导加载程序使用ReceivePacket()函数来接收或等待来自另一个设备的数据包。此功能不负责向其他设备确认或不确认数据包。这允许在发送回响应之前检查包的内容。要成功接收数据包,必须执行以下步骤:

1. 等待非零数据从设备返回。这是重要的,因为设备可以发送零字节之间的发送和接收数据包。接收到的第一个非零字节是正在接收的数据包的大小。2. 读取下一个字节,它将是数据包的校验和。3.从设备读取数据字节。将有包大小- 2字节的数据发送在数据阶段。例如,如果包大小是3,那么只有1字节的数据要接收。4. 计算数据字节的校验和,并确保它是否与数据包中接收到的校验和匹配。5. 发送一个确认或不确认到设备,以指示成功或不成功的接收包。

确认接收到数据包的必要步骤在AckPacket()函数中实现。只要引导加载程序成功地接收并验证了数据包,就会发送确认字节。当一个已发送的包被检测到有错误(通常是由于校验和错误或只是包中的数据格式不正确)时,就发送一个不确认字节。这允许发送者重新传输先前的数据包。

传输层

引导加载程序支持通过Tiva微控制器上可用的I2C、SSI和UART端口进行更新。SSI端口有支持更高和更灵活的数据速率的优势,但它也需要更多的连接到微控制器。UART的缺点是它的速率稍微低一些,而且可能不太灵活。然而,UART需要更少的插脚,并且可以很容易地通过任何标准的UART连接实现。I2C接口也提供了一个标准接口,只使用两根线,并且可以操作在可比速度的UART和SSI接口。

I2C处理函数是I2CSend()、I2CReceive()和I2CFlush()函数。使用I2C端口所需的连接是以下引脚:I2CSCL和I2CSDA。与引导加载程序通信的设备必须作为I2C主程序运行,并提供I2CSCL信号。I2CSDA引脚是开漏的,可以由主I2C设备或从I2C设备驱动。

SSI处理函数是SSISend()、SSIReceive()和SSIFlush()。使用SSI端口所需的连接是以下四个引脚:SSITx、SSIRx、SSIClk和SSIFss。与引导加载程序通信的设备负责驱动SSIRx、SSIClk和SSIFss引脚,而Tiva微控制器驱动SSITx引脚。用于SSI通信的格式是SPH设置为1和SPO设置为1的摩托罗拉格式(有关这种格式的更多信息,请参阅Tiva家庭数据表)。SSI接口有一个硬件要求,限制SSI时钟的最大速率至多是运行引导加载程序的微控制器频率的1/12。

UART处理函数是UARTSend()、UARTReceive()和UARTFlush()。使用UART端口所需的连接是以下两个引脚:U0Tx和U0Rx。与引导加载程序通信的设备负责驱动Tiva微控制器上的U0Rx pin,而Tiva微控制器驱动U0Tx pin。

而波特率是灵活的,UART串行格式是固定在8数据位,没有奇偶校验,和一个停止位。用于通信的波特率可以由引导加载程序自动检测(如果启用了自动波特特性),也可以固定在与引导加载程序通信的设备支持的波特率。波特率的唯一要求是波特率不应超过运行引导加载程序的微控制器频率的1/32。这是任何Tiva微控制器上UART的最大波特率的硬件要求。

当使用固定波特率时,连接到微控制器的晶体的频率必须指定。否则,引导加载程序将不能配置UART以请求的波特率操作。

引导加载程序提供了一种方法来自动检测用于与之通信的波特率。自动波特率检测是在UARTAutoBaud()函数中实现的。自动波特率函数尝试与更新程序同步,并指示它是否成功检测波特率,或是否未能正确检测波特率。引导加载程序可以多次调用UARTAutoBaud(),以便在第一次调用失败时尝试重试同步。在提供的示例引导加载程序中,当启用了auto-baud特性时,引导加载程序将永远等待来自主机的有效同步模式

在UART、SSI和I2C端口上的自定义协议使用以下命令:

COMMAND_PING此命令用于接收来自引导加载程序的确认信息,表明通信已经建立。这个命令是单个字节。

该命令的格式如下:

unsigned char ucCommand[1];
ucCommand[0] = COMMAND_PING;

COMMAND_DOWNLOAD此命令被发送到引导加载程序,以指示存储数据的位置以及接下来的COMMAND_SEND_DATA命令将发送多少字节。该命令由两个32位的值组成,它们都是首先传输的MSB。第一个32位值是开始编程数据的地址,而第二个是要发送的数据的32位大小。此命令还会根据所使用的地址触发对flash中的整个应用程序区域或整个flash的擦除。这将导致命令发送ACK/NAK以响应命令的时间更长。这个命令后面应该跟着一个COMMAND_GET_STATUS,以确保程序地址和程序大小对于运行引导加载程序的微控制器是有效的。

该命令的格式如下:unsigned char ucCommand[9];
ucCommand[0] = COMMAND_DOWNLOAD;
ucCommand[1] = Program Address [31:24];
ucCommand[2] = Program Address [23:16];
ucCommand[3] = Program Address [15:8];
ucCommand[4] = Program Address [7:0];
ucCommand[5] = Program Size [31:24];
ucCommand[6] = Program Size [23:16];
ucCommand[7] = Program Size [15:8];
ucCommand[8] = Program Size [7:0];

COMMAND_RUN此命令被发送到引导加载程序,以将执行控制权转移到指定的地址。该命令后面跟着一个32位的值,首先传输MSB,这是执行控制被传输到的地址。该命令的格式如下:

unsigned char ucCommand[5];
ucCommand[0] = COMMAND_RUN;
ucCommand[1] = Run Address [31:24];
ucCommand[2] = Run Address [23:16];
ucCommand[3] = Run Address [15:8];
ucCommand[4] = Run Address [7:0];

COMMAND_GET_STATUS此命令返回最后发出的命令的状态。通常,应该在发送每个命令之后接收此命令,以确保前一个命令成功,或者(如果不成功)正确地响应失败。命令要求数据包的数据中有一个字节,引导加载程序应该通过发送包含当前状态代码的一个字节数据的数据包来响应。

unsigned char ucCommand[1];
ucCommand[0] = COMMAND_GET_STATUS

当COMMAND_GET_STATUS被发送到微控制器时,引导加载程序可能返回的状态值的定义如下。

COMMAND_RET_SUCCESS
COMMAND_RET_UNKNOWN_CMD
COMMAND_RET_INVALID_CMD
COMMAND_RET_INVALID_ADD
COMMAND_RET_FLASH_FAIL

COMMAND_SEND_DATA如果需要更多数据,此命令应该只跟随COMMAND_DOWNLOAD命令或另一个COMMAND_SEND_DATA命令。连续的发送数据命令自动增加地址并从以前的位置继续编程。传输大小受引导加载程序中的接收缓冲区大小的限制(由BUFFER_SIZE参数配置)。一旦收到COMMAND_DOWNLOAD命令所指示的字节数,该命令将终止编程。每次调用该函数时,都应该在其后执行一个COMMAND_GET_STATUS命令,以确保数据已成功地编程到flash中。如果引导加载程序向这个命令发送一个NAK,那么引导加载程序将不会增加当前地址,从而允许重新传输以前的数据

unsigned char ucCommand[9];
ucCommand[0] = COMMAND_SEND_DATA
ucCommand[1] = Data[0];
ucCommand[2] = Data[1];
ucCommand[3] = Data[2];
ucCommand[4] = Data[3];
ucCommand[5] = Data[4];
ucCommand[6] = Data[5];
ucCommand[7] = Data[6];
ucCommand[8] = Data[7];

COMMAND_RESET此命令用于告诉引导加载程序重置。这是在将新映像下载到微控制器后使用的,以导致新的应用程序或新的引导加载程序从重置开始。出现正常的引导顺序,映像就像从硬件重置中一样运行。它还可以用于重置引导加载程序,如果发生严重错误,主机设备希望重新启动与引导加载程序的通信。在运行引导加载程序的微控制器上实际执行软件重置之前,引导加载程序以ACK信号响应主机设备。这将通知更新程序应用程序命令已成功接收,该部分将被重置

unsigned char ucCommand[1];
ucCommand[0] = COMMAND_RESET;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值