PM电源管理
初始化
drv_pm_hw_init -> rt_system_pm_init
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
timer_mask = 1UL << PM_SLEEP_MODE_DEEP;
pm->modes[pm->sleep_mode] = 1;
pm->module_status[PM_POWER_ID].req_status = 1;
pm->run_mode = RT_PM_DEFAULT_RUN_MODE;
|
pm设备注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
voidrt_pm_device_register(struct rt_device *device, conststruct rt_device_pm_ops *ops)
{
device_pm = (struct rt_device_pm *)RT_KERNEL_REALLOC(_pm.device_pm,
(_pm.device_pm_number + 1) * sizeof(struct rt_device_pm));
if (device_pm != RT_NULL)
{
_pm.device_pm = device_pm;
_pm.device_pm[_pm.device_pm_number].device = device;
_pm.device_pm[_pm.device_pm_number].ops = ops;
_pm.device_pm_number += 1;
}
}
voidrt_pm_device_unregister(struct rt_device *device)
{
if (_pm.device_pm[index].device == device)
{
for (; index < _pm.device_pm_number - 1; index ++)
{
_pm.device_pm[index] = _pm.device_pm[index + 1];
}
_pm.device_pm[_pm.device_pm_number - 1].device = RT_NULL;
_pm.device_pm[_pm.device_pm_number - 1].ops = RT_NULL;
_pm.device_pm_number -= 1;
break;
}
}
|
频率调整
- rt_pm_run_enter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| rt_err_trt_pm_run_enter(rt_uint8_tmode)
{
if (mode < pm->run_mode)
{
if(pm->ops != RT_NULL && pm->ops->run != RT_NULL)
{
pm->ops->run(pm, mode);
}
_pm_device_frequency_change(mode);
}
else
{
pm->flags |= RT_PM_FREQUENCY_PENDING;
}
pm->run_mode = mode;
}
|
调度
- 由空闲线程中执行
rt_system_power_manager
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| voidrt_system_power_manager(void)
{
if (_pm_init_flag == 0)
return;
_pm_frequency_scaling(&_pm);
_pm_change_sleep_mode(&_pm);
}
|
睡眠调度
1._pm_select_sleep_mode
获取sleep模式,选择请求的最高级别的模式
使用 rt_pm_request
和 rt_pm_release
进行请求和释放
对mode进行加减操作
1 2 3 4 5 6 7 8 9 10
| if (pm->modes[mode] < 255)
pm->modes[mode] ++;
if (pm->modes[mode] > 0)
pm->modes[mode] --;
|
2._pm_device_check_idle
检查设备是否在忙
使用 rt_pm_module_request
和 rt_pm_module_release
进行请求和释放
对mode进行加减操作,并设置请求状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| pm->module_status[module_id].req_status = 0x01;
if (pm->modes[mode] < 255)
pm->modes[mode] ++;
if (pm->modes[mode] > 0)
pm->modes[mode] --;
if (pm->modes[mode] == 0)
pm->module_status[module_id].req_status = 0x00;
|
rt_pm_module_delay_sleep
延迟睡眠
1 2 3 4 5 6 7
| pm->module_status[module_id].busy_flag = RT_TRUE;
pm->module_status[module_id].timeout = timeout;
pm->module_status[module_id].start_time = rt_tick_get();
|
- 判断idle空闲 可修改模式为idle模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
if (_pm_device_check_idle() == RT_FALSE)
{
sleep_mode = PM_BUSY_SLEEP_MODE;
if (sleep_mode < pm->sleep_mode)
{
pm->sleep_mode = sleep_mode;
}
}
|
- 进退睡眠模式执行通知函数
rt_pm_notify_set
注册通知函数
执行pm 设备 suspend
和 resume
- 计算tick补偿
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
if (pm->timer_mask & (0x01 << pm->sleep_mode))
{
timeout_tick = pm_timer_next_timeout_tick(pm->sleep_mode);
timeout_tick = timeout_tick - rt_tick_get();
pm->sleep_mode = pm_get_sleep_threshold_mode(pm->sleep_mode, timeout_tick);
if (pm->timer_mask & (0x01 << pm->sleep_mode))
{
if (timeout_tick == RT_TICK_MAX)
{
pm_lptimer_start(pm, RT_TICK_MAX);
}
else
{
pm_lptimer_start(pm, timeout_tick);
}
}
}
|
- SLEEP后等待触发唤醒
- 获取定时器经过时间,停止定时器;
设置系统滴答时间补偿,并执行调度器时间片检查与定时器检查