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.

[参考译文] Starterware/EK-TM4C1294XL:通过串行端口进行固件升级时出现异常行为。

Guru**** 2443910 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/630028/starterware-ek-tm4c1294xl-firmware-upgrade-via-serial-port-shows-anomalous-behavior

器件型号:EK-TM4C1294XL

工具/软件:Starterware

大家好、我已经尝试并研究了 TM4C1294Xl launchpad 示例文件夹中提供的引导加载程序示例。 在我的示例中、我尝试使用 API " ROM_FlashProgram (((uint32_t *)&FirmwareData、ui32ProgAddr、4)"来刷写固件字节(成功构建后在 bin 文件中生成的字节)。  USB_stick_update 示例中对此进行了说明。


串行获取 TIVAC 上 UART3上的字节、然后按预期成功地将其写入所需的存储器块。  

执行所有此操作的代码存储在存储器位置0x000中、接收到的串行数据存储在位置0x00011F40中。

在我的示例 中、我尝试刷写默认闪烁代码的应用程序启动 ADDR 更改为0x00011F40后生成的 bin 文件。  

现在、在闪存字节后、我还通过 LM 闪存编程器中的"Verify flash contents "选项验证存储器的内容。

到目前为止一切都很完美。

这是代码

代码1.

uint_fast32_t ui32ProgAddr = 0x00011F40;
void CallApplication (uint_fast32_t ui32StartAddr)
{
HWREG (NVIC_vtable)= ui32StartAddr;
_asm (" LDR r1、[r0]\n"
" mov SP、R1\n");
_asm (" LDR r0、[r0、#4]\n"
" BX r0\n");
}
int
main (void)
{

G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |SYSCTL_OSC_MAIN |SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480)、120000000);

SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0);
// //
SysCtlPeripheralEnable (SYSCTL_Periph_UART3);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
GPIOPinTypeGPIOOutput (GPIO_Porta_base、GPIO_PIN_6);
GPIOPinWrite (GPIO_Porta_base、GPIO_PIN_6、GPIO_PIN_6);
GPIOPinConfigure (GPIO_PA4_U3RX);
GPIOPinConfigure (GPIO_PA5_U3TX);
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_4 | GPIO_PIN_5);
UARTConfigSetExpClk (UART3_base、g_ui32SysClock、115200、(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

// ////

//
while (1)
{
if (APPflag = set) CallApplication (APP_START_ADDRESS);
while (UARTCharsAvail (UART3_base))
{
i++;
RDATA[i]= UARTCharGetNonBlocking (UART3_base);
Updatefirmware(i);//此函数将写入内存,并在写入所有字节时设置 APPflag
}
}

成功刷写后被调用的 CallApplication 函数中出现了问题。

HWREG (NVIC_vtable)= 0x00011F40;
_asm (" LDR r1、[r0]\n"
" mov SP、R1\n");
_asm (" LDR r0、[r0、#4]\n"
" BX R0\n");

现在观察到的结果是 LED 快速闪烁。 现在、这是我所讨论的异常行为。

我在 CCS 调试中选择了闪存必要页面选项、并将以下代码刷写到 TIVAC 中。

代码2.

#define APP_START_ADDRESS 0x00011F40
int
main (void)
{

ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOJ);
ROM_GPIODirModeSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_DIR_MODE_IN);
MAP_GPIOPadConfigSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);

SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPION))
{
}

GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0);
GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_1);
while (1)
{
if (ROM_GPIOPinRead (GPIO_PORTJ_BASE、GPIO_PIN_0)=0)
{
CallApplication (APP_START_ADDRESS);
}
}

void CallApplication (uint_fast32_t ui32StartAddr)
{
HWREG (NVIC_vtable)= ui32StartAddr;
_asm (" LDR r1、[r0]\n"
" mov SP、R1\n");
_asm (" LDR r0、[r0、#4]\n"
" BX R0\n");
}

注意: 此时、我将上述代码(CODE2)从0x000开始、并将之前代码(CODE1)的闪存 bin 文件内容从0x00011F40开始(因为我选择了仅在 CCS 调试中擦除必要页面)

在运行 CODE2后、执行过程完全转到 APP_START_ADDR、在我的示例中为0x00011F40、并且 blinky 完全执行。

本实验验证我用于写入闪存存储器(CODE1)的程序是否工作正常。 但是当我尝试在 CODE1中调用 CallApplication()时,它会显示程序的异常执行,当我尝试从 CODE2调用 CallApplication()时,该程序运行得非常好。 我不确定如何调试这种问题。

此致、  

