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.

[参考译文] RTOS/TMS320F28379D:中断完成后 SYSBIOS 崩溃。 Hwi 堆栈溢出。

Guru**** 2595805 points
Other Parts Discussed in Thread: TMS320F28379D, SYSBIOS

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/583026/rtos-tms320f28379d-sysbios-crashes-after-interrupt-finishes-hwi-stack-overflow

器件型号:TMS320F28379D
Thread 中讨论的其他器件: SYSBIOS

工具/软件:TI-RTOS

大家好、

我正在尝试使用 SYSBIOS 为 TMS320F28379D 创建一个程序来响应中断。 中断来自我已设置为 UART 的 sci 模块、当 FIFO 缓冲区中有8个字符时、中断将触发。 我认为我已经正确设置了中断、因为我可以在中断中设置一个断点、当我从终端程序发送第8个字符时会触发中断。 我可以单步执行中断并逐步退出中断、而不会出现任何问题。

该问题在我步出中断后发生。 如果我继续步进、当 BIOS 的 HWI 堆栈突然开始增长和增长时、它可能会运行30个步进(进入我看不到的代码)、并且当它超过 Hwi 堆栈大小时、它会导致 RTOS 崩溃。 这仅在我触发中断后发生、如果我从未触发中断、系统运行正常。

有关我如何设置和尝试以下内容的随机注释:

*我已经尝试修改了中断中的代码、但即使我有一个空中断、问题仍然会出现。 表明问题在某种程度上位于中断代码外部。

*在 SYSBIOS 中设置中断。 中断号为96、scia_Rx 中断。 我在启动时有启用的复选标记、并标记了自动确认 PIE 中断。 具有自我屏蔽选项。



我的项目中的代码片段:

void setUartRegisters (volatile struct sci_regs * regsToSet、unsigned long cpuFrequency、unsigned long baudRateToSet)
{

无符号长整型 LSPCLK;
无符号长整型 brr;

//regsToSet->SCIFFTX.all = 0xE040;// OLD,下面替换此行
regsToSet->SCIFFTX.bit.SCIRST = 1;//可以恢复发送
regsToSet->SCIFFTX.bit.SCIFFENA = 1;//启用 FIFO 增强功能
regsToSet->SCIFFTX.bit.TXFIFORESET = 1;//重新启用 FIFO 操作
regsToSet->SCIFFTX.bit.TXFFINTCLR = 1;//清除 FIFO 中断标志
regsToSet->SCIFFTX.bit.TXFFIENA = 1;//启用 FIFO 中断


//regsToSet->SCIFFRX.ALL = 0x2044;// OLD,下面替换此行
regsToSet->SCIFFRX.bit.RXFIFORESET = 1;//重新启用 FIFO 操作
regsToSet->SCIFFRX.bit.RXFFINTCLR = 1;//清除 FIFO 中断标志
regsToSet->SCIFFRX.bit.RXFFIENA=1;//启用 FIFO 中断

regsToSet->SCIFFRX.bit.RXFFIL = 0x08;//在 FIFO 状态(RXFFST[4:0])与该值匹配时生成中断
//五位值,最大11111


regsToSet->SCIFFCT.all = 0x00;//关闭自动波特率填充


regsToSet->SCICCR.all = 0x0007;// 1停止位,无回路
//无奇偶校验,8个字符位,
//异步模式,空闲线协议

//regsToSet->SCICTL1.all = 0x0003;//启用 TX、RX、内部 SCICLK、
//禁用 RX ERR、睡眠、TXWAKE

regsToSet->SCICTL1.bit.RXENA=1;//启用 RX
regsToSet->SCICTL1.bit.TXENA=1;//启用 TX

regsToSet->SCICTL2.bit.TXINTENA=1;//启用 TX 中断
regsToSet->SCICTL2.bit.RXBKINTENA=1;//启用 RX 中断



//*********
// sprug75a.pdf 中的公式表2-5
//1/4 SYSCLK = LSPCLK
// 200MHz SYSCLK = 50MHz LSPCLK

// 200MHz 9600波特 HBAUD = 0x02且 LBAUD = 0x8B。
// 120MHz 9600波特 HBAUD = 0x01且 LBAUD = 0x86。
// 200MHz 115200波特 HBAUD = 0x00、LBAUD = 0x35。
LSPCLK = cpuFrequency / 4;
BRR =(LSPCLK /(BaudRateToSet * 8))- 1;

//屏蔽位并分配寄存器
regsToSet->SCIHBAUD。all = brr >> 8;//屏蔽顶部字节
regsToSet->SCILBAUD.ALL = brr & 0xFF;//底部字节掩码
//*********

regsToSet->SCICTL1.all = 0x0023;//从复位中撤回 SCI

regsToSet->SCIFFTX.bit.TXFIFORESET = 1;
regsToSet->SCIFFRX.bit.RXFIFORESET = 1;



}


