主题中讨论的其他器件:TM4C1294NCPDT、、 UNIFLASH
工具与软件:
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具与软件:
您好!
我建议您以 UART bootloader 示例为例启动。 UART 引导加载程序可以在 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\boot_serial 中找到。 此示例将从 UART 接口下载/升级固件。 按照下面的示例、引导加载程序将调用 bl_main,c 文件中的 Updater ()函数。 请完成此功能、因为它实现了如何逐块擦除闪存和编程固件块。 如果您是通过 GSM 接收固件,那么通过 Updater ()函数执行相同的步骤是没有区别的。
另请参阅 TM4C 引导加载程序用户指南 以了解详细信息。
bl_main.c文件添加到我的闪烁项目并尝试执行基本闪烁 OTA? [报价]
我不清楚您的问题。 闪烁项目是一个非常简单的项目、只会使 LED 闪烁。 您希望执行基本闪烁 OTA 的意思是什么? 我想您会通过连接到 GSM 的 UART 收到一个程序。 GSM 向 MCU 发送什么数据? 这是另一个闪烁的程序吗? 您需要将 Updater ()复制到 RAM 中、以便 CPU 可以从 RAM 中执行编程和擦除闪存。
我强烈建议您同时运行 boot_serial (这是一个串行引导加载程序)示例和 boot_demo1 (这是一个示例应用程序)。 首先尝试使用这些示例、然后我认为引导加载程序的工作方式就会一目了然。 基本来说、boot_serial 首先 通过 JTAG 接口在0x0处加载到闪存中。 复位后、它将查明0x4000处是否已经有固件映像。 如果存在有效固件、则只需跳转到0x4000处的固件并执行固件。 如果没有有效的固件映像、那么它将尝试从 UART 端口下载固件(boot_demo1示例)。 引导加载程序会将引导加载程序代码复制到 RAM、以便 CPU 从 RAM 执行、然后使用从 UART 端口接收到的二进制文件将固件编程到闪存。 运行示例并了解其功能。
尊敬的 Charles:
感谢您的答复。
我分析了这两个代码并尝试boot_serial与一起刷写boot_demo1。 根据我的理解、我首先刷写了boot_demo1 具有闪烁功能的闪0x00004000存、它存储在闪存中(使用.cmd文件进行验证)。 然后,我闪boot_serial0x00000000存,它应该存储在闪存中。 刷写完成后、我将电路板复位。
根据我的理解、如果中存在有效的映像0x00004000、boot_serial应执行该映像、但它不执行、并且 LED 不闪烁。 如果我错了、请更正我。
您好!
否、您运行该示例的过程不正确。 boot_demo1是引导加载程序从 UART 下载的固件。 您不使用 JTAG 来加载 boot_deme1。 您应该首先使用 JTAG 加载 boot_serial。 在 boot_serial 加载并运行后、它将配置 UART 以下载 boot_demo1。 您仍然需要通过 UART 接口(而不是 JTAG)加载 boot_demo1。 这是引导加载的整个目的、除非您使用 JTAG 调试到第一个 boot_demo1。 当您首次加载 boot_deme1并随后加载 boot_serial 时、JTAG 加载 boot_serial 将首先擦除整个闪存、然后对 BOOT_SERIAL 进行编程。 然后、boot_deme1将被擦除。
尊敬的 Charles:
我理解您的观点。 我现已boot_serial0x00000000使用调试器刷写 AT 地址。 我单独构建了boot_demo1、二进制文件可以在以下路径中找到:/root/workspace_v11/boot_demo1/Debug/boot_demo1.bin。
如何将此二进制文件发送到 UART0? 是否可以使用 Minicom 以115200的波特率直接上传二进制文件、或者我是否需要使用自定义编程器或脚本发送二进制文件?
如果可能、您能否分享将二进制文件上传到 UART0的步骤?
如何将此二进制文件发送到 UART0? 是否可以使用 Minicom 以115200的波特率直接上传二进制文件、或者我是否需要使用自定义编程器或脚本发送二进制文件?
[报价]您可以使用 LM Flash 程序员。 请参见下文。

或者、您可以使用 C:\ti\TivaWare_C_Series-2.2.0.295\tools\bin 中提供的命令行 sflash.exe

