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.

[参考译文] UCD3138064:引导加载程序到应用问题

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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1497905/ucd3138064-bootloader-to-app-question

器件型号:UCD3138064
Thread 中讨论的其他器件: UCD3138UCD3138128

工具/软件:

尊敬的 Sirs:

我有疑问:由于 CRPS2.0要求、我需要开发引导加载程序。 目前、固件下载和闪存写入操作正常运行、应用程序(APP)可以独立运行。 但是、引导加载程序会禁用中断并跳转到 APP (位于闪存分区0x2000-0xFFFF、而引导加载程序占用0x0000-0x1FFF)后、应用程序将无法正常工作。 ​在将控制权移交给应用程序之前、引导加载程序应执行哪些关键步骤?

引导加载的代码如下所示:

void main()

MiscAnalogRegs.CLKTRIM.bit.HFO_LN_FILTER_EN = 0;
read_dflash_modelName_message();
read_dflash_upload_message();
Volatile Uint32 check_sum=*(volatile Uint32 *) 0x0000fffc;
if ((BootLoaderStructRam.UpdateMode==0)&&(check_sum==(calculate_checksum (0、0xfffc))))

JumpToApp (FLASHPROGRAMBASE);//0x2000
}
暴露

Firmwares Update_Handler ();

}

}

typedef void (* AppEntry)(void);

void JumpToApp (Uint32 app_address)

disable_interrupt ();
disable_fast_interrupt ();


AppEntry app_entry =(AppEntry)(*(volatile uint32_t *) app_address);


