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.

[参考译文] TMS320F28066:即使任务优先级为14并且其模式已就绪、也不会从 SYSBIOS 调用任务输入函数

Guru**** 2390755 points
Other Parts Discussed in Thread: SYSBIOS

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/837169/tms320f28066-task-entry-function-is-not-called-from-sysbios-even-though-task-priority-is-14-and-its-mode-is-ready

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

您好!

我遇到了一个问题、即使 任务优先级为14 (非-1)且其模式已就绪(我在运行时通过不同的任务检查了任务 stat)、也不会从 SysBIOS 调用任务条目函数。  此问题发生在我们的某些电路板上、但并不发生在所有其他电路板上(相同/相同的硬件设计)。   此任务是静态创建的。  如果我只是修改代码以输出一些调试日志、则不会出现此问题。  此外、调试器运行时不会出现此问题。  我确认了任务堆栈和系统堆栈(ISR)足够大、因此没有堆栈溢出。

我的环境:

CCS 版本: 5.5.0.00077  

编译器版本:TI v6.1.3

XDCtool 版本:3.25.4.88

SYSBIOS 版本:6.35.1.29

该任务按如下方式静态创建(实例#0):

/* Object__table_V */
ti_SysBIOS_KNL_Task_Object_ ti_SysBIOS_KNL_Task_Object_Table__V_V[6]={
{/*实例#0 */
{
((ti_SysBIOS_KNL_Queue_Elem*)((void*)&ti_SysBIOS_KNL_Task_Object__table_V[0].qElemm))、//下一步*/
((ti_SYSBIOS_KNL_Queue_Elem*)((void*)&ti_SYSBIOS_KNL_Task_Object_Table_V_V[0].qElem*))、/* prev */
}、//* qelem */
(XDC_INT) 0xe、/*优先级*/
(XDC_UINT) 0x4000、/*掩码*/
((XDC_ptr) 0)、/*上下文*/
TI_SYSBIOS_KNL_Task_Mode_inactive、/*模式*
((ti_sysbios_KNL_Task_PendElem*) 0)、/* pendElem *
(XDC_SizeT) 0x200、/* STACKSIZE *
(((void*) ti_SYSBIOS_KNL_Task_Instance_State_0_STACK__A)、/* STACK *
0、/* stackHeap */
(((XDC_void (*)(XDC_UARg、XDC_UARg))((XDC_Fxn) taskReceive))、/* fxn *
((XDC_UARg)(0x0))、/* arg0 */
(((XDC_UARg)(0x0))、/* arg1 */
((XDC_PTR) 0)、/* env */
(((void*) ti_SYSBIOS_KNL_Task_Instance_State_0_hookEnv__A)、/* hookEnv *
1、//* vitalTaskFlag */
0、/* readyQ */
(XDC_UINT) 0x0、/* curCoreId */
(XDC_UINT) 0x0、/*关联性*/
}、

如果您有任何信息/线索、 请提供支持。

谢谢!

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

    您好!

    我的第一个猜测是、较高优先级的任务正在耗尽较低优先级的任务。 如果在连接 CCS 时出现问题、 我建议查看 ROV 以查看正在运行的任务。 或启用日志记录并使用执行图。

    由于问题仅在没有调试器的情况下发生、您能否添加闪烁 LED 或 GPIO 的空闲函数。 然后、您可以确定可能发生饥饿。  高优先级任务如何放弃处理器?

    Todd

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

    感谢您的回复。  这是最高优先级的任务、因此不应让它挨饿。  任务函数甚至不会被调用。  其他较低优先级的任务也可以。

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

    当出现错误状态时、您可以从系统收集什么信息(如果有)?

    程序是否在杂草中出现,或者另一个线程是否仍在运行?

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

    其他线程正在运行(任务函数被调用)。  有两个优先级为14的任务(系统中最高)。  具有14的另一个任务是正常的(任务函数被调用并运行)、但该任务不是(任务函数未被调用)、即使其任务模式已就绪 且其优先级为14 (非-1)。  我使用 task_stat API 从其他任务收集了此信息。  其他任务(较低优先级) 也可以。  

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

    下一组问题是:

    1. 您在系统中做了什么?  您不断提到优先级不是(-1)、似乎建议在某个时候将任务优先级设置为-1?

    2. 您重现问题的容易程度如何?  您需要多长时间才能看到问题?

    3. 您是否已在调试器中尝试"免费运行"以查看是否可以重现问题?

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

    1)是的。  开始时、一个启动任务(最低优先级任务)运行(其余任务设置为-1优先级)。   然后、启动任务会将原始有效优先级设置回原来的有效优先级。  

    在启动任务中、

    taskKey = Task_disable(); 

    //将有效优先级设置回所有任务- Task_setPri
    Task_restore (taskKey);
    

    注意:我提到优先级-1的主要原因是没有执行优先级为-1的任务、所以我只想说不是这样。

    2) 2)这不是100%可重现的。  但一旦发生、之后很容易发生。

    3)我尝试在连接调试器的情况下重现此问题,但到目前为止,这是不幸运的。

    谢谢!

     

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

    您好、感谢您的帮助。   即使任务函数的优先级为14且模式就绪、也没有被调用的原因是什么? 我还确认了正确的函数指针在运行时存储在任务对象表 ti_sysbios_KNL_Task_Object__table__V 中。  模式已就绪、但任务函数未被调用。  此外、正在执行较低优先级的任务、这应该是不正确的、因为此任务是最高优先级的任务、并且模式已就绪。

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

    您是否有方法读取内存状态并在问题发生时进行打印?

    除非您有某种方法来执行此操作、否则无法判断任务在哪里。

    每个任务级别都有一个与其关联的就绪队列(双链接列表)。  最有可能发生的情况是任务被删除
    优先级为14的就绪队列。  如果您可以读取内存、那么我们可以查看队列并尝试确定任务的位置。

    在任务模块状态中、 有一组 readyQ。  您是否可以从另一个任务打印这些队列的状态?

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

    感谢您的回复。  出现问题后、我将尝试打印 readyQ。

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

    我没有在日志中输出整个 readyQ、但我在任务对象(ti_SysBIOS_KNL_Task_Object__table__V)中记录了"readyQ"。

    如果不出现此问题,则此 readyQ 具有 b4f8。  该地址来自下面的区域、因此看起来不错。

    0000b4c0 _ti_SysBIOS_KNL_Task_Module_State_0_readyQ__A

    当问题发生时、此 readyQ 为0x38。  这来自下面的区域。   

    00000037 __PLAT__

    根据 OFD200输出、这是 XDC.meta


    2>"XDC.meta" 加载地址: 0x00000000运行地址: 0x00000000 尺寸: 0xf6 对齐: 1 已加载到器件上:否 地址单元大小:16位 文件偏移量: 0xfb6. #相关信息: 0 重新分配文件偏移量:0x00000000 #行: 0 行文件偏移量:0x00000000 TI-COFF s_flags:0x00000050 TI-COFF s_flag: STYP_COPY TI-COFF s_flag: STYP_DATA

    如果您对此有任何信息、请提供建议。

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

    我从较低的任务中检查了任务模块中的 readyQ。 索引14的 readyQ 在"next "/"prev"变量中有自己的地址、这意味着它是空的。 我从优先级较低的任务中检查此值、因此无论是否存在问题、此值都是相同的。

    此外、我还检查了该任务的任务对象表中的 qelem 值。  当问题不存在时、任务对象表中的"qelem.next "包含优先级相同(14)的另一个任务的任务对象表的值。  当问题发生时、此"qelem.next "包含0x38、这毫无意义。

    为了确保存储器区域未损坏、我在该任务的任务对象表中检查了 curCoreId。  无论问题是否存在、该值都为零。

     

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

    我获得了有关该问题的更多信息。

    在主函数开始时、此任务对象中的 readyQ 包含正确的地址、_ti_SysBIOS_KNL_Task_Module_State_0_readyQ__A 的第14个索引
    我们的软件会初始化硬件(时钟、GPIO、UART 等)。 然后、通过调用 Task_setPri ()、它将所有任务(除了作为最低优先级任务的内务处理(即启动任务)任务)的优先级更改为-1。   因此、优先级为-1的所有任务都处于 inactiveQ 中。

    然后我们的软件通过调用 tibios_start()来启动 sysbiois。  后台处理任务运行。 然后执行与应用相关的初始化。  之后、我在该任务的任务对象中检查了 readyQ。 readyQ 包含任务模块状态下的 inactiveQ 的地址、该地址是正确的。  因此、在这一点上、它看起来很好。

    然后,所有其他任务的优先级由 set_pri ()设置回原始优先级。 然后调用 task_restore(),以触发任务切换到 最高优先级任务。  

    当问题发生时、 不调用此任务的任务函数、此任务的任务对象的 readyQ 为0x38。  当我出于调试目的更改代码时、此问题很容易变得不可重现、因此我很难找到将0x38写入 readyQ 的位置。

    我们的软件中总共有6个任务。 此任务是对象表中的第一个条目(ti_sysbios_KNL_Task_Object_Table___V)。   因此、当没有问题时 、此任务是执行的第一个任务、因为其优先级最高、为14。 当问题发生时、此任务不会执行、因此优先级为14的另一个任务 将首先执行。

    我还检查了问题发生时任务是处于 inactiveQ 还是 terminatedQ 中、但两者都是空的。  我将检查一个 Hwi 中断是否相关、但看起来不太可能。  如果您有任何线索/信息、请提供建议。

    [代码片段]

    在 Main 函数中、
    //初始化 HW
    inithw();

    //将优先级设置为-1,但后台处理任务除外
    对于(j=0;j < count_of (taskHandles);j++)

    if (taskHandles[j]=startup_task)
    继续;
    原始多数[j]= Task_getPri (taskHandles[j]);
    Task_setPri (taskHandles[j]、-1);

    //启动操作系统。 此函数永远不会返回。
    tibios_start();

    在后台处理任务中、

    XDC_UINT 任务键;

    // initi 应用程序
    initApplication();

    taskKey = Task_disable();

    //打开所有任务。
    对于(j=0;j < count_of (taskHandles);j++)

    if (taskHandles[j]=startup_task)
    继续;

    Task_setPri (taskHandles[j]、originalPriorities [j]);

    //重新启用任务抢占
    Task_restore (taskKey);

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

    您能否解释一下是否反复调用此过程、以及是否仅在您看到问题发生一段时间后才调用此过程?

    看起来任务对象中的某个对象可能破坏该指针。

    您能否尝试添加到.cfg 文件中:

    Task.objectCheckFlag = true;

    您还可以安装自己的自定义检查功能:

    **。cfg
    *@p (代码)
    * var 任务= xdc.useModule('ti.sysbios.knl.Task');
    *
    *//启用任务对象数据完整性检查
    * Task.objectCheckFlag = true;
    *
    *//安装自定义任务对象检查函数
    * Task.objectCheckFxn ="&myCheckFunc";
    *@p


    默认情况下、我们只检查任务对象中不会更改的字段、但您可以对其进行自定义。

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

    感谢您的回复。  问题是未调用任务函数、因此任务根本不运行。  正如我在上一个帖子中提到的、我在该任务的任务对象中检查了 readyQ、它在与应用程序相关的初始化之后具有 inactiveQ 的地址、因此看起来不错。  此外、我检查了模块状态下的 readyQ、这也具有正确的 readyQ 地址(即_ti_SysBIOS_KNL_Task_Module_State_0_readyQ_A)、因此看起来不错、因为当任务的优先级从-1更改为14时、任务对象中的 readyQ 分配给第14个 readyQ 的地址。  在 task_setpri ()中禁用 Hwi 中断、因此禁用 Hwi 中断。   

    我将尝试您的建议。  

    谢谢!

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

    在我使用的 SYSBIOS 版本(6.35.1.29)中,ObjectCheckFlag 不可用。

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

    是否可能出现硬件故障(例如 RAM 或闪存)?   如果是、您能告诉我如何检查它吗?

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

    不、我很确定情况并非如此。  在这样的情况下、我会期望出现某种异常或总线错误...这种情况更具灾难性。
    这听起来更像是某种导致腐败的种族状况。

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

    好的、只是问题仅发生在2块电路板上。  如果您有任何线索/信息、了解此任务任务任务对象中的 readyQ (我已经提供了代码片段)如何获得错误值(0x38)、请提供建议。

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

    我不知道为什么会在这里放置0x38的值。  在这种情况下、您需要调试器在地址设置一个硬件探测点并查看何时写入该值。

    是否可以移动到更高版本的 BIOS?

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

    遗憾的是、我无法使用调试器重现问题。  是的、我可以尝试使用更高版本的 BIOS 来找出根本原因。  您建议使用哪个版本?   唯一的问题是问题可能无法重现。  正如我提到过的、仅添加一些代码以进行调试就会使问题不可重现。   

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

    我没有更改过 sys biis 版本、但我进一步研究了它。

    我发现、仅仅放置一行 asm ("nop")即可解决问题。  我将其放入甚至不会执行的代码中(仅在问题发生后超过5秒才会执行)。  此更改会导致闪存中某些.text 段发生2个字节的移位、但 RAM 段保持不变。

    此外 、我不是在该位置放置 asm ("nop")、而是将它放置在 Task.c 的 Task_Self ()中  此更改将对.text 段的影响降至最低、因为 Task_self 被放置 在更靠近.text 段末尾的位置。  我的应用代码文本部分在闪存中保持不变。  此更改后、问题就会消失。   

    这2个字节的移位不会影响闪存扇区中的代码放置。   

    如果您有任何信息/线索、请提供建议。   

      

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

    没有已知的错误、代码的2个字节的移位可以解决问题。

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

    感谢您的回复。  我尝试了 SYS/BIOS 的更高版本(6.35.6.56)。  这样、问题就会消失。   由于闪存中上述2个字节的移位也会导致问题消失、 我无法确定根本原因是什么。