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.

关于TI-RTOS的休眠,使用例程rfWsnNode

Other Parts Discussed in Thread: CC1350STK

您好: 我使用例程rfWsnNode和rfWsnConcentrator进行通信,请问rfWsnNode这个例程是否没有休眠呢? 我目前去除了传感器控制器这部分,想单纯的用一个定时器,超时就发送一组包,发生完成就休眠,我使用的是NodeTask.c文件中已经配置好的定时器

/* setup timeout for fast report timeout    
Clock_setTimeout(fastReportTimeoutClockHandle,NODE_ADCTASK_REPORTINTERVAL_FAST_DURIATION_MS * 1000 / Clock_tickPeriod);
/* Start fast report and timeout */
Clock_start(fastReportTimeoutClockHandle);

然后在回调中发生数据包,重置定时器

工程有两个进程:

NodeRadioTask_init();
NodeTask_init();

里面分别有一个while(1)循环,NodeRadioTask中是在等待数据发送和接收的事件,NodeTask的循环是在等待定时器超时改变标志位进入,讲数据发送事件抛出。

我阅读了该工程的代码,没有发现在哪里能进入休眠,请问我如何才能在发送完数据包后进入休眠,然后再用定时器唤醒呢?谢谢

  • 如果程序中已经无其他任务,你可以调用 task_sleep进入睡眠;或者使用时钟定时,这部分可以参考SDK里的时钟example
  • 你好,我查看了时钟的例程,但发现里面没有使用到休眠和唤醒,貌似仅仅是定时,然后超时输出。主程代码如下:

    int main()
    {
        /* Construct BIOS Objects */
        Clock_Params clkParams;
    
        /* Call driver init functions */
        Board_initGeneral();
    
        Clock_Params_init(&clkParams);
        clkParams.period = 5000/Clock_tickPeriod;
        clkParams.startFlag = TRUE;
    
        /* Construct a periodic Clock Instance */
        Clock_construct(&clk0Struct, (Clock_FuncPtr)clk0Fxn,
                        5000/Clock_tickPeriod, &clkParams);
    
        clkParams.period = 0;
        clkParams.startFlag = FALSE;
    
        /* Construct a one-shot Clock Instance */
        Clock_construct(&clk1Struct, (Clock_FuncPtr)clk1Fxn,
                        11000/Clock_tickPeriod, &clkParams);
    
        clk2Handle = Clock_handle(&clk1Struct);
    
        Clock_start(clk2Handle);
    
        BIOS_start();    /* does not return */
        return(0);
    }
    
    /*
     *  ======== clk0Fxn =======
     */
    Void clk0Fxn(UArg arg0)
    {
        UInt32 time;
    
        time = Clock_getTicks();
        System_printf("System time in clk0Fxn = %lu\n", (ULong)time);
    }
    
    /*
     *  ======== clk1Fxn =======
     */
    Void clk1Fxn(UArg arg0)
    {
        UInt32 time;
    
        time = Clock_getTicks();
        System_printf("System time in clk1Fxn = %lu\n", (ULong)time);
        System_printf("Calling BIOS_exit() from clk1Fxn\n");
        BIOS_exit(0);
    }
    

  • 下面是两个task的主循环,标黄的语句都会将task block在pending event的状态,当两个task都处于blocked状态时,系统就会进入低功耗。
    你可以通过clock进行定时操作,在clock计时满的callback里面post对应的event,是task继续执行。
     
      /* Enter main task loop */
        while (1)
        {
            /* Wait for an event */
            uint32_t events = Event_pend(radioOperationEventHandle, 0, RADIO_EVENT_ALL, BIOS_WAIT_FOREVER);
            /* If we should send ADC data */
            if (events & RADIO_EVENT_SEND_ADC_DATA)
            {
                uint32_t currentTicks;
                currentTicks = Clock_getTicks();
                //check for wrap around
                if (currentTicks > prevTicks)
                {
                    //calculate time since last reading in 0.1s units
                    dmSensorPacket.time100MiliSec += ((currentTicks - prevTicks) * Clock_tickPeriod) / 100000;
                }
                else
                {
                    //calculate time since last reading in 0.1s units
                    dmSensorPacket.time100MiliSec += ((prevTicks - currentTicks) * Clock_tickPeriod) / 100000;
                }
                prevTicks = currentTicks;
                dmSensorPacket.batt = AONBatMonBatteryVoltageGet();
                dmSensorPacket.adcValue = adcData;
                dmSensorPacket.button = !PIN_getInputValue(Board_PIN_BUTTON0);
                sendDmPacket(dmSensorPacket, NODERADIO_MAX_RETRIES, NORERADIO_ACK_TIMEOUT_TIME_MS);
            }
            /* If we get an ACK from the concentrator */
            if (events & RADIO_EVENT_DATA_ACK_RECEIVED)
            {
                returnRadioOperationStatus(NodeRadioStatus_Success);
            }
            /* If we get an ACK timeout */
            if (events & RADIO_EVENT_ACK_TIMEOUT)
            {
                /* If we haven't resent it the maximum number of times yet, then resend packet */
                if (currentRadioOperation.retriesDone < currentRadioOperation.maxNumberOfRetries)
                {
                    resendPacket();
                }
                else
                {
                    /* Else return send fail */
                    Event_post(radioOperationEventHandle, RADIO_EVENT_SEND_FAIL);
                }
            }
            /* If send fail */
            if (events & RADIO_EVENT_SEND_FAIL)
            {
                returnRadioOperationStatus(NodeRadioStatus_Failed);
            }
    #ifdef FEATURE_BLE_ADV
            if (events & NODE_EVENT_UBLE)
            {
                uble_processMsg();
            }
    #endif
        }
        while (1)
        {
            /* Wait for event */
            uint32_t events = Event_pend(nodeEventHandle, 0, NODE_EVENT_ALL, BIOS_WAIT_FOREVER);
            /* If new ADC value, send this data */
            if (events & NODE_EVENT_NEW_ADC_VALUE) {
                /* Toggle activity LED */
    #if !defined __CC1350STK_BOARD_H__
                PIN_setOutputValue(ledPinHandle, NODE_ACTIVITY_LED,!PIN_getOutputValue(NODE_ACTIVITY_LED));
    #endif
                /* Send ADC value to concentrator */
                NodeRadioTask_sendAdcData(latestAdcValue);
                /* Update display */
                updateLcd();
            }
            /* If new ADC value, send this data */
            if (events & NODE_EVENT_UPDATE_LCD) {
                /* update display */
                updateLcd();
            }
        }
  • 非常感谢,我刚才在阅读低功耗的文档,是否需要 在 主函数中调用Power_enablePolicy(); 这个函数来启动呢? 还是直接如你说所直接pend即可?
  • 真的非常感谢,愿你身体健康,工作顺利~