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.

[参考译文] CCS/RM48L952:有关闪存 API 的 RM48 UART 引导加载程序问题

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/629032/ccs-rm48l952-rm48-uart-bootloader-question-regarding-flash-api

器件型号:RM48L952

工具/软件:Code Composer Studio

您好!

我正在尝试将 UART 引导加载程序项目集成到我的设计中。 我成功接收到第一个数据包(通过 YMODEM)、但无法通过 F021闪存 API 初始化闪存。 我可以单步执行代码、当它调用 Fapi_setActiveFlashBank()时它会失败、并在未定义指令中断(0x0004)处结束。

不过、我认为这有点令人发指的是、因为在其他帖子中进行读操作听起来好像我的闪存 API 可能不会复制到 RAM 中并从中执行。 人们建议在.cmd 文件中使用 ramfuncs 定义、但我完全不知道如何执行此操作、我还觉得 UART 引导加载程序项目可能已经设置了此设置?

有人能否提供一些有关如何将 F021闪存 API .lib 链接到工程中的见解? 我很确定这就是我的问题所在。

这是我的.cmd 文件:

//
//
// bl_link.cmd:链接器命令文件
//作者 :王杰。 qjwang@ti.com
//日期 :2012年9月19日
//
版权所有(c) 2006-2011 Texas Instruments Incorporated。 保留所有权利。
//软件许可协议
//
//德州仪器(TI)提供此软件仅供
和//仅供 TI 的微控制器产品使用。 软件归
// TI 和/或其供应商所有,并受适用的版权
//法律保护。 您不能将此软件与"病毒"开源
//软件组合在一起以形成更大的程序。
//
//此软件按“原样”提供,且存在所有故障。
//对于

本软件,不作任何明示、暗示或法定的保证,包括但不限于对适销性和适用性的暗示保证//特定用途。 在任何
//情况下、TI 不对任何
原因造成的特殊、意外或必然//损害负责。
////
*****************


--retain="*(.intvecs)"


内存
{
向量(X):origin=0x00000000 length=0x00000200
BOOT_LOAD (RX):origin=0x00000200 length=0x00001000
Flash_API (RX):origin=0x00001200 length=0x00001000
FLASH0 (Rx):origin=0x00002200 length=0x00018000
FLASH1 (Rx):origin=0x00020000 length=0x00060000
FLASH2 (Rx):origin=0x00080000 length=0x00080000
FLASH3 (Rx):origin=0x00100000 length=0x00080000
FLASH4. (Rx):origin=0x00180000 length=0x00080000
SRAM (RW):origin=0x08002000 length=0x0002D000
堆栈 (RW):origin=0x08000000 length=0x00001FF0
// RSV (RW):origin=0x08000000 length=0x00000010 fill=0
}
SECTIONS
{
.intvecs :{}> vectors

//boot_code :{..\Release\sys_core.obj (.text)}> boot_load
///eabi_start :{..\Release\sys_startup.obj (.text)}> boot_load_obj (.text
):{.boot_load.obj (.obj .text




//..\Release\BL_FLASH.obj (.text)
//..\Releases\Fapi_UserDefinedFunctions.obj (.text)
bl_flash.obj (.text)
fapi_UserDefinedFunctions.obj (.text)
//--library= F021_API_CortexR4_LE.lib <FlashStateMachine.obj
--library=.\lib\f021_API_CortexR4_LE.lib (.text)
}load = flash_API、run = SRAM、load_start (api_load)、run_start (api_run)、size (api_size)

.text > FLASH0
.const > FLASH0
.cinit > FLASH0
.pinit > FLASH0
.data > SRAM
.bss > SRAM
}

感谢您提供的任何帮助。

