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.

[参考译文] AM2634:如何为 AM2634 芯片中的浮点型数据分配值

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1606050/am2634-how-to-assign-values-to-float-type-data-in-the-am2634-chip

器件型号: AM2634

在测试程序时、我们发现分配期间代码中存在异常、这导致最初约 32V 的 Lvol 电压变为约 127。

如下图所示、我在程序中向 DCLvVolTest4 添加了 DCLvVolTest1、以观察变量赋值是否有任何异常。如果分配的数据为异常情况、且电压超过 83V、则再次调用读取函数:(void) LvPCmR_DC_ADC_Serv (&Model_DC_PCM_PCM_ConversionTPCR_ADC_Tmarid) Rte_Read_  

如消息所示、DCLvVolTest2 和 DCLvVolTest3 遇到读取异常、在程序执行期间、LVVol 值一次更改为 127。

FAAD7EA0-3E69-4a1a-93D4-F5BFB0A6FB59.png

之后、我们进行了仿真分析、发现对于 2634 芯片、浮点型变量的赋值一次完成 8 位。

在这种情况下、当为浮点类型分配值时、分配低 16 位、然后分配高 16 位的低 8 位之后、可能会触发 ADC 中断。 执行中断后、将继续分配高 16 位的高 8 位、而不会重新分配先前分配的值。 在 ADC 中断中、我们将再分配 LVVoL 电压。 如果该分配更改了我们数据的高 16 位的高 8 位、则可能会获取异常值。

我们希望了解我们如何避免这种情况、并期待您的回应。 谢谢你。

