ZHCU755D August   2022  – December 2022

 

  1.   说明
  2.   资源
  3.   特性
  4.   应用
  5.   5
  6. 1系统说明
    1. 1.1 关键系统规格
  7. 2系统概览
    1. 2.1 方框图
    2. 2.2 设计注意事项
      1. 2.2.1 构建块
      2. 2.2.2 闪存分区
      3. 2.2.3 LFU 切换概念
      4. 2.2.4 应用程序 LFU 流程
  8. 3硬件、软件、测试要求和测试结果
    1. 3.1 硬件要求
    2. 3.2 软件要求
      1. 3.2.1 软件包内容
      2. 3.2.2 软件结构
    3. 3.3 TIDM-DC-DC-BUCK 简介
    4. 3.4 测试设置
      1. 3.4.1 使用 CCS 将自定义引导加载程序和应用程序加载到闪存
    5. 3.5 测试结果
      1. 3.5.1 在 CPU 上运行控制循环时运行 LFU 演示
      2. 3.5.2 在 CLA 上运行控制循环时运行 LFU 演示
      3. 3.5.3 CPU 上的 LFU 流程
      4. 3.5.4 CLA 上的 LFU 流程
      5. 3.5.5 假设
      6. 3.5.6 为 LFU 准备固件
      7. 3.5.7 LFU 编译器支持
      8. 3.5.8 稳健性
      9. 3.5.9 LFU 用例
  9. 4FOTA 示例
    1. 4.1 摘要
    2. 4.2 引言
    3. 4.3 硬件要求
    4. 4.4 软件要求
    5. 4.5 运行示例
  10. 5设计和文档支持
    1. 5.1 软件文件
    2. 5.2 文档支持
    3. 5.3 支持资源
    4. 5.4 商标
  11. 6术语
  12. 7关于作者
  13. 8修订历史记录

CPU 上的 LFU 流程

在上面的 LFU 演示中,使用了两个应用程序映像。一个在闪存组 0 上运行,另一个在闪存组 1 上运行。BANK0_FLASH 构建配置被视为“旧”或“参考”固件,而 BANK1_FLASH 构建配置被视为“新”固件。这两个应用程序在其他方面都是相同的。它们之间没有源代码差异;但是,新固件有 25 个已定义和已初始化的新浮点变量。这两个应用程序通过 TIDM-DC-DC-BUCK 解决方案工程的两个构建配置来实现 – 即 BANK0_FLASH 和 BANK1_FLASH。顾名思义,BANK0_FLASH 从闪存组 0 执行,BANK1_FLASH 从闪存组 1 执行。这两个构建配置共享相同的源文件,但包含不同的链接器命令文件。此外,在代码中的不同位置,宏“#ifdef BANK0”和“ifdef BANK1”控制执行,它们运行相同的控制循环 ISR 和后台任务。

