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.

[参考译文] AM6422:程序入口点不正确

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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1628410/am6422-program-entry-point-is-incorrect

器件型号: AM6422

我使用 CCS v12、MCU SDK+ AM64X v 11_02_00_24。

我使用示例工程“open-pru\examples\empty_c"作为“作为起点。 当我构建 TMDS64VM 并加载到我时、它会按预期工作。

我在工程中手动添加一个新代码文件以扩展功能、并在生成的二进制文件中的“main"之前“之前添加了新代码文件、导致程序在新代码文件而不是 main 处错误地开始执行。 [从下面显示的映射文件中的“PRU_SetupFrameTimer"开始“开始。] 如何强制 main 返回到程序入口点?

 

由此产生的存储器映射:

段分配映射 

 输出                  Attributes/
段 页  原点   长度   输入段
-----   ------------------------  -----  ------------------------
.text   0  00000000  000001f4    
         00000000  000000dc  PRU_Timer.obj (.text:PRU_SetupFrameTimer)
         000000dc 00000084    main.obj (.text:main)
         00000160  00000070  PRU_TaskManager.obj (.text:PRU_SetupTaskMgr)
         000001d0  00000024  PRU_TaskManager.obj (.text:TestFunction)

.data   1  00000000  0000001d    
         00000000  00000010  main.obj (.data)
         00000010  00000008  PRU_Timer.obj (.data:ui64IEP0Cmp0Count)
         00000018  00000004  PRU_TaskManager.obj (.data)
         0000001c  00000001  PRU_Timer.obj (.data)

.cinit  1  00000000 00000000    未初始化



...



全局符号:按名称按字母顺序排序  

页面 地址 名称              
-----   -----              
0  00000000 PRU_SetupFrameTimer       
0  00000160 PRU_SetupTaskMgr        
0  000001d0 TestFunction          
ABS 00033000 __PRU_CREG_BASE_MII_G_RT    
ABS 00032400 __PRU_CREG_BASE_MII_MDIO    
ABS 00032000 __PRU_CREG_BASE_MII_RT  

...

ABS 0000001f _PRU_CREG_RSVD31        
ABS 0000000A __PRU_CREG_TM_CFG_PRU1     
ABS ffffffff __c_args__           
1  00000008 帧              
1  00000018 帧计数           
0  000000dc 主电源              
1  0000000c 共享 RAM            
1  00000000 步长              
1  00000010 ui64IEP0Cmp0Count        
1  0000001c ui8IEP0Cmp0 启动器         
1  00000004 等待       
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Seth。

    “你是不是很怕她?“

    一般而言、我预计 C 不会开始使用 main 执行、因为这会跳过 C 基础设施的初始化。 这就是为什么我要 从针对 C 工程的 example.projectspec 文件中删除--entry_point=main、这是一个仅 ASM 设置。

    请注意,未来的读者:当您稍后阅读时,这些 URL 将不会显示相同的内容,因为我指的是正在进行的工作。

    我认为错误的当前 CCS 设置: https://github.com/TexasInstruments/open-pru/blob/main/examples/empty_c/firmware/am64x-evm/icss_g0_pru0_fw/ti-pru-cgt/example.projectspec 

    修复程序的当前草稿: https://github.com/TexasInstruments/open-pru/blob/a0226750_remove_mcuplus_dependencies/examples/empty_c/firmware/am64x-evm/icss_g0_pru0_fw/ti-pru-cgt/example.projectspec 

    请注意、为了使用 PRUICSS API 从 MCU+内核加载 PRU C 代码、固件需要使用链接器标志 --ram_model 进行编译、以便 R5F 内核可以单独初始化 DMEM 区域。 我还没有时间将其添加到上面的 example.projectspec 文件中、但您可以在此处找到更多信息: https://github.com/TexasInstruments/open-pru/commit/5d72f4e9084f138ff6b1dcd418733a1163fa620b 

    此致、

    Nick

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

    我确实在经过一些试错后解决了这个问题。 我忘记了确切的顺序、但我最终窃取了 SDK 中“boot.c"例“例程的副本、并将其修整到我需要的例程 (_c_int00 _noinit_noargs)、将链接器中的 entry_point 标志定义到 该例程、然后使用链接器文件段定义将该例程放置在 PRU 存储器偏移量 0 处。 这两者都解决了我的正确入口调用树、还解决了我的堆栈指针__SP 未正确初始化的问题。 这会引发另几个问题...

    1) 我很高兴你提到“ram_model 编译器选项,因为我将需要长期. 是否更详细地说明了--ram_model 的作用、或者我需要在 PRU 或 R5F C 代码中做些什么来确保数据正确初始化?

    2) 我偶然发现 __sp 已在 SDK boot.c 文件中初始化、但无法在文档中的其他位置找到该关键字。 我假设加载时可能还需要从 Arm 内核初始化其他内置寄存器(例如.bss、.data 等 PRU 段)。 哪个文档包含此信息? “PRU 优化 C/C++ Compilter v2.3 用户指南“第 4.3.5 节列出了各种初始化和未初始化的区域、但不清楚这些段如何在代码中进行初始化。

    谢谢!

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

    您好、Seth。

    很高兴听到您能够不断取得进展。

    未来的读者、我与 Seth 谈论的更新都在这个拉取请求中。 我将在下周将这些更新标记为 OpenPRU v2026.1.0:
    https://github.com/TexasInstruments/open-pru/pull/125

    有关--ram_model vs --rom_model 的正式文档均位于 PRU C 编译器用户指南/PRU 汇编语言工具中。 出于某种原因、google 搜索不会为我显示最新版本的装配体文档、因此下面是链接、这些链接将始终带您进入最新版本:
    https://www.ti.com/lit/spruhv7
    https://www.ti.com/lit/spruhv6 

    -- ram_model vs - rom_model 是如何初始化 DMEM 的(可能有其他的差异,但这是我不得不在今年工作的部分)。 对于--ram_model、如果 DMEM 中的任何内容需要初始化、则 PRU 内核依靠初始化 PRU 子系统的任何人来加载该数据。 对于--rom_model、进入 DMEM 的值最初存储在指令存储器 (IMEM) 中。 因此、初始化 PRU 子系统的实体会加载 IMEM、然后 PRU 内核处理将数据从 IMEM 复制到 DMEM 的问题。

     如果要执行大量指令、--rom_model 选项会限制代码大小、因为 DMEM 值会占用 IMEM 中的空间。 但是、数据的压缩方式也有所不同。 在我运行的几个测试中、 使用--ram_model 时 PRU 二进制文件的总大小大致相同或稍小、但我被告知、如果将大量数据加载到 DMEM 中(例如,如果您有查找表,即 LUT)、那么压缩可能意味着 PRU 二进制文件的总大小会更小。 如果您使用的处理器与 AM64x 一样大、这可能不是您的关注点。

    我敢打赌__SP 是栈指针、我不记得默认情况下使用哪个 PRU 寄存器。 检查上面的文档、可能会在上面列出。

    此致、

    Nick