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.
工具与软件:
您好!
我已经完成了有关该主题的其他线程、但我仍然不太了解某些内容。
我要为280039C 创建定制 SPI 引导加载程序。 我希望此自定义 SPI 引导加载程序位于紧随其后的第一个闪存扇区中
"开始" : origin = 0x00080000, length = 0x00000002
/*闪存扇区*/
/*组0 */
SPI_BOOT_LOADER:origin = 0x080002、length = 0x000FFE
我将使用 C:\ti\c2000\C2000Ware_5_02_00_00\libraries\boot_rom\f28003x 中的引导 ROM 代码作为引导加载程序的起点。
我正在尝试了解这一切将如何工作的顺序。 我逐步完成了一个现有的 C2000Ware 项目。
在 linker.cmd 文件中、在闪存的开头有以下部分
begin :origin = 0x00080000、length = 0x00000002
部分中)
{
codestart :> beging, align(8)
在下载的应用程序中查看此位置、您会看到以下内容:
其中有用于跳转到0x8324D 的 OP 代码、 f28003x_codestartbranch.asm 所在的位置。
0008324d 00000008 f28003x_codestartbranch.obj (.text)
其中包含以下代码:
WD_DISABLE .set 1 ;set to 1 to disable WD, else set to 0 .ref _c_int00 .global code_start *********************************************************************** * Function: codestart section * * Description: Branch to code starting point *********************************************************************** .sect "codestart" .retain code_start: .if WD_DISABLE == 1 LB wd_disable ;Branch to watchdog disable code .else LB _c_int00 ;Branch to start of boot._asm in RTS library .endif ;end codestart section *********************************************************************** * Function: wd_disable * * Description: Disables the watchdog timer *********************************************************************** .if WD_DISABLE == 1 .text wd_disable: SETC OBJMODE ;Set OBJMODE for 28x object code EALLOW ;Enable EALLOW protected register access MOVZ DP, #7029h>>6 ;Set data page for WDCR register MOV @7029h, #0068h ;Set WDDIS bit in WDCR to disable WD EDIS ;Disable EALLOW protected register access LB _c_int00 ;Branch to start of boot._asm in RTS library .endif ;end wd_disable .end
问题:那么、 在 f28003x_codestartbranch.asm 中包含 linker.cmd 文件- codestart:> begin、align (8)-和 code_start (请参阅上面的代码)、会将 f28003x_codestartbranch.asm 的地址放在 开始0x80000处? 不确定这是怎么工作的?
它从这里分支到 LB _c_int00 ;分支到 boot28.asm 中 RTS 库的 boot._asm 的起始位置。 这会在跳转到 main 之前初始化一系列内容:
LCR __args_main ; execute main()
问题:我不确定上电时需要执行什么操作跳转到 0x080002处的自定义引导加载程序代码?
问题 启动序列中是否需要 f28003x_codestartbranch.asm 和 boot28.asm? 如果答案是肯定的、它们当前驻留在我的 SPI_BOOT_LOADER 段之外的.text 段中 。 我如何将其移至 SPI_BOOT_LOADER 部分?
感谢您的任何帮助、
Brent
您好、Brent:
您的问题可以在第二天或第二天内看到。
谢谢。此致、
Charles
您好!
只是对此采取后续行动。
我想出了如何将 f28003x_codestartbranch.asm 和 boot28.asm 代码放入我的专用 SPI 闪存引导加载程序部分:
.sect ".spi_bootloader"
我还有几个问题。 我正在努力理解事物的流动。 启动时、我相信您具有以下功能:
问:我的理解是否正确?
如果是、我想了解定制 SPI 引导加载程序是如何满足这一切需求的。 我目前已将 f28003x_codestartbranch.asm、boot28.asm 和 args_main.c 放入我的 SPI 引导加载程序闪存段中、在 args_main.c 中、它将跳转到我的 SPI 引导加载程序函数以开始执行。 完成后、它会跳转至应用程序的入口点。
问题:这是正确的流程吗?
我不确定的一个问题是、我不认为在链接器命令文件中、我需要。 cinit 的"SPI 引导加载程序 闪存"部分。 我想如果我这样做的话、我使用额外的已初始化全局变量更新了应用、这将增加 SPI 闪存部分的封装。 我想在 SPI 引导加载程序完成之前、我不想调用_cinit00。
问:我的理解是否正确?
我看到过这个帖子、他创建了一个不包含 cinit 例程的_c_int00 asm 函数、并在引导加载程序函数的末尾调用标准_c_int00。
引导加载程序和 cinit 部分- C2000微控制器论坛- C2000 ︎ 微控制器- TI E2E 支持论坛
问:这是不是最好的方法?
问题:.TI.ramfunc 应 位于何处? 找到此方法?
我已经 使用#pragma 将引导加载程序代码移至 SPI 引导加载程序闪存部分。
我看到为.cinit 段生成的.map 文件、其中 SpiBootloaderRAM 是一些未初始化全局变量的 SPI 引导加载程序 RAM 部分。
问题:如果.cinit 位于应用程序闪 存空间中、而不是 SPI 引导加载程序闪存段中、这是否会成为 SPI 引导加载程序 RAM 段中我的未初始化全局变量出现的问题? 我看到它有 zero_init。
.cinit 0 000800e8 00000028
000800e8 0000000b (.cinit..data.load)[加载映像、压缩= lzss]
000800f3 00000001 --孔--[填充=0]
000800f4 00000006 (__TI_HANDLER_TABLE)
000800fa 00000004 (.cinit..SpiBootloaderRAM.load)[加载映像、压缩= zero_init]
000800fe 00000004 (.cinit..bss.load)[加载映像、压缩= zero_init]
00080102 00000002 --孔--[填充=0]
00080104 0000000c (__TI_cinit_table)
我还在闪存的应用部分中看到以下内容、即使当前项目只是 SPI 引导加载程序。
问题:我不确定如何将这些内容移至 SPI 闪存部分、或者我是否需要这些内容?
0 00080008 _TI_decompress_lzss
0 00080036 __TI_auto_init_nobinit_nopinit
0 00080061 C$$EXIT
0 00080061 中止
0 00080063 退出
0 0008008a memcpy
0 000800c1 __TI_zero_init_nomemset
0 000800ce _register_unlock
0 000800d2_REGISTER_LOCK
0 000800d6 _nop
0 000800d7 __TI_decompress_none
0 000800df _system_pre_init
0 000800e1 _system_post_cinit
0 000800f4 __TI_ADC Handler_Table_Base
0 000800fa __TI_FET Handler_Table_Limit
0 00080104 __TI_CINIT_Base
0 00080110 __TI_CINIT_LIMIT
0 00080110 __TI_CINIT_WARM
感谢您的帮助、
Brent
好的、谢谢您让我来看看这个。
您好、Charles、
我遵循了这里的建议:
我已经为定制 SPI 引导加载程序创建了一个单独的项目。 根据上述建议、我在引导加载程序中添加了 RTS 库和 cinit 函数。 引导加载程序位于0x80000处 BEGIN 段之后的闪存第一个段、与应用闪存独立。
上电时、调用 f28003x_codestartbranch.asm 函数(地址为0x80000)。 这将禁用看门狗并在 boot28.asm 中调用引导加载程序 的 cinit ()、以设置 C 环境–栈指针初始化、将数据从闪存复制到 RAM 等 最后、它会调用__args_main、后者会调用开始执行的引导加载程序的 main ()。
引导加载程序能够读取应用程序(led_BLINK 代替闪存内核)、将其写入 RAM、然后跳转到其开始执行的 RAM 应用的入口点。
因此、我认为这种方法按预期运行。
然后、我创建了一个在 RAM 之外运行的定制 SPI 闪存内核(使用 SCI 1作为起点)、用于将应用程序写入闪存。 我再次使用了 LED 闪烁应用程序、它是构建在闪存不足的情况下运行的。 闪存内核能够通过 SPI 读取 LED 应用、并将应用程序写入闪存、就像引导加载程序跳转到位于应用开始部分(codestart)处的地址一样、引导加载程序类似 f28003x_codestartbranch.asm 也会禁用看门狗并在 boot28.asm 中调用 cinit ()、后者会调用_args_main ()来调用 LED main 闪烁并开始执行。
所以、我认为定制 SPI 闪存内核能够按预期工作?
我的问题是使 SPI 引导加载程序和应用程序协同工作、而不是相互单步执行?
上电后、我希望 SPI 引导加载程序首先执行、然后根据 GPIO 输入运行引导加载程序代码或跳转到应用程序代码以执行。
我不认为引导加载程序和应用程序都可以有- codestart :> begin, 对齐 (8)?
如果他们都有这个、我不确定是如何确定在上电时运行哪个 f28003x_codestartbranch.asm => cinit ()=>__args_main ()=> main ()的?
所以我只能有 codestart :>开始, 对齐 (8)为引导加载程序定义了什么?
从引导加载程序中、我是否跳转到将初始化应用程序内容的应用程序 cinit ()=>__ arg_main ()=> application main ()?
您能帮助我理解吗?
感谢您的帮助、
Brent
您好、Brent:
>所以我相信这是按预期工作吗?
是的、如果存储在闪存中并写入 RAM 的内核也写入 RAM 而不是闪存、则此流程是正确的。
>所以、我认为自定义 SPI 闪存内核正在按预期工作?
是的、这个流程是正确的、非常好、它正在工作。
>我不认为引导加载程序和应用程序都可以有- codestart :> begin, 对齐 (8)?
是的,引导加载程序和应用程序都可以有 codestart :> begin, 对齐 (8)部分。 这方面的一个示例是 BANK0_LDFU 构建配置中 F28003x 器件的 SCI 闪存内核。
>如果他们都有这种情况,我不知道如何确定什么 f28003x_codestartbranch.asm => cinit ()=>__ args_main ()=> main ()在通电时运行?
如果处于闪存引导模式、上电时、闪存引导加载程序将查看从0x80000开始。 例如、在 F28003x 器件的 SCI 闪存内核中、 BANK0_LDFU 构建配置不依赖 f28003x_codestartbranch.asm 文件来开始运行。
>所以我只有 codestart :>开始, 对齐 (8)为引导加载程序定义了什么?
您需要为引导加载程序和应用程序定义它。
>从引导加载程序跳转到应用程序 cinit (),它将初始化应用程序的内容=>__ arg_main ()=>应用程序 main ()?
您需要从引导加载程序分支到应用程序的入口地址。 应用程序的 codestart 段将处理正确的存储器位置放置和重定向(入口 地址分支=> codestart => c_int00 =>应用程序 main)。
谢谢。此致、
Charles