以下是控制循环在 CPU 上运行时的简要 LFU 流程。

  1. 器件复位时,执行从默认引导至闪存入口点 0x80000 处开始,这是组选择逻辑函数所在的位置。此函数检查任一闪存组或这两个闪存组中是否存在有效的应用程序,如果存在一个,则选择较新的版本并转移到该地址(0x8EFF0 或 0x9EFF0)。这些是各个应用程序的 code_start 位置,执行从这里进入 C 运行时初始化例程 (_c_int00),并进入相应应用程序的 main()。如果这两个闪存组都不包含有效的应用程序,则执行将等待主机完成自动波特率锁定,并等待主机通过 SCI 发送映像。
  2. 用户通过 Windows 命令提示符调用 LFU 命令“8 Live DFU”。
  3. 目标器件在 SCI 接收中断 ISR 中接收命令 ID“0x700”。
  4. 在 main() 中,在后台循环中调用函数 BUCK_LFU_runLFU()。当命令 ID 与“0x700”匹配时,SCI 中断被禁用,执行分支到自定义引导加载程序中 Live DFU (liveDFU()) 函数的地址。如果组 0 中的应用程序正在执行,则分支到组 0 中的自定义引导加载程序(地址 0x81000)。如果组 1 中的应用程序正在执行,则分支到组 1 中的自定义引导加载程序(地址 0x91000)。
  5. 自定义引导加载程序中的 liveDFU() 从主机接收应用程序映像并将其编程到闪存中。完成后,执行取决于是否定义了宏 LFU_WITH_RESET。如果是,则看门狗配置为生成复位信号,然后启用,因此发生器件复位。如果未定义宏,则执行分支到新应用程序映像的 LFU 入口点。这是组 0 的 0x8EFF8 和组 1 的 0x9EFF8。这与常规的闪存启动入口点不同。

  6. 函数 c_int_lfu() 位于组 0 上的 0x8eff8 和组 1 上的 0x9eff8。该函数可在不复位器件的情况下执行 LFU 切换。在该函数中:
    1. 调用编译器的 LFU 初始化例程 (__TI_auto_init_warm())。这将初始化已指示为需要初始化的任何变量。因此,它将初始化在 BANK1_Flash 构建配置中定义的 25 个新浮点变量。
    2. 设置一个标志以指示 LFU 正在进行中。在 F28004x 上,这是使用软件变量 lfuSwitch 实现的。在 F28003x 上,这是通过使用 LFU_setLFUCPU() 设置 LFUConfig SysCtl 寄存器的 LFU.CPU 位实现的。
    3. 调用 main()
  7. 在 main() 中,初始化进程取决于 LFU 是否正在进行中。这是通过访问 F28003x 上的 LFUConfig SysCtl 寄存器的 LFU.CPU 位或 F28004x 上的 lfuSwitch 实现的。如果该值为 0,则初始化会像发生器件复位一样进行。

  8. 如果该值不为 0,则执行有限初始化。首先,执行 init_lfu()。该函数将代码从闪存复制到 RAM,对应于用户已指示需要从 RAM 运行的程序代码。接下来,在 F28003x 上,它使用 Shadow_Interrupt_Register() 更新停用的 PIE 中断向量表。在 F28004x 上,中断向量表交换硬件特性不可用,因此不执行该特性。在 F28003x 上,还会更新一组停用的函数指针。在 F28004x 上,RAM 块交换硬件特性不可用,因此不执行该特性。
  9. 接下来,将变量 lfuSwitch_start 设置为 Lfu_switch_wait_for_isr。执行在此等待,直到下一个控制循环 ISR 开始执行,其中 lfuSwitch_start 从 Lfu_switch_wait_for_isr 移到 Lfu_switch_ready_to_switch。这有助于将 LFU 切换同步到控制循环 ISR 的末端,从而最大限度地利用控制循环中断之间的空闲时间
  10. 当执行继续时,将发生 LFU 切换步骤。首先,禁用全局中断。在 F28003x 上,执行 PIE 中断向量表交换和 RAM 块交换。在 F28004x 上,每个使用的 PIE 中断向量都需要在此处单独更新。同样,每个函数指针都需要在此处单独更新。然后执行 C28x CPU 端堆栈指针初始化,并重新启用全局中断。这表示 LFU 切换结束
  11. 在短时间内禁用全局中断。如果在此期间发生外设中断,它将继续保持锁定状态,并在重新启用全局中断时中断 CPU。这样做是为了避免在以下情况(不太可能发生)下出现不可预测的行为:发生中断,以及在更新向量表之时访问此向量表。
  12. 图 3-9 显示了另一个 LFU 用例,其中将在固件升级期间更新控制循环参数。在实践中,这可以使用补偿设计器实时完成,这里提供了这方面的用例进行说明。这对应于 buck_F28004x_lfu_controlloop 工程。在此工程中,BANK0_FLASH 构建配置包含对应于较小增益 (Kdc = 4000) 的系数。BANK1_FLASH 构建配置包含对应于较大增益 Kdc=38904 的系数(请参阅 buck.h 中的函数 BUCK_initControlLoopGlobals())。当启用有源负载时,这会导致 BANK0_FLASH 编译配置的瞬态性能较差,而 BANK1_FLASH 编译配置的瞬态性能更好。如果器件已经包含与 buck_f28004x_lfu 工程(或甚至 CLA)对应的应用程序文件,则可以使用与上一节相同的 LFU 命令运行此更新,但与此工程对应的已更新的 .txt 名称除外,如表 3-1 所示。在 buck_f28004x_lfu_controlloop 工程中,在器件复位时(而不是在 LFU 切换之后)在 main() 中启用有源负载,因此在运行 LFU 后复位器件非常重要,可为执行此初始化提供便利。器件复位只需执行一次

    然后,用户可以使用 controlloop 工程可执行文件,在不复位器件的情况下执行其他 LFU 更新。

注:

目前,仅在 F28004x 上创建启用了有源负载的 Controlloop 示例。

GUID-20201112-CA0I-KQB6-BQBM-FQ0HBHJR1TRZ-low.png图 3-9 LFU 切换和瞬态性能改善(控制循环在 CPU 上运行)