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.

[参考译文] TM4C1294NCPDT:编译错误-用于 FreeRTOS 的闪存保护

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1238944/tm4c1294ncpdt-compilation-error---for-flash-memory-protection-with-freertos

器件型号:TM4C1294NCPDT

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。 本应用手册中提供了软件配套资料。  

    https://www.ti.com/lit/pdf/spma085

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

    查尔斯,你好!

    感谢您提供文档。  实际上、我们已经将同一文档用于项目设置。

    实际上、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 应用程序代码添加"读取保护"。  

    在下面的论坛 讨论中,请找出  为什么 "嵌入式常量"需要使其关闭的问题的答案

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/807063/ccs-sw-tm4c-tiva-c-flash-memory-read-out-protection

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

    您好!

    在下面的论坛 讨论中,请找出  为什么 "嵌入式常量"需要使其关闭的问题的答案

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/807063/ccs-sw-tm4c-tiva-c-flash-memory-read-out-protection

    [/报价]

    感谢您分享该链接。 我正在学习一些关于 嵌入式常数的新东西。 我之前提到过、我支持 MCU。 编译器不是我的专长。 Bob 在线程中的意思是、通过使用 嵌入的常量、常量不会被分配到要保护为仅执行的闪存部分。 在链接器命令文件中、您需要创建一个要保护的存储器部分。 读取你的.cmd 文件、我只能看到 CODE_FLASH、但不知道 CODE_FLASH 会占用的闪存位置。  

    我们想要为 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。

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

    您好!

    在实际使用中、我们将创建 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 .text

    2. 如果应该将其关闭 ,如何解决编译错误?

    我迷路了。 您是在编译期间遇到编译问题还是遇到运行时错误? 如果您遇到编译问题、那么您是如何成功构建 blinky_queue 项目的?

    注:

    为清楚起见、我们刚刚创建了 Simple FreeRTOS 项目并测试了所有可能的闪存安全组合。  

    2."读保护(FMPPEn=1 FMPREN=0 ),我们在  driverlib/flash.c
    请查看下面随附的代码。 我添加了 flashprotectionset()@行 no: 124 main.c 文件,并在这个项目中为--embedded_constants 做了总结。

    [/报价]

    我确实看到了 您下面的代码片段有一个问题、您正在将地址范围从0xc000 - 0x2c000标记为  FlashExecuteOnly。  

    #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

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

    您好!

    让我再次简短地解释这一点。 因此、为了便于您理解、我首先使用"只执行"保护(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。

    e2e.ti.com/.../portasm.asm

     如果您想参考完整的项目、可以从之前的回复中下载完整的"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)的详细信息发生了更改。

    请使用 此应用手册来诊断故障原因。  https://www.ti.com/lit/pdf/spma043[/报价]

    如果您对此问题有任何解决方案、敬请告知。 同时、我还将查看上述文档。

     

    谢谢你。

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

    您好!

     您的故障状态寄存器指示一个值为0x00000400的不精确故障。 这很可能是由于某种类型的写入操作造成的、因为由读取操作引起的故障通常是精确的。  

     如果应用程序不基于 FreeRTOS 并且嵌入的常量设置为关闭、您是否会遇到同样的问题?

     我想知道如果你 把 portasm.obj 的所有部分都放在 闪存中而不是 CODE_FLASH 中、它会有什么不同吗?  

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

    您好!

     我真的认为这个帖子会解答您遇到 faultISR 的原因。  

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/927243/tm4c123gh6pz-flashprotectset-in-the-flash-protected-as-execute-only?tisearch=e2e-sitesearch&keymatch=FlashProtectSet#

    基本上有两个问题:

     -您调用 地址增量为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;

    -按如下方式添加链接顺序。