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.

[参考译文] TMS320C6713:CCSv5.5、DSP/BIOS v5.42:EDMA 中断使 SWI_POST 不起作用

Guru**** 2589300 points


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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/588391/tms320c6713-ccsv5-5-dsp-bios-v5-42-swi_post-not-working-from-edma-interrupt

器件型号:TMS320C6713

我有一个在 DSK6713板上运行的原型应用、我要将其转换为使用 DSP/BIOS、我遇到了一个问题、即从 HWI 发布时无法使 SWI 运行。  

tcf 配置如下:

bios.HWI.instance("HWI_INT8").fxn = prog.extern ("c_int08");
bios.HWI.instance("HWI_INT8").useDispatcher = 1;
bios.HWI.instance("HWI_INT8").interruptMask ="无";

BIOS.SWI.create ("SWI_PingRcv");
bios.SWI.instance("SWI_PingRcv").order = 1;
bios.SWI.instance("SWI_PingRcv").fxn = prog.extern ("setRcvPing");
bios.SWI.instance("SWI_PingRcv").priority = 1;

BIOS.SWI.create ("SWI_PongRcv");
bios.SWI.instance("SWI_PongRcv").order = 2;
bios.SWI.instance("SWI_PongRcv").fxn = prog.extern ("setRcvPong");
bios.SWI.instance("SWI_PongRcv").priority = 2;

从布置的 SWI 调用的中断例程和函数如下(EDMA 调度程序在 c_int08中断例程中调用 RcvPing 和 RcvPong):

void c_int08 (void)

EDMA_intDispatcher ();
返回;

}/*结束 c_int08 */

空 RcvPing()

EDMA_intClear (13);

//调用 setRcvPing
Swi_post (&Swi_PingRcv);
// setRcvPing();

空 RcvPong()

EDMA_intClear (15);

//调用 seetRcvPong
Swi_post (&SWi_PongRcv);
// setRcvPong();

使用此设置时、代码似乎会进入到电子邮件中、但如果我注释掉 SWI_POST 调用并取消注释对 setRcvPing 和 setRcvPong 的调用、则代码会正常工作。  

