TM4C129启动代码

        启动代码包含配置向量表、初始化内存、将引导加载程序从flash复制到SRAM以及从SRAM执行所需的最小代码集。因为一些特定于工具链的构造用于指示代码、数据和bss段驻留在内存中的位置,所以每个受支持的工具链都有自己的实现启动代码的单独文件。

        启动代码包含在以下文件中:

        bl_startup_ewarm.s (IAR嵌入式工作台)

        bl_startup_gcc.s(GNU GCC)bl_startup_rvmdk.s (Keil RV-MDK)

        bl_startup_sourcerygxx.S (source CodeBench)

        bl_startup_ccs .s (Texas Instruments Code Composer Studio)

        伴随着每个工具链的启动代码的是链接器脚本,用于将向量表、代码段、数据段初始化器和数据段放置在内存中的适当位置。这些脚本位于以下文件中:

        bl_link.ld (GNU GCC和Sourcery CodeBench)

        bl_link.sct (Keil RV-MDK)

        bl_link.xcl (IAR嵌入式工作台)

        bl_link_ccs.cmd (TI Code Composer Studio)

        引导加载程序的代码及其相应的链接器脚本使用完全存在于SRAM中的内存布局。这意味着代码和只读数据的加载地址与执行地址不相同。这个内存映射允许引导加载程序更新自己,因为它实际上只从SRAM运行。SRAM的第一部分用作引导加载程序的复制空间,而其余部分则为引导加载程序的堆栈和读/写数据保留。一旦引导加载程序调用应用程序,应用程序就可以使用所有SRAM。

        Cortex-M4微处理器的向量表包含四个必需的条目:初始堆栈指针、重置处理程序地址、NMI处理程序地址和硬故障处理程序地址。重置后,处理器加载初始堆栈指针,然后开始执行重置处理程序。初始堆栈指针是必需的,因为NMI或硬故障可以在任何时候发生;堆栈需要接受这些中断,因为处理器会自动将8项压入堆栈。

        vector数组包含引导加载程序的vector表,其大小根据添加的自动波特功能或USB DFU支持而变化。这些选项需要额外的中断处理程序来扩展向量表以填充相关条目。由于引导加载程序从SRAM执行,而不是从flash执行,因此使用工具链特定的构造向链接器提供提示,该数组位于0x2000.0000。

        IntDefaultHandler函数包含默认的错误处理程序。这是一个简单的无限循环,在发生任何意外错误时有效地停止应用程序。因此,应用程序状态将被保存以供调试器检查。如果需要,定制的引导加载程序可以通过向Vectors数组添加适当的处理程序来提供自己的处理程序。

        重置后,启动代码将引导加载程序从flash复制到SRAM,分支到SRAM中的引导加载程序副本,并通过调用CheckForceUpdate()检查是否应该执行应用程序更新。如果不需要更新,则调用应用程序。否则,所调用的函数将基于引导加载程序的操作模式。对于UART, SSI,和I2C,微控制器通过调用ConfigureDevice()初始化,然后引导负载调用串行控制循环Updater()。对于以太网,通过调用ConfigureEnet()来初始化微控制器,然后引导加载程序调用以太网控制循环UpdateBooTP()。对于CAN,微控制器通过调用ConfigureCAN()来初始化,然后引导加载程序调用CAN控制循环UpdaterCAN()。对于USB,微控制器通过调用ConfigureUSB()来初始化,之后函数UpdaterUSB()将USB接口配置为设备模式。

        应用程序更新的检查(在CheckForceUpdate()中)包括检查应用程序区域的开始部分和可选地检查GPIO引脚的状态。如果第一个位置是有效的堆栈指针(即,它位于SRAM中,值为Ox2xxx.xxxx),第二个位置是有效的重置处理程序地址(即,它位于flash中,值为Ox000x),则认为应用程序是有效的。Xxxx,其中值为奇数)。如果其中任何一个测试失败,则假定应用程序无效,并强制更新。可以使用bl_config.h头文件中的ENABLE_UPDATE_CHECK启用GPIO引脚检查,在这种情况下,可以通过改变GPIO引脚的状态来强制更新(例如,使用按钮)。如果应用程序有效且GPIO引脚没有请求更新,则调用应用程序。否则,将通过进入引导加载程序的主循环来启动更新。

        此外,应用程序可以调用引导加载程序以执行面向应用程序的更新。在这种情况下,引导加载程序假定应用程序已经配置了用于更新的外设。这允许引导加载程序按原样使用外设来执行更新。引导加载程序还假定对核心的中断也一直处于启用状态,这意味着应用程序在调用引导加载程序之前不应该调用IntMasterDisable()。一旦应用程序调用引导加载程序,引导加载程序将自己复制到SRAM,分支到引导加载程序的SRAM副本,并通过调用Updater()(用于UART、SSI和I2C)、UpdateBOOTP()(用于以太网)、AppUpdaterCAN()(用于CAN)或AppUpdaterUSB()(用于USB)来启动更新。vector表的svcall条目包含面向应用程序的更新入口点的位置。