app_entry();
}

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

    您好 Rex、

    我不会在 main 函数中处理像引导加载程序这样的问题。 我们有一个专用的软件中断处理程序、用于代码 访问敏感寄存器(例如数据闪存)。 尝试在中实现此功能  software_interrupt.c 添加到工程。

    有关软件中断的更多说明、请参阅该 E2E 文章: https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1495205/ucd3138128-program-flash-erase-issue 

    作为 si示 例、您可以点击在 E2E 中输入 C 代码 插入-->代码 然后选择  C 基准噪声值。 下面是的一个片段 software_interrupt.c 更新固件中进行更新。

    #include "function_definitions.h"
    #include "software_interrupts.h"
    #include "pmbus_common.h"
    
    extern Uint32 zero_out_integrity_word_1_start[32];
    extern Uint32 zero_out_integrity_word_2_start[32];
    extern Uint32 clear_program_flash_1_start[32];
    extern Uint32 clear_program_flash_2_start[32];
    extern Uint32 block_switch_at_startup_start[32];
    
    
    #pragma INTERRUPT(software_interrupt,SWI)
    void software_interrupt(Uint32 arg1, Uint32 arg2, Uint32 arg3, Uint8 swi_number)
    //void software_interrupt(Uint32 *address, Uint32 data, Uint32 more_data, Uint8 swi_number)
    {
    	//make sure interrupts are disabled
    
    	 asm(" STMFD SP!, {R4} "); //Store R4
    
    	 asm(" MRS r4, cpsr "); // get psr
    
    	 asm(" ORR r4, r4, #0xc0 "); // set interrupt disables
    
    	 asm(" MSR cpsr_cf, r4"); // restore psr
    
    	 asm(" LDMFD SP!, {R4} "); //Restore R4
    
    
    	switch (swi_number) //handle flash write/erase and ROM backdoor first
    	{
    		case 0: 
    	//--------------------------------------------------------------------------------------
    	// SWI ALIAS: erase_data_flash_segment()
    	// 	Erases one segment of Data Flash and wait for erase to complete.
    	//--------------------------------------------------------------------------------------
    		case 1: 	
    	//--------------------------------------------------------------------------------------
    	// SWI ALIAS: erase_dflash_segment_no_delay()
    	// 	Erase one segment of Data Flash and return without waiting for completion.
    	//--------------------------------------------------------------------------------------
    		{
    
    	        union DFLASHCTRL_REG dflashctrl_shadow;	// Shadow copy of control register
    			
    			if (arg1 >= DATA_FLASH_NUM_SEGMENTS)	
    			{
    				return;		// Invalid segment number
    			}
    			while(DecRegs.DFLASHCTRL.bit.BUSY != 0)
    			{
    				; //wait in case it's already programming
    			}
    			DecRegs.FLASHILOCK.all = 0x42DC157E; //unlock flash write;
      			// Set the bits in the Data Flash Control Register to erase the indicated segment
    			dflashctrl_shadow.all = DecRegs.DFLASHCTRL.all;	// Read the hardware register
    			dflashctrl_shadow.bit.PAGE_ERASE = 1; 			// Erase one segment
    			dflashctrl_shadow.bit.PAGE_SEL = arg1;		// Segment number
    			DecRegs.DFLASHCTRL.all = dflashctrl_shadow.all;	// Write the hardware register
    			if (swi_number == 1)	// 0= Wait for erase to complete, 1= return immediately
    		    {
    			  return;
    		    }
    
    			return;
    		
    		}

    此致、

    Jonathan Wong

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

    您好 Rex、

    我将在一周结束前作出答复。

    此致、

    Jonathan Wong

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

    您好 Rex、

    您是否看到过我们针对 UCD3138064的动态更新示例? 下面是 Ian Bower 的一篇文章、其中演示了这些步骤。 如果您对代码感兴趣、请告诉我。

    e2e.ti.com/.../On_2D00_the_2D00_fly-power-supply-firmware-upgrades.docx

    UCD3138064只有64KB 程序闪存。 如果我的理解正确、那么您不是在两个程序之间切换、而是从引导 ROM 转到应用程序?

    此致、

    Jonathan Wong

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

    您好 Jonathan、

    是的、由于容量限制、我不需要动态功能。 我当前的问题是跳转到应用程序后、引导加载程序无法正常工作。 所以,我的问题是:我的跳转代码是正确的吗? 如果方便、 您可以 与我共享您的动态代码、因为它包含跳转逻辑。 这将帮助我加深对 UCD3138跳转机制的理解!谢谢!

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

    您好 Rex、

    请接受朋友的请求、以便我可以与您共享即时更新固件。  

    我认为跳转代码不正确。 我认为还需要更多的资源。 本文重点介绍了如何在 Cortex-M0处理器上实现引导加载程序: https://interrupt.memfault.com/blog/how-to-write-a-bootloader-from-scratch 

    (UCD3138064是较旧的 ARM7TDMI-S 内核。  有关详细信息、请参阅 en.wikipedia.org/.../List_of_ARM_processors)。

    根据我的理解、您的  main() 功能如下:

    void main()
    {
        MiscAnalogRegs.CLKTRIM.bit.HFO_LN_FILTER_EN = 0;
        read_dflash_Modelname_message();
        read_dflash_upload_message();
        volatile Uint32 check_sum=*(volatile Uint32 *)0x0000fffc;
        if((BootLoaderStructRam.UpdateMode==0)&&(check_sum==(calculate_checksum(0,0xfffc))))
        {
            JumpToApp(FLASHPROGRAMBASE); //0x2000
        }
        else
        {
            FirmwareUpdate_Handler();
        }
    }

    您的  JumpToApp() 下方的传递函数

    typedef void (*AppEntry)(void);
    
    void JumpToApp(Uint32 app_address)
    {
        disable_interrupt();
        disable_fast_interrupt();
    
        AppEntry app_entry = (AppEntry)(*(volatile Uint32*)app_address);
        app_entry();
    }

    我认为您需要将此引导加载程序放入软件中断处理程序中。 访问数据闪存和程序闪存等敏感位置最好在软件中断中处理。 请参阅以下 E2E 了解 ARM 模式与 Thumb 模式: https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1495205/ucd3138128-program-flash-erase-issue 

    我也不确定您的校验和是否正确计算。 默认程序闪存校验和设置被32kB 块分开。 由于您使用的是在2个块之间拆分的53KB、因此即使64KB 中也包括引导加载程序、也可能会计算整个64KB 中的校验和。

    编程闪存地址 对闪存内容进行编程 尺寸小
    0x0000 引导加载程序启动
    0x1fff 引导加载程序结束 ~8kB
    0x2000 应用程序启动
    0xF400 应用端 ~53KB
    0xFFFF

    在上面的示例中、假设您有一个8kB 引导加载程序并在地址0x2000处启动该应用。 校验和可能不是仅仅计算53KB 范围的校验和、而是计算整个64KB 块、包括校验和+引导加载程序。

    下面是一些问题:

    • 您将输入到引导加载程序中的 APP_ADDRESS 是什么?
    • 什么是 AppEntry 类型? 这只是将 APP_ENTRY 转换为指向应用地址位置的指针吗?
    • 什么是 app_entry()函数?

    此致、

    Jonathan Wong

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

    您好 Rex、

    我已通过直接消息向您发送了动态更新固件。  

    对于 UCD3138064引导加载程序、我还收到了几个问题和想法:

    1. 此代码在哪一行出现故障? 生产线是否 
          if((BootLoaderStructRam.UpdateMode==0)&&(check_sum==(calculate_checksum(0,0xfffc))))
      正常工作? 这似乎是失败的最接近的代码。
    2. 您的  JumpToApp() 功能看起来正常。 尝试在不使用 if 语句的情况下运行引导加载程序代码、并查看是否是  JumpToApp() 执行函数。 如果是、那么我认为您的问题是校验和计算
    3. 为什么根据计算校验和  0 - 0xfffc ?  
    4. 提供了什么功能  固件 Update_Handler () 作用吗?
    5. 您的存储位置  设置自动扭矩  可以吗?  
      1. 您可以通过查看链接器文件找到程序存储的默认位置。 以下是的部分 Cyclone_64.cmd UCD3138064的链接器文件。 。  .text section 指定程序位置。 您可以将其设置为0x2000、以确保应用代码从0x2000开始。 然后、您可以查看  .map 此文件经过编译、用于仔细检查地址是否正确。
      2. /*==========================================================================================
        // cyclone.cmd  Linker command file for Cyclone
        //
        // In addtion to the memory sections specified here, functions existing in the ROM
        // are specified by RomFuncs.cmd which is automatically generated in the ROM build
        // process.
        //
        //    Available Cyclone memory:
        //    ---------------------------------
        //    P-Flash   32K   0x0000  - 0xFFFF
        //    ROM       8K    0xA000  - 0xBFFF	 
        //    D-Flash   2K    0x18800 - 0x18FFF
        //    RAM       4K    0x19000 - 0x19FFF
        //
        // Copyright (C) 2008 Texas Instruments Incorporated.
        //========================================================================================*/
        
        MEMORY
        {
        
            VECS           : org = 0x00000000, len = 0x00000020    /* Vector table                */
            /*------------------------------------------------------------------------------------*/
            /* ROM       8K    0xA000 - 0xBFFF                                                    */
            /*------------------------------------------------------------------------------------*/
            ROM     : org = 0x00020020   len = 0x00000FE0  /* SYSTEM ROM    */
        	SINE	: org = 0x00021000   len = 0x00000282  /*sine table in ROM */
        	EXP	: org = 0x00021282   len = 0x0000007A  /*exponent table in ROM */
        
            /*------------------------------------------------------------------------------------*/
            /* P-Flash   32K   0x0  - 0x7FFF                                                   */
            /*------------------------------------------------------------------------------------*/
            PFLASH    (RX) : org = 0x00000020, len = 0x00007F38    /* PFlash Main Program         */
            DEVICEID  (RX) : org = 0x00007F58, len = 0x00000020    /* Fixed Location for DEVICE_ID*/
            FIXTFA    (RX) : org = 0x00007F78, len = 0x00000004    /* Fixed Step Size for TFA     */
            FIXCONST  (RX) : org = 0x00007F7C, len = 0x00000080    /* Fixed-location Constants    */
            FLASHSUM  (RX) : org = 0x00007FFC, len = 0x00000004    /* Flash Checksum              */
        
        
            /*------------------------------------------------------------------------------------*/
            /* D-Flash   2K    0x18800 - 0x18FFF                                                  */
            /*------------------------------------------------------------------------------------*/
            DFLASH    (RX) : org = 0x00068800, len = 0x00000800
        
            /*------------------------------------------------------------------------------------*/
            /* RAM       4K    0x19000 - 0x19FFF                                                  */
            /*                                                                                    */
            /*    Partition RAM into four parts:                                                  */
            /*     1. Fixed at the start of RAM are tester variables.                             */
            /*        that can not move without breaking the tester.                              */
            /*     2. General variables.                                                          */
            /*     3. Stacks for the various operating modes.                                     */
            /*        NOTE!!  Stack size must be specified in build options too!!!                */
            /*     4. The interlock used to prevent rom from returing to flash - rom_flash_lock.  */
            /*------------------------------------------------------------------------------------*/
            RAM       (RW) : org = 0x00069000, len = 0x00001000
        }
        
        SECTIONS
        {
            /*------------------------------------------------------------------------------------*/
            /* P-Flash   32K   0x0  - 0x7FFF                                                   */
            /*                                                                                    */
            /*   Most of these sections are unused for the ROM build.                             */
            /*------------------------------------------------------------------------------------*/ 
        
            .fiq            : {} > 0x001C                    /* Fast Interrupt Handler            */
            .text           : {} > (PFLASH align(16))        /* Code                              */
            .const          : {} > (PFLASH align(16))        /* Constant data                     */
            .cinit          : {} > (PFLASH align(16))        /* Initialization tables             */
             FixedDeviceID  : {} > (DEVICEID)                /* Fixed location for Device ID      */
             FixedTfaStep   : {} > FIXTFA                    /* Fixed location TFA Step Size      */
             FixedConstants : {} > FIXCONST                  /* Fixed location constants          */ 
            .flashi         : {} > FLASHSUM                  /* PFlash Integrity Word             */
        
            /*------------------------------------------------------------------------------------*/
            /* ROM (8kB   0xA000 - 0xBFFF                                                         */
            /*------------------------------------------------------------------------------------*/
            .vectors        : {} > VECS
            .sine           : {} > SINE
        
            /*------------------------------------------------------------------------------------*/
            /* D-Flash   2K    0x18800 - 0x18FFF                                                  */
            /*------------------------------------------------------------------------------------*/
             .dflash   : {} > (DFLASH align(32))
        		//data flash
        	.CONFIG    : {} > (DFLASH align(32))
            .CONFIG_A  : {} > (DFLASH align(32))
            .CONFIG_B  : {} > (DFLASH align(32))
        	.PASSW     : {} > (DFLASH align(32))
            /*------------------------------------------------------------------------------------*/
            /* RAM       4K    0x19000 - 0x19FFF                                                  */
            /*------------------------------------------------------------------------------------*/
            .bss            : {} > RAM                       /* Global & Static vars              */
        
        }
    6. 关于如何将 UART 用作引导加载程序的未发布指南: e2e.ti.com/.../BootFlash_5F00_001.docx
      1. 有关代码示例、请参阅第3节和第4节
      2. load.asm 变化
        1.     .global rom_main
              .global _boot_upload_fw_vec
          rom_main .equ 0xffffa4dc
          ; these three lines are added for ti_uart_boot_loader option
              .sect ".bvectors"
              ; boot vectors - mostly go to vectors in main program flash.
              .state32
          _boot_upload_fw_vec
              .sect ".vectors"
              .state32
                  B c_int00
      3. Cycloner.cmd 更改(这是 UCD3138的链接器)
      4. main.c 变化

    此致、

    Jonathan Wong

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

    您好 Rex、

    由于您的问题仍然存在、下面提供了另一个建议来帮助您编写代码。

    我们有一个用于 UCD3138064和 UCD3138128示例代码的 UART 引导加载程序。 这是有关 UART bootflash 的暂定应用手册。 我直接向您发送了示例代码。

    e2e.ti.com/.../BootFlash_5F00_001.pdf

    此致、

    Jonathan Wong

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

    感谢您的帮助、我已解决了这个问题。