add power management apis to the OS, both driver implementations and BSP power states
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/e02f6678 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/e02f6678 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/e02f6678 Branch: refs/heads/develop Commit: e02f6678a022dc89a1e9ae36397ecc01cf497a61 Parents: a1d31de Author: Sterling Hughes <sterl...@apache.org> Authored: Tue Sep 13 17:37:46 2016 -0700 Committer: Sterling Hughes <sterl...@apache.org> Committed: Tue Sep 13 17:37:46 2016 -0700 ---------------------------------------------------------------------- drivers/adc/adc_nrf52/src/adc_nrf52.c | 4 +- drivers/uart/uart_hal/src/uart_hal.c | 2 +- hw/bsp/arduino_primo_nrf52/src/hal_bsp.c | 6 ++ hw/bsp/bmd300eval/src/hal_bsp.c | 8 ++- hw/bsp/native/src/hal_bsp.c | 8 ++- hw/bsp/nrf51-arduino_101/src/hal_bsp.c | 6 ++ hw/bsp/nrf51-blenano/src/hal_bsp.c | 8 ++- hw/bsp/nrf51dk-16kbram/src/hal_bsp.c | 8 ++- hw/bsp/nrf51dk/src/hal_bsp.c | 6 ++ hw/bsp/nrf52dk/src/hal_bsp.c | 6 ++ hw/bsp/nrf52pdk/src/hal_bsp.c | 6 ++ hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c | 6 ++ hw/hal/include/hal/hal_bsp.h | 9 +++ libs/os/include/os/os.h | 3 +- libs/os/include/os/os_dev.h | 38 ++++++++-- libs/os/src/os_dev.c | 73 ++++++++++++++++++-- 16 files changed, 177 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/drivers/adc/adc_nrf52/src/adc_nrf52.c ---------------------------------------------------------------------- diff --git a/drivers/adc/adc_nrf52/src/adc_nrf52.c b/drivers/adc/adc_nrf52/src/adc_nrf52.c index 2d8cb3b..d167175 100644 --- a/drivers/adc/adc_nrf52/src/adc_nrf52.c +++ b/drivers/adc/adc_nrf52/src/adc_nrf52.c @@ -107,9 +107,9 @@ nrf52_adc_open(struct os_dev *odev, uint32_t wait, void *arg) } } - if (odev->od_status & OS_DEV_STATUS_OPEN) { + if (odev->od_flags & OS_DEV_F_STATUS_OPEN) { os_mutex_release(&dev->ad_lock); - rc = -1; + rc = OS_EBUSY; goto err; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/drivers/uart/uart_hal/src/uart_hal.c ---------------------------------------------------------------------- diff --git a/drivers/uart/uart_hal/src/uart_hal.c b/drivers/uart/uart_hal/src/uart_hal.c index 7244240..5617f6b 100644 --- a/drivers/uart/uart_hal/src/uart_hal.c +++ b/drivers/uart/uart_hal/src/uart_hal.c @@ -77,7 +77,7 @@ uart_hal_open(struct os_dev *odev, uint32_t wait, void *arg) if (!uc) { return OS_EINVAL; } - if (odev->od_status & OS_DEV_STATUS_OPEN) { + if (odev->od_flags & OS_DEV_F_STATUS_OPEN) { return OS_EBUSY; } hal_uart_init_cbs(priv->unit, uc->uc_tx_char, uc->uc_tx_done, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c b/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c index 56501ac..90f3883 100644 --- a/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c +++ b/hw/bsp/arduino_primo_nrf52/src/hal_bsp.c @@ -61,3 +61,9 @@ bsp_get_refmv(void *cfgdata) { return (2800); } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/bmd300eval/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/bmd300eval/src/hal_bsp.c b/hw/bsp/bmd300eval/src/hal_bsp.c index 0ac5ca8..ae55a00 100644 --- a/hw/bsp/bmd300eval/src/hal_bsp.c +++ b/hw/bsp/bmd300eval/src/hal_bsp.c @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -65,3 +65,9 @@ bsp_core_dump(int *area_cnt) *area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]); return dump_cfg; } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/native/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/native/src/hal_bsp.c b/hw/bsp/native/src/hal_bsp.c index d65ac11..cabca3d 100644 --- a/hw/bsp/native/src/hal_bsp.c +++ b/hw/bsp/native/src/hal_bsp.c @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -41,3 +41,9 @@ bsp_flash_dev(uint8_t id) } return &native_flash_dev; } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/nrf51-arduino_101/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51-arduino_101/src/hal_bsp.c b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c index 22c54a4..f6af3f6 100644 --- a/hw/bsp/nrf51-arduino_101/src/hal_bsp.c +++ b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c @@ -64,3 +64,9 @@ bsp_core_dump(int *area_cnt) *area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]); return dump_cfg; } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/nrf51-blenano/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51-blenano/src/hal_bsp.c b/hw/bsp/nrf51-blenano/src/hal_bsp.c index ee84922..61fb8b5 100644 --- a/hw/bsp/nrf51-blenano/src/hal_bsp.c +++ b/hw/bsp/nrf51-blenano/src/hal_bsp.c @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -32,3 +32,9 @@ bsp_flash_dev(uint8_t id) } return &nrf51_flash_dev; } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c b/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c index 1558cd7..05883ad 100644 --- a/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c +++ b/hw/bsp/nrf51dk-16kbram/src/hal_bsp.c @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -77,3 +77,9 @@ bsp_hal_init(void) OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg); assert(rc == 0); } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/nrf51dk/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf51dk/src/hal_bsp.c b/hw/bsp/nrf51dk/src/hal_bsp.c index 83d9bee..538d007 100644 --- a/hw/bsp/nrf51dk/src/hal_bsp.c +++ b/hw/bsp/nrf51dk/src/hal_bsp.c @@ -91,3 +91,9 @@ bsp_get_refmv(void *cfgdata) return refmv; } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/nrf52dk/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf52dk/src/hal_bsp.c b/hw/bsp/nrf52dk/src/hal_bsp.c index 9446b45..242c862 100644 --- a/hw/bsp/nrf52dk/src/hal_bsp.c +++ b/hw/bsp/nrf52dk/src/hal_bsp.c @@ -57,3 +57,9 @@ bsp_get_refmv(void *cfgdata) { return (2800); } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/nrf52pdk/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf52pdk/src/hal_bsp.c b/hw/bsp/nrf52pdk/src/hal_bsp.c index 5a0ecdc..739e880 100644 --- a/hw/bsp/nrf52pdk/src/hal_bsp.c +++ b/hw/bsp/nrf52pdk/src/hal_bsp.c @@ -78,3 +78,9 @@ bsp_hal_init(void) OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg); assert(rc == 0); } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c index c0020e0..45f6dd8 100644 --- a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c +++ b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c @@ -75,3 +75,9 @@ bsp_core_dump(int *area_cnt) *area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]); return dump_cfg; } + +int +hal_bsp_power_state(int state) +{ + return (0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/hw/hal/include/hal/hal_bsp.h ---------------------------------------------------------------------- diff --git a/hw/hal/include/hal/hal_bsp.h b/hw/hal/include/hal/hal_bsp.h index c5d0ba1..0b4a39c 100644 --- a/hw/hal/include/hal/hal_bsp.h +++ b/hw/hal/include/hal/hal_bsp.h @@ -69,6 +69,15 @@ int bsp_hw_id(uint8_t *id, int max_len); struct adc_dev; uint16_t bsp_get_refmv(void *cfgdata); +#define HAL_BSP_POWER_ON (1) +#define HAL_BSP_POWER_WFI (2) +#define HAL_BSP_POWER_SLEEP (3) +#define HAL_BSP_POWER_DEEP_SLEEP (4) +#define HAL_BSP_POWER_OFF (5) +#define HAL_BSP_POWER_PERUSER (128) + +int hal_bsp_power_state(int state); + #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/libs/os/include/os/os.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/os.h b/libs/os/include/os/os.h index a8dbd5c..5b64159 100644 --- a/libs/os/include/os/os.h +++ b/libs/os/include/os/os.h @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -68,6 +68,7 @@ enum os_error { OS_NOT_STARTED = 9, /* Operating must be started to call this function, but isn't */ OS_ENOENT = 10, /* No such thing */ OS_EBUSY = 11, /* Resource busy */ + OS_ERROR = 12, /* Generic Error */ }; #define OS_WAIT_FOREVER (-1) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/libs/os/include/os/os_dev.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/os_dev.h b/libs/os/include/os/os_dev.h index 7cffd5e..be2123d 100644 --- a/libs/os/include/os/os_dev.h +++ b/libs/os/include/os/os_dev.h @@ -44,18 +44,22 @@ struct os_dev; * Device status, so functions can ensure device is called in a * consistent state. */ -#define OS_DEV_STATUS_BASE (1 << 0) -#define OS_DEV_STATUS_INITING (1 << 1) -#define OS_DEV_STATUS_READY (1 << 2) -#define OS_DEV_STATUS_OPEN (1 << 3) +#define OS_DEV_F_STATUS_READY (1 << 0) +#define OS_DEV_F_STATUS_OPEN (1 << 1) +#define OS_DEV_F_STATUS_SUSPENDED (1 << 2) +#define OS_DEV_F_INIT_CRITICAL (1 << 3) typedef int (*os_dev_init_func_t)(struct os_dev *, void *); typedef int (*os_dev_open_func_t)(struct os_dev *, uint32_t, void *); +typedef int (*os_dev_suspend_func_t)(struct os_dev *, os_time_t, int); +typedef int (*os_dev_resume_func_t)(struct os_dev *); typedef int (*os_dev_close_func_t)(struct os_dev *); struct os_dev_handlers { os_dev_open_func_t od_open; + os_dev_suspend_func_t od_suspend; + os_dev_resume_func_t od_resume; os_dev_close_func_t od_close; }; @@ -68,8 +72,8 @@ struct os_dev { void *od_init_arg; uint8_t od_stage; uint8_t od_priority; - uint8_t od_init_flags; - uint8_t od_status; + uint8_t od_open_ref; + uint8_t od_flags; char *od_name; STAILQ_ENTRY(os_dev) od_next; }; @@ -78,9 +82,31 @@ struct os_dev { (__dev)->od_handlers.od_open = (__open); \ (__dev)->od_handlers.od_close = (__close); +static inline int +os_dev_suspend(struct os_dev *dev, os_time_t suspend_t, uint8_t force) +{ + if (dev->od_handlers.od_suspend == NULL) { + return (0); + } else { + return (dev->od_handlers.od_suspend(dev, suspend_t, force)); + } +} + +static inline int +os_dev_resume(struct os_dev *dev) +{ + if (dev->od_handlers.od_resume == NULL) { + return (0); + } else { + return (dev->od_handlers.od_resume(dev)); + } +} + int os_dev_create(struct os_dev *dev, char *name, uint8_t stage, uint8_t priority, os_dev_init_func_t od_init, void *arg); int os_dev_initialize_all(uint8_t stage); +int os_dev_suspend_all(os_time_t, uint8_t); +int os_dev_resume_all(void); struct os_dev *os_dev_open(char *devname, uint32_t timo, void *arg); int os_dev_close(struct os_dev *dev); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e02f6678/libs/os/src/os_dev.c ---------------------------------------------------------------------- diff --git a/libs/os/src/os_dev.c b/libs/os/src/os_dev.c index 7c9a935..fbd70b8 100644 --- a/libs/os/src/os_dev.c +++ b/libs/os/src/os_dev.c @@ -34,7 +34,8 @@ os_dev_init(struct os_dev *dev, char *name, uint8_t stage, dev->od_stage = stage; dev->od_priority = priority; /* assume these are set after the fact. */ - dev->od_init_flags = 0; + dev->od_flags = 0; + dev->od_open_ref = 0; dev->od_init = od_init; dev->od_init_arg = arg; memset(&dev->od_handlers, 0, sizeof(dev->od_handlers)); @@ -137,11 +138,11 @@ os_dev_initialize_all(uint8_t stage) if (dev->od_stage == stage) { rc = dev->od_init(dev, dev->od_init_arg); if (rc != 0) { - if (dev->od_init_flags & OS_DEV_INIT_F_CRITICAL) { + if (dev->od_flags & OS_DEV_F_INIT_CRITICAL) { goto err; } } else { - dev->od_status |= OS_DEV_STATUS_READY; + dev->od_flags |= OS_DEV_F_STATUS_READY; } } } @@ -152,6 +153,57 @@ err: } /** + * Suspend all devices. + * + * @param dev The device to suspend + * @param suspend_t The number of ticks to suspend this device for + * @param force Whether or not to force suspending the device + * + * @return 0 on success, or a non-zero error code if one of the devices + * returned it. + */ +int +os_dev_suspend_all(os_time_t suspend_t, uint8_t force) +{ + struct os_dev *dev; + int suspend_failure; + int rc; + + suspend_failure = 0; + STAILQ_FOREACH(dev, &g_os_dev_list, od_next) { + rc = os_dev_suspend(dev, suspend_t, force); + if (rc != 0) { + suspend_failure = OS_ERROR; + } + } + + return (suspend_failure); +} + +/** + * Resume all the devices that were suspended. + * + * @return 0 on success, -1 if any of the devices have failed to resume. + */ +int +os_dev_resume_all(void) +{ + struct os_dev *dev; + int rc; + + STAILQ_FOREACH(dev, &g_os_dev_list, od_next) { + rc = os_dev_resume(dev); + if (rc != 0) { + goto err; + } + } + + return (0); +err: + return (rc); +} + +/** * Lookup a device by name, internal function only. * * @param name The name of the device to look up. @@ -185,6 +237,7 @@ struct os_dev * os_dev_open(char *devname, uint32_t timo, void *arg) { struct os_dev *dev; + os_sr_t sr; int rc; dev = os_dev_lookup(devname); @@ -193,7 +246,7 @@ os_dev_open(char *devname, uint32_t timo, void *arg) } /* Device is not ready to be opened. */ - if ((dev->od_status & OS_DEV_STATUS_READY) == 0) { + if ((dev->od_flags & OS_DEV_F_STATUS_READY) == 0) { return (NULL); } @@ -204,7 +257,10 @@ os_dev_open(char *devname, uint32_t timo, void *arg) } } - dev->od_status |= OS_DEV_STATUS_OPEN; + OS_ENTER_CRITICAL(sr); + ++dev->od_open_ref; + dev->od_flags |= OS_DEV_F_STATUS_OPEN; + OS_EXIT_CRITICAL(sr); return (dev); err: @@ -222,6 +278,7 @@ int os_dev_close(struct os_dev *dev) { int rc; + os_sr_t sr; if (dev->od_handlers.od_close) { rc = dev->od_handlers.od_close(dev); @@ -230,7 +287,11 @@ os_dev_close(struct os_dev *dev) } } - dev->od_status &= ~OS_DEV_STATUS_OPEN; + OS_ENTER_CRITICAL(sr); + if (--dev->od_open_ref == 0) { + dev->od_flags &= ~OS_DEV_F_STATUS_OPEN; + } + OS_EXIT_CRITICAL(sr); return (0); err: