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.

[参考译文] TM4C1230C3PM:通过 UART 配置和使用引导加载程序

Guru**** 2235160 points
Other Parts Discussed in Thread: TM4C1230C3PM
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/768934/tm4c1230c3pm-bootloader-configuration-and-use-via-uart

器件型号:TM4C1230C3PM

我将在基于 TM4C1230C3PM 的当前设计中添加引导加载程序。 我将 TivaWare 更新为最新版本(2.1.4.178)。 我编辑了 bl_config.h 文件、以反映我想要的引导加载方式(使用 PG4和 PG5上的 UART2通过引脚强制加载)。 下面显示的相关配置代码。 我遇到的第一个问题是 bl_main.c 引用了 UART_RX_PCTL 和 UART_TX_PCTL、因为它们在 BL_config.h 中定义了 UART_RXPIN_PCTL 和 UART_TXPIN_PCTL 在 TivaWare 版本中存在此错误似乎真的很奇怪。 我通过编辑 bl_main.c 来修复该问题、以匹配 bl_config.h 这允许我构建和刷写我的器件。 现在、我可以通过强制更新引脚成功控制执行。 低电平进入引导加载程序、高电平则加载我的应用程序并运行。 但是、我无法更新我的应用程序。 我不确定是因为我没有正确配置它、还是因为我使用的软件(还是其他东西?)。 我正在使用 LMFLASH 尝试通过串行进行更新。 查看旧 Stellaris 引导加载程序与 Tiva 引导加载程序的引导加载程序命令、我不能看到 LMFLAASH 无法工作的原因。 我也看不到任何与 LMFLASH 等效的程序。  

那么、总的来说、我的配置对于我尝试实现的目标是否合理、并且对于使用 TivaWare 引导加载程序进行串行更新是否有比 LMFLASH 更好的工具?

//
//
//用于为微控制器计时的晶体的频率。
//
//这定义了运行
//引导加载程序的微控制器所使用的晶振频率。 如果在生产时这是未知的、则使用
// UART_autobaud 特性来正确配置 UART。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
#define CRYSTICL_FREQ 16000000

//*********
//
//这可以将 LDO 电压升压到2.75V。 对于启用
PLL 的引导加载程序//配置(例如、使用以太网端口)
//对于具有 PLL 勘误表的器件,应启用此功能。 这适用于
//修订版 A2 Fury 级器件。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
//#define BOOST_LDO_VOLTAGE

//*********
//
//应用程序的起始地址。 这必须是1024
//字节的倍数(使其与页边界对齐)。 在
//这个位置应该有一个矢量表、而矢量表(位于
SRAM 中的堆栈、位于闪存中的复位矢量)的感知有效性被用作
应用程序映像的//有效性的指示。
//
//启动加载程序的闪存映像不得大于此值。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
#define APP_START_ADDRESS 0x00001000

//*********
//
//应用程序查找其异常向量表的地址。
//这必须是1KB 的倍数(使其与页边界对齐)。
//通常,应用程序将从其矢量表开始,此值
//将默认为 app_start_address。 提供此选项是为了满足
//从外部存储器运行的应用程序的需要,
而这些外部存储器可能无法被// NVIC 访问(矢量表偏移寄存器只有30位长)。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
#define VTABLE vstart_address 0x00001000

//*********
//
//闪存中单个可擦除页的大小。 这必须是电源
//为2。 1KB 的默认值表示
所有 Tiva MCU 上的内部//闪存的页大小、并且只有
在//配置引导加载程序以访问页面大小//
与此不同的外部闪存器件时、才应覆盖此值。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
#define FLASH_PAGE_SIZE 0x00000400

//*********
//
//闪存末尾要保留的空间量。 这必须是
1024字节的//倍数(使其与页边界对齐)。
当应用程序被更新时、这个//保留空间不会被擦除、从而提供
//可被用于参数的非易失性存储。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
//#define FLASH_RSVD_SPACE 0x00000800

//*********
//
//要为引导加载程序保留的堆栈空间字的数量。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
#define STACK_SIZE 64

/*************
//
//数据缓冲区中用于接收数据包的字数。 此
//值必须至少为3。 如果在 UART 上使用自动辅助、则必须为
//至少20。 最大可用值为65 (较大的值将导致
//缓冲区中未使用的空间)。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
#define buffer_size 20

//*****************
//
//启用对引导加载程序的更新。 更新引导加载


程序是一个不安全的//操作、因为它不是完全容错的(虽然部分路径会导致引导加载程序不再出现在//闪存中)。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
//#define ENABLE_BL_UPDATE

//*********
//
//此定义将导致引导加载程序在
//更新到引导加载程序时擦除整个闪存,或者
在//应用程序更新时擦除整个应用程序区域。 这会在
//更新固件之前擦除闪存中的所有未使用段。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
//#define FLASH_CODE_protection

//*********
//
//启用调用,以便在将下载的数据写入
//闪存之前对其进行解密。 参考引导加载程序源中的解密例程为空、
//它只是提供了一个用于添加实际解密器的占位符。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
//#define ENABLE_Decryption

//*********
//
//在 NMI 中断中启用对 MOSCFAIL 处理程序的支持。
//注意:Sandstorm 或 Fury 器件不提供 MOSCFAIL 复位、因此
不应为这些器件启用此//功能。
//
//取决于:无
//不包括:无
//要求:无
//
//*********
//#define ENABLE_MOSCFAIL_handler

//*********
//
//启用基于引脚的强制更新检查。 启用后、如果
引脚被读取
、引导加载程序//将进入更新模式、而不是调用应用程序、//处于特定极性、强制执行更新操作。 在任一种情况下、
//应用程序仍能将控制权返回给引导加载程序、以便
//开始更新。
//
//取决于:无
//不包括:无
//需要:Forced_update_Periph、Forced_update_port、Forced_update_PIN、
// Forced_update_polarity
//
////***************
#define ENABLE_UPDATE_CHECK

//*********
//
//要启用 GPIO 模块以检查强制更新。 这将
//是 SYSCTL_RCGCGPIO_Rx 值之一、其中 Rx 会对所需
的// GPIO 端口进行抑制。 这适用于 Blizzard 类以及用于 forced_update_port 的更高版本器件。
//
//取决于:enable_update_check
//不包括:none
// requss: none
//
//*********
#define forced_update_Periph sysctl_RCGCGPIO_R1

//*********
//
// GPIO 端口检查强制更新。 这将是
// GPIO_Portx_BASE 值之一,其中"x"替换为端口名称(如
// B)。 "x"的值应与
// Forced_update_Periph 的"x"的值匹配。
//
//取决于:enable_update_check
//不包括:none
// requss: none
//
//*********
#define Forced_update_port GPIO_PORTB_BASE

//*********
//
//检查强制更新的引脚。 这是一个介于0和7之间的值。
//
//取决于:enable_update_check
//不包括:none
// requss: none
//
//*********
#define Forced_update_pin 7

//*************
//
//导致强制更新的 GPIO 引脚的极性。 如果
引脚应该为低电平、这个值//应该为0;如果引脚应该为高电平、这个值应该为1。
//
//取决于:enable_update_check
//不包括:none
// requss: none
//
//*********
#define Forced_update_polarity 0

//*********
//
//这为强制更新中使用的 GPIO 引脚启用弱上拉。 如果
引脚应具有内部弱下拉电阻、则该//值应为0;
如果引脚应具有内部弱上拉电阻、则该//值应为1。
//只应定义 Forced_update_WPU 或 Forced_update_wpd,或两者都不应定义。
//
//取决于:enable_update_check
//不包括:none
// requss: none
//
//*********
//#define forced_update_WPU
//#define forced_update_wpd

//*********
//
//这使得能够使用 GPIO_LOCK 机制来配置
//受保护的 GPIO 引脚(例如 JTAG 引脚)。 如果未定义此值、
//将不使用锁定机制。 此
//功能的唯一合法值是 Fury 器件的 GPIO_LOCK_KEY 和不
支持此功能的 Sandstorm 器件以外的所有//其他器件的 GPIO_LOCK_KEY_DD。
//
//取决于:enable_update_check
//不包括:none
// requss: none
//
//*********
//#define forced_update_key GPIO_LOCK_KEY
//#define Forced_update_key GPIO_LOCK_KEY_DD

//*********
//
////选择 UART 作为与引导加载程序通信的端口。
//
//取决于:无
//不包括:CAN_ENABLE_UPDATE、ENET_ENABLE_UPDATE、I2C_ENABLE_UPDATE、
// SSI_ENABLE_UPDATE、USB_ENABLE_UPDATE
//需要:UART_autobaud 或 UART_FIXED_BAUDRATE、UART_CLOCK_ENABLE、
// UARTx_BASE、UART_RXPIN_CLOCK_ENABLE、UART_RXPIN_BASE、
// UART_RXPIN_PCTL、UART_RXPIN_POS、UART_TXPIN_CLOCK_ENABLE、
// UART_TXPIN_BASE、UART_TXPIN_PCTL 和 UART_TXPIN_POS
//
//*********
#define UART_ENABLE_UPDATE

//*********
//
//启用自动波特率检测。 如果晶振
//频率未知、或者需要以不同的波特率运行、则可以使用此参数。
//
//取决于:UART_ENABLE_UPDATE
//不包括:UART_FIXED_BAUDRATE
//要求:无
//
//*********
//#define UART_autobaud

//*********
//
////选择 UART 使用的波特率。
//
//取决于:uart_enable_update、crystal_FREQ
//不包括:uart_autobaud
//要求:无
//
//*********
#define UART_FIXED_BAUDRATE 115200

//*********
//
////选择 UART 外设模块的时钟启用
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UARTx_BASE
//
*********
#define UART_CLOCK_ENABLE SYSCTL_RCGCUART_R2

//*********
//
////选择 UART 外设模块的基址
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_CLOCK_ENABLE
//
*********
#define UARTx_BASE UART2_BASE

//*********
//
//为对应于 UART RX 引脚的 GPIO 选择时钟启用
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_RXPIN_BASE、UART_RXPIN_PCTL 和 UART_RXPIN_POS
//
*********
#define UART_RXPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R6

//*********
//
//为对应于 UART RX 引脚的 GPIO 选择基址
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_RXPIN_CLOCK _ENABLE、UART_RXPIN_PCTL 和 UART_RXPIN_POS
//
*********
#define UART_RXPIN_BASE GPIO_PORTG_BASE

//*********
//
//为对应于 UART RX 引脚的 GPIO 选择端口控制值
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_RXPIN_CLOCK_ENABLE、UART_RXPIN_BASE 和 UART_RXPIN_POS
//
*********
#define UART_RXPIN_PCTL 0x1

//*********
//
//为对应于 UART RX 引脚的 GPIO 选择引脚编号
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_RXPIN_CLOCK _ENABLE、UART_RXPIN_BASE 和 UART_RXPIN_PCTL
//
*********
#define UART_RXPIN_POS 4

//*************
//
//为对应于 UART TX 引脚的 GPIO 选择时钟启用
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_TXPIN_BASE、UART_TXPIN_PCTL 和 UART_TXPIN_POS
//
*********
#define UART_TXPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R6

//*********
//
//为对应于 UART TX 引脚的 GPIO 选择基地址
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_TXPIN_CLOCK _ENABLE、UART_TXPIN_PCTL 和 UART_TXPIN_POS
//
*********
#define UART_TXPIN_BASE GPIO_PORTG_BASE

//*********
//
//为对应于 UART TX 引脚的 GPIO 选择端口控制值
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_TXPIN_CLOCK_ENABLE、UART_TXPIN_BASE 和 UART_TXPIN_POS
//
*********
#define UART_TXPIN_PCTL 0x1

//*********
//
//为对应于 UART TX 引脚的 GPIO 选择引脚编号
//
取决于:UART_ENABLE_UPDATE
//不包括:none
//需要:UART_TXPIN_CLOCK _ENABLE、UART_TXPIN_BASE 和 UART_TXPIN_PCTL
//
*********
#define UART_TXPIN_POS 5. 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Jason、

    请撤消您所做的命名更改、TivaWare 是准确的。 在 bl_uart.h 文件中、您将找到定义如何链接在一起:

    //
    //
    ///这定义了引导加载程序正在使用的 UART 接收引脚。
    ////
    *****************
    #define UART_RX (1 << UART_RXPIN_POS)
    #define UART_RX_PCTL (UART_RXPIN_PCTL <<(4 * UART_RXPIN_POS))
    
    //*********
    //
    //定义引导加载程序正在使用的 UART 发送引脚。
    ////
    *****************
    #define UART_TX (1 << UART_TXPIN_POS)
    #define UART_TX_PCTL (UART_TXPIN_PCTL <<(4 * UART_TXPIN_POS)) 

    如果您将 bl_config.h 命名改回、它是否起作用?

    如果没有、您能描述如何连接到 LM 闪存吗? 您在两者之间使用的是 FTDI 芯片吗? 如果是、您是否已测试 UART 连接是否正确建立? 您可以通过修改 UART 回波示例来验证这一点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ralph、

    感谢您的回复... 周日!

    我使用的是具有 FTDI FT2232芯片组的 USB-RS232适配器。 我对所有布线都很有信心、因为我的应用使用相同的设置在同一 UART 外设上进行串行通信、而不会出现任何问题。  我使用终端来查看是否可以对 ping 命令(0x20)做出响应、但我没有得到任何回报。

    我将 bl_main.c 改回、它会生成(发现阻止编译的问题)、但仍然无法正常工作。 但是、成功的程度很小。 我已临时将一个 AckPack()硬编码到 BL_main.c 的 Updater 函数中,并且我确实接收它。 当我尝试发送 ping 命令时、我没有得到任何响应。

    我遇到的另一个问题是无法调试引导加载程序。 我在调试时会得到非常奇怪的活动。 调试时 PC 出现问题、我执行垃圾处理。 不过、我认为这与 IAR 设置完全相关。 如果我只是让引导加载程序在调试器之外运行、它的行为就像预期的那样。 最好能够进行调试、这样我就可以看到 UART/GPIO 寄存器、这将更好地帮助我解决问题。  

    谢谢、

    Jason

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Jason、
    如果闪存中只有引导加载程序(无应用程序代码)、并且如果您运行引导加载程序、它会下载应用程序吗?

    关于 PC 漂移、您能否在关闭优化的情况下重新编译引导加载程序? 有时、通过高度优化、程序计数器可以在您单步执行时跳转。 不确定这是不是你看到的问题,但值得先试。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Jason、
    我没有听到你的反馈。 您是否自行解决了该问题? 我现在要关闭这个线程。 如果您有新的问题、您可以打开新的主题、如果您需要进一步的阻力、也可以重新打开此主题。