我们希望了解我们如何避免这种情况、并期待您的回应。 谢谢你。

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

    下面的视频展示了我们的仿真测试过程、该过程可以验证我们在上面所做的假设。

    e2e.ti.com/.../6471.screen_5F00_recording_5F00_2026_2D00_01_2D00_13_5F00_20_2D00_49_2D00_13.mp4

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

    如果您在读取操作前禁用全局中断、并在读取完成后再次启用它们、这也可以防止该问题发生。 但是、这样做会影响直流/直流环路的运行、因此这种方法实际上是不可行的。

    下面是当时的测试消息

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

    尊敬的 Li:

    看看您在视频中共享的汇编代码会在两个存储器地址之间按字节复制存储器、这在浮点值的值分配方面不是预期行为。 有编译器应生成的单指令 32 位内存读取/写入指令的指令。 这可能与您在 C 代码中使用的数据类型有关。

    您能否分享一个可以重现此错误的简单项目? 我们需要重现它以进行进一步调试。 谢谢。

    Han

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

    我们再次尝试测试 ADC 中断中的分配是否存在问题。 以下是我们的测试结果:在视频中、全部以 32 位一次性完成分配、这与任务中的 8 位 x 8 位分配明显不同。 我们希望了解此问题的原因以及如何避免任务中出现异常分配。

    e2e.ti.com/.../screen_5F00_recording_5F00_2026_2D00_01_2D00_14_5F00_22_2D00_10_2D00_16.mp4

    同时、我们还尝试了 TI 的示例、ADC 中断中的分配行为与我们的工程一致。 稍后、我们将向示例中添加任务、以查看是否存在任何异常分配。

    e2e.ti.com/.../screen_5F00_recording_5F00_2026_2D00_01_2D00_14_5F00_19_2D00_49_2D00_31.mp4

    我们想知道为什么在任务中分配浮点类型数据有时会发生在 8 字节的块中、这是由于中断还是其他一些原因、以及如何避免。

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

    您能否分享重新创建字节复制行为的整个代码? 这可能与如何定义数据类型有关。 或者、可能是由于对齐(如果源/目标是 32 位对齐)。

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

    我使用我们的代码创建了一个最小的项目并将其发送给您。 您可以在此工程中对其进行验证。 主要变化发生在内核 3 的代码中、您可以参阅下图了解详细信息。

    下面的视频展示了使用超小设置时的测试结果。

    e2e.ti.com/.../screen_5F00_recording_5F00_2026_2D00_01_2D00_15_5F00_21_2D00_50_2D00_07.mp4

    这是我们的最小项目。 我们希望您能帮助我们尽快解决这个问题。 谢谢你。

    e2e.ti.com/.../Draco1_5F00_2P2Z_5F00_3_5F00_1_5F00_unsec.rar

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

    尊敬的 Li:

    您可以尝试在 CCS 中启用该选项吗? -- use_memcpy 一样快。

    这存在于 Properties > Arm Linker > Advanced Options > Linker Optimization >--use_memcpy 中  

    此致、

    Aswin

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

    尊敬的 Aswin:

    我遵循了您所说的、并将 use_memcpy 更改为“fast",“,这、这解决了我的问题。 您可以在下面的视频中看到具体的调试结果。 但是、这项更改是否还会有其他问题? 我们不希望仅仅为了创造新的问题而解决这个问题。 另外、我还是有点困惑、因为在您提供的示例中、未选择此选项;使用了默认值、即 use_memcpy 作为“small"。“。 您是否尝试过示例以了解指针分配是否也存在一次分配 8 位的问题? 您可以参考我为您提供的最小项目、并对其进行修改、看看它是否出现了我们遇到的相同问题。 最好是可以录制屏幕并向我展示。 我们只想确认问题的原因是否确实是您提到的问题、以及以这种方式更改问题是否会导致其他问题。 期待您的答复、谢谢。

        e2e.ti.com/.../screen_5F00_recording_5F00_2026_2D00_01_2D00_27_5F00_15_2D00_06_2D00_31.mp4

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

    尊敬的 Li:

    我遵循了您所说的内容、并将 use_memcpy 更改为“fast",“,这、这解决了我的问题。 您可以在下面的视频中看到具体的调试结果。 但是、这项更改是否还会有其他问题? 我们不希望只为了创建新问题而解决这个问题。

    ti ARM CLANG 文档提到了如何基于代码大小使用此标志。

    默认情况下、SDK 示例使用倾向于优化代码大小的操作系统选项。 因此链接器 将 选择--use_memcpy=small。

    该标志只是决定要使用的 memcpy 的实现。  编译器选项需要与编译器资质审核套件保持一致。

    https://www.ti.com/tool/download/ARM-CLANG-CQKIT 2.1.3.LTS

    另外、我还是有点困惑、因为在您提供的示例中、此选项未被选中;

    我知道它是哪个示例。 您能指出一个示例、如果它在 SDK 中、 我的屏幕截图来自一个自定义示例、我创建该示例来模拟浮点副本。

    您是否尝试过示例来看看指针分配是否也存在一次分配 8 位的问题? 您可以参考我为您提供的最小项目、并对其进行修改、看看它是否出现了我们遇到的相同问题。 最好是可以录制屏幕并向我展示。 我们只想确认问题的原因是否确实是您提到的问题、以及以这种方式更改问题是否会导致其他问题。 期待您的答复、谢谢。

    打开工程时、我看到 system.xml 未填充。 您能告诉我哪个工程进入了哪些内核吗?

    此外、我还能够在另一个项目中模拟此场景。

    另外、由于我们必须复制结构体、所以通过字段赋值而不是执行基于指针参考的复制、因为它涉及整个结构体、这是否更好和安全?

    此致、

    Aswin

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

    您好 

      您可以在 SDK 库中使用此示例进行测试。

       TI\MCU_PLUS_SDK_am263x_10_00_00_35\examples\drivers\adc\adc_soc_epwm\am263x-cc

    结构体和函数定义如下

    ///////////////////////////////////////////

    typedef 结构

    浮动 HvVol;
    浮动 HvCur;
    浮动 LVVol;
    浮动绿袖;
    Float LVCur1;
    Float LVCur2;
    浮动绿 Cur3;
    浮动绿 Cur4;
    浮点 Lv Cur_Mid;
    悬空 LVCC;
    漂浮绿卷;
    浮动 HvVolAD;
    浮动 HvCurAD;
    浮标 LVVolAD;
    浮动 LvCurAD;
    浮点 LVCurOBD_AD;
    Float LVOringAD;
    浮点 TEMP3_AD;
    浮点 TEMP2_AD;
    悬空 NTC_Ref_ad;
    浮点 OringTempAD;
    浮点 LVCCAD;
    浮点 CTCurAD;
    } DC_ADC_Serv;
    DC_ADC_Serv DC_UNBUS;    

    DC_ADC_Serv DC_UNBUS_1;

    typedef unsigned short uint16;
    UINT16 Rte_Read_ DC_PCM_PCMR_DC_ADC_Serv (DC_ADC_Serv*data)

    // HwiP_disable();
    *(DATA)= DC_UNBUS;
    // HwiP_enable ();
    返回 1;
    }
    define Rte_Read_ PCmR_DC_ADC_Serv Rte_Read_ DC_PCM_PCMR_DC_ADC_Serv

    UINT16 Rte_Read_ PCmR_DC_ADC_Serv (DC_ADC_Serv* u);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////

    并将屏幕截图红色框内的内容添加到 ADC 中断、以检查在中断执行期间是否以八位块形式分配了 DC_UNBUS_1.LVVol 变量。

    关于您的问题,与我们的工程代码对应的核心显示在屏幕截图中。同时,在我的前一个答复中,我还录制了一个视频,显示了使用我发送给您的最小项目复制这种异常现象。 您可以在我的答复中查看视频。

    为了让您更容易进行测试、我截取了我的 Core 3 测试代码所在位置的屏幕截图并将其发送给您、以便您可以更轻松地找到它。如果您有其他问题、您可以回复此帖子并询问。 我会与你合作。 谢谢、我期待您的答复。

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

    尊敬的 Li Li:

    对延迟的回复表示歉意。

    我运行了示例 ADC_SoC_EPWM 并看到您提到的问题也发生了。 memcpy 逐字节执行。

    e2e.ti.com/.../issue_5F00_recording.mp4

    一旦 我更改了标志编译器选项、便可以看到以下观察结果。

    e2e.ti.com/.../post_5F00_memcpy_5F00_flag_5F00_change.mp4

    我能够在 SDK 的示例中重现问题、修改编译器标志就解决了这个问题。

    此致、

    Aswin  

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

    您好  Aswin:

    感谢您的答复。 是的、切换 Linker Optimization >--use_memcpy 选项以 FAST 可以解决问题、但我们还有一个问题。 为 use_memcpy 选择 FAST 和 Small 之间存在差异。 选择快速均值分配是一次 16 位还是一次 32 位? 如果是 16 位赋值、那么对于浮点变量、即使选择 FAST 选项也可能会导致赋值异常、只是概率较低。 因此、我们需要阐明 use_memcpy 的 fast 和 small 之间的差异、这是我们关心的问题。 我们希望有一个基本的战略来解决这个问题,并期待着你的答复。 谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    y 选择快速均值分配是一次 16 位还是一次 32 位? 如果是 16 位赋值、那么对于浮点变量、即使选择 FAST 选项也可能会导致赋值异常、只是概率较低。 因此、我们需要阐明 use_memcpy 的 fast 和 small 之间的差异、这是我们关心的问题。

    让编译器团队更好地回答这个问题。  

    我们想知道  

    1.将 USE_memcpy 设置为 FAST 会产生什么副作用?

    2. 将 use_memcpy 设置为 fast 和 small 之间有什么区别? 此副本是如何进行的。 是按 8 位还是按 16 位还是按 32 位?

    此致、

    Aswin

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

    有关该选项的一般背景信息 -- use_memcpy 、请参见 tiarmclang 在线手册的 RTS 优化(--use_memcpy 和--use_memset 选项)部分。   

    将 use_memcpy 设置为 fast 和 small 之间有何区别? 此副本是如何进行的。 它是按 8 位还是按 16 位还是按 32 位?

    --use_memcpy=small 含义 Memcpy 一次复制 1 个 8 位字节。  --use_memcpy=fast 更复杂。  它使用多个不同的加载/存储指令。  有些字节一次工作 16 个字节、其他的字节一次工作 1 个字节、而它们之间有几个不同之处。  要查看此代码、请查看文件 compiler_install_root \lib\memcpy32.S src

    谢谢。此致、

    -乔治

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

    您好、George、

    感谢您的回答。

    很明显  --use_memcpy=small  含义  Memcpy  一次复制 1 个 8 位字节。

    关于 --use_memcpy=fast 、如何 显式制作 Memcpy  一次复制 32 位或 64 位、以保证类型为 float 或 double 的变量的数据完整性?

    谢谢。  

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

    您好、George、

    从客户端添加更多信息。

    在使用 C2000 编译器的 F280039 上、没有类似的问题。 Memcpy 正确复制 uint32 和 float 变量。

    您还能帮助指出 C2000 器件/编译器如何保证 32 位变量的数据完整性吗?

    谢谢。

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

    您好、George、

       关于 Fan_Zhang 的问题、我们还有一个问题。 我们还想知道您推荐为--use_memset 选择什么。 在示例中、默认情况下未选择任何设置。 这也会导致 8 位 x 8 位分配问题吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    关于 --use_memcpy=fast 、如何 显式制作 Memcpy  一次复制 32 位或 64 位、以保证类型为 float 或 double 的变量的数据完整性?

    您不能通过任何机制强制 memcpy 使用特定指令进行读取或写入。  不过、在这种特定情况下、将复制一个结构、其中每个成员的类型都在该结构中 悬空 。  这意味着每个结构都至少与一个 4 字节边界对齐。  在这种情况下、memcpy 使用的最小加载/存储指令 FAST 是 32 位。

    指出 C2000 器件/编译器如何保证 32 位变量的数据完整性。

    C2000 上的 memcpy 函数一次复制 1 个 16 位字。  结构体赋值通过调用 memcpy 来实现。   

    您建议为-use_memset
    选择的内容

    回想一下、定义 memset 以初始化存储器范围中具有相同字符宽度值的每个字符宽度位置。  典型的实现方式一次写入一个字符。  更智能的实现可以一次编写多个字符。  这只是一个不同的操作,不受同样的问题。

    -乔治

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

    尊敬的 Li Li:

    对上述评论的任何进一步疑问。

    我们关于实施的一项建议是、

    最好不要复制这样的结构体、而是将该结构体的地址返回给调用方。 由于在 ISR 中发生这种情况、因此大量复制会进一步延迟代码执行。

    此致、

    Aswin