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.

cc2530下移植contiki操作系统中关于RDC层电源管理方面的问题

Other Parts Discussed in Thread: CC2530

  CC2530平台下,contiki系统中RDC层跑的contikimac实现电源管理,怎么让radio关闭的时候,同时让CPU进入睡眠,radio打开前CPU唤醒,从而实现系统周期性的唤醒,节省功耗呢?

#if RDC_CONF_MCU_SLEEP

static uint8_t sleepcycle;
if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) {
rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start));
} else {
sleepcycle = 0;
schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
PT_YIELD(&pt);
}
#else
schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
PT_YIELD(&pt);
#endif

以上为comtikimac.c文件部分代码,其中comtikimac.c文件中的rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start))函数是可以实现这个功能的,但是发现在cc2530下未定义,有没有谁又遇到或解决了这个问题,希望能给我些指导

  • 应该把CC2530 PM2对应的休眠方式,跟RDC的接口定义就可以吧。

    其他的应该是系统的调度。

  • 可以说的详细点吗?

    我自己定义了rtimer_arch_sleep(rtimer_clock_t t)函数

    方案一:

    void
    rtimer_arch_sleep(rtimer_clock_t t)
    {
    // watchdog_stop();
    rtimer_arch_schedule(t);

    SLEEPCMD = (SLEEPCMD & 0xFC) | 0x01;
    /* Go IDLE or Enter PM1 */
    PCON |= PCON_IDLE;

    }

    这个就是在调用这个函数的时候设置好rtimer的寄存器,然后进入PM1模式,理论rtimer产生中断时,PM1恢复至活跃状态,但是rtimer采用的是timer1定时器,在PM1模式下,应该不能工作了,个人觉得这个方法是不对的,实际调试一直未成功。

    第二种方案:也是自定义rtimer_arch_sleep(rtimer_clock_t t)函数

    void 
    rtimer_arch_sleep(rtimer_clock_t t)
    {

    Set_ST_Period(t);            //设置sleep定时器的睡眠时间
    // printf("sleep-2 \n");

    /******************************PM1模式下的系统时钟配置*******************************/
    SLEEPCMD &= ~SLEEP_OSC_PD; /* Make sure both HS OSCs are on */
    while(!(SLEEPSTA & SLEEP_HFRC_STB)); /* Wait for RCOSC to be stable */
    CLKCONCMD |= CLKCONCMD_OSC; /* Switch to the RCOSC */
    while(!(CLKCONSTA & CLKCONCMD_OSC)); /* Wait till it's happened */
    SLEEPCMD |= SLEEP_OSC_PD; /* Turn the other one off */

    /******************************PM1模式下的系统时钟配置*******************************/

    SLEEPCMD = (SLEEPCMD & 0xFC) | 0x01;

    /* Go IDLE or Enter PM1 */
    PCON |= PCON_IDLE;                                      //此时进入PM1模式

    /* First instruction upon exiting PM1 must be a NOP */
    ASM(nop);
    printf("sleep-2 \n");                                  //打印标记

    /******************************恢复活跃状态的系统时钟配置*******************************/
    SLEEPCMD &= ~SLEEP_OSC_PD; /* Make sure both HS OSCs are on */
    while(!(SLEEPSTA & SLEEP_XOSC_STB)); /* Wait for XOSC to be stable */
    CLKCONCMD &= ~CLKCONCMD_OSC; /* Switch to the XOSC */
    /*
    * On occasion the XOSC is reported stable when in reality it's not.
    * We need to wait for a safeguard of 64us or more before selecting it
    */
    clock_delay(10);
    while(CLKCONSTA & CLKCONCMD_OSC); /* Wait till it's happened */
    /* Tickspeed 500 kHz for timers[1-4] */
    CLKCONCMD |= 0x20 | 0x10;
    while(CLKCONSTA != CLKCONCMD);

    /******************************恢复活跃状态的系统时钟配置*******************************/

    printf("PM0\n");

    }

    这个就是调用这个函数设置好时钟,利用睡眠定时器中断唤醒系统,但是觉得这种方法可能会导致内核时钟混乱等影响,这种方法测试的时候,发现系统一直处于睡眠模式出不来:“printf("sleep-2 \n");                                  //打印标记”    这一步一直执行不到

    这是我目前采用的两个方案,可能是我的思路错了,希望能给我些具体点的建议。