本帖最后由 le062 于 2015-3-19 00:21 编辑
在单片机中,一般通过中断事件唤醒CPU,比如IO,AD,UART,TIMER等等。
以如下代码为例:
当__wfi();被执行后,cpu暂停,进入休眠模式。此后,cpu需等待一个唤醒事件,这儿假设使能了一个周期为1ms的定时器中断,那么当定时器中断产生后,cpu被唤醒,并进入定时器中断函数中运行,中断函数执行完毕后,再次执行指令B。
现在我们考虑下一个简单任务,一个LED_A随机闪烁:
- while(1)
- {
- set_led_a_high;
- delay_ms(random(100, 1000)); //延时随机时间,时间范围从100ms到1000ms
- set_led_a_low;
- delay_ms(random(100, 1000));
- }
复制代码
如果只需要让单片机跑一个LED_A任务,那是非常简单,把伪代码翻译成C语言就行,但如果需要在加个LED_B,LED_C呢?
这时候,轮询也能解决问题,在子任务中记录状态,不断判断即可:
- void led_a_task()
- {
- static int status = 0;
- switch (status)
- {
- case...........
- }
- }
-
- void main()
- {
- while(1)
- {
- led_a_task();
- led_b_task();
- led_c_task();
- }
- }
-
复制代码
在这段轮询代码中,cpu绝大部分时间是用来查询delay时间是否到达,而任务中的核心代码IO操作和random计算只消耗了非常少的CPU资源。
我所期望的一个解决方案是综合所有任务中的delay时间,通过排序获得最近的唤醒时间点,然后设置硬件定时器间隔,这样就能做到无无效唤醒。
在后面的帖子中,我会在LPC54102的M0核心中演示这个功能。
题外话,计划中的另外两个特性:CPU使用率监控,动态频率调整。