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.

[参考译文] TM4C129XNCZAD:TM4C129XNCZAD

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1276391/tm4c129xnczad-tm4c129xnczad

器件型号:TM4C129XNCZAD

 对于 用于 ISR 的 TM4C129X、尤其是对于 UART 中断、是否有 IRAM_ATTR 等属性等效?

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

    您好!

     您发现  受支持的 IRAM_ATTR 有哪些工具链? 我对 IRAM_ATTR 不熟悉、如果它特定于第三方工具链或器件的话。 在 TI Arm 编译器中、您可以使用 SET_CODE_SECTION 或 CODE_SECTION pragma 将您的一段代码(例如、函数)映射到用户定义的段。 在链接器中、您可以将该用户定义的段分配到 RAM 中的存储器区域。 这可能接近于 IRAM_ATTR。 作为应用的一部分、您需要将这段代码从闪存复制到 SRAM、以便  从 SRAM 运行该代码。 请参阅有关加载和运行地址的汇编器/连接器用户指南。 话虽如此、您为什么要从 SRAM 运行 UART ISR? 我真的没有看到任何显著的好处。 是的、我同意 SRAM 的读取和写入是在120MHz 的频率下一个周期操作。 然而、对于流水线电路、由于内置4x256预取缓冲器、从闪存运行代码的周期也几乎为一个。  

    TI Arm 编译器用户指南: https://www.ti.com/lit/pdf/spnu151。 搜索 CODE_SECTION 或 SET_CODE_SECTION。

    TI 汇编器/连接器用户指南:  https://www.ti.com/lit/ug/spnu118u/spnu118u.pdf。 转至第3.1.1节、了解加载和运行地址。  

    3.1.1加载和运行地址考虑一个嵌入式器件、其程序的加载映像在 EPROM/ROM 中。 程序中的可变数据必须是可写入的、因此必须位于可写存储器中、通常是 RAM。 但是、RAM 具有易失性、这意味着断电时其中的内容会丢失。 如果此数据必须有初始值、该初始值必须存储在加载映像中的其他位置、否则在下电上电时该值会丢失。 在使用之前、初始值必须从非易失性 ROM 复制到它在 RAM 中的运行时位置。 参见第8.8节了解完成此操作的方法。 加载地址是对象在加载映像中的位置。 运行地址是对象在程序执行期间所处的位置。 对象是一块存储器。 它表示一个段、区段、函数或数据。 对象的加载地址和运行地址可能相同。 对于程序代码和只读数据、例如.const 段、通常就是这种情况。 在这种情况下、程序可以直接从加载地址读取数据。 没有初始值的段、例如.bss 段、没有加载数据、被视为具有相同的加载地址和运行地址。 如果为未初始化的段指定不同的加载地址和运行地址、链接器会发出警告并忽略加载地址。 对象的加载地址和运行地址可能不同。 对于可写数据、例如.data 段、通常就是这种情况。 将.data 段的起始内容放入 ROM 并复制到 RAM。 通常在程序启动时执行此操作、但根据对象的需求、该操作可能会延迟执行、如第3.5节中所述。 汇编代码和目标文件中的符号几乎始终是指运行地址。 查看程序中的地址时、几乎总是查看运行地址。 加载地址很少用于初始化以外的任何其他事务。 段的加载地址和运行地址由链接器命令文件控制并记录在目标文件元数据中。

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

    您好!

    谢谢各位说明、我提到 IRAM_ATTR 只是作为指示、是的、它是您所理解的正确的、它关乎以可能的最大速度运行代码、我指定了 UART 是有原因的、 我们看到 UART 错误标志报告了很多溢出错误、我的目的是在 SRAM 内运行 UART ISR、理论上比内部闪存快。

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

    我成功使用了#pragma code_section (".fastRAM")

    但随后调试器无法刷写处理器、我还注意到、与没有 CODE_SECTION pragma 指令的原始 bin 文件相比、新的二进制文件的大小更小且具有不同的字节。

    我在这里遗漏了什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我指定 UART 的原因是,我们看到 UART 错误标志报告了许多溢出错误,我打算在 SRAM 内部运行 UART ISR,这在理论上比内部闪存快。

    我怀疑溢出是由于 ISR 的执行速度较慢。 同意闪存 比 SRAM 慢一点(当您的代码不是按顺序运行时)、但该差异不足以导致溢出。 您使用的波特率是多少? 我假设您以快速波特率运行。 在任何情况下、与 CPU 相比、UART 是一个相对慢的器件。  

    我建议您查看以下内容。

    -你是否有任何优先级更高的中断抢占 UART 中断?

    -不确定您是直接在 ISR 内处理传入的 UART 数据。 这通常不是处理数据的最佳方式。 您应该在 ISR 之外处理数据。 当您接收到一个 UART 中断时、在 ISR 中、您应该清除中断标志并设定一个标志、然后快速退出 ISR。 在主代码中、等待设置标志。 设置标志后、您将处理 UART 数据、然后清除标志。 当你在一个 ISR 内部花费过多的时间时、它将防止下一个 UART 中断被处理并且中断将因此丢失。 这可能是您遇到溢出的一个可能原因。 缩短 ISR 是用于实时操作的 RTOS 的基础。 您希望模仿 RTOS 针对快速 ISR 响应的中断处理。  

     -检查是否已启用 FIFO。 RX FIFO 是16 x 8深。 如果您启用 FIFO、它可以在生成中断之前缓冲数据。 如果您具有快速波特率、这尤其有用。 此外、确保您设置了生成中断的阈值。 阈值可以设置为1/8、1/4、1/2等。   

    我成功使用了#pragma code_section (".fastRAM")

    但随后调试器无法刷写处理器、我还注意到、与没有 CODE_SECTION pragma 指令的原始 bin 文件相比、新的二进制文件的大小更小且具有不同的字节。

    [/报价]

    我不知道是什么原因。 我不擅长使用 CODE_SECTION。 如果无法刷写处理器、屏幕上会出现什么错误?

    我建议您首先在 code_section 中放置一小段测试代码、看看它是否起作用。 您的链接器命令文件有什么内容?  您将.fastRAM 分配给了哪个存储器? 您是否设置了运行和加载地址? 您是否将.flashRAM 代码从闪存复制到 RAM? 请回答所有问题、以便我可以将您的问题转发给我们的编译器专家以寻求帮助。  

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

    您好、感谢您的快速响应、  

    关于 UART 溢出、您在中提到的内容完全正确、我 已经实现了一个在 ISR 外部处理数据的循环缓冲区、我将使用115200波特率、我们的系统中有大量数据在传输、 问题在于、我们的最小消息长度为一个字节、因此我们将阈值设置为1个数据字节。

    我的最后一个解决方案是尝试使用 RAM 选项。

    我尝试配置存储器的映射方式如下:

    部分
    {
    .intvecs:> INTERNAL_FLASH_START_ADDR
    .text :>闪存
    .const :>闪存
    cinit :>闪存
    请输入您的密码:> FLASH
    init_array:> FLASH

    .vtable:> internal_RAM_START_ADDR
    bss :> SRAM
    .stack:> SRAM
    .data :> SRAM
    .sysmem:> SRAM

    .fastRam:>SRAM


    编译成功没有问题、但我无法刷写处理器、我认为调试器无法写入/验证 bin 文件。

    无法确定存储器的分区是否可用于我需要的用途。

    XDS200尝试刷写二进制文件、但没有成功。

      pragma code_section (".fastRAM")的值小于旧值时、二进制输出的大小。  

    以下是来自调试器的错误消息:

    [ 2023年10月3日、3:55:12 PM] [INFO_Cortex_M4_0:GEL 输出:存储器映射初始化完成
    [ 2023年10月3日、3:56:01 PM ] [警告] Cortex_M4_0:加载程序:程序的一个或多个段放入不可写的存储器区域。 这些区域实际上不会写入目标。 检查链接器配置和/或存储器映射。
    [ 2023年10月3日、3:56:05 PM ] [错误] Cortex_M4_0:文件加载程序:验证失败:地址0x01005F80的值不匹配请验证目标内存和内存映射。

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

    您好!

     正如我在您刚刚创建的另一个新线程中所提到的、您的链接器文件不足以从 RAM 运行代码。 您是否已经浏览过有关加载和运行地址的用户指南? 我在另一篇文章中回复了您、并附有以下备注。 此外、如果您的问题未得到解决、我们应针对同一主题使用一个线程进行沟通。 对于同一主题、无需打开多个线程。   

    请确保您的链接器文件不足以实现从 SRAM 运行代码。 正如我在另一篇文章中提到的以及链接器用户指南中所述、您不仅仅需要分配.fastRAM:> SRAM。 这是不够的。 调试器不会将您的.flashRAM 代码编程到 RAM 中。 它不是那么简单。 这就是我让您查看用户指南中加载和运行地址说明的原因。 您还必须将代码从加载地址复制到运行地址。 该复制例程必须由您的应用程序执行、而不是由调试器编程人员执行。   

    下面是一个示例、我看到有人使用 SET_CODE_SECTION。  

    extern uint32_t _mode7_ld_start;
    extern uint32_t _mode7_rn_start;
    extern uint32_t _mode7_code_size;

    #pragma SET_CODE_SECTION (".l2flash_mode7")

    void yourfunction ()

    {

    #pragma Set_code_section()

    在链接器文件中:

    .l2flash_mode7:{}palign (32)
    运行= RAM、LOAD = FLASH0、
    Load_start (_mode7_ld_start)、
    RUN_START (_mode7_rn_start)、
    load_size (_mode7_code_size)

    您必须将代码从加载地址复制到运行地址。 还是请参阅"加载和运行地址"用户指南。   

    3.1.1加载和运行地址考虑一个嵌入式器件、其程序的加载映像在 EPROM/ROM 中。 程序中的可变数据必须是可写入的、因此必须位于可写存储器中、通常是 RAM。 但是、RAM 具有易失性、这意味着断电时其中的内容会丢失。 如果此数据必须有初始值、该初始值必须存储在加载映像中的其他位置、否则在下电上电时该值会丢失。 在使用之前、初始值必须从非易失性 ROM 复制到它在 RAM 中的运行时位置。 参见第8.8节了解完成此操作的方法。 加载地址是对象在加载映像中的位置。 运行地址是对象在程序执行期间所处的位置。 对象是一块存储器。 它表示一个段、区段、函数或数据。 对象的加载地址和运行地址可能相同。 对于程序代码和只读数据、例如.const 段、通常就是这种情况。 在这种情况下、程序可以直接从加载地址读取数据。 没有初始值的段、例如.bss 段、没有加载数据、被视为具有相同的加载地址和运行地址。 如果为未初始化的段指定不同的加载地址和运行地址、链接器会发出警告并忽略加载地址。 对象的加载地址和运行地址可能不同。 对于可写数据、例如.data 段、通常就是这种情况。 将.data 段的起始内容放入 ROM 并复制到 RAM。 通常在程序启动时执行此操作、但根据对象的需求、该操作可能会延迟执行、如第3.5节中所述。 汇编代码和目标文件中的符号几乎始终是指运行地址。 查看程序中的地址时、几乎总是查看运行地址。 加载地址很少用于初始化以外的任何其他事务。 段的加载地址和运行地址由链接器命令文件控制并记录在目标文件元数据中。