尊敬的 Charles:
很抱歉耽误你的时间。
我尝试使用发送二进制文件sflash.exe,但它被卡住了。 我第一次闪存boot_serial using JTAG。
小程序
{
Flash (RX):origin = 0x00000000、length = 0x00010000
SRAM (RWX):origin = 0x20000000、length = 0x00010000
}
然后、我boot_demo1使用以下命令编译并尝试发送二进制文件。
#define APP_BASE 0x00004000
#define RAM_BASE 0x20000000
小程序
{
FLASH (RX): origin = APP_BASE, length = 0x000fc000
SRAM (RWX):origin = 0x20000000、length = 0x00040000
}
使用的命令:
.\sflash.exe boot_demo1.bin -p 0x00004000 -r 0x20000000 -c 7 -b 115200 -s 1224
使用该-h选项时、我可以看到帮助控制台、帮助控制台确认.exe文件执行正确。 但我不知道为什么在发出上述命令时会被阻滞。
尊敬的 Charles:
我最初错过了偏移0x4000、但现在它对我有效。 我能够使用 LM Flash Programmer 将 boot_demo1.bin 刷写。 但是、当我按下 SW1按钮时、它会返回引导加载程序模式。
我还有一个问题。 目前、我的程序正在从内部闪存 AT 中执行 0x00000000 . 现在、我从 GSM 模块在 UART 0上接收到1224字节的数据、并将其存储在名为的缓冲区中 GSM_缓冲区[1224] . 写入这些数据 0x00004000 在内部闪存中、然后将执行地址从更改为这个新位置 未切换到引导加载程序的当前应用程序?
我最初漏掉了偏移量0x4000、但现在却可以使用了。 我能够使用 LM Flash Programmer 将 boot_demo1.bin 刷写。 但是、当我按下 SW1按钮时、它会返回引导加载程序模式。
您好!
很高兴您启动了该工具。 它是应用 boot_demo 1的一部分、允许用户通过按 SW1再次更新固件。
我还有一个查询。 目前、我的程序正在从内部闪存 AT 中执行 0x00000000 . 现在、我从 GSM 模块在 UART 0上接收到1224字节的数据、并将其存储在名为的缓冲区中 GSM_缓冲区[1224] . 写入这些数据 0x00004000 在内部闪存中、然后将执行地址从更改为这个新位置 未切换到引导加载程序的当前应用程序? [报价]新代码是否具有1124字节的所有空间?
您当前驻留在0x0的代码有多大? 如果它超过了0x4000、如果您要在0x4000处编程某些代码、不是吗?
为什么不想使用引导加载程序? 要对闪存进行编程、您需要从 RAM 运行引导加载程序代码、以便它可以擦除新代码并将其编程到闪存中。 如果您没有引导加载程序、而只有您的应用程序位于0x0、则需要以某种方式将应用程序移动到 RAM、以便您可以将新代码编程到闪存中。 我建议您使用引导加载程序。
尊敬的 Charles:
在本例中、我使用 UART 0与 EC21E GSM 模块进行 TM4C 控制器通信。 我的当前应用程序在地址0x00000000处运行、该地址读取8引脚的 ADC 值、并通过 UART 0 AT 命令将其与格式化的数据一起发送到 GSM 模块、以将数据推送到 MQTT 服务器。
如果我发送特定的 AT 命令以及服务器 URL 和主题、我的固件更新二进制文件将下载并存储在 GSM 模块的本地 UFS 中。 然后,我将使用文件处理 AT 命令通过 UART 0将该 bin 文件读取到 TM4C 控制器,并将 bin 数据存储在名为的缓冲区中GSM_Buffer[1224]。 此时、我需要将此 bin 文件刷写到内部闪存中并执行它。
这是我的疑问—如何刷写boot_serial第一个? 我需要集成代码来实现这一点。
我无法跟踪int main()boot_serial 示例中的函数。 您能告诉我在哪个 .c文件中开始执行吗?
尊敬的 Charles:
我的 GSM_Buffer[1224]="µDÇDÃDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅD -éðG„FFVHßøT‘ßøX h ê˜E μ s Oð
Oð μ A
úóBøÄ"ÜøÄ ÂóA³@ CÌøÄ"èÛ"¿Üø5CÜø5‹CÌø5 " 5CÜ5‹CÌ5 "¿Üø5CÜø5‹CÌø5hLFEF@"ÐR "¿Üø" " " <%
CÜø ŠCÌø¿ü<%'ŠCÌø%¿Üø:' %
CÜø ŠCÌø%h@¥ˆCô@ÌøD¿Üø@CÜø@ˆCÌø@/¿Üø(êÜø L FðIø Fð*Ø(úÐNL %! 0F
JÀó#ôÿQðÿ¡õ01Ò!Ð~AAêqAê€Aðph±pGÀFêôÿQðÿ¡õP1Ò!Aê€Aðp`pGÀFæ@!Ð~AAêq "¿Ð4 "¿Ðø$ CÐø$êÀø pH€h@ô`¿¿ðø ÿ÷sÿ(Fÿ÷Èÿ8½@Ø! pGÿ÷Ø¿pG pG¿þçþçþçþç Ω"
由 GSM 模块通过 TM4C 控制器的 UART 0读取。
我无法跟踪int main()boot_serial示例中的函数。 您能告诉我在哪个.c文件中开始执行吗?
引导加载程序从 bl_startup_ccs.s 文件开始。 您可以在 C:\ti\TivaWare_C_Series-2.2.0.295\boot_loader 的引导加载程序文件夹中找到此文件。 按照此文件查看引导加载程序如何启动 UART 接口并通过调用 Updater ()函数对应用程序固件进行编程。 为了将应用程序固件编程到闪存中、引导加载程序需要首先将自身从闪存复制到 RAM、并让 CPU 从 RAM 中执行引导加载代码。 不能在对闪存编程的同时将代码从闪存中运行出去。
我的 GSM_Buffer[1224]="µDÇDÃDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅDÅD -éðG„FFVHßøT‘ßøX h ê˜E μ s Oð
Oð μ A
úóBøÄ"ÜøÄ ÂóA³@ CÌøÄ"èÛ"¿Üø5CÜø5‹CÌø5 " 5CÜ5‹CÌ5 "¿Üø5CÜø5‹CÌø5hLFEF@"ÐR "¿Üø" " " <%
CÜø ŠCÌø¿ü<%'ŠCÌø%¿Üø:' %
CÜø ŠCÌø%h@¥ˆCô@ÌøD¿Üø@CÜø@ˆCÌø@/¿Üø(êÜø L FðIø Fð*Ø(úÐNL %! 0F
JÀó#ôÿQðÿ¡õ01Ò!Ð~AAêqAê€Aðph±pGÀFêôÿQðÿ¡õP1Ò!Aê€Aðp`pGÀFæ@!Ð~AAêq "¿Ð4 "¿Ðø$ CÐø$êÀø pH€h@ô`¿¿ðø ÿ÷sÿ(Fÿ÷Èÿ8½@Ø! pGÿ÷Ø¿pG pG¿þçþçþçþç Ω" [报价]这是什么? 这是新代码还是数据? 对我来说、它似乎只是数据。 我不能镜像整个固件小于1KB。
尊敬的 Charles:
我已经开始修改bl_main.c我的应用程序的文件。 我对 LM Flasher 和中的偏移设置有疑问slafsh.exe。 在这些工具中、我们将偏移指定为 0x00004000。 但在本例中、我将使用以下命令通过 UART 0从 GSM 模块的 UFS 读取原始二进制数据:
AT+QFDWL="Blinky.bin"
此命令从指定文件检索原始二进制数据。 在这种情况下、我应该如何处理失调值? 如何在本例中指定偏移地址?
我将尝试使用SendPacket中的函数bl_packet.c通过 UART0发送此命令。 我曾在更新程序开始时调用此函数、但如果我包含此行、则无法发送二进制数据。
SendPacket ("AT+QFDWL=\"Blinky.bin\"\r\n"、26);
请对此提供帮助通过 UART0发送 donwload 命令后、gsm 模块将在 UART0中发回二进制数据、接收到的数据应存储在闪存中、需要开始引导。
尊敬的 Charles:
是否有可能在 updateer 函数中将 Blinky 的二进制数据硬编码为十六进制值作为数组、然后将此值写入闪存0x00004000?这样可以、我将使用 hexdump 工具从二进制文件中获取此十六进制值。
unsigned char Blinky_bin[]={
0x00、0x02、0x00、0x20、0xb5、 0x44、0x00、0x00、0xc7、0x44、 0x00、0x00、
0xc3、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0x00、 0x00、0x00、0x00、0x00、0x00、 0x00、0x00、
0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0x00、 0x00、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0x00、0x00、0x00、0x00、0x00、 0x00、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0x00、0x00、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0xc5、0x44、 0x00、0x00、
0xc5、0x44、0x00、0x00、0xc5、 0x44、0x00、0x00、0x2D、0xe9、 0xf0、0x47、
0x84、0x46、0x1f、0x46、0x56、 0x48、0xdf、0xF8、0x54、0x91、 0xdf、0xF8、
0x58、0x81、0x03、0x68、0x09、 0xEA、0x03、0x03、0x98、0x45、 0x1b、0xd0、
0x00、0x24、0x4f、0xf0、0x01、 0x0A、0x4f、0xf0、0x03、0x0E、 0x0A、0xfa、
0x04、0xF3、0x19、0x42、0x0F、 0xd0、0xdc、0xf8、0xc4、0x3f、 0x66、0x00、
0x0E、0xfa、0x06、0xf5、0xab、 0x43、0xcc、0xF8、0xc4、0x3f、 0xdc、0xF8、
0xc4、0x5f、0xC2、0xF3、0x41、 0x13、0xb3、0x40、0x2b、0x43、 0xcc、0xF8、
0xc4、0x3f、0x64、0x1c、0x08、 0x2C、0xe8、0xdb、0x53、0x08、 0x27、0xbf、
0xdc、0xF8、0x00、0x35、0x0B、 0x43、0xdc、0xf8、0x00、0x35、 0x8b、0x43、
0xcc、0xF8、0x00、0x35、0x93、 0x08、0x27、0xbf、0xdc、0xf8、 0x04、0x35、
0x0B、0x43、0xdc、0xf8、0x04、 0x35、0x8b、0x43、0xcc、0xF8、 0x04、0x35、
0xd3、0x08、0x27、0xbf、0xdc、 0xF8、0x08、0x35、0x0B、0x43、 0xdc、0xF8、
0x08、0x35、0x8b、0x43、0xcc、 0xF8、0x08、0x35、0x13、0x09、 0x27、0xbf、
0xdc、0xF8、0x18、0x35、0x0B、 0x43、0xdc、0xf8、0x18、0x35、 0x8b、0x43、
0xcc、0xF8、0x18、0x35、0x03、 0x68、0x4c、0x46、0x45、0x46、 0x23、0x40、
0x9d、0x42、0x09、0xd0、0x52、 0x09、0x27、0xbf、0xdc、0xf8、 0x3c、0x25、
0x0A、0x43、0xdc、0xf8、0x3c、 0x25、0x8a、0x43、0xcc、0xF8、 0x3c、0x25、
0x7a、0x08、0x27、0xbf、0xdc、 0xF8、0x0c、0x25、0x0a、0x43、 0xdc、0xF8、
0x0C、0x25、0x8a、0x43、0xcc、 0xF8、0x0c、0x25、0xba、0x08、 0x27、0xbf、
0xdc、0xf8、0x10、0x25、0x0a、 0x43、0xdc、0xf8、0x10、0x25、 0x8a、0x43、
0xcc、0xF8、0x10、0x25、0xfa、 0x08、0x27、0xbf、0xdc、0xf8、 0x14、0x25、
0x0A、0x43、0xdc、0xf8、0x14、 0x25、0x8a、0x43、0xcc、0xF8、 0x14、0x25、
0x3a、0x09、0x27、0xbf、0xdc、 0xF8、0x1c、0x25、0x0a、0x43、 0xdc、0xF8、
0x1c、0x25、0x8a、0x43、0xcc、 0xF8、0x1c、0x25、0x00、0x68、 0x04、0x40、
0xA5、0x42、0x14、0xd0、0xb8、 0x0A、0x27、0xbf、0xdc、0xf8、 0x44、0x05、
0x08、0x43、0xdc、0xf8、0x44、 0x05、0x88、0x43、0x17、0xf4、 0x40、0x7F、
0xcc、0xF8、0x44、0x05、0x19、 0xbf、0xdc、0xf8、0x40、0x05、 0x08、0x43、
0xdc、0xF8、0x40、0x05、0x88、 0x43、0xcc、0xF8、0x40、0x05、 0x00、0x2F、
0x19、0xbf、0xdc、0xf8、0x28、 0x05、0x20、0xEA、0x01、0x01、 0xdc、0xF8、
0x28、0x05、0x01、0x43、0xcc、 0xF8、0x28、0x15、0xBD、0xe8、 0xf0、0x87、
0x00、0x00、0xff、0x70、0x00、 0xe0、0x0F、0x40、0x00、0x00、 0x05、0x10、
0x7c、0xb5、0x15、0x4c、0x20、 0x46、0x00、0xf0、0x49、0xF8、 0x20、0x46、
0x00、0xf0、0x2A、0xf8、0x00、 0x28、0xfa、0xd0、0x11、0x4e、 0x01、0x21、
0x30、0x46、0x00、0xf0、0x85、 0xF8、0x10、0x4c、0x00、0x25、 0x01、0x21、
0x30、0x46、0x0a、0x46、0x00、 0xf0、0x8b、0xF8、0x00、0x95、 0x00、0x98、
0x84、0x42、0x0c、0xd8、0x30、 0x46、0x01、0x21、0x2A、0x46、 0x00、0xf0、
0x82、0xF8、0x00、0x95、0x00、 0x98、0x84、0x42、0xED、0xd9、 0x00、0x98、
0x40、0x1c、0x00、0x90、0xF8、 0xe7、0x00、0x98、0x40、0x1c、 0x00、0x90、
0xeb、0xe7、0xc0、0x46、0x0c、 0x08、0x00、0xf0、0x00、0x40、 0x06、0x40、
0x40、0x0d、0x03、0x00、0x0c、 0x4a、0xc1、0x08、0xc0、0xf3、 0x07、0x23、
0x01、0xf4、0xff、0x51、0x00、 0xf0、0xff、0x00、0xa1、0xf5、 0x30、0x31、
0xd2、0x18、0x21、0xf0、0x7E、 0x41、0x12、0x0F、0x41、0xEA、 0x02、0x71、
0x41、0xEA、0x80、0x01、0x41、 0xF0、0x00、0x70、0x01、0x68、 0x00、0x20、
0x01、0xb1、0x01、0x20、0x70、 0x47、0xc0、0x46、0x00、0xEA、 0x0F、0x40、
0x0B、0x4a、0xc1、0x08、0xc0、 0xF3、0x07、0x23、0x01、0xF4、 0xFF、0x51、
0x00、0xf0、0xff、0x00、0xa1、 0xF5、0x50、0x31、0xd2、0x18、 0x21、0xf0、
0x7E、0x41、0x12、0x0F、0x41、 0xEA、0x02、0x71、0x01、0x22、 0x41、0xEA、
0x80、0x01、0x41、0xf0、0x00、 0x70、0x02、0x60、0x70、0x47、 0xc0、0x46、
0x00、0xe6、0x0F、0x40、0x53、 0x08、0x27、0xbf、0xd0、0xf8、 0x00、0x34、
0x0B、0x43、0xd0、0xF8、0x00、 0x34、0x8b、0x43、0x92、0x08、 0xc0、0xF8、
0x00、0x34、0x27、0xbf、0xd0、 0xF8、0x20、0x24、0x11、0x43、 0xd0、0xF8、
0x20、0x24、0x22、0xEA、0x01、 0x01、0xc0、0xF8、0x20、0x14、 0x70、0x47、
0x08、0x48、0x80、0xF3、0x08、 0x88、0x08、0x49、0x08、0x68、 0x40、0xf4、
0x70、0x00、0x08、0x60、0x00、 0xbf、0xb00、0xbf、0x00、0xf0、 0x1d、0xF8、
0x00、0x20、0xff、0xf7、0x73、 0xFF、0x01、0x20、0x00、0xf0、 0x19、0xF8、
0x00、0x02、0x00、0x20、0x88、 0xED、0x00、0xe0、0x38、0xb5、 0x01、0x22、
0x0C、0x46、0x05、0x46、0x08、 0x23、0xff、0xf7、0xaf、0xFE、 0x01、0x22、
0x21、0x46、0x28、0x46、0xff、 0xf7、0xc8、0xff、0x38、0xbd、 0x40、0xF8、
0x21、0x20、0x70、0x47、0xff、 0xf7、0xd8、0xbf、0x70、0x47、 0x01、0x20、
0x70、0x47、0x00、0xbf、0xFE、 0xe7、0xFE、0xe7、0xFE、0xe7、 0xFE、0xe7
};
unsigned int blinky_bin_len = 1224;
不可以、您不能将 blink.bin 原样使用、因为原始 blink.bin 是编译并链接到从0x0 (而不是0x4000)开始的。 如果您希望 blinky.bin 从0x4000开始、则 必须 重新编译 blinky 工程并修改.cmd 文件、使其链接到0x4000。 如果您查看 boot_demo1工程.cmd 文件、您会发现 APP_BASE 从0x4000开始。
#define APP_BASE 0x00004000#define RAM_BASE 0x20000000
/* System memory map */
MEMORY{ /* Application stored in and executes from internal flash */ FLASH (RX) : origin = APP_BASE, length = 0x000fc000 /* Application uses internal RAM for data */ SRAM (RWX) : origin = 0x20000000, length = 0x00040000
您好!
为什么不首先加载修改后的 blinky.out 文件并在 CCS Memory Browser 窗口中查看该文件? 请参阅下面的、我在这里重新编译了闪烁、以从0x4000开始。 如您所见、它已正确编程为0x4000、其中 SP 指向0x20000200、Reset Vector 指向0x000044B5。

接下来、您只需手动强制 PC 为0x44B4、然后让它运行。 您的闪烁程序应使 LED 在程序从0x4000开始时闪烁。

由于您不使用引导加载程序、而是使用位于0x0的应用程序来对闪存的另一个区域进行编程、因此可以使用 FlashProgram() API。 有关详细信息、请参阅以下和外设驱动程序用户指南。 它将类似于:
FlashProgram ( Blinky_bin、0x4000、Blinky_bin_len);

如果0x4000处已经有数据、则必须首先使用 FlashErase () API 擦除闪存。
尊敬的 Charles:
感谢您的讲解!
那么、如果我错了、请纠正我的问题、您告诉的是、我的当前应用程序是否存储在闪存0x00000000中并正在执行、如果我尝试使用当前应用向闪存的另一个区域写入新的闪烁二进制数据、您告诉我使用闪存程序 API 将我的闪烁二进制 hexa 数据写入闪存0x0000400、而不是立即使用引导加载程序?
我还可以使用 binary Wright 中的 hexa 数据吗? 我已经使用 hexdump 工具获取了二进制文件的 hexa 值!
请分享外设驱动程序用户指南的链接。
有。
请与我分享外设驱动程序用户指南的链接。
您可以在 TivaWare SDK 文档目录或 https://www.ti.com/lit/ug/spmu298a/spmu298a.pdf 中找到该文档
有。
请与我分享外设驱动程序用户指南的链接。
您可以在 TivaWare SDK 文档目录或 https://www.ti.com/lit/ug/spmu298a/spmu298a.pdf 中找到该文档
您可以参考 bl_startup_ccs.s 文件。 可以使用 BX r0指令跳转到应用程序入口点。 r0寄存器将包含应用起点地址。 在您修改的闪烁测试用例中、r0寄存器应包含0x000044B5。
;;;
;;从应用程序的向量表中加载堆栈指针。
;;;
.if (APP_START_ADDRESS!= VTABLE_START_ADDRESS)
MOVW r0、#(APP_START_ADDRESS 和0xFFFF)
.if (APP_START_ADDRESS > 0xFFFF)
movt r0、#(APP_START_ADDRESS >> 16)
.endif
.endif
LDR sp、[r0]
;;;
;;从应用程序的向量表中加载初始 PC 并分支到
;;应用程序的入口点。
;;;
LDR r0、[R0、#4]
Bx r0
尊敬的 Charles:
下面是示例函数。 如果可行、请告诉我。 我已从 Blinky 二进制文件中获取这些十六进制值、该二进制文件使用 xxd hexdump 工具(xxd -g 4 Blinky.bin)针对地址0x00004000进行编译。 我将它们写入为32位值、因为闪存组0的第二个扇区从地址0x00004000 (32位)开始。
int perform_ota (void){
uint32_t Blinky_bin[]={
0x00020020、0xb5440000、0xc7440000、0xc3440000
0xc5440000、0xc5440000、0xc5440000、0x00000000、
0x00000000、0x00000000、0x00000000、0xc5440000
0xc5440000、0x00000000、0xc5440000、0xc5440000、
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0x00000000、0x00000000、0xc5440000、0xc5440000、
0xc5440000、0xc5440000、0x00000000、0xc5440000、
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0xc5440000、0xc5440000、0xc5440000、0xc5440000
0x2de9f047、0x84461f46、0x5648dff8、0x5491dff8、
0x58810368、0x09ea0303、0x98451bd0、0x00244ff0、
0x010a4ff0、0x030e0afa、0x04f31942、0x0fd0dcf8
0xc43f6600、0x0efa06f5、0xab43ccf8、0xc43fdcf8、
0xc45fc2f3、0x4113b340、0x2b43ccf8、0xc43f641c
0x082ce8db、0x530827bf、0xdcf80035、0x0b43dcf8
0x00358b43、0xccf80035、0x930827bf、0xdcf80435、
0x0b43dcf8、0x04358b43、0xccf80435、0xd30827bf
0xdcf80835、0x0b43dcf8、0x08358b43、0xccf80835、
0x130927bf、0xdcf81835、0x0b43dcf8、0x18358b43、
0xccf81835、0x03684c46、0x45462340、0x9d4209d0、
0x520927bf、0xdcf83c25、0x0a43dcf8、0x3c258a43、
0xccf83c25、0x7a0827bf、0xdcf80c25、0x0a43dcf8
0x0c258a43、0xccf80c25、0xba0827bf、0xdcf81025、
0x0a43dcf8、0x10258a43、0xccf81025、0xfa0827bf、
0xdcf81425、0x0a43dcf8、0x14258a43、0xccf81425、
0x3a0927bf、0xdcf81c25、0x0a43dcf8、0x1c258a43、
0xccf81c25、0x00680440、0xa54214d0、0xb80a27bf、
0xdcf84405、0x0843dcf8、0x44058843、0x17f4407f、
0xccf84405、0x19bfdcf8、0x40050843、0xdcf84005
0x8843ccf8、0x4005002f、0x19bfdcf8、0x280520ea、
0x0101dcf8、0x28050143、0xccf82815、0xbde8f087、
0x0000ff70、0x00e00f40、0x00000510、0x7cb5154c、
0x204600f0、0x49f82046、0x00f02af8、0x0028fad0、
0x114e0121、0x304600f0、0x85f8104c、0x00250121、
0x30460a46、0x00f08bf8、0x00950098、0x84420cd8、
0x30460121、0x2a4600f0、0x82f80095、0x00988442、
0xedd90098、0x401c0090、0xf8e70098、0x401c0090、
0xebe7c046、0x0c0800f0、0x00400640、0x400d0300、
0x0c4ac108、0xc0f30723、0x01f4ff51、0x00f0ff00、
0xa1f53031、0xd21821f0、0x7e41120f、0x41ea0271、
0x41ea8001、0x41f00070、0x01680020、0x01b10120、
0x7047c046、0x00ea0f40、0x0b4ac108、0xc0f30723、
0x01f4ff51、0x00f0ff00、0xa1f55031、0xd21821f0、
0x7e41120f、0x41ea0271、0x012241ea、0x800141f0、
0x00700260、0x7047c046、0x00e60f40、0x530827bf、
0xd0f80034、0x0b43d0f8、0x00348b43、0x9208c0f8、
0x003427bf、0xd0f82024、0x1143d0f8、0x202422ea、
0x0101c0f8、0x20147047、0x084880f3、0x08880849、
0x086840f4、0x70000860、0x00bf00bf、0x00f01df8、
0x0020fff7、0x73ff0120、0x00f019f8、0x00020020、
0x88ed00e0、0x38b50122、0x0c460546、0x0823fff7、
0xaffe0122、0x21462846、0xfff7c8ff、0x38bd40f8、
0x21207047、0xFFf7d8bf、0x70470120、0x704700bf、
0xfee7fee7、0xfee7fee7
};
uint32_t address = flash_start_address;
int32_t Result1 = FlashErase (address);
if (Result1 =0){
//闪存块已成功擦除
其他{
//擦除闪存块时出错
}
int32_t Result2 = FlashProgram (Blinky_bin、address、sizeof (Blinky_bin));
if (Result2=0){
//闪存编程成功
其他{
//编程闪存时出错
}
返回0;
}
我的当前应用是11,136字节、大约是10.875KB、我的 Blinky 应用程序是1224字节、大约是1.195KB。 所以、它不应导致任何问题、对吧? 当前的应用(10KB)将适合于存储体0第一个扇区(0x00000000、16KB)、这不会产生任何问题、对吧?
为了您的参考、我在下面附上了闪存库映像:

我当前的应用程序是11,136字节、约为10.875 KB、我的 Blinky 应用程序是1224字节、约为1.195 KB。 所以、它不应导致任何问题、对吧? 当前应用(10KB)适用于存储体0第一个扇区(0x00000000、16KB)、这不会产生任何问题、对吗?[/QUOT]您的应用程序小于0x4000、因此应该没有问题。
尊敬的 Charles:
我已经在 CCS 的存储器浏览器中验证了修改后的 Blinky 二进制应用程序(0x00004000)的存储器地址。 第一个地址(0x00004000)的值为0x20000200、最后一个地址(0x000044C4)的值为0xE7FEE7FE。
同样、我已经为我的二进制数组建立了框架、并使用运行在0x00000000的当前应用程序将值正确写入0x00004000。 但是、我收到了擦除 API 和闪存 API 的返回值0。 我在擦除后检查存储器浏览器、0x00004000处的值变为0xFFFFFFFF。 写入后、这些值被正确放置、与实际的 Blinky 应用类似。 第一个地址(0x00004000)为0x20000200、最后一个地址(0x000044C4)为0xE7FEE7FE。
我已在下面附上图像。
请帮助我执行当前应用程序0x00000000中指向新地址0x00004000的代码。
闪烁应用程序0x00004000:


我的应用程序在0x00000000中运行并在0x00004000中写入值:


下面是我的当前应用程序(0x00000000) startup_ccs.c 文件、请告诉我如何将当前应用 CCS 文件修改为指向0x00004000地址来执行。
e2e.ti.com/.../6232.startup_5F00_ccs.c
尊敬的 Charles:
感谢您的支持、
下面的逻辑对我来说是有效的、写入该值后、我将使用下面的行 在主函数中指向我的代码
uint32_t APP_START_ADDRESS = 0x00004000;
uint32_t * vector_table;
uint32_t stack_pointer、entry_point;
Vector_table =(uint32_t *) APP_START_ADDRESS;
stack_pointer = vector_table[0];
__SET_MSP (STACK_POINTER);
entry_point = vector_table[1];
(( void (*)(void))entry_point)();
尊敬的 Charles:
这是我从调用的函数main。 请告诉我如何0x00004000在下电上电后从引导。 有没有 API 可实现这一点? 0x00000000一旦完成 OTA、便不应从该引导加载程序引导。
int perform_ota (void){
uint32_t Blinky_bin[]={--------------- Heaxa 数据------- };
uint32_t address = flash_start_address;
int32_t Result1 = FlashErase (address);
if (Result1 =0){
UART6Write ((uint8_t *)"擦除成功\r\n"、16);
其他{
UART6Write ((uint8_t *)"擦除失败\r\n"、18);
}
int32_t Result2 = FlashProgram (Blinky_bin、address、sizeof (Blinky_bin));
if (Result2=0){
UART6Write ((uint8_t *)"\r\n 闪存成功\r\n\r\n\r\n"、20);
其他{
UART6Write ((uint8_t *)"Flash unsuccessful\r\n"、18);
}
uint32_t APP_START_ADDRESS = 0x00004000;
uint32_t * vector_table;
uint32_t stack_pointer、entry_point;
Vector_table =(uint32_t *) APP_START_ADDRESS;
stack_pointer = vector_table[0];
__SET_MSP (STACK_POINTER);
entry_point = vector_table[1];
(( void (*)(void))entry_point)();
返回0;
}
当 CPU 完成复位后、它 将从地址为零的矢量表引导。 请参阅 Arm Cortex-M4 TRM。 https://developer.arm.com/documentation/ka001197/latest/
您可以更改处理器的矢量表地址。 请参阅器件数据表。 您还可以参考 bl_startup 文件了解如何更改矢量表地址。
系统复位时、向量表固定在地址0x0000.0000。 特权软件可以写入
通过向量表偏移量(VTABLE)寄存器、将向量表的起始地址重新定位为不同的地址
存储器位置、范围在0x0000.0400到0x3FFF.FC00之间(见119页的"向量表")。 注释
在配置 VTABLE 寄存器时、偏移量必须在1024字节的边界对齐。

另请参阅有关此主题的 Arm TRM。
尊敬的 Charles:
谢谢。
我已经实现了一些逻辑来检查0x00004000处是否存在有效映像、我的当前应用程序应指向该映像并将矢量表移动到该新地址。
如果找不到有效的映像、OTA 进程将对其进行处理并指向新地址。
我还有一个问题。 为什么在我关闭电源并在电路板上安装之后 boot_demo1示例不会执行? 它存储在位于0x00004000的闪存中、那么为什么在一个循环通电后没有被指向它呢? 是否在0x00000000处搜索映像?
我还有一个查询。 为什么在我关闭电源并在电路板上安装之后 boot_demo1示例不会执行? 它存储在位于0x00004000的闪存中、那么为什么在一个循环通电后没有被指向它呢? 是否在0x00000000处搜索映像?[/QUOT]BOOT_DEMO1要求 BOOT_SERIAL (引导加载程序)驻留在0x0。 您是否故意非故意擦除了引导加载程序? 您可以使用 CCS 存储器浏览器查看引导加载程序是否在0x0处。 复位后、处理器从0x0引导。 如果存在 boot_serial、引导加载程序将检查0x4000处的固件是否有效。 如果在0x4000处找到有效固件、则它将跳转至0x4000以执行固件。 请查看 bl_startup 文件。