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.

[参考译文] LP-CC1312R7:在通过无线电发送时滞留在 SemaphoreP_PEND 中。

Guru**** 2482105 points
Other Parts Discussed in Thread: CC1125, CC1312R7

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

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1262054/lp-cc1312r7-stuck-in-semaphorep_pend-while-sending-over-radio

器件型号:LP-CC1312R7
主题中讨论的其他器件:CC1125CC1312R7

您好!

Im´基于 CC1312R7开发应用 μ P、以替代基于 CC1125+MCU 的旧系统。

´ve 代码的移植几乎是完成的、但我发现如果在短时间内发送多条消息、程序将卡在以下位置:

RF_EventMask terminationReason = RF_runCmd (rfHandle、(RF_Op*)&RF_cmdPropTx、 RF_PriorityNormal、NULL、0);

在其内部、它卡在 SemaphoreP_pend 函数的 while 循环中、在这个 while 循环中没有退出:

SemaphoreP_Status SemaphoreP_pend(SemaphoreP_Handle handle, uint32_t timeout)
{
    SemaphoreP_Obj *pSemaphore = (SemaphoreP_Obj *)handle;
    SemaphoreP_Status status;
    ClockP_Struct clockStruct;
    uintptr_t key;

    /*
     * Always add Clock (but don't start) so that ClockP_isActive() below
     * is valid.  It's OK to add a Clock even when timeout is 0 or forever
     * (but it is not OK to start it).
     */
    ClockP_add(&clockStruct, clkFxn, timeout, (uintptr_t)NULL);

    if ((timeout != 0) && (timeout != SemaphoreP_WAIT_FOREVER))
    {
        ClockP_start((ClockP_Handle)&clockStruct);
    }

    key = HwiP_disable();

    pendInProgress = true;

    while ((pSemaphore->count == 0) &&
           ((timeout == SemaphoreP_WAIT_FOREVER) || ClockP_isActive((ClockP_Handle)&clockStruct)))
    {

        /* HwiP must be disabled while checking the loop-condition and calling the callback function.
         * Otherwise, the count could increase at this point, and no further interrupts occur to
         * wake up the CPU and proceed from the callback.
         */

        /* Call the registered callback */
        if (pSemaphore->params.callback != NULL)
        {
            pSemaphore->params.callback();
        }

        HwiP_restore(key);

        if (doEnablePolicy)
        {
            Power_enablePolicy();
            doEnablePolicy = false;
        }

        key = HwiP_disable();
    }

    pendInProgress = false;

    if (pSemaphore->count > 0)
    {
        (pSemaphore->count)--;
        status = SemaphoreP_OK;
    }
    else
    {
        status = SemaphoreP_TIMEOUT;
    }

    HwiP_restore(key);

    ClockP_destruct(&clockStruct);

    return (status);
}

