cc2530下移植contiki操作系统中关于RDC层电源管理方面的问题
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"); //打印标记” 这一步一直执行不到
这是我目前采用的两个方案,可能是我的思路错了,希望能给我些具体点的建议。