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.

[参考译文] CC1310:SimpleLink SDK WOR 空指针硬件故障

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

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1320730/cc1310-simplelink-sdk-wor-null-pointer-hard-fault

器件型号:CC1310

我有25个 CC1310板、它们运行 TI-RTOS 和最新的  SimpleLink CC13x0 SDK (4.20.02.07)。  对电路板进行编程、以使用 RF_runCmd 每秒执行一次 WOR、以检查是否有人试图与它进行通信等。  我有一个问题 、就是在 WOR 线程时、电路板会随机出现硬故障。  我通常得到1-2板,硬故障每天,每个都有同样的问题。  我还没有找到重复问题的方法、因此我必须等到发生一个硬故障后再进行调试。

以下是 ROV Hwi 例外:

将 PC、SP 和 LR 寄存器值更改为异常中的值后、我可以看到 List_put 的 elem 变量中的空指针是什么:

回到在 RF_postCmd 中调用 List_Put 的堆栈跟踪、我看到有一些检查可以确保 pCmd 不为空、因此我不知道为什么会发生这种情况:

如何 进行进一步调试?   所有这些都指向 SDK 代码、因此我不知道有什么地方出错或者 SDK 中有错误...

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

    周老师、您好!

    我假设您以 WakeOnRadioRX 为基础而不是以 TX 为基础?

    此外、您可以共享监听命令的结构/设置吗? 此外、它是像示例一样的简单环路吗?  

    此致、

    SID

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

    可以、这是在使用 WakeOnRadioRx。  以下是所有相关的射频设置:

    void init_RF(void) {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        rfParams.nInactivityTimeout = 1;  //Power down the radio if there are no pending commands after 1us
    
        /****** TX ******/
    
        RF_cmdPropTx.pPkt = packet;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.syncWord = DEFAULT_SYNC_WORD;  //Everything sent uses the default sync word
    
        /****** TX WHEN CLEAR ******/
        /* Check if channel is busy before sending packet */
        /* Customize the CMD_PROP_TX command for this application */
        RF_cmdNop.startTrigger.triggerType = TRIG_NOW;
        RF_cmdNop.startTrigger.pastTrig = 1;
    
        /* Set up the next pointers for the command chain */
        RF_cmdNop.pNextOp = (rfc_radioOp_t*)&RF_cmdPropCs;
        RF_cmdPropCs.pNextOp = (rfc_radioOp_t*)&RF_cmdCountBranch;
        RF_cmdCountBranch.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx;
        RF_cmdCountBranch.pNextOpIfOk = (rfc_radioOp_t*)&RF_cmdPropCs;
        RF_cmdPropTx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropRx;
    
        RF_cmdPropTx.condition.rule = COND_STOP_ON_FALSE;  //Only run the RX command if TX is successful
    
        RF_cmdCountBranch.counter = CS_RETRIES_WHEN_BUSY;
    
    
        /****** TX WHEN CLEAR CS ******/
        /* Set correct trigger types */
        RF_cmdPropCs.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropCs.startTrigger.pastTrig    = 1;
        RF_cmdPropCs.csEndTrigger.triggerType   = TRIG_REL_START;
    
    
        /****** RX/WOR ******/
        /* Create queue and data entries */
        if (RFQueue_defineQueue(&dataQueue,
                                rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer),
                                NUM_DATA_ENTRIES,
                                MAX_PACKET_SIZE + NUM_APPENDED_BYTES))
        {
            /* Failed to allocate space for all data entries */
            while(1);
        }
    
        /****** RX (used for receiving ACKs after TX) ******/
        RF_cmdPropRx.pQueue = &dataQueue;           // Set the Data Entity queue for received data
        RF_cmdPropRx.pktConf.bRepeatOk = 0;         // End operation after receiving a packet correctly
        RF_cmdPropRx.pktConf.bRepeatNok = 1;        // Go back to sync search after receiving a packet with CRC error
        RF_cmdPropRx.pktConf.bUseCrc = 1;           // Check CRC
        RF_cmdPropRx.pktConf.bVarLen = 1;           // Receive length as first byte
        RF_cmdPropRx.pktConf.bChkAddress = 1;       // Check address
    
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;  // Discard ignored packets from Rx queue
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;   // Discard packets with CRC error from Rx queue
        RF_cmdPropRx.rxConf.bIncludeHdr = 1;        // Include the received header or length byte in the stored packet
    
        RF_cmdPropRx.maxPktLen = MAX_PACKET_SIZE; // Implement packet length filtering (excluding length byte)
    
        RF_cmdPropRx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropRx.startTrigger.pastTrig = 1;
    
        RF_cmdPropRx.endTrigger.triggerType   = TRIG_REL_PREVEND;
        RF_cmdPropRx.endTime                  = (uint32_t)(ACK_MILLISECONDS * 1000 * US_TO_RAT_TICKS);
    
        RF_cmdPropRx.syncWord = DEFAULT_SYNC_WORD;  //Everything received (except the first packet of a command in RF_cmdPropRxSniff) uses the default sync word
    
    
        /****** WOR (used for receiving commands) ******/
        /* Copy all RX options from the SmartRF Studio exported RX command to the RX Sniff command */
        initializeSniffCmdFromRxCmd(&RF_cmdPropRxSniff, &RF_cmdPropRx);
    
        RF_cmdPropRxSniff.endTrigger.triggerType = TRIG_REL_START;
    
        RF_cmdPropRxSniff.pOutput   = (uint8_t*)&rxStatistics;
    
        /****** WOR/CS ******/
        /* Configure Sniff-mode part of the RX_SNIFF command */
        configureSniffandCsCmd(&RF_cmdPropRxSniff, &RF_cmdPropCs);
    
    
    
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        if (rfHandle == NULL) {  //RF_open() failed
            while(1);
        }
    }

    /* Copies all RX options from the SmartRF Studio exported RX command to the RX Sniff command */
    static void initializeSniffCmdFromRxCmd(rfc_CMD_PROP_RX_SNIFF_t* rxSniffCmd, rfc_CMD_PROP_RX_t* rxCmd)
    {
    
        /* Copy RX configuration from RX command */
        memcpy(rxSniffCmd, rxCmd, sizeof(rfc_CMD_PROP_RX_t));
    
        /* Change to RX_SNIFF command from RX command */
        rxSniffCmd->commandNo = CMD_PROP_RX_SNIFF;
    }

    static void configureSniffandCsCmd(rfc_CMD_PROP_RX_SNIFF_t* rxSniffCmd, rfc_CMD_PROP_CS_t* rxCsCmd) {
        /* Enable or disable RSSI */
        if ((WOR_MODE == CarrierSenseMode_RSSI) || (WOR_MODE)) {
            rxSniffCmd->csConf.bEnaRssi         = 1;
            rxCsCmd->csConf.bEnaRssi            = 1;
        } else {
            rxSniffCmd->csConf.bEnaRssi         = 0;
            rxCsCmd->csConf.bEnaRssi            = 0;
        }
    
        /* Enable or disable PQT */
        if ((WOR_MODE == CarrierSenseMode_PQT) || (WOR_MODE == CarrierSenseMode_RSSIandPQT)) {
            rxSniffCmd->csConf.bEnaCorr             = 1;
            rxCsCmd->csConf.bEnaCorr                = 1;
            rxSniffCmd->csEndTrigger.triggerType    = TRIG_REL_START;
            rxCsCmd->csEndTrigger.triggerType       = TRIG_REL_START;
        } else {
            rxSniffCmd->csConf.bEnaCorr             = 0;
            rxCsCmd->csConf.bEnaCorr                = 0;
            rxSniffCmd->csEndTrigger.triggerType    = TRIG_NEVER;
            rxCsCmd->csEndTrigger.triggerType       = TRIG_NEVER;
        }
    
        /* General Carrier Sense configuration */
        rxSniffCmd->csConf.operation        = 1; /* Report Idle if RSSI reports Idle to quickly exit if not above RSSI threshold */
        rxCsCmd->csConf.operation           = 1;
        rxSniffCmd->csConf.busyOp           = 0; /* End carrier sense on channel Busy (the receiver will continue when carrier sense ends, but it will then not end if channel goes Idle) */
        rxCsCmd->csConf.busyOp              = 0;
        rxSniffCmd->csConf.idleOp           = 1; /* End on channel Idle */
        rxCsCmd->csConf.idleOp              = 1;
        rxSniffCmd->csConf.timeoutRes       = 1; /* If the channel is invalid, it will return PROP_DONE_IDLE_TIMEOUT */
        rxCsCmd->csConf.timeoutRes          = 1;
    
        /* RSSI configuration */
        rxSniffCmd->rssiThr                 = RSSI_THRESHOLD; /* Set the RSSI threshold in dBm */
        rxCsCmd->rssiThr                    = RSSI_THRESHOLD;
        rxSniffCmd->numRssiIdle             = NUM_RSSI_MEASUREMENTS; /* 50 idle RSSI samples signals that the channel is idle */
        rxCsCmd->numRssiIdle                = NUM_RSSI_MEASUREMENTS;
        rxSniffCmd->numRssiBusy             = NUM_RSSI_MEASUREMENTS; /* 50 busy RSSI samples signals that the channel is busy */
        rxCsCmd->numRssiBusy                = NUM_RSSI_MEASUREMENTS;
    
        /* Calculate basic timing parameters */
        uint32_t datarate = calculateSymbolRate(RF_cmdPropRadioDivSetup.symbolRate.preScale, RF_cmdPropRadioDivSetup.symbolRate.rateWord);
        uint32_t symbolLengthUs  = 1000000UL/datarate;
        uint32_t preambleSymbols = 8*8;
        uint32_t payloadSymbols = MAX_PACKET_SIZE*8;
        uint8_t syncWordSymbols  = RF_cmdPropRadioDivSetup.formatConf.nSwBits;
    
        /* Calculate sniff mode parameters */
    
        /* Represents the maximum time from the startTrigger to when we expect a sync word to be received. */
        uint32_t rxEndTimeUs = (preambleSymbols + syncWordSymbols + payloadSymbols)*symbolLengthUs;
    
        /* Set sniff mode timing configuration in sniff command in RAT ticks */
        rxSniffCmd->endTime     = (uint32_t)(rxEndTimeUs * US_TO_RAT_TICKS);
    }

    这是 WOR 函数:

    static void WOR_Function(UArg arg0, UArg arg1) {
        Semaphore_pend(WOR_SemHandle, BIOS_WAIT_FOREVER);
    
        while (1) {
            /* Run WOR */
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRxSniff, RF_PriorityNormal, &receivePacket_Callback, RF_EventRxEntryDone);
    
            if (RF_cmdPropRxSniff.status == PROP_DONE_OK) {
                Task_sleep(TASK_SLEEP_SECONDS(BASE_WAKE_INTERVAL_SECONDS));
    
                //If we successfully received a packet, send an ACK
                if (sendACKpacket == true) {
                    sendACKpacket = false;
    
                    //Send the bytes in ACKpacket instead of packet
                    RF_cmdPropTx.pPkt = ACKpacket;
    
                    setPayloadLength(0);
    
                    setFrequencyMHz(secondary_freq_MHz);
    
                    /* Send ACK when clear */
                    RF_cmdPropTx.pNextOp = NULL;  //We don't want to chain the TX to an RX when we send ACKs
                    RF_runCmd(rfHandle, (RF_Op*)&RF_cmdNop, RF_PriorityNormal, NULL, 0);
    
                    //Send bytes again from packet
                    RF_cmdPropTx.pPkt = packet;
                }
            } else {
                Task_sleep(TASK_SLEEP_SECONDS(WAKE_INTERVAL));
            }
        }
    }

    我尚未尝试删除所有其他功能以查看这是否是由另一个任务引起的、但我可以在旁边尝试缩小问题范围。

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

    周老师、您好!

    问题可能是什么、这一点并不明显。 似乎在命令链执行过程中做出了一些逻辑和决策。  

    但是,在您调用 rf_runCmd 以运行无线电唤醒之前,请尝试调用 rf_FlushCmd () API ,以确保在执行监听之前重置无线电队列。  

    请使用此命令。 这些参数会取消所有命令并清除命令队列。

    rfStatus = RF_flushCmd(rfHandle, RF_CMDHANDLE_FLUSH_ALL , 0);

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

    这似乎解决了问题。  我想这可能是由 TX 和 RX 任务相互优先引起的、但您的建议是有效的。