通过无线电发送和接收的代码基于未进行修改、 没有 RTOS 的示例 UARTBridge。

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

    Javier、您好!

    如果器件在信标挂起中"卡住"、那么它会等待发布一个信标。 您是否可以发布一个代码片段并解释调用 Semaphore_post 的上下文?

    BTW 我希望您能了解有关从 CC11xx 迁移到 CC13xx 的指南:

    https://dev.ti.com/tirex/explore/content/simplelink_cc13xx_cc26xx_sdk_7_10_01_24/docs/proprietary-rf/proprietary-rf-users-guide/proprietary-rf/cc1101-migration.html

    谢谢、

    M·H

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

    Marie、您好!

    是的、我一直在使用本指南添加 LQI 和 RSSI 测量等功能、感谢您的帮助。

    此函数就是函数卡住的地方。

    /*Send packet*/
        RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*) &RF_cmdPropTx,  RF_PriorityNormal, NULL, 0);

    我知道信标应打开或超时、但它不会阻止使用器件的无线电 API 的程序和程序。

    这是通过无线电发送的完整功能:

    //Function to send package over radio.
    uint16_t Sent_Radio_Package(mesh_packet_t *packet_to_sent)
    {
        /*The packet length is set to the number of bytes in packet_to_sent->packet.packet_length*/
        RF_cmdPropTx.pktLen = packet_to_sent->packet.packet_length;
    
        uint16_t i = 0;
    
        for (i = 0; i < packet_to_sent->packet.packet_length - 1; i++)
        {
            packet[i] = packet_to_sent->buff[i + 1];
        }
    
        /*Cancel the ongoing command*/
        RF_cancelCmd(rfHandle, rfPostHandle, 1);
    
        /*Send packet*/
        RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*) &RF_cmdPropTx,  RF_PriorityNormal, NULL, 0);
    
        uint16_t error = 0;
    
        switch (terminationReason)
        {
        case RF_EventLastCmdDone:
            // A stand-alone radio operation command or the last radio
            // operation command in a chain finished.
            error = false;
            break;
        case RF_EventCmdCancelled:
            // Command cancelled before it was started; it can be caused
            // by RF_cancelCmd() or RF_flushCmd().
            error = true;
            break;
        case RF_EventCmdAborted:
            // Abrupt command termination caused by RF_cancelCmd() or
            // RF_flushCmd().
            error = true;
            break;
        case RF_EventCmdStopped:
            // Graceful command termination caused by RF_cancelCmd() or
            // RF_flushCmd().
            error = false;
            break;
        default:
            // Uncaught error event
            error = true;
            break;
        }
        uint32_t cmdStatus = ((volatile RF_Op*) &RF_cmdPropTx)->status;
        switch (cmdStatus)
        {
        case PROP_DONE_OK:
            error = false;
            break;
        case PROP_DONE_STOPPED:
            // received CMD_STOP while transmitting packet and finished
            // transmitting packet
            error = true;
            break;
        case PROP_DONE_ABORT:
            // Received CMD_ABORT while transmitting packet
            error = true;
            break;
        case PROP_ERROR_PAR:
            // Observed illegal parameter
            error = true;
            break;
        case PROP_ERROR_NO_SETUP:
            // Command sent without setting up the radio in a supported
            // mode using CMD_PROP_RADIO_SETUP or CMD_RADIO_SETUP
            error = true;
            break;
        case PROP_ERROR_NO_FS:
            // Command sent without the synthesizer being programmed
            error = true;
            break;
        case PROP_ERROR_TXUNF:
            // TX underflow observed during operation
            error = true;
            break;
        default:
            error = true;
            break;
    
        }
        /* Resume RF RX */
        rfPostHandle = RF_postCmd(rfHandle, (RF_Op*) &RF_cmdPropRx,
                                  RF_PriorityNormal, &ReceivedOnRFcallback,
                                  RF_EventRxEntryDone);
        return (error);
    }

    这是我的 init 函数,可能有些事情做不正确?

    //Initializes radio peripherial.
    void Radio_Init(uint16_t radio_band,uint16_t radio_channel, int8_t power,uint8_t device_address)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        if (RFQueue_defineQueue(&dataQueue, rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer), NUM_DATA_ENTRIES,
                                MAX_LENGTH + NUM_APPENDED_BYTES))
        {
            /* Failed to allocate space for all data entries */
            while (1)
                ;
        }
        /*Modifies settings to be able to do RX*/
        /* Set the Data Entity queue for received data */
        RF_cmdPropRx.pQueue = &dataQueue;
        /* Discard ignored packets from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
        /* Discard packets with CRC error from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
        RF_cmdPropRx.maxPktLen = MAX_LENGTH;
        RF_cmdPropRx.pktConf.bRepeatOk = 1;
        RF_cmdPropRx.pktConf.bRepeatNok = 1;
    
        RF_cmdPropTx.pPkt = packet;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
    
    
        uint8_t length = sizeof(PowerTable)/(sizeof(PowerTable[0][0])*2);
    
        for(uint8_t index = 0;index < length+1;index++)
        {
            if(index == length)//end of the power table.
            {
                RF_cmdPropRadioDivSetup.txPower = PowerTable[4][1];//0 dB as default;
                break;
            }
            if(PowerTable[index][0] == power)//has found the value
            {
                RF_cmdPropRadioDivSetup.txPower = PowerTable[index][1];// code to be introduced to have this power
                break;
            }
        }
    
    
        switch(radio_band)
        {
        case BAND_868_MHZ:
        {
            RF_cmdFs.fractFreq = Frequency_channel_config_868_frequency_var[radio_channel][1];
            RF_cmdFs.frequency = Frequency_channel_config_868_frequency_var[radio_channel][0];
            break;
        }
        case BAND_865_MHZ:
        {
            RF_cmdFs.fractFreq = Frequency_channel_config_865_frequency_var[radio_channel][1];
            RF_cmdFs.frequency = Frequency_channel_config_865_frequency_var[radio_channel][0];
            break;
        }
        case BAND_915_MHZ:
        {
            RF_cmdFs.fractFreq = Frequency_channel_config_915_frequency_var[radio_channel][1];
            RF_cmdFs.frequency = Frequency_channel_config_915_frequency_var[radio_channel][0];
            break;
        }
        default:
        {
            RF_cmdFs.fractFreq = Frequency_channel_config_868_frequency_var[0][1];
            RF_cmdFs.frequency = Frequency_channel_config_868_frequency_var[0][0];
            break;
        }
        }
        RF_cmdPropRx.pktConf.bChkAddress = 0x01;
        RF_cmdPropRx.address0 = 0x00;//Broadcast address
        RF_cmdPropRx.address1 = device_address;
        
        /* Request access to the radio */
        rfHandle = RF_open(&rfObject, &RF_prop,(RF_RadioSetup*) &RF_cmdPropRadioDivSetup, &rfParams);
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        rfPostHandle = RF_postCmd(rfHandle, (RF_Op*) &RF_cmdPropRx,
                                  RF_PriorityNormal, &ReceivedOnRFcallback,
                                  RF_EventRxEntryDone);
        packetRxCb = NO_PACKET;
    }

    感谢您提供的任何帮助、因为被阻止的设备是一个严重错误。

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

    Javier、您好!

     Rf_cancelCmd ()的状态是什么?

    您是否在文档中读过此内容:"如果从优先级与 RF 驱动器 Swi 相同或更高的 Swi 上下文调用 RF_cancelCmd、当射频内核断电时、取消回调将延迟到下一个上电周期。"

    谢谢、

    M·H

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

    我已经能够以这种方式解决此问题(如果其他人面临此问题):

    在 Rx 命令 config 中进行更改:

    RF_cmdPropRx.pktConf.bRepeatOk = 1;
    RF_cmdPropRx.pktConf.bRepeatNok = 1;

    实现

    RF_cmdPropRx.pktConf.bRepeatOk = 0;
    RF_cmdPropRx.pktConf.bRepeatNok = 0;

    我想系统会卡在某些意外状态。

    系统现在按预期工作、但我想更多地处理无线电命令流程、以在通话前添加监听、因此将来会更改此设置。

    我想知道系统是否可以挑选几个消息,并将它们保存在缓冲区(Rf_queue.c 提供现在只存储2个消息),因为我的系统使广播从主控到可变数量的从属(多达10个), 我的想法是实施 LBT 以避免答案重叠(当前解决方案只是随机化仿真时间以避免重叠并进行多次搜索)。 然后选择答案、但在我的初始测试中、系统仅从两个从器件中挑选一条消息、甚至对从器件进行编程以将答案 间隔100ms (发送时间为27ms 测量的程序运行时间为10-50ms) 另一个连接到 Smart RF Studio 的 CC1312R7板能够拾取这两条消息。  

    我是否会看到有关此问题的新问题?

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

    Javier、您好!

    很高兴听到您找到了解决方案。

    是的、请在新问题中打开一个新问题。

    谢谢、

    M·H