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.

[参考译文] CC1352R:TI15.4堆栈-新任务优先级问题

Guru**** 2484615 points
Other Parts Discussed in Thread: CC1352R

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

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1195929/cc1352r-ti15-4-stack---new-task-priority-problem

器件型号:CC1352R

大家好、

我将使用 TI15.4堆栈和基于收集器示例(SDK6.20)的 CC1352R 开发应用。

我为要求严苛的实时应用添加了一项新任务、该任务可能占用收集器处理时间的约50-60%、并且对时间非常敏感。 这是一种专有的、不断重复的有线通信协议、这是这个新任务所控制的。  

我遇到的问题是这个新任务的时间、大部分时间它工作正常、但有时处理对于我的应用来说太晚了。 我尝试了不同的优先级、我尝试了与应用任务相同的级别、以及高于应用和 Mac 任务的级别、但延迟有时仍然会发生。 我已禁用演示中的所有耗时功能、如 CUI、UART、SPI、显示等。 我怀疑这个问题可能与无线电/Mac 端发生的 Hwi 或 Swi 有关。 我知道无线电/无线协议对时间非常敏感、但这种有线通信也是如此。 因此、我必须找到一种在需要时允许这两项任务的好方法、而不会导致彼此之间出现延迟。

是否有任何帮助查找和/或解决问题? 我创建的这项新任务不能有任何延迟、任何高于50us 的任务都已经存在问题。

