samples: power: Add test for device Idle PM
Added test for Device Idle Power Management to invoke device_pm_get/put API's. Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
This commit is contained in:
parent
6b21e1b7a7
commit
d910aa6029
9 changed files with 336 additions and 0 deletions
|
@ -228,6 +228,7 @@
|
||||||
/samples/net/sockets/ @jukkar @tbursztyka @pfalcon
|
/samples/net/sockets/ @jukkar @tbursztyka @pfalcon
|
||||||
/samples/sensor/ @bogdan-davidoaia
|
/samples/sensor/ @bogdan-davidoaia
|
||||||
/samples/subsys/usb/ @jfischer-phytec-iot @finikorg
|
/samples/subsys/usb/ @jfischer-phytec-iot @finikorg
|
||||||
|
/samples/subsys/power/ @ramakrishnapallala @pizi-nordic
|
||||||
/scripts/coccicheck @himanshujha199640 @JuliaLawall
|
/scripts/coccicheck @himanshujha199640 @JuliaLawall
|
||||||
/scripts/coccinelle/ @himanshujha199640 @JuliaLawall
|
/scripts/coccinelle/ @himanshujha199640 @JuliaLawall
|
||||||
/scripts/elf_helper.py @andrewboie
|
/scripts/elf_helper.py @andrewboie
|
||||||
|
|
6
samples/subsys/power/device_pm/CMakeLists.txt
Normal file
6
samples/subsys/power/device_pm/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
cmake_minimum_required(VERSION 3.13.1)
|
||||||
|
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||||
|
project(device)
|
||||||
|
|
||||||
|
FILE(GLOB app_sources src/*.c)
|
||||||
|
target_sources(app PRIVATE ${app_sources})
|
3
samples/subsys/power/device_pm/prj.conf
Normal file
3
samples/subsys/power/device_pm/prj.conf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
CONFIG_SYS_POWER_MANAGEMENT=y
|
||||||
|
CONFIG_DEVICE_POWER_MANAGEMENT=y
|
||||||
|
CONFIG_DEVICE_IDLE_PM=y
|
6
samples/subsys/power/device_pm/sample.yaml
Normal file
6
samples/subsys/power/device_pm/sample.yaml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
sample:
|
||||||
|
name: Device Idle Power Management
|
||||||
|
tests:
|
||||||
|
ospm.dev_idle_pm:
|
||||||
|
platform_whitelist: nrf52840_pca10056 nrf52_pca10040
|
||||||
|
tags: power
|
167
samples/subsys/power/device_pm/src/dummy_driver.c
Normal file
167
samples/subsys/power/device_pm/src/dummy_driver.c
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <misc/printk.h>
|
||||||
|
#include "dummy_parent.h"
|
||||||
|
#include "dummy_driver.h"
|
||||||
|
|
||||||
|
static struct k_poll_event async_evt;
|
||||||
|
u32_t device_power_state;
|
||||||
|
static struct device *parent;
|
||||||
|
|
||||||
|
static int dummy_open(struct device *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int signaled = 0, result;
|
||||||
|
|
||||||
|
printk("open()\n");
|
||||||
|
|
||||||
|
/* Make sure parent is resumed */
|
||||||
|
ret = device_pm_get_sync(parent);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = device_pm_get(dev);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk("Async wakeup request queued\n");
|
||||||
|
|
||||||
|
do {
|
||||||
|
(void)k_poll(&async_evt, 1, K_FOREVER);
|
||||||
|
k_poll_signal_check(&dev->config->pm->signal,
|
||||||
|
&signaled, &result);
|
||||||
|
} while (!signaled);
|
||||||
|
|
||||||
|
async_evt.state = K_POLL_STATE_NOT_READY;
|
||||||
|
k_poll_signal_reset(&dev->config->pm->signal);
|
||||||
|
|
||||||
|
if (result == DEVICE_PM_ACTIVE_STATE) {
|
||||||
|
printk("Dummy device resumed\n");
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
printk("Dummy device Not resumed\n");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_read(struct device *dev, u32_t *val)
|
||||||
|
{
|
||||||
|
struct dummy_parent_api *api;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
printk("read()\n");
|
||||||
|
|
||||||
|
api = (struct dummy_parent_api *)parent->driver_api;
|
||||||
|
ret = api->transfer(parent, DUMMY_PARENT_RD, val);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_write(struct device *dev, u32_t val)
|
||||||
|
{
|
||||||
|
struct dummy_parent_api *api;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
printk("write()\n");
|
||||||
|
api = (struct dummy_parent_api *)parent->driver_api;
|
||||||
|
ret = api->transfer(parent, DUMMY_PARENT_WR, &val);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_close(struct device *dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
printk("close()\n");
|
||||||
|
ret = device_pm_put_sync(dev);
|
||||||
|
if (ret == 1) {
|
||||||
|
printk("Async suspend request ququed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parent can be suspended */
|
||||||
|
if (parent) {
|
||||||
|
device_pm_put(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32_t dummy_get_power_state(struct device *dev)
|
||||||
|
{
|
||||||
|
return device_power_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
printk("child suspending..\n");
|
||||||
|
device_power_state = DEVICE_PM_SUSPEND_STATE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_resume_from_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
printk("child resuming..\n");
|
||||||
|
device_power_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_device_pm_ctrl(struct device *dev, u32_t ctrl_command,
|
||||||
|
void *context, device_pm_cb cb, void *arg)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
switch (ctrl_command) {
|
||||||
|
case DEVICE_PM_SET_POWER_STATE:
|
||||||
|
if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
|
||||||
|
ret = dummy_resume_from_suspend(dev);
|
||||||
|
} else {
|
||||||
|
ret = dummy_suspend(dev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEVICE_PM_GET_POWER_STATE:
|
||||||
|
*((u32_t *)context) = dummy_get_power_state(dev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(dev, ret, context, arg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dummy_driver_api funcs = {
|
||||||
|
.open = dummy_open,
|
||||||
|
.read = dummy_read,
|
||||||
|
.write = dummy_write,
|
||||||
|
.close = dummy_close,
|
||||||
|
};
|
||||||
|
|
||||||
|
int dummy_init(struct device *dev)
|
||||||
|
{
|
||||||
|
parent = device_get_binding(DUMMY_PARENT_NAME);
|
||||||
|
if (!parent) {
|
||||||
|
printk("parent not found\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
device_pm_enable(dev);
|
||||||
|
device_power_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
|
|
||||||
|
k_poll_event_init(&async_evt, K_POLL_TYPE_SIGNAL,
|
||||||
|
K_POLL_MODE_NOTIFY_ONLY, &dev->config->pm->signal);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEVICE_DEFINE(dummy_driver, DUMMY_DRIVER_NAME, &dummy_init,
|
||||||
|
dummy_device_pm_ctrl, NULL, NULL, APPLICATION,
|
||||||
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs);
|
24
samples/subsys/power/device_pm/src/dummy_driver.h
Normal file
24
samples/subsys/power/device_pm/src/dummy_driver.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <device.h>
|
||||||
|
#define DUMMY_DRIVER_NAME "dummy_driver"
|
||||||
|
|
||||||
|
typedef int (*dummy_api_open_t)(struct device *dev);
|
||||||
|
|
||||||
|
typedef int (*dummy_api_read_t)(struct device *dev,
|
||||||
|
u32_t *val);
|
||||||
|
typedef int (*dummy_api_write_t)(struct device *dev,
|
||||||
|
u32_t val);
|
||||||
|
typedef int (*dummy_api_close_t)(struct device *dev);
|
||||||
|
|
||||||
|
struct dummy_driver_api {
|
||||||
|
dummy_api_open_t open;
|
||||||
|
dummy_api_read_t read;
|
||||||
|
dummy_api_write_t write;
|
||||||
|
dummy_api_close_t close;
|
||||||
|
};
|
85
samples/subsys/power/device_pm/src/dummy_parent.c
Normal file
85
samples/subsys/power/device_pm/src/dummy_parent.c
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <misc/printk.h>
|
||||||
|
#include "dummy_parent.h"
|
||||||
|
|
||||||
|
static u32_t store_value;
|
||||||
|
u32_t parent_power_state;
|
||||||
|
|
||||||
|
static int dummy_transfer(struct device *dev, u32_t cmd, u32_t *val)
|
||||||
|
{
|
||||||
|
printk("transfer()\n");
|
||||||
|
|
||||||
|
if (cmd == DUMMY_PARENT_WR) {
|
||||||
|
store_value = *val;
|
||||||
|
} else {
|
||||||
|
*val = store_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32_t dummy_get_power_state(struct device *dev)
|
||||||
|
{
|
||||||
|
return parent_power_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
printk("parent suspending..\n");
|
||||||
|
parent_power_state = DEVICE_PM_SUSPEND_STATE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_resume_from_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
printk("parent resuming..\n");
|
||||||
|
parent_power_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy_parent_pm_ctrl(struct device *dev, u32_t ctrl_command,
|
||||||
|
void *context, device_pm_cb cb, void *arg)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
switch (ctrl_command) {
|
||||||
|
case DEVICE_PM_SET_POWER_STATE:
|
||||||
|
if (*((u32_t *)context) == DEVICE_PM_ACTIVE_STATE) {
|
||||||
|
ret = dummy_resume_from_suspend(dev);
|
||||||
|
} else {
|
||||||
|
ret = dummy_suspend(dev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEVICE_PM_GET_POWER_STATE:
|
||||||
|
*((u32_t *)context) = dummy_get_power_state(dev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(dev, ret, context, arg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dummy_parent_api funcs = {
|
||||||
|
.transfer = dummy_transfer,
|
||||||
|
};
|
||||||
|
|
||||||
|
int dummy_parent_init(struct device *dev)
|
||||||
|
{
|
||||||
|
device_pm_enable(dev);
|
||||||
|
parent_power_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEVICE_DEFINE(dummy_parent, DUMMY_PARENT_NAME, &dummy_parent_init,
|
||||||
|
dummy_parent_pm_ctrl, NULL, NULL, POST_KERNEL,
|
||||||
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &funcs);
|
18
samples/subsys/power/device_pm/src/dummy_parent.h
Normal file
18
samples/subsys/power/device_pm/src/dummy_parent.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <device.h>
|
||||||
|
#define DUMMY_PARENT_NAME "dummy_parent"
|
||||||
|
|
||||||
|
#define DUMMY_PARENT_RD 0
|
||||||
|
#define DUMMY_PARENT_WR 1
|
||||||
|
|
||||||
|
typedef int (*dummy_api_transfer_t)(struct device *dev, u32_t cmd, u32_t *val);
|
||||||
|
|
||||||
|
struct dummy_parent_api {
|
||||||
|
dummy_api_transfer_t transfer;
|
||||||
|
};
|
26
samples/subsys/power/device_pm/src/main.c
Normal file
26
samples/subsys/power/device_pm/src/main.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <misc/printk.h>
|
||||||
|
#include "dummy_driver.h"
|
||||||
|
|
||||||
|
/* Application main Thread */
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
struct device *dev;
|
||||||
|
struct dummy_driver_api *api;
|
||||||
|
int ret, val;
|
||||||
|
|
||||||
|
printk("Device PM sample app start\n");
|
||||||
|
dev = device_get_binding(DUMMY_DRIVER_NAME);
|
||||||
|
api = (struct dummy_driver_api *)dev->driver_api;
|
||||||
|
ret = api->open(dev);
|
||||||
|
val = 10;
|
||||||
|
ret = api->write(dev, val);
|
||||||
|
ret = api->read(dev, &val);
|
||||||
|
ret = api->close(dev);
|
||||||
|
printk("Device PM sample app complete\n");
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue