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/PROCESSOR-SDK-AM335X:信标发布时的数据中止

Guru**** 2925060 points

Other Parts Discussed in Thread: SYSBIOS

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/666426/rtos-processor-sdk-am335x-data-abort-on-semaphore-post

器件型号:PROCESSOR-SDK-AM335X
Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

您好!

我使用 CCS 7.2、TI 编译器17.9、BIOS 6.46.5.55作为我的环境。

我正在尝试使用自己的低级接口将自己的 USB 数据连接插入 NDK 中:

//NIMUDeviceTable[0].init =&CpswEmacInit;
NIMUDeviceTable[0].init =&USBCxnInit; 

一切正常、除非我在激活 DNS 模块时获得可靠的数据中止异常。 它们是可靠且可重复的。  每次都是如此。

首先、我是否正确分析了这一点?

ThreadType_Hwi 中发生异常。
Hwi 句柄:0x0。
Hwi 堆栈基地址:0x804b3cf8。
Hwi 堆栈大小:0x10000。
R0 = 0x80005eb4 R8 = 0x80005ea8
R1 = 0x14d20300 R9 = 0x6000011f
R2 = 0x00000001 R10 = 0x48200000
R3 = 0x804c3c34 R11 = 0x00000001
R4 = 0x00000001 R12 = 0xe6e5fcc
R5 = 0x804c90ac SP (R13)= 0x804c4c
R8 = 0x804c R15 = 0x804c (R180x804c) R180x804c = 0x804c (R180x80245c) R8
= 0x804c (0x804c) R180x80245c = 0x80245c (0x80245r4
0x804c90a4
DFSR = 0x00000005 IFSR = 0x00000000
DFAR = 0xe6e5f857 IFAR = 0x00000000
ti.sysbios.family.arm.exc.exc.exc 例外:第205行:E_dataAbort:PC = 0x8048d26c、LR = 0x804212cc。
xdc.runtime.Error.raise:终止执行 

PC 与 SP...相同。  现在、这很奇怪。  将 PC 重新放入 CCS 内的寄存器并不起作用、因为它来自 Sys/BIOS 内部、SP 寄存器不正确。  但我查看了 PC 中的地址、以及它在映射文件中的位置:

8048 cfd8. 000001e8. :unified_locale.obj (.text:_ZNSt4priv11__put 浮点 ISt19ostreambuf_iterIwSt11char_traitsIwEEEET_Rns_16_basical_ioceES5_RSt8ios_basewwwjRKss)
8048d1c0 000001e0 SYSBIOS.aea8fnv:BIOS.obj (.text:ti_SysBIOS_KNL_Semaphore_post__E)
8048d3a0 000001dc rtsv7A8_a_le_n_v3_eabi.lib:unified_locale.obj (.text:_ZNKSt9Money _putIwSt19ostreambuf_iterIwSt11char_traitsIwEEE6do _putES3_bRSt8ios_Basewe) 

这就在 Semaphore_post 调用的中间。 确切地说、172个字节在中、或43个字(32位)在中。

那么、下面是正在进行的操作:

我有一个 USB 硬件中断、它正在加载缓冲区并从中断内部调用"Semaphore_post"来告诉"NetCtrl.c - NetScheduler() "任务数据已就绪、它会调用"NIMUPacketService"、它从 PBM 获取数据包并将其传递到堆栈。

在一种情况下、它会将数据传递到我的代码中、每个人都很高兴。 我的服务器工作正常。

在 DNS 情况下、它会创建一个任务来处理该请求、当下一个硬件中断发生时、它似乎处于处理过程中、而下一个硬件中断又从 HWI 内部调用 Semaphore_Post、并发生"数据中止"。

我正在按照 Sys/BIOS 文档的指示使用"Hwi_create()"创建硬件中断。

Hwi_Params_init (&usbInterruptParams);
ERROR_INIT (&usbInterruptEb);
usbInterruptParams.arg = 0;
usbInterruptParams.priority =-1;
usbInterruptParams.enableInt = false;
usbHwi = Hwi_create (18、USBInterruptHandler、&usbInterruptParams、&usbInterruptEb);
if (usbHwi = NULL){
返回 false;
} 

我已经对其进行了测试、将大量数据传递到我的服务器代码中、没有问题。 在 DNS 情况下、消息很小、因此我确信它不是缓冲区溢出或类似的任何内容。

我已将任务堆栈大小设置为8192、远远超过 NDK 建议的5120。

那么、我的问题是 :什么可能导致 HWI 内部的数据中止(该数据中止是使用正常的 Hwi_create()调用和默认值创建的)? (这种情况的"默认"优先级是多少?  该文档只是说它将使用"适当"的值)。

或者、NDK 内的 DNS 任务中的什么可能与来自中断的 Semaphore_Post()调用发生冲突?  这两个函数都是 TI 库中的函数、因此我对它们的了解不够清楚。

或者、我还可以查看哪些其他信息来帮助更接近原因?

或者有其他有关调试它的建议吗?

任何建议都值得赞赏。

-CSW

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    RTOS 团队已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Chris、

    Hwi 的默认优先级(-1)定义为:
    /*
    *-1 Sentinel 优先级是 hal Hwi_create()传递的默认优先级。
    *将其转换为可能的最低(逻辑)优先级,即
    *我们的默认优先级。
    *
    if (params->priority =-1){
    hwi->priority = Hwi_NUM_Priorities - 1;


    Hwi 的优先级始终高于任何任务。 数据中止问题应与优先级设置无关。

    您是否尝试使用 ROV 来分析问题? 请参阅 processors.wiki.ti.com/.../BIOS_FAQs

    使用一个可调试定制 SYS/BIOS 库也可能有所帮助: processors.wiki.ti.com/.../BIOS_FAQs

    幻灯片中介绍了更详细的异常调试技术:
    training.ti.com/.../TIRTOS_CCSDebugging.pdf (training.ti.com/debugging-common-application-issues-ti-rtos)

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

    车架、

    感谢您的回复、我查看了相关链接、信息具有教育意义...  但我无法使用这些工具到达任何位置

    CCS 中的 CFG 文件"可用产品"没有任何 UIA、因此无法添加任何仪器。

    每次我尝试启动 ROV 时、我都会收到一条消息:"器件保持在复位状态"。 所以这不会让我在任何地方。

    我启用了所有堆栈和堆检查、但没有向我发出任何警报。  崩溃仍然相同。

    Todd 的视频、在中大约6:50提到使用 MPU 来锁定堆栈顶部的一个小块。 但是、他很快就解决了这个问题、我在 GUI (XGCONF)的任何位置都找不到任何 MPU 模块。 这似乎是一个好主意、但我必须完全分解每个任务的单个堆栈、然后手动修改 MMU 表以设置权限。 不是一个有趣的潜在客户。 此外、当异常发生时、我无法知道它是哪个任务。

    我尝试实现"解码处理程序"、但该视频用于"ti.sysbios.family.arm.m3/Hwi"。 从逻辑上讲、我尝试将其更改为"ti.sysbios.family.arm.a8.hwi"、但 XDC 编译步骤被条形化。 除了 M3、我不知道它应该是什么。。。 (愚蠢的我认为它的组织结构是一样的)。  我不确定它是否已启用、因为内核转储在我单步执行时会存储大量 MCU 状态、这是我在原始帖子中粘贴的内容。  但检查 CFG 文件不会告诉我是否已启用。

    大多数情况下、我会得到数据中止、但有时是"无效指令"、有时是其他事项。  因此、我的工作原理是、某些缓冲区溢出或堆栈溢出会导致它"弹出"一个无效的返回地址到 PC 中、然后它进入某个深度空间。

    因此、我能够确定 DNS 任务使用的堆栈太小。  假设使用 XGCONF 工具为任务设置堆栈大小可以满足这一要求、我很傻。  事实证明、NDK 需要在运行时使用配置调用设置堆栈大小:

    结果= 16384;//大于3100字节...
    CfgAddEntry (netcfg、CFGTAG _OS、CFGITEM_OS_TASKLOW、
    CFG_ADDMODE_UNIQUE、sizeof (unsigned int)、(unsigned char *)&result、0); 

    这是 DNSServerOpen()启动"dns"任务时使用的值...  但是、"dns"任务启动"dnss_task"任务、硬编码值为1200。  因此、CFG 文件不仅不会对该任务堆栈大小执行任何操作、还会忽略配置设置。  

    最好是在 第3.1.2.2.1节中的 NDK SPRU523说"在选择任务堆栈大小时应小心、并使用 SPRU524第 H.3.9节中描述的 CfgAddEntry 调用进行设置"。  如果拔出灰色的毛发,我将会节省一周时间。

    因此、对于下一个尝试学习此内容的人:请勿依赖 CFG 工具设置任务堆栈大小。  使用 CfgAddEntry 调用、并知道在 NDK 中、仍然有一个可能太小的硬编码值、因此应该对其进行修改并重建 NDK (或者像我正在做的那样简单地将源代码导入到项目中)。

    -CSW

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

    你真的深入到了 NDK 堆栈中、很高兴知道你有一个突破!
    让我在内部检查 DNS 服务器任务中为什么硬编码值为1200。

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

    Garrett、
    谢谢。
    我不知道哪个任务正在堆栈上(或下)、因为有两个任务、一个任务启动另一个任务。 因此、我不知道1200字节的值是不是问题、还是另一个问题。 在这个阶段、我只是安全地使用这两个器件(我将1200更改为5120、而不是16K)

    谢谢。
    -CSW

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

    Chris、

    任务堆栈从堆中分配。 您是否尝试增加.cfg 中配置的堆大小? Todd 幻灯片中描述的 HeapTrack 可以帮助您确定所需的堆大小。

    您可能知道、对于 TI-RTOS、有两种不同类型的堆栈硬件中断(Hwi)和软件中断(Swi)使用单个系统堆栈。 此堆栈的大小可通过.cfg 文件进行配置、例如
    program.stack = 8192;

    任务堆栈:每个任务都有自己的堆栈。 此堆栈的大小在创建任务并从堆中分配时指定。 堆的大小可通过.cfg 文件进行配置、例如
    VAR BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.heapSize = 16384

    此致、
    Garrett

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

    Garrett、

    我已经将 program.stack 大小增加到了荒谬的值。  例如0x4FFFF。  没有什么不同。  与 BIOS.heap 相同。

    我意识到每项任务都必须有自己的堆栈、我只是不清楚它是如何或在何处从...获取该内存的。  

    从主程序堆栈中删除?  然后、它必须确保与主 CPU 堆栈没有冲突。

    从堆? 然后、它必须在动态"Create_Task"函数中包含分配。

    现在、由于您的回复、我看到任务堆栈来自堆、与程序堆栈无关、而程序堆栈可能仅供任务管理器和"主"线程中的任何内容使用。

    但 CFG 文件中的这些大小与 NDK 没有任何区别。 由于在 NDK 的层级中、堆栈大小值取自其他设置、而不是来自 CFG 文件。  我认为这些值 需要在程序堆栈或堆的大小限制范围内、因为它们仅在这些范围内使用该内存(作为故障排除步骤、我已经大幅增加了该内存)

    因此、崩溃不是因为堆太小。  它足够大、可以容纳大量任务。  这是因为任务堆栈的 NDK 分配太小。

    -CSW