谢谢。

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

    您好!

    您是否有一个基准、使此有线通信任务能够始终独立运行? 也就是说、当删除包括 TI 15.4 Stack 在内的所有其他内容时。

    我已通知 SUB1-GHz 团队、以获得进一步的见解和评论。

    谢谢、
    Toby

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

    尊敬的 Toby:

    感谢您的快速回复。

    是的、如果我从未启动主应用程序和 Mac、则此新任务将完美运行。  

    谢谢

    JD

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

    JD、您好!  

    HWI 具有最高优先级、并且堆栈时序对于保持堆栈级最后期限至关重要。  

    当堆栈的时序至关重要并且可能以最高优先级执行时、我可以考虑几种情形:CSMA/LBT 和信标/广播消息的传输。  

    您如何测量应用中的延迟? 计划命令或触发事件的时间点到预期发生的操作之间的持续时间。  您预计在艰难的最后期限内会发生什么?  

    此致、

    SID

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

    您好 Sid、

    现在、我进行了以下设置。

    1 -一个 Launchpad 用作波形发生器来模拟我的有线协议、我这样做了、您可以在您的一侧对其进行测试。 此 Launchpad 的代码是此线程中相关性较低的部分、但如果您想复制该代码、仍然很重要。 它基于 SDK 中的 timerled 演示。 代码为:

    #include <stddef.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/Timer.h>
    #include "ti_drivers_config.h"
    
    static Timer_Handle timer0;
    static Timer_Params params;
    
    static Timer_Handle timer1;
    static Timer_Params params1;
    
    void timerCallback(Timer_Handle myHandle, int_fast16_t status);
    void timerCallback1(Timer_Handle myHandle, int_fast16_t status);
    
    void *mainThread(void *arg0)
    {
        GPIO_init();
        Timer_init();
    
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
    
        Timer_Params_init(&params); //off time
        params.period        = 938;
        params.periodUnits   = Timer_PERIOD_US;
        params.timerMode     = Timer_ONESHOT_CALLBACK;
        params.timerCallback = timerCallback;
    
        Timer_Params_init(&params1);// on time
        params1.period        = 265;
        params1.periodUnits   = Timer_PERIOD_US;
        params1.timerMode     = Timer_ONESHOT_CALLBACK;
        params1.timerCallback = timerCallback1;
    
        timer0 = Timer_open(CONFIG_TIMER_0, &params);
        timer1 = Timer_open(CONFIG_TIMER_1, &params1);
    
       if (timer0 == NULL || timer1 == NULL)
        {
            GPIO_write(CONFIG_GPIO_LED_1, 1);
            while (1) {}
        }
    
        if (Timer_start(timer0) == Timer_STATUS_ERROR)
        {
            while (1) {}
        }
    
        while(1) {}
    
        return (NULL);
    }
    
    void timerCallback(Timer_Handle myHandle, int_fast16_t status)
    {
        GPIO_toggle(CONFIG_GPIO_LED_0);
        Timer_stop(timer0);
        Timer_start(timer1);
    }
    
    void timerCallback1(Timer_Handle myHandle, int_fast16_t status)
    {
        GPIO_toggle(CONFIG_GPIO_LED_0);
        Timer_stop(timer1);
        Timer_start(timer0);
    }

    该信号仿真占空比约为22%的时钟波形、然后为其他器件(在本例中为收集器)发送数据打开一个机会窗口。 虽然我在这个演示中没有发送任何数据、因为我在发生计时问题之前就遇到过。

    2 -一个从 SDK 运行收集器演示的 launchpad、在 FH 模式下、广播和跟踪被禁用、我在 main 中向其中添加了一个新任务、与应用任务相同的任务参数、但 我选择的优先级为5、 排除应用程序和 Mac 任务创建的延迟。 main.c 中的新任务函数遵循与收集器应用任务相同的架构:

    Void newTaskFxn(UArg a0, UArg a1)
    {
        newtask_init();
        while (1)
        {
            newtask_process();
        }
    }
     

    然后我创建了一个 newtask.c 文件和相应的头文件。 在 c 文件中、我具有以下内容:

    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/BIOS.h>
    #include <stdint.h>
    #include <stddef.h>
    #include <stdio.h>
    #include <ti/drivers/GPIO.h>
    #include "ti_drivers_config.h"
    
    Semaphore_Struct sleeperSem;
    Semaphore_Handle sleeperSemHandle;
    uint32_t timestamp,currentTime, elapsedTime;
    
    void dataCallback(uint_least8_t index)
    {
        GPIO_toggle(CONFIG_GPIO_3);
        timestamp = Clock_getTicks();
        Semaphore_post(sleeperSemHandle);
        GPIO_toggle(CONFIG_GPIO_3);
    }
    
    void newtask_init(void)
    {
        GPIO_init();
        GPIO_setConfig(CONFIG_GPIO_3, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_4, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_16, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        GPIO_setConfig(CONFIG_GPIO_DATA_IN, GPIO_CFG_IN_PD | GPIO_CFG_IN_INT_RISING );
        GPIO_setCallback(CONFIG_GPIO_DATA_IN, dataCallback);
        GPIO_enableInt(CONFIG_GPIO_DATA_IN);
    
        Semaphore_Params semParam;
        Semaphore_Params_init(&semParam);
        semParam.mode = Semaphore_Mode_BINARY;
        Semaphore_construct(&sleeperSem, 0, &semParam);
        sleeperSemHandle = Semaphore_handle(&sleeperSem);
    }
    
    void newtask_process(void)
    {
        Semaphore_pend(sleeperSemHandle, BIOS_WAIT_FOREVER);
        GPIO_toggle(CONFIG_GPIO_4);
        GPIO_toggle(CONFIG_GPIO_4);
        currentTime = Clock_getTicks();
        elapsedTime = (currentTime >= timestamp) ? (currentTime - timestamp) : (UINT32_MAX - timestamp + currentTime + 1);
        if ((elapsedTime) >= 100 / Clock_tickPeriod)
        {
            GPIO_toggle(CONFIG_GPIO_16);
            GPIO_toggle(CONFIG_GPIO_16);
        }
    }

    新任务处理在信号量上挂起、该信号量通过 GPIO_DATA_IN 上的上升沿中断创建的 GPIO 回调进行发布、而 GPIO_DATA_IN 上的上升沿中断通过一根导线物理连接到信号发生器 Launchpad 的 LED_0。  

    为了进行调试、我添加了 GPIO3、在 GPIO 数据回调函数的开始和结束时切换2次、以及在 newtask_process 中的信标挂起后切换2次的 GPIO4、 GPIO16在信标挂起后也被切换2次、但只有在回调被激活后超过100us 的情况下、才能完成此操作、方法是在回调开始时、在信标挂起之后通过 clock_getTicks()手动收集时间戳、并计算经过的时间。 那么、这就是我轻松识别发生的延迟的方法。   

    对于调试信号、根据您提到的内容、我还将这些添加到 main.c 中的 appTaskFxn 中、以便将延迟与 TX 和 RX 相关联:

    IOCPortConfigureSet(CONFIG_GPIO_24, IOC_PORT_RFC_GPO3, IOC_IOMODE_NORMAL); //TX
    IOCPortConfigureSet(CONFIG_GPIO_22, IOC_PORT_RFC_GPO0, IOC_IOMODE_NORMAL); //LNA

    3 -我还有3个其他 LaunchPad、它们也以 FH 模式运行传感器演示。 但是、即使没有传感器、您仍然可以看到发生了延迟、尽管传感器会使情况恶化。

    4 -我有一个检查所有这些信号的逻辑分析仪。

    如果我放大红色信号的一个脉冲、即指示延迟的 GPIO16、我可以看到它几乎始终与 LNA 信号的转换相关:

    最后一个屏幕截图也显示了黄色切换之间的一些轻微延迟(回调持续时间)、但这些延迟相对较小、因此不是一个大问题。 但是、回调和挂起后运行的代码之间的延迟太大、不符合我们的要求。 我还尝试添加我希望在回调中运行的代码、而不是在挂起之后运行、以便使我的一侧的处理更加紧急、但回调也会等待 LNA 转换中发生的任何情况。

    我不确定导致延迟的原因、但它肯定与无线电相关。 但我最重要的问题是、如果可能、如何避免这种情况呢? 因为这种延迟会使收集器对信号中的数据的响应对于线协议来说太晚、通信将失败。 但我也明白对讲机不能等待其他任何操作、否则对讲机将失败。  

    这里有什么可能性吗?  

    我尝试使用传感器控制器来处理这种有线协议、但不幸的是、我内存不足... 我正在尽量避免在混合中添加另一个 CPU。

    谢谢  

    JD

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

    JD、您好!  

    感谢您提供详细的响应和逻辑分析仪跟踪。 由于您提到了导致最大延迟的 LNA 信号转换、因此您能否检查您是否将跳频范围缩小为仅一个通道、您是否会得到相同的延迟。

    此致、

    SID

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

    嗨、Sid、

    好的、我将通道数量更改为仅1。

    我让它运行了50多个、并通过2个传感器进行通信。 然后、我关闭传感器50多岁、LNA 转换消失了。

    LNA 转换时的延迟(485us):

    无 LNA 转换时的延迟(122us):  

    关于延迟问题、当传感器消失时、它们明显减小、但它们仍然存在、尽管持续时间要小得多。  但是、我必须考虑网络中是否存在传感器节点、因此延迟较高。

    谢谢、

    JD

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

    JD、您好!

    转换的可能原因似乎是传感器和收集器之间的消息交换。

    看起来、即使在单通道设置中也会执行频率同步命令。 在跳频模式下、由于跳频要求导致这些转换不可避免、因此很遗憾、这种延迟会存在。  

    您是否考虑过此应用的其他模式(如果可以接受)?  

    此致、
    SID