//********* 静态 char rxIsrBuffer[32]; 静态 int putRxBuffer=0; void sciaRxFifoIsr (void) { // FIFO 中有数据时 while (SCI_A_Regs.SCIFFRX.bit.RXFFST!= 0) { rxIsrBuffer[putRxBuffer]= SCI_A_Regs.SCIRXBUF.ALL;//读取数据 ++putRxBuffer; } SCI_A_Regs.SCIFFRX.bit.RXFFOVRCLR=1;//清除溢出标志 SCI_A_Regs.SCIFFRX.bit.RXFFINTCLR=1;//清除中断标志 }


//*********

我对如何诊断此问题的想法不多。 我将尝试设置其他中断、以查看我现在是否遇到相同的问题。

感谢您的帮助!

Scott

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

    这里似乎有两个问题在工作。

    1) 1)我怀疑您已使用"Hwi.MaskingOption_NONE"配置有问题的中断。 此配置将导致 ISR 被同一中断抢占。 如果您无法在下一个中断发生之前处理中断、则会发生您描述的情况。

    2) 2)是否确定要在中断源正确清除中断?

    我还担心"putRxBuffer"未复位为0、并且没有边界检查。 如果它的增量超过31、则阵列将溢出并导致各种问题。

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

    1) 1)我返回到 cfg 文件中的 HWI 设置部分、以确保我具有正确的掩码设置、并且在 CCS 中发现了一个错误。 默认情况下、选择 MaskingOption_Self。 我决定仔细检查生成的脚本是否与此匹配、我找不到本应生成的命令。 我必须返回 GUI、更改选项并保存、然后重新更改并保存、然后在脚本中显示生成的代码行之前进行保存。 我现在可以确认、设置了"是"、MaskingOption_Self。 我认为这可能需要解决、如果硬件默认值不是 MaskingOption_Self、则 GUI 不会假定与硬件相同的默认状态、并且可能不是唯一设置正确状态的状态。

    我清理/编译/运行了工程、并且在 RXINT 中断处理第一个中断后、仍会崩溃。

    2) 2)为了正确清除源、我一直使用 sci_loopback_interrupts_cpu01作为参考(它不是一个 symbisis 示例、我找不到该处理器的任何 SYSBIOS 库) 并初始化所有 sci 寄存器、使用相同的代码行清除中断中的寄存器。 我也已经浏览过数据表(sprug75a.pdf)、除非我遗漏了一些内容、否则一切看起来都是正确的。

    3) 3)我同意、putRxBuffer 确实有超出界限的可能性、我把它扔到那里、让我的脚弄湿、然后通过、看看寄存器发生了什么。 但是、我可以保证它不是、我一直在中断内设置一个断点、中断只会触发一次、BIOS 在中断后很快崩溃。 我还尝试完全注释掉中断中的所有代码、我遇到了相同的问题、第一次中断发生、留下中断、BIOS 在不久后崩溃。

    IV 能够使同一 sci 模块的 TX 中断多次触发、并且它不会使 BIOS 崩溃、但是一旦 RX 中断第一次触发并完成、BIOS 就会崩溃。

    我明天也会做这个工作、希望很快能再听到您的声音!
    Scott
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗯。

    我可以查看你的.cfg 文件吗?

    您是否曾尝试在.cfg 文件中使用 Program.stack 来增大 Hwi 堆栈大小?

    Alan

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

    当然、这是我的当前配置。

    e2e.ti.com/.../5277.app.cfg

    是的、已尝试增加硬件堆栈。 我已将其从256增加到512和1024、堆栈崩溃。

    我们又回来了,再次走过,仔细检查了发生的情况。 我步出 RX 中断、它将我带回到文件 HWI_ASM.s28 HWI_switchAndDispatch __I 函数。 硬件堆栈在178时保持稳定。 我单步执行该函数大约5个步骤、直到它在末尾到达 lretr、然后跳转到不可见的代码。 如果我再执行11次、Hwi 堆栈开始以线性方式增加而不停止。 之后的每一步都会将堆栈增加大约16、直到达到最大堆栈大小且 BIOS 崩溃。

    Scott

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您正在使用哪个版本的 SYS/BIOS? 这听起来像是 Hwi_switchAndDispatch ()中的一个错误、我们在后面修复了一个错误。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此外、我注意到您的 Rx 中断将"enableActk"参数设置为 true、但 TX 中断不会。 由于这两个都是 PIE 中断、它们是否应该配置相同?

    Alan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    哦、有趣的是、CCS 的另一个示例实际上没有更新脚本。 我在 GUI 中使用相同的设置、但脚本显示、否则、很好。 我已切换框并点击"保存一组"、它们现在在脚本中是相同的。

    嗯、这是一个很好的线索、我的故障或 BIOS 确认可能会发生一些问题。 我没有意识到 TX 在我的测试中没有这么做。

    我的 ti 目录中安装了 BIOS 6_46_04_53。

    问题:如果我使用 BIOS GUI 创建 HWI、BIOS 是否会为我正确设置 PIE 矢量表和 PIE 多路复用器? 是仅设置矢量表、多路复用器是我的责任吗?

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

    我非常确信、我们会执行启用中断所需的所有 PIE 管道。

    6.46.04.53中没有所有好的东西。

    尝试将 ti/sysbios/family/c28/Hwi_dep_asm.s28的副本与所附的版本进行交换(从文件名中删除'.txt'后)、然后重新构建您的应用程序。

    e2e.ti.com/.../3364.Hwi_5F00_disp_5F00_asm.s28.txt

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

    好的、听起来不错、我会尝试一下、让您知道我发现了什么。

    Scott

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尝试了新文件、没有更改任何内容。 仍然以相同的方式崩溃。

    我还尝试关闭 PIE 确认并手动将确认添加到 ISR、BIOS 仍然以相同的方式崩溃。

    我想我将尝试下一次:
    1) 1)安装新的 BIOS 版本只是因为、请确保它不会缺少其他一些错误修复。
    2) 2)可能会尝试手动设置 PIE 矢量表和多路复用器、BIOS 和 GUI 可能无法正确执行此操作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    啊啊啊啊啊,太适合安装新的 BIOS 了。 我将 properties/general/rtsc/products 和 repositors/sysbios 更改为最新版本(6.50.0.10)、并得到一整组编译错误。 我将为该问题启动一个新的线程。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、解决了这个问题、有助于安装所需的新 XDC 工具、并确保目标设置正确。

    最新版本的 BIOS 仍然崩溃。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    从中断返回时将执行的指令的地址可以在 Hwi 模块的'basic' ROV 视图中看到。 大概这是'lretr'跳转到的指令。 也许研究该指令之前的代码将提供故障的线索。

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

    您好、Alan、

    我返回到单步执行该程序、但我没有意识到对于显示"无可用源代码"的代码、您可以在"Disassembly"查看器中查看正在执行的操作。 在 lretr 之后、它会跳到地址0。 该段标记为__ISA:,汇编命令为 ITRAP0。 如果我保持步进、我保持在地址0、并且在经过12个步进后、HWI 堆栈开始增长。 我可以继续步进、直到它崩溃 Hwi 堆栈。

    在 ROV 视图中进行 poking、BIOS 空闲任务是运行中断之前被抢先的任务、返回地址本应位于 ti_sysBIOS_knL_idle_run__e_e ()内、但它跳转到地址0。


    是否正在取得进展:-)有什么想法为什么它一直跳到 ISR 陷阱?

    Scott

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我仍然怀疑接收 ISR 正在破坏堆栈。 堆栈上的返回地址与进入 ISR 时的返回地址不同。 该返回地址被推送到被中断的任务的堆栈。 您是否尝试增加空闲任务堆栈大小? ROV 任务详细视图是否显示所有任务堆栈均正常?

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

    ROV 显示任务堆栈和空闲堆栈正常、HWI 在卡在 ITRAP0中后最终溢出。

    堆栈确实已损坏、但我对此没有任何意义。 我创建了一个空闲循环、该循环使用增加的堆栈大小。 我已经将 ISR 修改为只有2或3行代码来清除中断、并且增加了 Hwi 堆栈大小、看不到它会破坏堆栈的任何原因。

    我想知道发送程序是否由于某种原因未正确保存和恢复堆栈。 当我离开中断并到达 HWI_ASM.s28的第105行时、它会执行分支检查、并决定将海峡跳转到第113行(非零$)、并且不执行中间的任何 movv 或 movel 指令。 在什么情况下、它决定不移回这些值、这是正常的吗?

    Scott

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    已决定检查 TX (工作)中断的工作原理、以便我可以比较和对比发生的情况并查找差异。

    在处理中断的方式上存在明显的差异。 这里是我在单步执行 TX 和 RX 中断时发现的内容

    TX:(正在工作)
    步出中断、跳转至 hwi.c 的第1142行 我可以继续步进、直到它到达第1189行、然后它跳转到 Hwi_asm.s28的第102行。 当它到达 lretr 时、它会跳回到 hwi.c 的1189 我可以继续单步执行而不会崩溃、似乎工作良好。

    RX:(崩溃)
    步出中断、跳转至 Hwi_asm_s28的第102行(从不转至 hwi.c)。 当我到达 lretr 时、我跳转到地址0和 ITRAP0。 一段时间后、Hwi 堆栈崩溃。

    我感觉共生过程中出现了问题、它没有为此特定处理器正确配置该特定中断。 我不明白为什么这些中断应该以不同的方式处理。 RX 中断不会返回到 hwi.c、所以 BIOS 无法正确处理它。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当发生嵌套中断时、两个返回路径之间会出现差异。 在非嵌套的情况下、不会采用分支并且 SP 会更新为指向任务堆栈地址、在切换到使用 Hwi 堆栈运行 ISR 之前存储根寄存器上下文的位置。 在嵌套中断情况下、假设返回寄存器上下文已经在 Hwi 堆栈上、因此不执行 SP 切换。

    在这两种情况下、RPC 寄存器都包含执行 ldtr 时将加载到 PC 中的值。

    在好的和坏的情况下,在执行 ldtr 之前 RPC 和 SP 寄存器的值是什么?

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

    右前 TX:(良好)
    RPC:0x08b1d8 (ti_sysbios_family_c28_hwi_dispatchC__i () hwi.c 行1084)
    SP:0x017e

    右前 RX:(不良)
    RPC:0x0892d0 (TI_SYSBIOS_family_c28_hwi_d调度 Core__I () Hwi.c 第1143行)
    SP:0x0130

    Scott
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    因此、错误情况下的 ldtr 应将0x892d0移动到 PC 中、并将0x130位置处的内容加载到 RPC 中。
    在错误情况下、恰好在 lretr 执行之前从0x130进行存储器转储可能会有所帮助。
    假设0x130中有不良的东西、检查它在 Rx 中断开始时的值、看看它是否会在 ldtr 指令期间获取的时间发生变化。
    如果它发生了变化、您可以在写入位置0x130时配置硬件观察点、并查看谁在执行写入操作。

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

    这是个好主意:-)

    好的、这里是我的屏幕截图。 第一个屏幕截图是我第一次进入中断时的存储器位置:




    内存不会改变、直到我进入 lretr、它在那里写入该地址。 0x0892D0处的指令是一个推送命令。 但是、"Disassembly"视图显示它会跳转至地址0、并在我继续步进时保持在该位置

    这里是22个步骤后、继续向下一个地址写入相同的重复值。

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

    我失去了函数原型的跟踪、但没有意识到它在我的头文件中。 问题是原型:
    中断空 sciaRxFifoIsr (void);

    我的函数被正确实现为:
    空 sciaRxFifoIsr (空)

    所以我推断它是一个原型名称中由非 BIOS 处理的中断、这一定是它从未使用过 hwi.c 的原因 我很惊讶、编译器没有对我说、它们都没有相同的格式。

    感谢 Alan 的帮助! 我真的很感激:-)
    Scott