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.

[参考译文] TMS320F28374S:使用 VCU 和中断的 CRC 计算(代码可重入性)

Guru**** 2526870 points
Other Parts Discussed in Thread: TMS320F28374S

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/768816/tms320f28374s-crc-calculation-using-vcu-and-interrupt-code-reentrancy

器件型号:TMS320F28374S

Hallo 专家。

在我的应用中、我需要计算2种类型的 CRC:CRC 8和 CRC16 (Modbus)。

出于性能考虑、我想使用由 TI 提供的库来使用 VCU 外设。

在应用中、CRC 8在中断例程中计算、由计时器触发、而 CRC16在主函数中计算。 因此、可能会发生以下情况:CRC16计算被计时器中断中断、并开始其他 CRC 计算(使用不同的参数)。

那么问题是:如果 CRC16计算被计时器中断(因此在中断例程中执行 CRC 8)、在中断例程结束时 、CRC16计算是否恢复并正确完成、或者 CRC16结果将会错误?

如果、正如我预期的那样、答案是 CRC16将会错误、您是否有任何建议或权变措施来使用 VCU 计算 CRC?

提前感谢。
Paolo Andreuzza

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    要尝试的一点是:在 CRC16之前禁用中断、然后重新启用。 这可能会非常严重吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Paolo、

    我的预期是、您将为 CRC8和 CRC16定义单独的 CRC 对象、因此 CRC16将在主函数中执行、ISR 将中断它、因此与任何函数调用/ISR 一样、上下文将存储在栈中、然后在之后恢复。

    因此、从这个角度来看、我不明白为什么您的设计会出现问题。

    这是您可以快速尝试和测试的吗?

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

    谢谢 Todd。

    这是我的第一个想法、但它取决于 CRC 16计算需要多长时间。

    在我的应用中、计算是在一个非常大的数据缓冲区上完成的、CRC_run16BitPoly1函数在整个缓冲区大小上执行分频、因此可以在很长的时间范围内禁用中断。

    无论如何、这可能是一个解决方案。

    Paolo

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

    谢谢你,Sira。

    是的、我有两个单独的 CRC 对象、一开始我认为这是应该的、但查看库源文件、似乎这不会保留完整的上下文。

    如果我的读数正确、请查看 vcu2_crc_16.asm 文件中的_crc_run16BitPoly1函数、首先有一个用于将 CRC 结果寄存器复位的结构、 然后、将一些作为参数传递给函数的值移动到正确的寄存器(AR0和 VCRC)、然后启动循环、根据输入缓冲区中的值馈送 CRC 单元。

    在函数的开头、有一个宏(crc_context_save)保存了 XAR1、XAR2、XAR3、但我认为不应该管理代码可重入性。

    在本例中、在中断函数中启动的 CRC8计算将中断 crc16计算、 复位 CRC 单元并修改结果寄存器。 当中断函数结束时、将在 CRC 单元上下文完全更改的情况下恢复 crc16计算。

    我是对的吗?

    因此、Todd 的建议似乎是计算两个 CRC 的独特方法、一个在 iterrupt 函数中、一个在主级别、我再也不想了...

    有什么建议?

    谢谢你。

    Paolo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    可能值得测量在相应 CRC 计算中花费的时间、尤其是在 main 中。 如果您暂停中断、这是否会造成灾难性的后果?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Paolo、

    我的建议是尝试一下。 你吗?

    在软件应用中、您尝试执行的操作并不少见。 当您退出 CRC16汇编函数时、处理器可能会在函数内的任何位置执行指令。 因此、我认为、在这里、context_save 和 context_restore 不起作用。 上下文(即寄存器等)将被压入栈、以便从主应用程序退出到 ISR、 然后、当 ISR 完成且控制权交还给主应用程序时、自动恢复、以便在中断的位置继续执行。 这正是我预期会发生的情况。

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

    Sira、

    我还没有尝试、原因有两个。
    第一个是我还没有硬件、第二个是我应该制作许多测试用例、以确保涵盖实际使用中可能发生的所有可能情况。
    尽管我想在"项目阶段"确定、但我会尽快尝试使用硬件平台。

    无论如何、都是通过该 C 代码生成的

    __attribute__((interrupt)
    void Interrupt500us (void)
    {
    crc_run16BitPoly1 (&hndCRC16);
    } 

    编译器生成此汇编代码:

    ;--------------------------------------------------------------
    ;359| void Interrupt500us (void)
    ;--------------------------------------------------------------
    
    ;*********
    ;* FNAME:_Interrupt500us FR 大小:24. *
    ;* *
    ;*函数环境 *
    ;* *
    ;*函数属性 *
    ;* 0参数、0 AUTO、24 SOE *
    ;*********
    
    _Interrupt500us:
    ASP ;[cpu_alu]
    按 Rb ;[cpu_fpu]
    按 AR1H:AR0H ;[cpu_alu]
    MOVL *SP++、XT ;[cpu_alu]
    MOVL *SP++、XAR4 ;[cpu_alu]
    MOVL *SP++、XAR5 ;[cpu_alu]
    MOVL *SP++、XAR6 ;[cpu_alu]
    MOVL *SP++、XAR7 ;[cpu_alu]
    MOV32. * SP++、STF ;[cpu_fpu]
    MOV32. *SP++、R0H ;[cpu_fpu]
    MOV32. *SP++、R1H ;[cpu_fpu]
    MOV32. *SP++、R2H ;[cpu_fpu]
    MOV32. *SP++、R3H ;[cpu_fpu]
    SETFLG RNDF32=1,RNDF64=1;[CPU_FPU]
    SPM 0 ;[cpu_alu]
    CLRC PAGE0、OVM ;[cpu_alu]
    CLRC AMODE ;[CPU_ALU]
    ;-----------------
    ;361 | crc_run16BitPoly1 (&hndCRC16);
    ;--------------------------------------------------------------
    MOVL XAR4、#_hndCRC16 ;[CPU_ARAU]|361|
    LCR #_CRC_run16BitPoly1;[CPU_ALU]|361|
    ;调用发生[#_CRC_run16BitPoly1];[]|361|
    MOV32. R3H,*--SP ;[cpu_fpu]
    MOV32. R2H、*--SP ;[cpu_fpu]
    MOV32. R1H,*--SP ;[cpu_fpu]
    MOV32. R0H,*--SP ;[cpu_fpu]
    MOV32. STF、*--SP ;[cpu_fpu]
    MOVL XAR7,*--SP ;[cpu_alu]
    MOVL XAR6、*--SP ;[cpu_alu]
    MOVL XAR5、*--SP ;[cpu_alu]
    MOVL XAR4、*--SP ;[cpu_alu]
    MOVL XT、*--SP ;[cpu_alu]
    弹出 AR1H:AR0H ;[cpu_alu]
    SETC INTM、DBGM ;[cpu_alu]
    弹出 Rb ;[cpu_fpu]
    NASP ;[cpu_alu]
    IRET ;[cpu_alu]
    ;返回发生;[] 

    我想回顾一下编译器生成的汇编代码:

    许多寄存器被压入堆栈、但与 VCU 单元无关。 我希望至少 VCRC 寄存器(即结果寄存器、它被用作下一个字节的种子)被压入堆栈... 但也许我会误解一些东西。

    如果您确定有两个不同的 CRC 对象足以使两者正常工作、即使在中断函数中触发其中一个也是如此、对我来说是可以的。


    谢谢你
    Paolo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    大家好。
    昨天我收到了一个配备 TMS320F28374S 的电路板、因此我已经按照建议进行了一些测试。
    这里是我的测试结果。
    正如我预期的那样、CRC 16计算在被其他 CRC 计算(由中断例程触发)中断时失败。
    如 Todd 所示、在 CRC 16计算期间禁用中断、结果(CRC8和 CRC 16)都是正确的。
    无论如何、通过对库进行一些修改、我们能够保护 CRC 计算、从而使代码可重入性成为可能。

    此致。

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

    感谢您对其进行测试并确认实际行为、并与我们分享结果。 抱歉、事实证明我确实对行为错误了、尽管我现在正在进行内部讨论、以确定为什么 VCU 默认不提供可重入性功能。 作为未来改进的一项要求、这是我将要提出的(现在正在讨论中)。

    您能否与我分享您对库的修改、以使可重入成为可能。 我可以使用这种方法作为我的建议的良好起点。

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

    我想更好地理解的另一件事是您同时进行2次 CRC 计算的用例-一个在 main()中、另一个在 ISR 中。 您能不能再详细说明一下?

    谢谢、
    Sira
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Sira、
    我修改了 TI 提供的 CRC 库使用示例、以执行您要求的测试。
    因为我在源文件注释中写过、在我看来、这不是库问题、而是编译器问题、当启用 VCU 的使用时、这不会保存完整的上下文。
    从我的测试中可以看到、在中断例程中只会堆栈一个寄存器、这会使所有寄存器正常工作。
    如果在库中进行此修改、则执行一条在中断例程之外调用函数时不需要的指令。
    如果我的英语不是很清楚,我很抱歉,但我希望我的想法得到理解。
    请告诉我如何将测试用例的源文件发送给您? (为了保持螺纹清洁、我认为将其安装在此处不是一个好主意)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Paolo、

    谢谢、如果您可以在此处共享源代码、那会很好、但如果您不愿意在此处共享、您可以通过电子邮件发送给我:s-rao2@ti.com

    谢谢、
    Sira