我正在研究使用EFM Gekko控制器(http://energymicro.com/)来开发电池供电的软件,并且希望该控制器在无用的情况下都能入睡。WFI(等待中断)指令用于此目的。它将使处理器进入睡眠状态,直到发生中断。
如果通过在某个地方存储东西来进行睡眠,则可以使用独占负载/独占存储操作来执行以下操作:
//每当发生某事时,dont_sleep都会加载2 //应该强制主循环至少循环一次。如果有中断 //在以下语句中导致将其重置为2, //行为就像中断发生在它之后一样。 store_exclusive(load_exclusive(dont_sleep)>> 1); while(!dont_sleep) { //如果下一条语句与store_exclusive之间发生中断,请不要入睡 load_exclusive(SLEEP_TRIGGER); 如果(!dont_sleep) store_exclusive(SLEEP_TRIGGER); }
如果在load_exclusive和store_exclusive操作之间发生中断,则将导致跳过store_exclusive,从而使系统再循环运行一次(以查看中断是否设置了dont_sleep)。不幸的是,Gekko使用WFI指令而不是写地址来触发睡眠模式。像这样写代码
如果(!dont_sleep) WFI();
冒着可能在'if'和'wfi'之间发生中断并设置dont_sleep的风险,但是wfi仍会继续执行。防止这种情况的最佳方式是什么?将PRIMASK设置为1以防止中断在执行WFI之前中断处理器,并在之后立即将其清除?还是有更好的技巧?
编辑
我想知道事件位。通过一般描述,它想用于多处理器支持,但是想知道是否可以使用以下内容:
如果(dont_sleep) SEV(); / *将使以下WFE清除事件标志但不休眠* / WFE();
设置don_t_sleep的每个中断也应执行SEV指令,因此,如果该中断发生在“ if”测试之后,则WFE将清除事件标志,但不会进入睡眠状态。听起来像是一个好范例吗?