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.

[参考译文] MSPM0G1507:启用 GPIO 引脚 PA8 输出仅在通过引导加载程序上载应用时才会挂起

Guru**** 2523320 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1555830/mspm0g1507-enabling-gpio-pin-pa8-output-hangs-the-application-only-when-it-is-uploaded-through-bootloader

部件号:MSPM0G1507


工具/软件:

您好、

在我的当前项目中、我开发了基于刷写的定制辅助 BSL 并使用它通过 UART 串行通信上传应用程序。

但我的目的是在器件上电时进入 BSL、这样我将 BSL 定位在 闪存的 0x00000000 处、位于应用程序代码 0x00002000 处。

在 BSL 应用程序内部、 PA8 用作 GPIO 输出并设置为高电平 以便启用“输出“UART IC 的功能并上传应用代码。 上传和验证 过程完成后、BSL 将跳转到有效的应用程序起始地址。

但在应用程序代码中、我发现一旦该 PA8 初始化为 GPIO 输出、程序就会“挂起“。 为了解决问题、我禁用了 PA8 数字输出 再次上传应用程序代码、即可正常运行。

奇怪的问题是我 如果我在没有引导加载程序的情况下直接刷写到器件、则可以启用 PA8 数字输出 在另一个器件上、即应用代码照常从 0x00000000 开始、应用代码再次正常工作。

因此、只有通过引导加载程序上传代码时、问题才会存在。  

原因是什么? 有什么我漏掉的吗? 请提前提出建议并表示感谢。 Slight smilePrayμ s

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

    您好、

    您使用哪个引脚来调用 BSL?

    马修

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

    你好,马修,我道歉的晚答复。
    我不使用 GPIO 调用 BSL。 BSL 位于 0x00000000、因此只要电源复位、就会调用 BSL。 我以这种方式来调用 BSL、即使应用程序挂起并且看门狗触发电源复位也是如此。  

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

    您能描述一下代码挂起时会发生什么情况吗?

    您能分享您的代码吗?

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

    您好、Matthew、  

    很抱歉我无法共享完整的应用代码、

    但这是 GPIO Init 函数(我在应用程序代码中实现的函数,而不是在  SYSCFG 中进行配置,以找出根本原因。)

    void Appl_Output_GPIO_Init ()
    {
        DL_GPIO_initDigitalOutputFeatures(IOMUX_PINCM19,
    		 DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
    		 DL_GPIO_DRIVE_STRENGTH_HIGH, DL_GPIO_HIZ_DISABLE);
    
        DL_GPIO_initDigitalOutputFeatures(IOMUX_PINCM14,
    		 DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
    		 DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_ENABLE);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM19);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM1);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM10);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM8);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM11);
    
        DL_GPIO_clearPins(GPIOA, DL_GPIO_PIN_8 |
        	DL_GPIO_PIN_7 |
    		DL_GPIO_PIN_0 |
    		DL_GPIO_PIN_5 |
    		DL_GPIO_PIN_3 |
    		DL_GPIO_PIN_6);
        DL_GPIO_setPins(GPIOA, DL_GPIO_PIN_7);
    
    
        DL_GPIO_enableOutput(GPIOA, //DL_GPIO_PIN_8 |
        	DL_GPIO_PIN_7 |
    		DL_GPIO_PIN_0 |
    		DL_GPIO_PIN_5 |
    		DL_GPIO_PIN_3 |
    		DL_GPIO_PIN_6);
    
    
    }

    如以上函数中所示、如果我像以上代码中的第 30 行注释掉了“启用输出“引脚 8、应用程序将成功运行、这意味着器件可以在 OLED 单色显示屏上连续显示测量数据。

    但如果我取消对此函数的注释、器件的 OLED 不会显示任何内容。

    为了验证这一点、我在调用此函数之前添加了 LED 闪烁功能、可以看到 LED 闪烁。

    但如果我将闪烁的 LED 函数放在这个 GPIO_Init 下面,那么我甚至无法在设备加电时看到闪烁的 LED。  

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

    您好、

    您能告诉我如何跳转到您的应用代码吗?

    马修

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

    您好、Matthew、  

    void CMD_API_startApplication(void)
    {
                //Check Marker Byte and Branch to app only it's correct
                if( (*(uint8_t*)(APP_UPDATE_MARKER_BYTE_ADDRESS))==APP_UPDATE_MARKER_BYTE)
                {
                    /* Start application */
                    DL_SYSCTL_resetDevice(SYSCTL_RESETLEVEL_LEVEL_BOOT);     
                    /* Wait until reset happens */
                    while (1)
                        ;
                }
    }

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

    确保 VTOR 指向应用程序内存的起始位置。 下面的示例说明了如何操作:  

    dev.ti.com/.../node

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

    您好、Matthew、  

    感谢您的答复。  
    我实际上将启动文件复制并粘贴到工程目录中、在 SYSCFG 文件中取消选中“Startup file Reference“、这是我在 startup .c 文件的 ResetHandler 函数中添加的内容。

    /* Forward declaration of the default fault handlers. */
    /* This is the code that gets called when the processor first starts execution */
    /* following a reset event.  Only the absolutely necessary set is performed,   */
    /* after which the application supplied entry() routine is called.  Any fancy  */
    /* actions (such as making decisions based on the reset cause register, and    */
    /* resetting the bits in that register) are left solely in the hands of the    */
    /* application.                                                                */
    void Reset_Handler(void)
    {
        /* Jump to the ticlang C Initialization Routine. */
        SCB->VTOR = (volatile uint32_t) interruptVectors;
        __asm(
            "    .global _c_int00\n"
            "    b       _c_int00");
    }

    这是我用于应用程序的.cmd 文件。

    /*****************************************************************************
    
      Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
    
      Redistribution and use in source and binary forms, with or without
      modification, are permitted provided that the following conditions
      are met:
    
       Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    
       Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the
       distribution.
    
       Neither the name of Texas Instruments Incorporated nor the names of
       its contributors may be used to endorse or promote products derived
       from this software without specific prior written permission.
    
      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    *****************************************************************************/
    -uinterruptVectors
    --stack_size=512
    
    MEMORY
    {
        INT_VECS		(RX)  : origin = 0x00002000, length = 0x000000C0
        FLASH           (RX)  : origin = 0x000020C0, length = 0x0001DF40
        SRAM            (RWX) : origin = 0x20200000, length = 0x00008000
        BCR_CONFIG      (R)   : origin = 0x41C00000, length = 0x00000080
        BSL_CONFIG      (R)   : origin = 0x41C00100, length = 0x00000080
    
    }
    
    SECTIONS
    {
        .intvecs:   > INT_VECS
        .marker:  > 0x0001FFF0
        .text   : palign(8) {} > FLASH
        .const  : palign(8) {} > FLASH
        .cinit  : palign(8) {} > FLASH
        .pinit  : palign(8) {} > FLASH
        .rodata : palign(8) {} > FLASH
        .ARM.exidx    : palign(8) {} > FLASH
        .init_array   : palign(8) {} > FLASH
        .binit        : palign(8) {} > FLASH
        .TI.ramfunc   : load = FLASH, palign(8), run=SRAM, table(BINIT)
    
        .vtable :   > SRAM
        .args   :   > SRAM
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM (HIGH)   
    
        .BCRConfig  : {} > BCR_CONFIG
        .BSLConfig  : {} > BSL_CONFIG
    }


    我在 cmd 文件中找到位于 0x00002000 的应用程序中断矢量、该文件是正确的应用程序所在的位置。

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

    您的问题是否已解决? (我离开办公室一段时间,因此我对延误表示歉意)