是否有任何关于 SWI_POST 调用为何无法正常工作的建议?

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

    我已通知 RTOS 专家。 他们的反馈将在此处发布。

    此致、
    Yordan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否已确认 Swi 运行(例如、设置断点、点亮 LED 等)? 是否可以检查工具->ROV-BIOS ->扫描错误... 在 CCS 中? 如果系统堆栈不够大、您可能会使其熔断。

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

    如果我在代码中放置断点、我可以在 SWI 被布置的位置停止、但在 SWI 调用的例程内没有遇到断点命中。  

    在我使用的 CCSv5.5版本中、Tools->ROV 下面没有菜单项。  我将堆栈大小设置如下:

    BIOS.MEM.STACKSIZE = 0x2000;  

    我将全局缓冲区用于任何具有重要大小的东西、因此我不认为我会过度运行堆栈。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    查看 ROV KNL 条目、我注意到堆栈正在上升。 如果我设置一个断点、我会看到每当我单击 c_int08中断例程时、StackPeak 值会上升~200 (如下所示)。 即使 EDMA 调度程序已注释掉、但在这个代码设置中、我没有在系统中调用任何用户定义的 SWI 或 TSK、因此我看不到它是如何泄漏内存的。

    void c_int08 (void)

    // EDMA_intDispatcher ();
    if (EDMA_intTest (12)){
    EDMA_intClear (12);

    如果(EDMA_intTest (13)){
    EDMA_intClear (13);

    如果(EDMA_intTest (15)){
    EDMA_intClear (15);

    IRQ_CLEAR (IRQ_EVT_EDMAINT);
    返回;

    }/*结束 c_int08 */
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是否可以尝试将 HWI_INT8 interruptMask 更改为"self"?

    此致、

    - Rob
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我之前建议将 interruptMask 更改为"self"可能会解决堆栈爆炸的问题、但我会感觉到您在不断地接受中断、将掩码更改为 self 不会停止这种情况(但会停止 HWI 嵌套、这会导致堆栈爆炸)。 如果您持续接受中断、则这意味着需要清除中断源(大概是 EDMA)。

    我看不到以下项的任何设置:
    bios.HWI.instance("HWI_INT8").interruptSelectNumber = ;

    似乎映射到 INT8的默认事件是 EDMAINT、这可能是您想要的、但最好显式分配此类事件。 也许您正在 IRQ_MAP()中使用 CSL 执行此操作?

    您的陈述
    IRQ_CLEAR (IRQ_EVT_EDMAINT);
    需要首先调用 IRQ_MAP( 8)、即使映射正确、也只是将 IFR 寄存器的 INT8位清零、如果 INT8的源仍然升高、则 INT8将立即在 IFR 中再次置位。 您能否在调试器中单步执行该代码? 如果是这样、请查看在单步执行 IRQ_CLEAR()之后 IFR 的位8是否仍然被置位。 如果是、您需要在 EDMA 中执行一些操作来停止它发出中断。

    我不太熟悉 EDMA 硬件、因此我对该硬件的帮助能力有限。

    通常、您不应在 CSL 与 DSP/BIOS 相交的位置使用它。 IRQ API 是 CSL 的一部分、DSP/BIOS 具有用于中断处理的 HWI、因此您根本不应该使用 IRQ API (并且 HWI 中应该有所需的 IRQ API 对应方)。 DSP/BIOS 没有任何 EDMA 支持、因此可以与 DSP/BIOS 结合使用。

    此致、

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

    将 interruptMask 更改为 self 可防止堆栈弹出、但程序在杂草中仍会关闭。  EDMA 配置为生成中断、但 EDMA_intDispatcher 函数处理 CIPR 寄存器中的位的清零、因此 EDMA 不应连续接收中断。

    bios.HWI.instance("HWI_INT8").interruptSelectNumber = 8;是默认值、当我在配置工具中打开 HWI_INT8时、它会在属性窗格中显示中断选择号= 8。  我认为它没有明确设置、因为我没有将其从配置工具中的默认值更改为默认值。

    它看起来是冗余的、因为 BIOS 必须清除 IFR 位、所以我从 c_int08例程中删除了 IRQ_CLEAR (IRQ_EVT_EDMAINT)、但是它没有改变运行方式。

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

    [引用 user="Dan Wickstrom18"]将 interruptMask 更改为 self 可防止堆栈弹出,但程序在杂草中仍会关闭

    它是进入到杂草中、还是继续处理 EDMA 中断?  我期待后者。

    [引用用户="Dan Wickstrom18"] EDMA 被配置为生成中断,但 EDMA_intDispatcher 函数处理 CIPR 寄存器中的位的清零,因此 EDMA 不应连续接收中断。

    没错、EDMA_intDispatcher 将清除 IPR 中的所有中断、这意味着您的服务函数无需执行此操作(如上所示)。

    [引用用户="Dan Wickstrom18"]由于 BIOS 必须清除 IFR 位,因此我从 c_int08例程中删除了 IRQ_CLEAR (IRQ_EVT_EDMAINT),但它没有改变行为。

    供参考、IFR 位永远不需要由软件清除、因为硬件在处理中断时会自动将该位从 IFR 中清除、所以 BIOS 不会这样做。   只有 当中断被禁用、并且您不希望为 IFR 中已经标记的中断提供服务时、才能帮助在 IFR 中手动清除位(如果启用了全局 中断、  您永远不会在 IFR 中看到已启用中断集的位、因为中断会立即得到服务并在获取中断时清除)。

    使用 CCS 尝试此操作...

    在 c_int08中单步执行到 EDMA_intDispatcher 的调用。  此时 IFR 位8是否仍然置位?  如果是、则需要弄清楚原因。  可能有一些无限链传输正在进行中。  可能还有另一个处于活动状态的中断源、该中断源不由 EDMA 调度程序处理(某些错误条件或此类错误条件)。

    此致、

    - Rob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我更改了 HWI_int08配置以直接调用 EDMA 调度程序、它现在工作正常:

    // bios.HWI.instance("HWI_INT8").fxn = prog.extern ("c_int08");
    bios.HWI.instance("HWI_INT8").fxn = prog.extern ("edma_intDispatcher);

    我不理解这一点、因为 c_int08只调用 EDMA_intDispatcher。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我建议这样做、但只是为了节省额外的函数调用、而不是因为我认为它可以解决这个问题。

    您是否有机会使用"interrupt"关键字声明 c_int08? (或等效 的#pragma)

    此致、

    - Rob
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    否、文档警告在使用 DSP/BIOS HWI 模块时不要使用中断关键字、因此我没有使用它。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我不知道为什么仅仅用 EDMA_intDispatcher 替换调用 EDMA_intDispatcher 的函数会起任何作用。 使用您的函数"trampoline"时、栈使用量略有增加、但这是唯一的差异。

    是否要使用 c_int08进一步诊断故障情况、或者是否可以继续使用 EDMA_intDispatcher 直接插入 IRQ 的"解决方案"?

    如果从 c_int08中更改 ISR 的名称会产生什么影响、这一点会稍微有趣一些。 尝试一些不以 c_int 开头的名称。 该名称略接近特殊符号 c_int00 (或 COFF obj 文件的 asm 中的_c_int00)。

    此致、

    - Rob
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我尝试将名称更改为 edmaInterrupt、如下所示:

    空 edmaInterrupt()

    EDMA_intDispatcher ();


    它不会再次起作用。

    有趣的是、我在另一个论坛上发现了一个帖子、其中有人有相同的问题、他们以相同的方式解决了这个问题。

    我可以继续使用 EDMA_intDispatcher 解决方案。

    感谢你的帮助。