Nishit。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    问题是与映射文件有关还是与 TIVAC 的引导顺序有关?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Nishit、您好!

    对于一个、

    if (APPflag = set) CallApplication (APP_START_ADDRESS); 

    这是错误的编码、可能会导致奇数错误、请尝试使用:

    if (APPflag = set)
    {
    CallApplication (APP_START_ADDRESS);
    } 

    第二, 关于 APPflag,在哪里设置它? 我不清楚您的代码1示例的流程。

    第三、每当我听到 LED 快速闪烁时、我认为预期 CPU 频率和实际 CPU 频率之间存在不匹配。 您的 Blinky 代码是否完全包含 SysCtlClockFreqSet 配置?

    查看代码1和代码2、代码2没有 SysCtlClockFreqSet 配置、但代码1有。  代码1中的 SysCtlClockFreqSet 是否会将时钟设置得比闪烁代码所期望的快?

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

    ***类似***  (不知为何-仍然找不到“相似”按钮!)

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

    [引用 USER="Ralph Jacobi"]注意到了 if (APPflag == set){ CallApplication (app_start_address);}。

    [引用 user="Ralph Jacobi">关于 APPflag,该设置在哪里? 我不清楚您的代码1示例的流程。

    该标志已在 Updatefirmware()例程中设置。

    void Updatefirmware (int cnt)
    {
    //
    *对从 UART 接收到的数据进行一些计算
    *然后在正确的存储器地址写入正确的字节,直到写入所有字节
    *这是由 ROM_FlashProgram ((uint32_t *)&FirmwareData、ui32ProgAddr、4)完成的;
    *在所有字节都被写入后、按如下所示设置 APPflag
    */
    APPflag = set;
    } 

    [引用 USER="Ralph Jacobi"]我认为预期 CPU 频率和实际 CPU 频率之间存在不匹配[/引用]

    好的。 我将了解一下这个。

    还有一件我不知道的事-这两个复位是否执行相同的功能?
    1. HWREG (NVIC_APINT)= NVIC_APINT_VECTKEY |NVIC_APINT_SYSRESETREQ;
    2.按下板载复位按钮。

    当上述过程被单独执行时、CPU 确切地做了什么(在执行流程、寄存器(SP 和 PC)电平、矢量表移位等方面)? 有关这两个方面的文档不足。 我对那个很好奇。

    此致、
    Nishit。

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

    非常感谢您的观看。 没有任何问题。 执行和代码工作正常。 LED 具有不同的频率、这就是它具有该行为的原因。

    正如 CB1_MOBILE 一直说的那样、"应该存在一个类似的按钮。"

    感谢 Ralph 和 CB1_MOBILE、感谢您快速回复并每次提供要点答案。

    此致、

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

    对你来说很好-很高兴你专注-坚持-接受的方向... 成功!

    特别好,感谢拉尔夫。 (谁"超越"努力提供帮助!)

    现在、在您的写作中、"LED 有不同的频率"-您是说"闪烁频率"-完全在您的控制下-是"太快"-还是 Ralph 闪耀的"系统时钟"(自身)已经改变-(导致闪烁速率高于预期的原因?)

    不久之后、"您"就能在这里帮助他人-(也许)论坛独裁者会"重新确定(如此)有价值/被寻求的人、就像!"
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    [报价 USER="CB1_MOBIT"]系统时钟"(自身)已更改-(闪烁速率高于预期的原因?)[/QUERP]

    是的。 这正是发生的事情。 我通过设置我在 CODE1中使用的时钟来更改默认闪烁示例、并将该代码刷写到微控制器中并观察输出。 我观察到的是 LED 以相同的快速速率闪烁。 因此、由于控制器以不同的频率运行、因此异常行为实际上是正确的。   

    此外、请指导我回答另一个问题、

    1. HWREG (NVIC_APINT)= NVIC_APINT_VECTKEY |NVIC_APINT_SYSRESETREQ;
    2.按下板载复位按钮。

    当上述过程被单独执行时、CPU 确切地做了什么(在执行流程、寄存器(SP 和 PC)电平、矢量表移位等方面)? 有关这两个方面的文档不足。 我对那个很好奇。

     

    谢谢、  

    Nishit。

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

    [引用 user="Nishit"] CPU 的确切作用是什么(在执行流程、寄存器(SP 和 PC)级别、矢量表移位等方面)

    公司和我与多家 ARM MCU 合作-来自多家供应商-因此我没有"准确"的详细信息、"准备就绪"。

    这最好由供应商员工回答-他们"免费"限制他们的注意力"。   ("一个也只有一个"(供应商器件行为)是其章程!)

    请注意、如果(真的)有兴趣-您不能-通过"kiss"进行实验-并"证明"您寻求的"确切性"?

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

    您好!

    好的、因此根据我的观察结果和数据表中提供的细节信息、它确认每当按下复位按钮时、CPU 都会检查是否有一个有效的 PC 和 SP 值加载到闪存位置0x0和0x4中。 如果是、则用户按下复位按钮后立即执行该程序。 如果位置为0xFF、即未编程、则 PC 和 SP 值从 ROM 的存储器位置加载(这些是预定义的位置)。   

    现在,我的问题是,我是否可以通过软件(API 调用)来描述这种确切的行为?

    其次、当执行该特定语句时、执行会发生什么变化?

    HWREG (NVIC_APINT)= NVIC_APINT_VECTKEY |NVIC_APINT_SYSRESETREQ; 


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

    Nishit、您好!

    [引用用户="Nishit"]

    1. HWREG (NVIC_APINT)= NVIC_APINT_VECTKEY |NVIC_APINT_SYSRESETREQ;

    2.按下板载复位按钮。

    [/报价]

    案例1是软件复位。

    情况2是通过外部复位输入引脚(~RST)进行复位。

    数据表文档是从221页开始的第5.2.2节中为这些事件提供的信息的范围。 我不是完全清楚通过了解确切的 CPU 流程、您将获得什么?

    对于一些已添加的信息、下面是另一位专家对过去 E2E 帖子的描述(请注意、CM4 = Cortex-M4):"加电后、CM4从 ROM 执行代码。 外设/系统寄存器复位为默认值、CM4未分配默认值。 然后、它会检查闪存应用程序代码、如果它没有看到应用程序代码、它会有 ROM 引导加载程序来搜索串行接口以查找引导映像。 如果闪存中有一个有效的应用程序代码(检查是查看0x0和0x4的位置以查看似乎有效的 SP-PC)、它将跳转到闪存映像。"