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.
FreeRTOS 版本:v9.0
Tivaware 版本: TivaWare_C_Series-2.2.0.295
CCS 版本: 12.1.0.00007
问题:编译错误 "[E0002] PC 相对访问违反了禁用嵌入常量的操作"。
@ file portasm.asm 和
@第99行: LDR r0、ulMax扇 区 InterruptPrimorityConst
@行112: LDR R3、pxCurrentTCBConst
@第127行: LDR r0、ulMax扇 区 InterruptPrimorityConst
@行160: LDR R3、pxCurrentTCBConst
@行177: LDR r0、NVICOffsetConst
@行195:ldr.w r0、CPACRConst
背景:
我们为 Simple FreeRTOS 项目启用了"仅执行"闪存保护。 但会出现 如上所述的编译错误。
实际上、在没有 FreeRTOS 的情况下进行存储器保护工作 正常。
对于 PE、论坛建议 我们进行了以下 更改:
1. 为--embedded_constants 选择"off"
2. 已完成内存部分更改、如下所示。
部分
{
.intvecs:>0x00000000
.libraries:>闪存
{
--library=rtsv7M4_T_le_v4SPD16_eabi.lib (.text)
}
.text :> code_flash
.const :>闪存
cinit :>闪存
请输入您的密码:> FLASH
init_array:> FLASH
.vtable:> 0x20000000
.data :> SRAM
bss :> SRAM
.sysmem:> SRAM
.stack:> SRAM
}
关于
V·帕拉尼萨米
您好!
请参阅此应用手册、了解如何集成 FreeRTOS 以适用于 TM4C。 本应用手册中提供了软件配套资料。
查尔斯,你好!
感谢您提供文档。 实际上、我们已经将同一文档用于项目设置。
实际上、FreeRTOS 项目的设置是无可挑剔的。
1.在没有闪存保护的情况下,FreeRTOS 项目已成功编译,目前正在工作。
2.对没有 FreeRTOS 的项目还可以提供内存闪存保护。
我们在针对 FreeRTOS 项目进行内存保护编译时遇到问题。 即 为- embedded_constants 选择"off"时。
如果我们 为嵌入式常量选择"on"、则 FreeRTOS 项目将会成功编译 、但会在运行时获取故障 ISR。
关于
V·帕拉尼萨米
您可以查看 FreeRTOS portasm.asm 文件、并检查是否存在可能导致编译错误的 PC 相关常量访问。
尊敬的 Zain Nasir:
是的,当"关闭"被选择用于"-嵌入式常量"时,以下四个常量的编译在 portasm.asm 中失败。
为什么会出现这些错误、如何修复这些错误?
由于默认的 FreeRTOS portasm.asm 文件产生错误、因此出现了是否使用 TM4C 上的 FreeRTOS 验证了存储器保护的问题。
关于
V·帕拉尼萨米
我们在针对 FreeRTOS 项目进行内存保护编译时遇到问题。 即 为- embedded_constants 选择"off"时。
如果我们 为嵌入式常量选择"on"、则 FreeRTOS 项目将会成功编译 、但会在运行时获取故障 ISR。
[/报价]我不是编译器专家、不知道开关 embedded_constants 将做什么? 为了实现存储器保护、您想要实现什么目标? 根据编译器用户指南、默认情况下它已开启。 我需要将您的问题转发给我们的编译器、以阐明此开关的实际作用。
如果处理器跳至 faultISR、则通常意味着处理器正在访问无效/非法的存储器 位置、或者您正在尝试访问尚未启用外设的外设寄存器。 在您的情况下、它很可能与无效的存储器位置有关。 您可以使用此应用手册来诊断故障原因。 https://www.ti.com/lit/pdf/spma043
TM4C129包含硬件闪存保护功能 、您可以对其进行配置、使给定的闪存页受到仅执行保护。 这 始终是我们客户用于保护闪存的方法。 有关详细信息、请参阅8.2.3.4下的数据表、了解受保护的闪存寄存器。
我们要为 FreeRTOS 应用程序代码添加"读取保护"。
在下面的论坛 讨论中,请找出 为什么 "嵌入式常量"需要使其关闭的问题的答案。
您好!
在下面的论坛 讨论中,请找出 为什么 "嵌入式常量"需要使其关闭的问题的答案。
[/报价]感谢您分享该链接。 我正在学习一些关于 嵌入式常数的新东西。 我之前提到过、我支持 MCU。 编译器不是我的专长。 Bob 在线程中的意思是、通过使用 嵌入的常量、常量不会被分配到要保护为仅执行的闪存部分。 在链接器命令文件中、您需要创建一个要保护的存储器部分。 读取你的.cmd 文件、我只能看到 CODE_FLASH、但不知道 CODE_FLASH 会占用的闪存位置。
[/quote]我们想要为 FreeRTOS 应用程序代码添加"读取保护"。 [/报价]如果你想要的只是"读取保护",那么为什么你需要 -嵌入式常量? 您只需要做的就是 FlashProtectSet (YourAddrRange、 FlashReadOnly)。 只读保护旨在防止闪存被擦除或重新编程。 请参阅下面的数据表说明。
8.2.3.6只读保护
只读保护可防止 Flash 块的内容被重新编程、而仍然
从而允许通过处理器或调试接口读取内容。 请注意、如果 FMPREn 位
已清零、不允许对 Flash 存储器块的所有读访问、包括任何数据访问。
必须注意的是、不得将所需的数据存储在具有相关 Flash 存储器
FMPREn 位清零。
只读模式不会阻止对存储程序的读取访问、但它提供了
防止意外(或恶意)擦除或编程。 只读模式在使用
对于引导加载程序等实用程序、当调试接口永久禁用时。 在这些
组合、向 Flash 存储器提供访问控制的引导装载程序受保护
免受擦除或修改。
12.2.2.14 FlashProtectSet
设置闪存块的保护设置。
原型:
int32_t
FlashProtectSet (uint32_t ui32Address、
tFlashProtection eProtect)
参数:
ui32Address 是要保护的闪存块的起始地址。
eProtect 是要对块施加的保护。 您可以是 FlashReadWrite 之一、
FlashReadOnly 或 FlashExecuteOnly。说明:
此函数用于设置指定闪存块的保护。 请参阅器件数据表
以确定每个保护选项的粒度。 可以构建可读取/写入的块、
只读或只执行。 只读块可以设为只执行。 构建的块、
都不能修改只执行保护。 尝试进行块保护
不那么严格(即只读到读取/写入)会导致故障(并可通过
硬件)。
对闪存保护的更改只在下次复位前被保持。 该协议允许
要在所需的闪存保护环境中执行的应用程序、以检查是否存在不适当的
闪存访问(通过闪存中断)。 要永久实行闪存保护、请使用
FlashProtectSave()函数。
返回:
成功时返回0、如果指定了无效地址或无效保护、则返回-1。
您好!
在实际使用中、我们将创建 USB-DFU 类固件更新工具。
我们打算在0x0000000位置刷写自定义 USB-DFU 引导加载程序、而不是使用 ROM 引导加载程序。
Bootloader 将 "只执行保护(FMPPEn=0 FMPREN=0) 。 因此、它将受到读写保护、并且只能在出厂时通过调试器进行擦除或更新。
其中 FreeRTOS 应用程序 都将是可加载映像。 该应用程序代码将通过字段中的引导加载程序动态更新;因此、"仅执行保护"不适用。 因此、我们打算在 "读保护"(FMPPEn=1 FMPREN=0、即块可以被写入、擦除或执行、但不能被读取。) FreeRTOS 应用程序代码的程序代码,以防止其 未经授权的 访问。
我们提出以下意见:
请确认是否
1、 在下列情况下,应关闭或打开嵌入式常量: "读保护"(FMPPEn=1 FMPREN=0) ?
2.如果它应该被关闭 ,如何解决编译错误?
注:
为清楚起见、我们刚刚创建了 Simple FreeRTOS 项目并测试了所有可能的闪存安全组合。
2."读保护(FMPPEn=1 FMPREN=0 ),我们在 driverlib/flash.c
请查看下面随附的代码。 我添加了 flashprotectionset()@行 no: 124 main.c 文件,并在这个项目中为--embedded_constants 做了总结。
e2e.ti.com/.../blinky_5F00_queue.zip
关于
V·帕拉尼萨米
您好!
其中 FreeRTOS 应用程序 都将是可加载映像。 该应用程序代码将通过字段中的引导加载程序动态更新;因此、"仅执行保护"不适用。 因此、我们打算在 "读保护"(FMPPEn=1 FMPREN=0、即块可以被写入、擦除或执行、但不能被读取。) 用于 FreeRTOS 应用程序代码,以防止 未经授权的 访问。
您似乎选择了一个 不太可能使用的组合(FMPPEn =1,FMPREn =0 )。 尽管数据表中进行了说明、但如果您坚持使用此组合、我不会看到问题。 重要的是、 常量和字面量池数据必须存储在处理器可读的闪存页中。 读取常量和文本池将 使用 LDR 指令。 当从不受读取保护的闪存页读取这些常量、字面量池数据时、闪存控制器将向处理器发送总线错误信号、从而导致处理器故障。
请确认是否
1、 在下列情况下,应关闭或打开嵌入式常量: "读保护"(FMPPEn=1 FMPREN=0) ?
2.如果它应该被关闭 ,如何解决编译错误?[/报价]可以、应关闭嵌入式常量、以便常量、文字池数据不会驻留在.text 段中。 您可以在.map 文件中验证此情况。 下面是我在您的.map 文件中看到的内容。 乍一看、您的.intvecs、.const、.libraries 和.cinit 不在您从0xc000 - 0x2c000分配的 CODE_FLASH 部分。 如.map 文件中所示、您的.text 段从0xc000开始。
分段分配映射
运行原点 load origin length init length attrs 成员
---------------- ---------------- ---------------- ---------------- -------- ----------------
00000000 00000000 00001598 00001598 r-x
00000000 00000000 00000200 00000200 r--.intvecs
00000200 00000200 00000f84 00000f84 r--.const
00001184 00001184 000003ca 000003ca r-x .libraries
00001550 00001550 00000048 00000048 r--.cinit
0000c000 0000c000 0000274a 0000274a r-x
0000c000 0000c000 0000274a 0000274a r-x .text2. 如果应该将其关闭 ,如何解决编译错误?我迷路了。 您是在编译期间遇到编译问题还是遇到运行时错误? 如果您遇到编译问题、那么您是如何成功构建 blinky_queue 项目的?
[/quote]注:
为清楚起见、我们刚刚创建了 Simple FreeRTOS 项目并测试了所有可能的闪存安全组合。
2."读保护(FMPPEn=1 FMPREN=0 ),我们在 driverlib/flash.c
[/报价]
请查看下面随附的代码。 我添加了 flashprotectionset()@行 no: 124 main.c 文件,并在这个项目中为--embedded_constants 做了总结。我确实看到了 您下面的代码片段有一个问题、您正在将地址范围从0xc000 - 0x2c000标记为 FlashExecuteOnly。
Fullscreen1234567891011121314151617#if 1uint32_t count = 0;/* Memory Protection for Code. i.e, Flash Address range: 0xC000 - 0x2BFFF* All memory allocations are mentioned in blinky_queue_ccs.cmd file*/for(count=0;count<0x20000;count++){////Protecting 128KB of Code flash from the address of 0xC000//to 0x2C000.//FlashProtectSet(0xC000+count, FlashExecuteOnly);//FlashProtectSet(0xC000+count, FlashReadProtection);}FlashProtectSave();XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#if 1 uint32_t count = 0; /* Memory Protection for Code. i.e, Flash Address range: 0xC000 - 0x2BFFF * All memory allocations are mentioned in blinky_queue_ccs.cmd file*/ for(count=0;count<0x20000;count++) { // //Protecting 128KB of Code flash from the address of 0xC000 //to 0x2C000. // FlashProtectSet(0xC000+count, FlashExecuteOnly); //FlashProtectSet(0xC000+count, FlashReadProtection); } FlashProtectSave();我看到的问题是你调用 FlashProtectSave()。 该调用会使 PFPPEn 和 FMPREn 寄存器永久化。 这些 是非易失性 寄存器。 一旦您对它们进行一次编程、当您尝试使用不同的值再次对它们进行编程时、例如将值从0更改为1时、它们不会改变。 例如、你首先 调用 FlashProtectSet 来为只执行设置一个特定的地址范围。 如果您只是简单地修改程序以 在 API 调用中更改新的地址范围或保护模式、这将导致尝试将 FMPPEn 和 FMPREn 从一个设置更改为另一个设置、但在您重新构建项目后无法正常工作。 FMPPEn 和 FMPREn 寄存器不会更改为新值。 这些是非易失性 寄存器、在再次使用新值进行编程之前、必须完成完全解锁操作。 请参阅以下数据表和外设驱动程序用户指南中的说明。 也许您可以在每次更改 FMPPEn 和 FMPREn 设置前确认是否执行了解锁操作。
如果您从未对处理器执行过解锁操作、我建议您执行以下操作。
1.执行解锁操作以将设备恢复到出厂设置。
2.注释掉 FlashProtectSave 直到您确定您希望永久设置生效。 如果没有 FlashProtectSave、 FMPPEn 和 FMPREn 设置中的新设置将在下一个 POR 周期生效。 阅读数据表说明。 这意味着您不能在调试器中重新加载代码。 在重新加载新代码之前、必须首先复位器件。
FMPREn 和 FMPPEn 寄存器在出厂时被设置为1、该值适用于所有已实现的
银行。 这些设置创建了一个开放的访问和可编程性策略。 寄存器的位可以
通过清除特定的寄存器位来更改。 这种改变不是永久性的、除非寄存器
已提交(保存)、此时位的改变是永久性的。 如果一个位从1变成
0且未提交、可以通过执行任何仿真上电复位(SIM_POR)来恢复它
事件的执行。 这些更改需要用 Flash 存储器控制(FMC)寄存器来提交。 详细信息
对这些位进行编程将在"非易失性寄存器编程-- Flash 存储器"中讨论
驻留寄存器"在第613页。使用 Flash 存储器控制(FMC)寄存器的 COMT 位来提交寄存器的值、
寄存器内容变为非易失性、因此在下电上电后予以保留。 单次触发模式
寄存器的内容被提交、恢复出厂默认值的唯一方法是执行
第213页的"恢复一个"锁死的"微控制器"中描述的序列。
除 BOOTCFG 寄存器之外、所有的 FMPREn、FMPPEn 和 USER_REGn 寄存器
可在非易失性存储器中提交。 FMPREn、FMPPEn 和 USER_REGn 寄存器可以
在提交前被测试;BOOTCFG 寄存器不能。 要对 BOOTCFG 寄存器进行编程、
该值必须在提交前写入 Flash 存储器数据(FMD)寄存器。 为
在提交到非易失性存储器之前、无法尝试和验证 BOOTCFG 配置。
重要:所有 Flash 存储器驻留寄存器的位只能由用户由1变为0
编程。 FMPREn、FMPPEn 和 BOOTCFG 寄存器可被确认
但 USER_REGn 寄存器只能被置位一次、这个时间在
整个寄存器已设置为1。 提交后、USER_REGn 寄存器
只能通过执行该序列使其恢复为全为1的出厂默认值
在第213页的"恢复一个"锁死的"微控制器"中描述。 整体擦除
由该序列引起的主 Flash 存储器阵列在恢复操作之前执行
这些寄存器。
最后、请务必使用 此应用手册来诊断故障原因。 https://www.ti.com/lit/pdf/spma043
您好!
让我再次简短地解释这一点。 因此、为了便于您理解、我首先使用"只执行"保护(FMPPEn=0 FMPREN=0)、然后我们将讨论其他保护选项、例如读出保护(FMPPEn=1 FMPREN=0)和只读保护(FMPPEn=0 FMPREN=1)。
实际上、我们已开始使用不使用 FreeRTOS 的基本示例项目测试闪存保护功能、例如 project0、Hello from TivaWare_C_Series-2.2.0.295)。 在这里、我们在代码中使用了三个非常重要的东西。
1.我们做了 在.cmd 中分配闪存 文件。 我们给出了 一个 数据闪存区域、另一个代码区域。
2.使用相同范围的代码内存并使用函数 FlashProtectSet (地址、FlashExecuteOnly)、 这将 保护 代码存储器不受读取、写入和擦除操作的影响。 我们还使用了函数 FlashProtectSave ()使其永久化。
当这些常量从受读保护的闪存页读取文字池数据时,闪存控制器将向处理器发出总线错误信号,导致处理器出现故障。 [/报价]3.在测试过程中,我们看到了您所描述的相同的错误信号,我们了解-嵌入式常量的重要性。 然后、我们 选择关闭- embedded_constants 告知编译器将常量嵌入到数据存储器等可读闪存区域中(如.cmd 文件所述)。
最终、我们在"仅执行"保护的情况下测试了 project0代码、并使用 TM4C1294NCPDT 微控制器验证了结果。 代码运行成功(LED 闪烁)、未出现任何总线错误或故障。 我们无法擦除、重写或读取闪存中的代码区域。 然后、我们通过执行"恢复锁定的微控制器"程序来解锁微控制器。 最后、我们成功实现了、Flash 存储器保护没有问题。
然后、我们进一步使用 FreeRTOS (v9.0)示例项目"blinky_queue "测试"仅执行"保护功能。
首先,我们下载并测试了 blinky_queue,但未进行任何更改。 这是一个很好的地方。
然后、我们在 blinky_queue 中添加了相同的3个存储器保护步骤、并编译 blinky_queue 项目。 但在这里我们发现了在 Portable /ccs/arm_cm4F/portasm.asm 文件中的编译错误、如"[E0002] PC 相对访问违反了嵌入式常量的禁用。 特别是,每当我选择- embedded_constants 时,我都会看到这些错误。
请 在 --embedded_constants=off 时检查 portasm.asm 中的以下错误行
@第99行:LDR r0、ulMax扇 区 InterruptPrimorityConst
@行112:LDR R3、pxCurrentTCBConst
@第127行:LDR r0、ulMax扇 区 InterruptPrimorityConst
@行160:LDR R3、pxCurrentTCBConst
@行177:LDR r0、NVICOffsetConst
@行195:ldr.w r0、CPACRConst
我们现在进行了结构化、需要帮助来解决此问题。 越来越多的人提出这样的问题、
1.编译器错误"[E0002] PC 相对访问违反了对嵌入式常量的禁用"是什么意思? 如何解决该问题?
2.从 portasm.asm 文件中提到的这些行做了什么?
3.为什么编译器(ti-cgt-arm_20.2.7.sts)在 portasm.asm 文件中选择了--embedded_constants 后,列出了这一错误?
4.-embedded_constants 与 portasm.asm 文件中提及的行之间的关系
5.无论是编译器设置还是 FreeRTOS 文件,我需要关注哪些方面来解决此错误?
6.有没有其他方法可以为 FreeRTOS 项目实现这种"仅执行"的闪存保护?
帮助 我们 在 FreeRTOS 项目中执行此存储器保护功能。
您好!
请 在 --embedded_constants=off 时检查 portasm.asm 中的以下错误行
@第99行:LDR r0、ulMax扇 区 InterruptPrimorityConst
@行112:LDR R3、pxCurrentTCBConst
@第127行:LDR r0、ulMax扇 区 InterruptPrimorityConst
@行160:LDR R3、pxCurrentTCBConst
@行177:LDR r0、NVICOffsetConst
@行195:ldr.w r0、CPACRConst
我们现在进行了结构化、需要帮助来解决此问题。 越来越多的人提出这样的问题、
1.编译器错误"[E0002] PC 相对访问违反了对嵌入式常量的禁用"是什么意思? 如何解决该问题?
2.从 portasm.asm 文件中提到的这些行做了什么?
3.为什么编译器(ti-cgt-arm_20.2.7.sts)在 portasm.asm 文件中选择了--embedded_constants 后,列出了这一错误?
4.-embedded_constants 与 portasm.asm 文件中提及的行之间的关系
5.无论是编译器设置还是 FreeRTOS 文件,我需要关注哪些方面来解决此错误?
6.有没有其他方法可以为 FreeRTOS 项目实现这种"仅执行"的闪存保护?
[/报价]我需要我们的编译器专家的帮助、并查看是否有针对编译错误的权变措施。 我将把您的问题转交给他们。 根据编译器误差、我们需要首先了解什么是 PC 相对寻址。 PC 相对寻址是 一种通过将有符号 偏移量加减 至 PC 寄存器来指定操作数地址的方法。 偏移通常在指令中编码为立即值、并表示从当前指令到目标位置的字节数。 如果将嵌入式常量设置为 off、错误可能表示目标位置的 PC 相关地址与当前指令相差太远。 不过、您可能会争辩说、当嵌入式常量设置为关闭时、编译器为什么不选择不使用 PC 相对寻址。 "我想知道你的想法。" 希望编译器设置中有一些开关可以解决您看到的错误。 我会让我们的编译器专家对此发表意见。
尊敬的 Charles:
很高兴收到您的 回复、并 了解您对该问题的参与程度。
期待进行精彩的讨论、并希望找到该问题的解决方案。
谢谢你。
您好!
您能否附加 portasm.asm 文件、以便我们的编译器专家进行调查?
您好!
是的、我可以。 此处、我已将 portasm.asm 文件从 third_party\freertos\Source\ccs\arm_cm4F 文件夹附加。 其版本为 v9.0.0。
如果您想参考完整的项目、可以从之前的回复中下载完整的"blinky_queue "项目以进行进一步验证。
谢谢你。
当您使用 -- embedded_constants=off 中,您告诉编译器工具不允许在具有可执行代码的段中使用嵌入常量。 但编码 portasm.asm 正是这样。 您必须更改代码。 下面是一个例子...
; ldr r0, ulMaxSyscallInterruptPriorityConst movw r0, ulMaxSyscallInterruptPriorityConst movt r0, ulMaxSyscallInterruptPriorityConst
将问题说明注释掉、并替换为两条新说明。 需要在文件中的其他几个位置进行同样的更改。
我在下一个变革方面的专业知识有点超出我的专长。 我认为这些线...
NVICOffsetConst: .word 0xE000ED08 CPACRConst: .word 0xE000ED88 pxCurrentTCBConst: .word pxCurrentTCB ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority
... 进行更改、使它们 不会出现在包含可执行代码的段中。 使用以下命令将它们放入具有其他名称的段中: .sect 指令。 我缺乏有关使用哪个节或该节应在内存中分配到何处的专业知识。
谢谢。此致、
-乔治
您好、George、
根据你的建议,我首先用另外两行替换了每一条错误行,每一行都有 MOVW 和 MOVT 指令。
然后我做了一个 .sect 常数一起构成了该指令。 我为它们提供了一个存储器空间(0x0000–0xC000)、代码常量放在闪存中。
您可以查看这些图像以供参考。
最初、我计划对代码进行上述更改、并 在没有任何存储器保护的情况下、 我选择了 -- embedded_constants =关闭。
完成这些更改后、我编译了项目。 现在、我不会遇到这些错误。 然后、我将 FreeRTOS 应用程序代码(Blinky_queue)上传到 TM4C1294微控制器中。 LED 没有响应。 我在.sect 指令的.map 文件中检查了该命令、确实如此。
我确认了".pc_const"指令放置在数据区域中、而不是代码区域中。 然后、我介绍了调试选项。 这是 FaultISR 问题。 微控制器正在执行代码、直到 "basetype_t xPortStartScheduler( void )" 生成0、0和1的输出函数。 执行行后、微控制器转至 FaultISR 函数。
最后,编译错误通过"--embedded_constants = off"来修复,但应用程序由于某些故障而无法工作。 我想解决这个问题,但我不能。 请在这里帮助我。 我为何要面对这个问题? 我漏掉了什么东西、还是做错了什么?
您可以检查这些文件。
e2e.ti.com/.../7065.portasm.asme2e.ti.com/.../port.c
提前感谢。
您好!
最后,使用"--embedded_constants = off"修复了编译错误,但应用程序由于某些故障而无法运行。 我试图解决这个问题,但我无法解决。
很高兴您在没有编译错误的情况下取得了一些进展。 你能否进行单步调试来找出哪个违反汇编指令会导致故障? 是否在打开任何闪存保护的情况下出现此故障? 或在没有任何闪存保护的情况下仍会出现故障? 如果您没有启用存储器保护(例如将某些闪存页面设置为只执行或其他保护模式)并且仍然收到错误、那么我不确定是什么导致了这些错误。 故障发生时、对于以下寄存器、显示了什么? 如果故障是精确的故障、它们应该提供一些线索。
请务必使用 此应用手册来诊断故障原因。 https://www.ti.com/lit/pdf/spma043
尊敬的 Charles:
我也很高兴在你和乔治的帮助下的改进。
现在、我有同一个项目、没有任何闪存保护。 I maked --embedded_constants = off。 在执行时、我遇到 FaultISR 问题。 那么、我使用调试选项执行了代码。 我可以转到第一个图像中所示的此行、还可以看到寄存器详细信息。
当我从左边的行跳到下一行时、
/*总是懒惰的保存。 */
*( portFPCCR )|= portASPEN_and_LSPEN_BITS;
然后从 FreeRTOS 的 port.c 进入至 faultisr() 看到寄存器(NVIC_DEBUG_STAT)的详细信息发生了更改。
您好!
您的故障状态寄存器指示一个值为0x00000400的不精确故障。 这很可能是由于某种类型的写入操作造成的、因为由读取操作引起的故障通常是精确的。
如果应用程序不基于 FreeRTOS 并且嵌入的常量设置为关闭、您是否会遇到同样的问题?
我想知道如果你 把 portasm.obj 的所有部分都放在 闪存中而不是 CODE_FLASH 中、它会有什么不同吗?
您好!
我真的认为这个帖子会解答您遇到 faultISR 的原因。
基本上有两个问题:
-您调用 地址增量为1的 FlashProtectSet()的方式是错误的。 即使保护方案相同、也不要尝试更改同一个块的保护方案。 换句话说、如果一个2k 闪存块被保护为只执行、那么你就不应该尝试再次使用只执行对同一个块进行编程。 硬件不喜欢。 您应该将地址增量设置为2048。 有关详细信息、请参阅博文。
- drivelib.lib 未 被编译为关闭嵌入式常量、因此 driverlib API 调用导致 FaultISR。 您需要重新构建 driverlib.lib 以 关闭嵌入式常量。 但是如果你看看这个建议、你为什么不把整个 driverlib.lib (.text 和.const)分配到一个非受保护区域、这样就可以简化操作了。 我甚至建议不要保护整个 FreeRTOS 代码或至少 portasm.obj 这导致了您的编译问题。 您需要保护的是定制固件、而不是 driverlib 和 FreeRTOS、因为它们无论如何都是开源代码。
您好!
是的、这给了我一个解决方案。 现在、FreeRTOS 和内存保护正在工作。
谢谢!
很高兴您的问题得到解决。 只是为了向可能遇到同样问题的其他人澄清。 下面是需要完成的操作。
-除了 George 提到的 LDR 指令更改到 MOVW 和 MOVT 之外,还需要其他指令。 例如、 让我们看看以下几行代码。 第一个注释行是执行间接寻址的原始行。 当被 MOVDW 和 MOVET 取代时、它成为 一个直接寻址模式、在这个模式中、它将 CPACRConst 载入为一个立即值。 因此、需要对代码进行修改以插入 LDR R0、[R0]、以首先读取 R0的内容。
;ldr.w r0, CPACRConst movw r0, CPACRConst movt r0, CPACRConst ldr r0, [r0] ldr r1, [r0]
下面是 portasm.asm 文件的完整更改。
e2e.ti.com/.../7723.portasm.asm
-按如下方式更改.cmd 文件。 请确保 driverlib.lib 被分配给未受保护区域、因为 driverlib.lib 最初是在打开嵌入式常量的情况下构建的。 如果要将 driverlib.lib 分配到受保护区域、则需要在重新构建时关闭嵌入式常量。
/* The starting address of the application. Normally the interrupt vectors */ /* must be located at the beginning of the application. */ #define APP_BASE 0x00000000 #define RAM_BASE 0x20000000 /* System memory map */ MEMORY { /* Application stored in and executes from internal flash */ FLASH (RX) : origin = APP_BASE, length = 0xC000 CODE_FLASH (X) : origin = 0xC000, length = 0x20000 /* Application uses internal RAM for data */ SRAM (RWX) : origin = 0x20000000, length = 0x00040000 } /* Section allocation in memory */ SECTIONS { .intvecs: > APP_BASE .libraries : > FLASH { --library=driverlib.lib (.text) --library=rtsv7M4_T_le_v4SPD16_eabi.lib(.text) } .text : > CODE_FLASH .const : > FLASH .cinit : > FLASH .pinit : > FLASH .init_array : > FLASH .pc_const :> FLASH .vtable : > RAM_BASE .data : > SRAM .bss : > SRAM .sysmem : > SRAM .stack : > SRAM } __STACK_TOP = __stack + 4096;
-按如下方式添加链接顺序。