-Brian

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

    RM48有2个闪存组。 如果您的闪存 API 相关代码位于 bank0、并且您希望擦除 bank0的扇区、则必须将闪存 API 相关代码复制到 SRAM 并在 SRAM 中执行这些代码。 如果要擦除 bank1的扇区、则不必在 SRAM 中执行闪存 API 相关代码。

    更改为:
    闪存 API:

    bl_flash.obj (.text)
    fapi_UserDefinedFunctions.obj (.text)
    --library=.\lib\f021_API_CortexR4_LE.lib (.text)
    }load = flash_API、run = SRAM、load_start (api_load)、run_start (api_run)、size (api_size)

    并在 main ()的开头或调用 main ()之前调用复制函数(_copyAPI 2RAM、位于 sys_core.asm 中)(位于 sys_startup.c 中)

    ;------------------------------------------------------------------
    ;将闪存 API 从闪存复制到 SRAM。

    .def copyAPI 2RAM_
    asmfunc

    copyAPI 2RAM_

    .ref API_load
    FLASH_LOAD .word API_LOAD
    .ref API_run
    FLASH_run .word API_run
    .ref API_size
    FLASH_SIZE .word API_SIZE

    LDR r0、FLASH_LOAD
    LDR R1、FLASH_RUN
    LDR R2、FLASH_SIZE
    添加 R2、R1、R2
    COPY_Loop1:
    LDR r3、[r0]、#4
    结构 R3、[R1]、#4
    CMP R1、R2
    BLT COPY_LOOP1
    BX LR
    endasmfunc
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复。 我仍然有问题。

    我已经在我的汇编语言中有了 APIcopy2RAM (sys_core.asm)、并且已经在 main()之前调用了它。

    我的.cmd 文件看起来与您的建议非常相似、除了--library 标注之后的<.obj>定义。 我尝试删除了这些内容、现在我得到了一个"程序不能放入可用内存中"。 编译时出错。 您能告诉我这是您打算从.cmd 文件中删除的内容、还是缺少您建议的其他内容? 此内存容量错误是真实的、还是语法错误的副产品?

    以下是供参考的新.cmd 文件:

    --retain="*(.intvecs)"
    
    
    内存
    {
    向量(X):origin=0x00000000 length=0x00000200
    BOOT_LOAD (RX):origin=0x00000200 length=0x00001000
    Flash_API (RX):origin=0x00001200 length=0x00001000
    FLASH0 (Rx):origin=0x00002200 length=0x00018000
    FLASH1 (Rx):origin=0x00020000 length=0x00060000
    FLASH2 (Rx):origin=0x00080000 length=0x00080000
    FLASH3 (Rx):origin=0x00100000 length=0x00080000
    FLASH4. (Rx):origin=0x00180000 length=0x00080000
    SRAM (RW):origin=0x08002000 length=0x0002D000
    堆栈 (RW):origin=0x08000000 length=0x00001FF0
    // RSV (RW):origin=0x08000000 length=0x00000010 fill=0
    }
    SECTIONS
    {
    .intvecs :{}> vectors
    
    //boot_code :{..\Release\sys_core.obj (.text)}> boot_load
    ///eabi_start :{..\Release\sys_startup.obj (.text)}> boot_load_obj (.text
    ):{.boot_load.obj (.obj .text
    
    
    
    
    //..\Release\BL_FLASH.obj (.text)
    //..\Releases\Fapi_UserDefinedFunctions.obj (.text)
    bl_flash.obj (.text)
    fapi_UserDefinedFunctions.obj (.text)
    //--library= F021_API_CortexR4_LE.lib FLASH0
    .const > FLASH0
    .cinit > FLASH0
    .pinit > FLASH0
    .data > SRAM
    .bss > SRAM 

    再次感谢、
    -Brian

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

    您好 QJ、

    有没有关于.cmd 配置可能仍然错误的想法?

    我一直在尝试不同的东西、我的闪存 API 函数似乎都没有正确复制到 RAM、因为当我单步执行代码时、它看起来有问题。 我对.cmd 设置感到困惑、因此任何帮助都将不胜感激。

    谢谢!

    -Brian

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

    QJ、

    我一直在单步执行代码、在第一个 Fapi 调用(Fapi_setActiveFlashBank)时出现问题。 我可以在反汇编中看到问题:

    $VEN$TO$L$PI$$$Fapi_setActiveFlashBank():
    08002dd4:E59FC000 LDR R12、[PC]
    08002dd8:E12FFF1C BX R12
    08002ddc:00004625 andeq R4、r0、R5、LSR #12
    $Tramp$AA$L$PI$UART_putString ():
    08002de0:E51FF004 LDR PC、[PC、#-4]
    08002de4:000033E8 andeq R3、r0、R8、Mirror #7
    08002de8:00000000 andeq r0、r0、r0
    08002dec:00000000 andeq r0、r0、r0
    08002df0:00000000 andeq r0、r0、r0
    08002df4:00000000 andeq r0、r0、r0

    这看起来不是很好- Fapi_setActiveFlashBank 看起来像是被 UART_putString()覆盖了,除非我对汇编语言进行了误读(完全可能)。

    重申一下、我正在为 RM48使用示例 TI UART 引导加载程序项目、因此我觉得所有默认设置都应该正常工作、不必进行太多更改。 这就是为什么我感到困惑的原因、为什么 RAM 中会出现明显的损坏或一般问题。

    有人有建议吗?  

    -Brian

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

    我通过大量的试错解决了一些问题。

    我发现我需要在.cmd 文件的 flashAPI 部分中显式调用我在 FAPI 中所需的函数。 我的 cmd 文件现在发出:

    FlashStateMachine.InitializeFlashBanks.obj
    FlashStateMachine.SetActiveBank.obj
    FlashStateMachine.EnableMainSects.obj
    FlashStateMachine.IssueFsmCommand.obj
    FlashStateMachine.ScaleFclk.IssueCommandFlashStateMachine.obj FlashWithAddress.obj
    

    我发现其中一些函数仍在闪存中、这导致了问题。 我只找到了这些链接函数的名称、其中包含 build_information.txt (来自 F021 API)和 linkInfo.xml 的组合。 必须有更好的方法来查找链接的函数名称、但这就是我解决它的方法。

    我现在在擦除闪存时遇到新问题。 在 BL_FLASH.c 中、有一个循环擦除每个扇区(在组0中):

    执行{
    STAT = Fapi_issue当 命令地址(Fapi_EraseSector、eraseStartAddr);
    while (fapi_check_FSM_ready_busy =fapi_Status_FsmBusy);
    while (fapi_get_FSM_status!= fapi_Status_Success);
    
    remaining -= flash_sector[j++].length;
    eraseStartAddr = FLASH_Sector[j].start;
    
    }while (((剩余> 0)&&(j < flash_bank[bk].numOfSecors)); 

    我在这里的问题非常奇怪。 前几个组成功擦除、但当 j 为8时、FAPI_GET_FSM_STATUS 检查不通过。 看起来我的 FMdlStat 寄存器是0x11而不是0。

    有人对第8区有什么重要意义有任何想法? 这是地址0x000A0000。 FAPI 和我的处理器之间必须设置有问题...

    谢谢!

    -Brian

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

    我在这里取得了一些重大进展、并希望为未来需要帮助的人记录这一点。

    我最初的想法是、我应该停止通过从 RAM 中执行 FAPI 来抖动、因为目前我的应用程序是~1.1MB、它将安装在组1中(即1536k)。 因此我将所有内容都更改为该值、但仍然发现扇区8无法擦除。 嗯、这毫无意义。

    我从 FMdlStat 中查看了0x11的含义、发现只有在文档中详细介绍的明确情况下才应设置 SLOCK (位0)。 我还在对这一点进行刮擦、直到我最终意识到 FBSE 设置不正确。 我花了很长时间没有意识到0xFF 不会启用255个扇区、而是只启用8个扇区(位掩码上的脸棕榈-有时您太深、无法看到简单的东西)。 因此、我修复了 TI 的示例代码(!) 在 BL_FLASH.c 中::Fapi_BlockErase:

    对于(bk = ucStartBank;bk < ucEndBank+1;bk++){
    
    Fapi_setActiveFlashBank ((Fapi_FlashBankType) bk);
    
    如果(bk = 0){
    J = ucStartSector;
    剩余= size_in_bytes;
    }否则{
    J = 0;
    }
    
    Fapi_enableMainBankSectors (0xFFFF); /*用于 API 2.01*/ 

    在示例代码中、Fapi_enableMainBankSectors (0xFF)会执行此操作、这与组1的大小有4位的害羞、而组0则是7位的缩写。 我只需将其设置为最大值即可启用所有功能。 我猜 TI 没有使用此引导加载程序测试非常大的应用程序、或者我们只需知道如何解决这个问题。 令人沮丧,但不管怎样。

    这使我能够使用我的程序对整个闪存进行编程。

    我今天一直在做的下一步是确定如何生成二进制文件。 我之前使用.out 文件进行测试、但当我最终在十六进制编辑器中查看它时、我在其中看到引导加载程序不感兴趣的所有类型的链接器垃圾。 我在 Code Composer 的链接器设置中充满了十六进制输出选项、但实际上没有找到原始二进制文件。 这里一定有一个、但我没有找到它。

    因此、我采用了我已经用于 MSP432的 TI-txt 文件格式(顺便说一下、更不用说引导加载程序)、并编写了一个转换程序将该 ASCII 转换为二进制文件。 这让我非常接近。

    我现在正在使用我新开发的.cmd 编辑技能将中断矢量和主应用程序的闪存偏移到0x20000。 对于未来的搜索者、如下所示:

    内存
    {
    引导程序(X):origin=0x00020000 length=0x00000020
    FLASH0 (RX):origin=0x00020020 length=0x0015FFE0
    FLASH1 (RX):origin=0x00180000 length=0x00180000
    堆栈(RW):origin=0x08000000 length=0x00001500
    RAM (RW):origin=0x08001500 length=0x0003eb00 

    我想我在这里非常接近、并想记录我的进度。 当程序成功启动时、我将返回并将其标记为 Resolved (已解决)。

    谢谢阅读...

    -Brian

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

    我的引导加载程序现在都在工作。 跳转到主应用程序后遇到问题、代码无法完全启动。 我无法真正对其进行调试、因此我只是单步执行汇编代码。 它看起来很早就卡住了、我终于诊断出它一直在等待时钟或 PLL 锁定。

    我意识到我可能不应该设置两次内核硬件寄存器。 因此、我开始了所有工作、并复制了我的整个主应用项目。 然后我放入引导加载程序代码。 修复了所有问题、我的引导加载程序现在可以正常工作。 我还可以通过选择性地只为主应用程序写入闪存的部分(而不是擦除所有内容)来调试主应用程序。

    我希望这对将来的人有所帮助、如果您对 TI 示例项目的运行有疑问、请告诉我。 因为它看起来不是一个受良好支持的代码段、它需要大量的 fiddling 和错误修复才能使其正常工作!

    -Brian