sys: onoff: generalize and shorten API
The original API was misnamed, as the intent was to provide a manager that decoupled state management from the service that needed to be turned on or off. Update all the names, shortening them where appropriate removing unncessary internal components like _service. Also remove some API that misled developers into believing that onoff managers are normally expected to be exposed directly to consumers. While this is a use case, in most situations there are service or client-specific actions that need to be coupled to transition events. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
fadd98aad2
commit
8bd676ed38
4 changed files with 344 additions and 328 deletions
|
@ -10,21 +10,24 @@ complexity of properly managing multiple consumers of a device in a
|
|||
multithreaded system, especially when transitions may be asynchronous,
|
||||
suggests that a shared implementation is desirable.
|
||||
|
||||
Zephyr provides managers for several coordination policies. These
|
||||
managers are embedded into services that use them for specific
|
||||
functions.
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 2
|
||||
|
||||
|
||||
.. _resource_mgmt_onoff:
|
||||
|
||||
On-Off Services
|
||||
***************
|
||||
On-Off Manager
|
||||
**************
|
||||
|
||||
An on-off service supports an arbitrary number of clients of a service
|
||||
An on-off manager supports an arbitrary number of clients of a service
|
||||
which has a binary state. Example applications are power rails, clocks,
|
||||
and binary device power management.
|
||||
|
||||
The service has the following properties:
|
||||
The manager has the following properties:
|
||||
|
||||
* The stable states are off, on, and error. The service always begins
|
||||
in the off state. The service may also be in a transition to a given
|
||||
|
@ -39,8 +42,8 @@ The service has the following properties:
|
|||
* Each service configuration provides functions that implement the
|
||||
transition from off to on, from on to off, and optionally from an
|
||||
error state to off. Transitions that may put a calling thread to
|
||||
sleep must be flagged in the configuration to support safe invocation
|
||||
from non-thread context.
|
||||
sleep must be flagged in the configuration to support detecting unsafe
|
||||
invocation from non-thread context.
|
||||
* All operations are asynchronous, and are initiated by a function call
|
||||
that references a specific service and is given client notification
|
||||
data. The function call will succeed or fail. On success, the
|
||||
|
@ -58,15 +61,15 @@ Requests are reference counted, but not tracked. That means clients are
|
|||
responsible for recording whether their requests were accepted, and for
|
||||
initiating a release only if they have previously successfully completed
|
||||
a request. Improper use of the API can cause an active client to be
|
||||
shut out, and the service does not maintain a record of specific clients
|
||||
shut out, and the manager does not maintain a record of specific clients
|
||||
that have been granted a request.
|
||||
|
||||
Failures in executing a transition are recorded and inhibit further
|
||||
requests or releases until the service is reset. Pending requests are
|
||||
requests or releases until the manager is reset. Pending requests are
|
||||
notified (and cancelled) when errors are discovered.
|
||||
|
||||
Transition operation completion notifications are provided through any
|
||||
of the following mechanisms:
|
||||
Transition operation completion notifications are provided through the
|
||||
standard :ref:`async_notification`, supporting these methods:
|
||||
|
||||
* Signal: A pointer to a :c:type:`struct k_poll_signal` is provided, and
|
||||
the signal is raised when the transition completes. The operation
|
||||
|
@ -81,5 +84,5 @@ Synchronous transition may be implemented by a caller based on its
|
|||
context, for example by using :cpp:func:`k_poll()` to wait until the
|
||||
completion is signalled.
|
||||
|
||||
.. doxygengroup:: resource_mgmt_apis
|
||||
.. doxygengroup:: resource_mgmt_onoff_apis
|
||||
:project: Zephyr
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Peter Bigot Consulting, LLC
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -16,7 +17,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup resource_mgmt_apis Resource Management APIs
|
||||
* @defgroup resource_mgmt_onoff_apis On-Off Service APIs
|
||||
* @ingroup kernel_apis
|
||||
* @{
|
||||
*/
|
||||
|
@ -24,57 +25,63 @@ extern "C" {
|
|||
/**
|
||||
* @brief Flag fields used to specify on-off service behavior.
|
||||
*/
|
||||
enum onoff_service_flags {
|
||||
enum onoff_manager_flags {
|
||||
/**
|
||||
* @brief Flag used in struct onoff_service_transitions.
|
||||
* @brief Flag used in struct onoff_manager_transitions.
|
||||
*
|
||||
* When provided this indicates the start transition function
|
||||
* may cause the calling thread to wait. This blocks attempts
|
||||
* to initiate a transition from a non-thread context.
|
||||
*/
|
||||
ONOFF_SERVICE_START_SLEEPS = BIT(0),
|
||||
ONOFF_START_SLEEPS = BIT(0),
|
||||
|
||||
/**
|
||||
* @brief Flag used in struct onoff_service_transitions.
|
||||
* @brief Flag used in struct onoff_manager_transitions.
|
||||
*
|
||||
* As with @ref ONOFF_SERVICE_START_SLEEPS but describing the
|
||||
* stop transition function.
|
||||
* As with @ref ONOFF_START_SLEEPS but describing the stop
|
||||
* transition function.
|
||||
*/
|
||||
ONOFF_SERVICE_STOP_SLEEPS = BIT(1),
|
||||
ONOFF_STOP_SLEEPS = BIT(1),
|
||||
|
||||
/**
|
||||
* @brief Flag used in struct onoff_service_transitions.
|
||||
* @brief Flag used in struct onoff_manager_transitions.
|
||||
*
|
||||
* As with @ref ONOFF_SERVICE_START_SLEEPS but describing the
|
||||
* reset transition function.
|
||||
* As with @ref ONOFF_START_SLEEPS but describing the reset
|
||||
* transition function.
|
||||
*/
|
||||
ONOFF_SERVICE_RESET_SLEEPS = BIT(2),
|
||||
ONOFF_RESET_SLEEPS = BIT(2),
|
||||
|
||||
/* Internal use. */
|
||||
ONOFF_SERVICE_HAS_ERROR = BIT(3),
|
||||
ONOFF_HAS_ERROR = BIT(3),
|
||||
|
||||
/* This and higher bits reserved for internal use. */
|
||||
ONOFF_SERVICE_INTERNAL_BASE = BIT(4),
|
||||
ONOFF_INTERNAL_BASE = BIT(4),
|
||||
};
|
||||
|
||||
#define ONOFF_SERVICE_START_SLEEPS __DEPRECATED_MACRO ONOFF_START_SLEEPS
|
||||
#define ONOFF_SERVICE_STOP_SLEEPS __DEPRECATED_MACRO ONOFF_STOP_SLEEPS
|
||||
#define ONOFF_SERVICE_RESET_SLEEPS __DEPRECATED_MACRO ONOFF_RESET_SLEEPS
|
||||
#define ONOFF_SERVICE_HAS_ERROR __DEPRECATED_MACRO ONOFF_HAS_ERROR
|
||||
#define ONOFF_SERVICE_INTERNAL_BASE __DEPRECATED_MACRO ONOFF_INTERNAL_BASE
|
||||
|
||||
/* Forward declaration */
|
||||
struct onoff_service;
|
||||
struct onoff_manager;
|
||||
|
||||
/**
|
||||
* @brief Signature used to notify an on-off service that a transition
|
||||
* @brief Signature used to notify an on-off manager that a transition
|
||||
* has completed.
|
||||
*
|
||||
* Functions of this type are passed to service-specific transition
|
||||
* functions to be used to report the completion of the operation.
|
||||
* The functions may be invoked from any context.
|
||||
*
|
||||
* @param srv the service for which transition was requested.
|
||||
* @param mgr the manager for which transition was requested.
|
||||
*
|
||||
* @param res the result of the transition. This shall be
|
||||
* non-negative on success, or a negative error code. If an error is
|
||||
* indicated the service shall enter an error state.
|
||||
*/
|
||||
typedef void (*onoff_service_notify_fn)(struct onoff_service *srv,
|
||||
typedef void (*onoff_notify_fn)(struct onoff_manager *mgr,
|
||||
int res);
|
||||
|
||||
/**
|
||||
|
@ -89,10 +96,10 @@ typedef void (*onoff_service_notify_fn)(struct onoff_service *srv,
|
|||
*
|
||||
* The stop function will be called only from the on state.
|
||||
*
|
||||
* The reset function may be called only when
|
||||
* onoff_service_has_error() returns true.
|
||||
* The reset function may be called only when onoff_has_error()
|
||||
* returns true.
|
||||
*
|
||||
* @param srv the service for which transition was requested.
|
||||
* @param mgr the manager for which transition was requested.
|
||||
*
|
||||
* @param notify the function to be invoked when the transition has
|
||||
* completed. The callee shall capture this parameter to notify on
|
||||
|
@ -100,41 +107,40 @@ typedef void (*onoff_service_notify_fn)(struct onoff_service *srv,
|
|||
* asynchronous, notify shall be invoked before the transition
|
||||
* function returns.
|
||||
*/
|
||||
typedef void (*onoff_service_transition_fn)(struct onoff_service *srv,
|
||||
onoff_service_notify_fn notify);
|
||||
typedef void (*onoff_transition_fn)(struct onoff_manager *mgr,
|
||||
onoff_notify_fn notify);
|
||||
|
||||
/** @brief On-off service transition functions. */
|
||||
struct onoff_service_transitions {
|
||||
struct onoff_transitions {
|
||||
/* Function to invoke to transition the service to on. */
|
||||
onoff_service_transition_fn start;
|
||||
onoff_transition_fn start;
|
||||
|
||||
/* Function to invoke to transition the service to off. */
|
||||
onoff_service_transition_fn stop;
|
||||
onoff_transition_fn stop;
|
||||
|
||||
/* Function to force the service state to reset, where supported. */
|
||||
onoff_service_transition_fn reset;
|
||||
onoff_transition_fn reset;
|
||||
|
||||
/* Flags identifying transition function capabilities. */
|
||||
u8_t flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief State associated with an on-off service.
|
||||
* @brief State associated with an on-off manager.
|
||||
*
|
||||
* No fields in this structure are intended for use by service
|
||||
* providers or clients. The state is to be initialized once, using
|
||||
* onoff_service_init(), when the service provider is initialized.
|
||||
* In case of error it may be reset through the
|
||||
* onoff_service_reset() API.
|
||||
* onoff_manager_init(), when the service provider is initialized. In
|
||||
* case of error it may be reset through the onoff_reset() API.
|
||||
*/
|
||||
struct onoff_service {
|
||||
struct onoff_manager {
|
||||
/* List of clients waiting for completion of reset or
|
||||
* transition to on.
|
||||
*/
|
||||
sys_slist_t clients;
|
||||
|
||||
/* Transition functions. */
|
||||
const struct onoff_service_transitions *transitions;
|
||||
const struct onoff_transitions *transitions;
|
||||
|
||||
/* Mutex protection for flags, clients, releaser, and refs. */
|
||||
struct k_spinlock lock;
|
||||
|
@ -149,7 +155,7 @@ struct onoff_service {
|
|||
u16_t refs;
|
||||
};
|
||||
|
||||
/** @brief Initializer of transitions structure.
|
||||
/** @brief Initializer for a onoff_transitions object.
|
||||
*
|
||||
* @param _start a function used to transition from off to on state.
|
||||
*
|
||||
|
@ -158,21 +164,30 @@ struct onoff_service {
|
|||
* @param _reset a function used to clear errors and force the service to an off
|
||||
* state. Can be null.
|
||||
*
|
||||
* @param _flags any or all of the flags from enum onoff_service_flags.
|
||||
* @param _flags any or all of the flags from enum onoff_manager_flags.
|
||||
*/
|
||||
#define ONOFF_SERVICE_TRANSITIONS_INITIALIZER(_start, _stop, _reset, _flags) { \
|
||||
#define ONOFF_TRANSITIONS_INITIALIZER(_start, _stop, _reset, _flags) { \
|
||||
.start = _start, \
|
||||
.stop = _stop, \
|
||||
.reset = _reset, \
|
||||
.flags = _flags, \
|
||||
}
|
||||
|
||||
#define ONOFF_SERVICE_TRANSITIONS_INITIALIZER(_start, _stop, _reset, _flags) \
|
||||
__DEPRECATED_MACRO \
|
||||
ONOFF_TRANSISTIONS_INITIALIZER(_start, _stop, _reset, _flags)
|
||||
|
||||
|
||||
/** @internal */
|
||||
#define ONOFF_SERVICE_INITIALIZER(_transitions) { \
|
||||
#define ONOFF_MANAGER_INITIALIZER(_transitions) { \
|
||||
.transitions = _transitions, \
|
||||
.flags = (_transitions)->flags, \
|
||||
}
|
||||
|
||||
#define ONOFF_SERVICE_INITIALIZER(_transitions) \
|
||||
__DEPRECATED_MACRO \
|
||||
ONOFF_MANAGER_INITIALIZER(_transitions)
|
||||
|
||||
/**
|
||||
* @brief Initialize an on-off service to off state.
|
||||
*
|
||||
|
@ -182,7 +197,7 @@ struct onoff_service {
|
|||
*
|
||||
* This function should never be invoked by clients of an on-off service.
|
||||
*
|
||||
* @param srv the service definition object to be initialized.
|
||||
* @param mgr the manager definition object to be initialized.
|
||||
*
|
||||
* @param transitions A structure with transition functions. Structure must be
|
||||
* persistent as it is used by the service.
|
||||
|
@ -190,8 +205,8 @@ struct onoff_service {
|
|||
* @retval 0 on success
|
||||
* @retval -EINVAL if start, stop, or flags are invalid
|
||||
*/
|
||||
int onoff_service_init(struct onoff_service *srv,
|
||||
const struct onoff_service_transitions *transitions);
|
||||
int onoff_manager_init(struct onoff_manager *mgr,
|
||||
const struct onoff_transitions *transitions);
|
||||
|
||||
/* Forward declaration */
|
||||
struct onoff_client;
|
||||
|
@ -204,7 +219,7 @@ struct onoff_client;
|
|||
* pre-kernel, ISR, or cooperative or pre-emptible threads.
|
||||
* Compatible functions must be isr-callable and non-suspendable.
|
||||
*
|
||||
* @param srv the service for which the operation was initiated.
|
||||
* @param mgr the manager for which the operation was initiated.
|
||||
*
|
||||
* @param cli the client structure passed to the function that
|
||||
* initiated the operation.
|
||||
|
@ -216,7 +231,7 @@ struct onoff_client;
|
|||
* service-specific, but the value shall be non-negative if the
|
||||
* operation succeeded, and negative if the operation failed.
|
||||
*/
|
||||
typedef void (*onoff_client_callback)(struct onoff_service *srv,
|
||||
typedef void (*onoff_client_callback)(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli,
|
||||
void *user_data,
|
||||
int res);
|
||||
|
@ -232,11 +247,7 @@ typedef void (*onoff_client_callback)(struct onoff_service *srv,
|
|||
* when a pointer to the object is passed to any on-off service
|
||||
* function. While the service provider controls the object the
|
||||
* client must not change any object fields. Control reverts to the
|
||||
* client:
|
||||
* * if the call to the service API returns an error;
|
||||
* * if the call to the service API succeeds for a no-wait operation;
|
||||
* * when operation completion is posted (signalled or callback
|
||||
* invoked).
|
||||
* client concurrent with release of the owned sys_notify structure.
|
||||
*
|
||||
* After control has reverted to the client the state object must be
|
||||
* reinitialized for the next operation.
|
||||
|
@ -383,7 +394,7 @@ static inline void onoff_client_init_callback(struct onoff_client *cli,
|
|||
* transition to on can sleep, the transition cannot be started and
|
||||
* the request will fail with `-EWOULDBLOCK`.
|
||||
*
|
||||
* @param srv the service that will be used.
|
||||
* @param mgr the manager that will be used.
|
||||
*
|
||||
* @param cli a non-null pointer to client state providing
|
||||
* instructions on synchronous expectations and how to notify the
|
||||
|
@ -399,7 +410,7 @@ static inline void onoff_client_init_callback(struct onoff_client *cli,
|
|||
* context and successful initiation could result in an attempt to
|
||||
* make the calling thread sleep.
|
||||
*/
|
||||
int onoff_request(struct onoff_service *srv,
|
||||
int onoff_request(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli);
|
||||
|
||||
/**
|
||||
|
@ -415,7 +426,7 @@ int onoff_request(struct onoff_service *srv,
|
|||
* actual release fails. Always check the operation completion
|
||||
* result.
|
||||
*
|
||||
* @param srv the service that will be used.
|
||||
* @param mgr the manager that will be used.
|
||||
*
|
||||
* @param cli a non-null pointer to client state providing
|
||||
* instructions on how to notify the client when release completes.
|
||||
|
@ -431,7 +442,7 @@ int onoff_request(struct onoff_service *srv,
|
|||
* to off
|
||||
* @retval -EBUSY if the service is transitioning to on
|
||||
*/
|
||||
int onoff_release(struct onoff_service *srv,
|
||||
int onoff_release(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli);
|
||||
|
||||
/**
|
||||
|
@ -439,13 +450,17 @@ int onoff_release(struct onoff_service *srv,
|
|||
*
|
||||
* This function can be used to determine whether the service has
|
||||
* recorded an error. Errors may be cleared by invoking
|
||||
* onoff_service_reset().
|
||||
* onoff_reset().
|
||||
*
|
||||
* This is an unlocked convenience function suitable for use only when
|
||||
* it is known that no other process might invoke an operation that
|
||||
* transitions the service between an error and non-error state.
|
||||
*
|
||||
* @return true if and only if the service has an uncleared error.
|
||||
*/
|
||||
static inline bool onoff_service_has_error(const struct onoff_service *srv)
|
||||
static inline bool onoff_has_error(const struct onoff_manager *mgr)
|
||||
{
|
||||
return (srv->flags & ONOFF_SERVICE_HAS_ERROR) != 0;
|
||||
return (mgr->flags & ONOFF_HAS_ERROR) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -453,7 +468,7 @@ static inline bool onoff_service_has_error(const struct onoff_service *srv)
|
|||
* state.
|
||||
*
|
||||
* A service can only be reset when it is in an error state as
|
||||
* indicated by onoff_service_has_error().
|
||||
* indicated by onoff_has_error().
|
||||
*
|
||||
* The return value indicates the success or failure of an attempt to
|
||||
* initiate an operation to reset the resource. If initiation of the
|
||||
|
@ -465,15 +480,12 @@ static inline bool onoff_service_has_error(const struct onoff_service *srv)
|
|||
* Note that the call to this function may succeed in a case where the
|
||||
* actual reset fails. Always check the operation completion result.
|
||||
*
|
||||
* This function is blocking if the reset transition is blocking,
|
||||
* unless client notification specifies no-wait.
|
||||
*
|
||||
* @note Due to the conditions on state transition all incomplete
|
||||
* asynchronous operations will have been informed of the error when
|
||||
* it occurred. There need be no concern about dangling requests left
|
||||
* after a reset completes.
|
||||
*
|
||||
* @param srv the service to be reset.
|
||||
* @param mgr the manager to be reset.
|
||||
*
|
||||
* @param cli pointer to client state, including instructions on how
|
||||
* to notify the client when reset completes. Behavior is undefined
|
||||
|
@ -481,11 +493,11 @@ static inline bool onoff_service_has_error(const struct onoff_service *srv)
|
|||
* operation.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -ENOTSUP if reset is not supported
|
||||
* @retval -EINVAL if the parameters are invalid, or if the service
|
||||
* @retval -EALREADY if the service does not have a recorded error
|
||||
* @retval -ENOTSUP if reset is not supported by the service.
|
||||
* @retval -EINVAL if the parameters are invalid.
|
||||
* @retval -EALREADY if the service does not have a recorded error.
|
||||
*/
|
||||
int onoff_service_reset(struct onoff_service *srv,
|
||||
int onoff_reset(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli);
|
||||
|
||||
/**
|
||||
|
@ -511,7 +523,7 @@ int onoff_service_reset(struct onoff_service *srv,
|
|||
* If the cancellation fails the service retains control of the client
|
||||
* object, and the client must wait for operation completion.
|
||||
*
|
||||
* @param srv the service for which an operation is to be cancelled.
|
||||
* @param mgr the manager for which an operation is to be cancelled.
|
||||
*
|
||||
* @param cli a pointer to the same client state that was provided
|
||||
* when the operation to be cancelled was issued. If the cancellation
|
||||
|
@ -530,7 +542,7 @@ int onoff_service_reset(struct onoff_service *srv,
|
|||
* likely indicates that the operation and client notification had
|
||||
* already completed.
|
||||
*/
|
||||
int onoff_cancel(struct onoff_service *srv,
|
||||
int onoff_cancel(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli);
|
||||
|
||||
/** @} */
|
||||
|
|
251
lib/os/onoff.c
251
lib/os/onoff.c
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Peter Bigot Consulting, LLC
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -7,33 +8,32 @@
|
|||
#include <kernel.h>
|
||||
#include <sys/onoff.h>
|
||||
|
||||
|
||||
#define SERVICE_CONFIG_FLAGS \
|
||||
(ONOFF_SERVICE_START_SLEEPS \
|
||||
| ONOFF_SERVICE_STOP_SLEEPS \
|
||||
| ONOFF_SERVICE_RESET_SLEEPS)
|
||||
(ONOFF_START_SLEEPS \
|
||||
| ONOFF_STOP_SLEEPS \
|
||||
| ONOFF_RESET_SLEEPS)
|
||||
|
||||
#define SERVICE_REFS_MAX UINT16_MAX
|
||||
|
||||
#define SERVICE_STATE_OFF 0
|
||||
#define SERVICE_STATE_ON ONOFF_SERVICE_INTERNAL_BASE
|
||||
#define SERVICE_STATE_TRANSITION (ONOFF_SERVICE_INTERNAL_BASE << 1)
|
||||
#define SERVICE_STATE_TO_ON (SERVICE_STATE_TRANSITION | SERVICE_STATE_ON)
|
||||
#define SERVICE_STATE_TO_OFF (SERVICE_STATE_TRANSITION | SERVICE_STATE_OFF)
|
||||
#define ST_OFF 0
|
||||
#define ST_ON ONOFF_INTERNAL_BASE
|
||||
#define ST_TRANSITION (ONOFF_INTERNAL_BASE << 1)
|
||||
#define ST_TO_ON (ST_TRANSITION | ST_ON)
|
||||
#define ST_TO_OFF (ST_TRANSITION | ST_OFF)
|
||||
|
||||
#define SERVICE_STATE_MASK (SERVICE_STATE_ON | SERVICE_STATE_TRANSITION)
|
||||
#define ST_MASK (ST_ON | ST_TRANSITION)
|
||||
|
||||
static void set_service_state(struct onoff_service *srv,
|
||||
static void set_service_state(struct onoff_manager *mgr,
|
||||
u32_t state)
|
||||
{
|
||||
srv->flags &= ~SERVICE_STATE_MASK;
|
||||
srv->flags |= (state & SERVICE_STATE_MASK);
|
||||
mgr->flags &= ~ST_MASK;
|
||||
mgr->flags |= (state & ST_MASK);
|
||||
}
|
||||
|
||||
static int validate_args(const struct onoff_service *srv,
|
||||
static int validate_args(const struct onoff_manager *mgr,
|
||||
struct onoff_client *cli)
|
||||
{
|
||||
if ((srv == NULL) || (cli == NULL)) {
|
||||
if ((mgr == NULL) || (cli == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -47,8 +47,8 @@ static int validate_args(const struct onoff_service *srv,
|
|||
return rv;
|
||||
}
|
||||
|
||||
int onoff_service_init(struct onoff_service *srv,
|
||||
const struct onoff_service_transitions *transitions)
|
||||
int onoff_manager_init(struct onoff_manager *mgr,
|
||||
const struct onoff_transitions *transitions)
|
||||
{
|
||||
if (transitions->flags & ~SERVICE_CONFIG_FLAGS) {
|
||||
return -EINVAL;
|
||||
|
@ -58,24 +58,25 @@ int onoff_service_init(struct onoff_service *srv,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
*srv = (struct onoff_service)ONOFF_SERVICE_INITIALIZER(transitions);
|
||||
*mgr = (struct onoff_manager)ONOFF_MANAGER_INITIALIZER(transitions);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void notify_one(struct onoff_service *srv,
|
||||
static void notify_one(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli,
|
||||
int res)
|
||||
{
|
||||
void *ud = cli->user_data;
|
||||
onoff_client_callback cb =
|
||||
(onoff_client_callback)sys_notify_finalize(&cli->notify, res);
|
||||
|
||||
if (cb) {
|
||||
cb(srv, cli, cli->user_data, res);
|
||||
cb(mgr, cli, ud, res);
|
||||
}
|
||||
}
|
||||
|
||||
static void notify_all(struct onoff_service *srv,
|
||||
static void notify_all(struct onoff_manager *mgr,
|
||||
sys_slist_t *list,
|
||||
int res)
|
||||
{
|
||||
|
@ -86,18 +87,18 @@ static void notify_all(struct onoff_service *srv,
|
|||
struct onoff_client,
|
||||
node);
|
||||
|
||||
notify_one(srv, cli, res);
|
||||
notify_one(mgr, cli, res);
|
||||
}
|
||||
}
|
||||
|
||||
static void onoff_start_notify(struct onoff_service *srv,
|
||||
static void onoff_start_notify(struct onoff_manager *mgr,
|
||||
int res)
|
||||
{
|
||||
k_spinlock_key_t key = k_spin_lock(&srv->lock);
|
||||
sys_slist_t clients = srv->clients;
|
||||
k_spinlock_key_t key = k_spin_lock(&mgr->lock);
|
||||
sys_slist_t clients = mgr->clients;
|
||||
|
||||
/* Can't have a queued releaser during start */
|
||||
__ASSERT_NO_MSG(srv->releaser == NULL);
|
||||
__ASSERT_NO_MSG(mgr->releaser == NULL);
|
||||
|
||||
/* If the start failed log an error and leave the rest of the
|
||||
* state in place for diagnostics.
|
||||
|
@ -110,13 +111,13 @@ static void onoff_start_notify(struct onoff_service *srv,
|
|||
* clients of operation completion.
|
||||
*/
|
||||
if (res < 0) {
|
||||
srv->flags &= ~SERVICE_STATE_TRANSITION;
|
||||
srv->flags |= ONOFF_SERVICE_HAS_ERROR;
|
||||
mgr->flags &= ~ST_TRANSITION;
|
||||
mgr->flags |= ONOFF_HAS_ERROR;
|
||||
} else {
|
||||
sys_snode_t *node;
|
||||
unsigned int refs = 0U;
|
||||
|
||||
set_service_state(srv, SERVICE_STATE_ON);
|
||||
set_service_state(mgr, ST_ON);
|
||||
|
||||
SYS_SLIST_FOR_EACH_NODE(&clients, node) {
|
||||
refs += 1U;
|
||||
|
@ -125,78 +126,78 @@ static void onoff_start_notify(struct onoff_service *srv,
|
|||
/* Update the reference count, or fail if the count
|
||||
* would overflow.
|
||||
*/
|
||||
if (srv->refs > (SERVICE_REFS_MAX - refs)) {
|
||||
srv->flags |= ONOFF_SERVICE_HAS_ERROR;
|
||||
if (mgr->refs > (SERVICE_REFS_MAX - refs)) {
|
||||
mgr->flags |= ONOFF_HAS_ERROR;
|
||||
} else {
|
||||
srv->refs += refs;
|
||||
mgr->refs += refs;
|
||||
}
|
||||
__ASSERT_NO_MSG(srv->refs > 0U);
|
||||
__ASSERT_NO_MSG(mgr->refs > 0U);
|
||||
}
|
||||
|
||||
sys_slist_init(&srv->clients);
|
||||
sys_slist_init(&mgr->clients);
|
||||
|
||||
k_spin_unlock(&srv->lock, key);
|
||||
k_spin_unlock(&mgr->lock, key);
|
||||
|
||||
notify_all(srv, &clients, res);
|
||||
notify_all(mgr, &clients, res);
|
||||
}
|
||||
|
||||
int onoff_request(struct onoff_service *srv,
|
||||
int onoff_request(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli)
|
||||
{
|
||||
bool add_client = false; /* add client to pending list */
|
||||
bool start = false; /* invoke start transition */
|
||||
bool notify = false; /* do client notification */
|
||||
int rv = validate_args(srv, cli);
|
||||
int rv = validate_args(mgr, cli);
|
||||
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
k_spinlock_key_t key = k_spin_lock(&srv->lock);
|
||||
k_spinlock_key_t key = k_spin_lock(&mgr->lock);
|
||||
|
||||
if ((srv->flags & ONOFF_SERVICE_HAS_ERROR) != 0) {
|
||||
if ((mgr->flags & ONOFF_HAS_ERROR) != 0) {
|
||||
rv = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Reject if this would overflow the reference count. */
|
||||
if (srv->refs == SERVICE_REFS_MAX) {
|
||||
if (mgr->refs == SERVICE_REFS_MAX) {
|
||||
rv = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
u32_t state = srv->flags & SERVICE_STATE_MASK;
|
||||
u32_t state = mgr->flags & ST_MASK;
|
||||
|
||||
switch (state) {
|
||||
case SERVICE_STATE_TO_OFF:
|
||||
case ST_TO_OFF:
|
||||
/* Queue to start after release */
|
||||
__ASSERT_NO_MSG(srv->releaser != NULL);
|
||||
__ASSERT_NO_MSG(mgr->releaser != NULL);
|
||||
add_client = true;
|
||||
rv = 3;
|
||||
break;
|
||||
case SERVICE_STATE_OFF:
|
||||
case ST_OFF:
|
||||
/* Reject if in a non-thread context and start could
|
||||
* wait.
|
||||
*/
|
||||
if ((k_is_in_isr() || k_is_pre_kernel())
|
||||
&& ((srv->flags & ONOFF_SERVICE_START_SLEEPS) != 0U)) {
|
||||
&& ((mgr->flags & ONOFF_START_SLEEPS) != 0U)) {
|
||||
rv = -EWOULDBLOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Start with first request while off */
|
||||
__ASSERT_NO_MSG(srv->refs == 0);
|
||||
set_service_state(srv, SERVICE_STATE_TO_ON);
|
||||
__ASSERT_NO_MSG(mgr->refs == 0);
|
||||
set_service_state(mgr, ST_TO_ON);
|
||||
start = true;
|
||||
add_client = true;
|
||||
rv = 2;
|
||||
break;
|
||||
case SERVICE_STATE_TO_ON:
|
||||
case ST_TO_ON:
|
||||
/* Already starting, just queue it */
|
||||
add_client = true;
|
||||
rv = 1;
|
||||
break;
|
||||
case SERVICE_STATE_ON:
|
||||
case ST_ON:
|
||||
/* Just increment the reference count */
|
||||
notify = true;
|
||||
break;
|
||||
|
@ -207,32 +208,32 @@ int onoff_request(struct onoff_service *srv,
|
|||
|
||||
out:
|
||||
if (add_client) {
|
||||
sys_slist_append(&srv->clients, &cli->node);
|
||||
sys_slist_append(&mgr->clients, &cli->node);
|
||||
} else if (notify) {
|
||||
srv->refs += 1;
|
||||
mgr->refs += 1;
|
||||
}
|
||||
|
||||
k_spin_unlock(&srv->lock, key);
|
||||
k_spin_unlock(&mgr->lock, key);
|
||||
|
||||
if (start) {
|
||||
__ASSERT_NO_MSG(srv->transitions->start != NULL);
|
||||
srv->transitions->start(srv, onoff_start_notify);
|
||||
__ASSERT_NO_MSG(mgr->transitions->start != NULL);
|
||||
mgr->transitions->start(mgr, onoff_start_notify);
|
||||
} else if (notify) {
|
||||
notify_one(srv, cli, 0);
|
||||
notify_one(mgr, cli, 0);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void onoff_stop_notify(struct onoff_service *srv,
|
||||
static void onoff_stop_notify(struct onoff_manager *mgr,
|
||||
int res)
|
||||
{
|
||||
bool notify_clients = false;
|
||||
int client_res = res;
|
||||
bool start = false;
|
||||
k_spinlock_key_t key = k_spin_lock(&srv->lock);
|
||||
sys_slist_t clients = srv->clients;
|
||||
struct onoff_client *releaser = srv->releaser;
|
||||
k_spinlock_key_t key = k_spin_lock(&mgr->lock);
|
||||
sys_slist_t clients = mgr->clients;
|
||||
struct onoff_client *releaser = mgr->releaser;
|
||||
|
||||
/* If the stop operation failed log an error and leave the
|
||||
* rest of the state in place.
|
||||
|
@ -244,72 +245,72 @@ static void onoff_stop_notify(struct onoff_service *srv,
|
|||
* waiting clients of operation completion.
|
||||
*/
|
||||
if (res < 0) {
|
||||
srv->flags &= ~SERVICE_STATE_TRANSITION;
|
||||
srv->flags |= ONOFF_SERVICE_HAS_ERROR;
|
||||
mgr->flags &= ~ST_TRANSITION;
|
||||
mgr->flags |= ONOFF_HAS_ERROR;
|
||||
notify_clients = true;
|
||||
} else if (sys_slist_is_empty(&clients)) {
|
||||
set_service_state(srv, SERVICE_STATE_OFF);
|
||||
set_service_state(mgr, ST_OFF);
|
||||
} else if ((k_is_in_isr() || k_is_pre_kernel())
|
||||
&& ((srv->flags & ONOFF_SERVICE_START_SLEEPS) != 0U)) {
|
||||
set_service_state(srv, SERVICE_STATE_OFF);
|
||||
&& ((mgr->flags & ONOFF_START_SLEEPS) != 0U)) {
|
||||
set_service_state(mgr, ST_OFF);
|
||||
notify_clients = true;
|
||||
client_res = -EWOULDBLOCK;
|
||||
} else {
|
||||
set_service_state(srv, SERVICE_STATE_TO_ON);
|
||||
set_service_state(mgr, ST_TO_ON);
|
||||
start = true;
|
||||
}
|
||||
|
||||
__ASSERT_NO_MSG(releaser);
|
||||
srv->refs -= 1U;
|
||||
srv->releaser = NULL;
|
||||
__ASSERT_NO_MSG(srv->refs == 0);
|
||||
mgr->refs -= 1U;
|
||||
mgr->releaser = NULL;
|
||||
__ASSERT_NO_MSG(mgr->refs == 0);
|
||||
|
||||
/* Remove the clients if there was an error or a delayed start
|
||||
* couldn't be initiated, because we're resolving their
|
||||
* operation with an error.
|
||||
*/
|
||||
if (notify_clients) {
|
||||
sys_slist_init(&srv->clients);
|
||||
sys_slist_init(&mgr->clients);
|
||||
}
|
||||
|
||||
k_spin_unlock(&srv->lock, key);
|
||||
k_spin_unlock(&mgr->lock, key);
|
||||
|
||||
/* Notify the releaser. If there was an error, notify any
|
||||
* pending requests; otherwise if there are pending requests
|
||||
* start the transition to ON.
|
||||
*/
|
||||
notify_one(srv, releaser, res);
|
||||
notify_one(mgr, releaser, res);
|
||||
if (notify_clients) {
|
||||
notify_all(srv, &clients, client_res);
|
||||
notify_all(mgr, &clients, client_res);
|
||||
} else if (start) {
|
||||
srv->transitions->start(srv, onoff_start_notify);
|
||||
mgr->transitions->start(mgr, onoff_start_notify);
|
||||
}
|
||||
}
|
||||
|
||||
int onoff_release(struct onoff_service *srv,
|
||||
int onoff_release(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli)
|
||||
{
|
||||
bool stop = false; /* invoke stop transition */
|
||||
bool notify = false; /* do client notification */
|
||||
int rv = validate_args(srv, cli);
|
||||
int rv = validate_args(mgr, cli);
|
||||
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
k_spinlock_key_t key = k_spin_lock(&srv->lock);
|
||||
k_spinlock_key_t key = k_spin_lock(&mgr->lock);
|
||||
|
||||
if ((srv->flags & ONOFF_SERVICE_HAS_ERROR) != 0) {
|
||||
if ((mgr->flags & ONOFF_HAS_ERROR) != 0) {
|
||||
rv = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
u32_t state = srv->flags & SERVICE_STATE_MASK;
|
||||
u32_t state = mgr->flags & ST_MASK;
|
||||
|
||||
switch (state) {
|
||||
case SERVICE_STATE_ON:
|
||||
case ST_ON:
|
||||
/* Stay on if release leaves a client. */
|
||||
if (srv->refs > 1U) {
|
||||
if (mgr->refs > 1U) {
|
||||
notify = true;
|
||||
rv = 1;
|
||||
break;
|
||||
|
@ -319,23 +320,23 @@ int onoff_release(struct onoff_service *srv,
|
|||
* wait
|
||||
*/
|
||||
if ((k_is_in_isr() || k_is_pre_kernel())
|
||||
&& ((srv->flags & ONOFF_SERVICE_STOP_SLEEPS) != 0)) {
|
||||
&& ((mgr->flags & ONOFF_STOP_SLEEPS) != 0)) {
|
||||
rv = -EWOULDBLOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
stop = true;
|
||||
|
||||
set_service_state(srv, SERVICE_STATE_TO_OFF);
|
||||
srv->releaser = cli;
|
||||
set_service_state(mgr, ST_TO_OFF);
|
||||
mgr->releaser = cli;
|
||||
rv = 2;
|
||||
|
||||
break;
|
||||
case SERVICE_STATE_TO_ON:
|
||||
case ST_TO_ON:
|
||||
rv = -EBUSY;
|
||||
break;
|
||||
case SERVICE_STATE_OFF:
|
||||
case SERVICE_STATE_TO_OFF:
|
||||
case ST_OFF:
|
||||
case ST_TO_OFF:
|
||||
rv = -EALREADY;
|
||||
break;
|
||||
default:
|
||||
|
@ -344,57 +345,57 @@ int onoff_release(struct onoff_service *srv,
|
|||
|
||||
out:
|
||||
if (notify) {
|
||||
srv->refs -= 1U;
|
||||
mgr->refs -= 1U;
|
||||
}
|
||||
|
||||
k_spin_unlock(&srv->lock, key);
|
||||
k_spin_unlock(&mgr->lock, key);
|
||||
|
||||
if (stop) {
|
||||
__ASSERT_NO_MSG(srv->transitions->stop != NULL);
|
||||
srv->transitions->stop(srv, onoff_stop_notify);
|
||||
__ASSERT_NO_MSG(mgr->transitions->stop != NULL);
|
||||
mgr->transitions->stop(mgr, onoff_stop_notify);
|
||||
} else if (notify) {
|
||||
notify_one(srv, cli, 0);
|
||||
notify_one(mgr, cli, 0);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void onoff_reset_notify(struct onoff_service *srv,
|
||||
static void onoff_reset_notify(struct onoff_manager *mgr,
|
||||
int res)
|
||||
{
|
||||
k_spinlock_key_t key = k_spin_lock(&srv->lock);
|
||||
sys_slist_t clients = srv->clients;
|
||||
k_spinlock_key_t key = k_spin_lock(&mgr->lock);
|
||||
sys_slist_t clients = mgr->clients;
|
||||
|
||||
/* If the reset failed clear the transition flag but otherwise
|
||||
* leave the state unchanged.
|
||||
*
|
||||
* If it was successful clear the reference count and all
|
||||
* flags except capability flags (sets to SERVICE_STATE_OFF).
|
||||
* flags except capability flags (sets to ST_OFF).
|
||||
*/
|
||||
if (res < 0) {
|
||||
srv->flags &= ~SERVICE_STATE_TRANSITION;
|
||||
mgr->flags &= ~ST_TRANSITION;
|
||||
} else {
|
||||
__ASSERT_NO_MSG(srv->refs == 0U);
|
||||
srv->refs = 0U;
|
||||
srv->flags &= SERVICE_CONFIG_FLAGS;
|
||||
__ASSERT_NO_MSG(mgr->refs == 0U);
|
||||
mgr->refs = 0U;
|
||||
mgr->flags &= SERVICE_CONFIG_FLAGS;
|
||||
}
|
||||
|
||||
sys_slist_init(&srv->clients);
|
||||
sys_slist_init(&mgr->clients);
|
||||
|
||||
k_spin_unlock(&srv->lock, key);
|
||||
k_spin_unlock(&mgr->lock, key);
|
||||
|
||||
notify_all(srv, &clients, res);
|
||||
notify_all(mgr, &clients, res);
|
||||
}
|
||||
|
||||
int onoff_service_reset(struct onoff_service *srv,
|
||||
int onoff_reset(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli)
|
||||
{
|
||||
if (srv->transitions->reset == NULL) {
|
||||
if (mgr->transitions->reset == NULL) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
bool reset = false;
|
||||
int rv = validate_args(srv, cli);
|
||||
int rv = validate_args(mgr, cli);
|
||||
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
|
@ -402,70 +403,70 @@ int onoff_service_reset(struct onoff_service *srv,
|
|||
|
||||
/* Reject if in a non-thread context and reset could wait. */
|
||||
if ((k_is_in_isr() || k_is_pre_kernel())
|
||||
&& ((srv->flags & ONOFF_SERVICE_RESET_SLEEPS) != 0U)) {
|
||||
&& ((mgr->flags & ONOFF_RESET_SLEEPS) != 0U)) {
|
||||
return -EWOULDBLOCK;
|
||||
}
|
||||
|
||||
k_spinlock_key_t key = k_spin_lock(&srv->lock);
|
||||
k_spinlock_key_t key = k_spin_lock(&mgr->lock);
|
||||
|
||||
if ((srv->flags & ONOFF_SERVICE_HAS_ERROR) == 0) {
|
||||
if ((mgr->flags & ONOFF_HAS_ERROR) == 0) {
|
||||
rv = -EALREADY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((srv->flags & SERVICE_STATE_TRANSITION) == 0) {
|
||||
if ((mgr->flags & ST_TRANSITION) == 0) {
|
||||
reset = true;
|
||||
srv->flags |= SERVICE_STATE_TRANSITION;
|
||||
mgr->flags |= ST_TRANSITION;
|
||||
}
|
||||
|
||||
out:
|
||||
if (rv >= 0) {
|
||||
sys_slist_append(&srv->clients, &cli->node);
|
||||
sys_slist_append(&mgr->clients, &cli->node);
|
||||
}
|
||||
|
||||
k_spin_unlock(&srv->lock, key);
|
||||
k_spin_unlock(&mgr->lock, key);
|
||||
|
||||
if (reset) {
|
||||
srv->transitions->reset(srv, onoff_reset_notify);
|
||||
mgr->transitions->reset(mgr, onoff_reset_notify);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int onoff_cancel(struct onoff_service *srv,
|
||||
int onoff_cancel(struct onoff_manager *mgr,
|
||||
struct onoff_client *cli)
|
||||
{
|
||||
int rv = validate_args(srv, cli);
|
||||
int rv = validate_args(mgr, cli);
|
||||
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = -EALREADY;
|
||||
k_spinlock_key_t key = k_spin_lock(&srv->lock);
|
||||
u32_t state = srv->flags & SERVICE_STATE_MASK;
|
||||
k_spinlock_key_t key = k_spin_lock(&mgr->lock);
|
||||
u32_t state = mgr->flags & ST_MASK;
|
||||
|
||||
/* Can't remove the last client waiting for the in-progress
|
||||
* transition, as there would be nobody to receive the
|
||||
* completion notification, which might indicate a service
|
||||
* error.
|
||||
*/
|
||||
if (sys_slist_find_and_remove(&srv->clients, &cli->node)) {
|
||||
if (sys_slist_find_and_remove(&mgr->clients, &cli->node)) {
|
||||
rv = 0;
|
||||
if (sys_slist_is_empty(&srv->clients)
|
||||
&& (state != SERVICE_STATE_TO_OFF)) {
|
||||
if (sys_slist_is_empty(&mgr->clients)
|
||||
&& (state != ST_TO_OFF)) {
|
||||
rv = -EWOULDBLOCK;
|
||||
sys_slist_append(&srv->clients, &cli->node);
|
||||
sys_slist_append(&mgr->clients, &cli->node);
|
||||
}
|
||||
} else if (srv->releaser == cli) {
|
||||
} else if (mgr->releaser == cli) {
|
||||
/* must be waiting for TO_OFF to complete */
|
||||
rv = -EWOULDBLOCK;
|
||||
}
|
||||
|
||||
k_spin_unlock(&srv->lock, key);
|
||||
k_spin_unlock(&mgr->lock, key);
|
||||
|
||||
if (rv == 0) {
|
||||
notify_one(srv, cli, -ECANCELED);
|
||||
notify_one(mgr, cli, -ECANCELED);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Peter Bigot Consulting, LLC
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -11,7 +12,7 @@ static struct onoff_client spinwait_cli;
|
|||
|
||||
static int callback_res;
|
||||
static void *callback_ud;
|
||||
static void callback(struct onoff_service *srv,
|
||||
static void callback(struct onoff_manager *srv,
|
||||
struct onoff_client *cli,
|
||||
void *ud,
|
||||
int res)
|
||||
|
@ -52,8 +53,8 @@ struct transit_state {
|
|||
const char *tag;
|
||||
bool async;
|
||||
int retval;
|
||||
onoff_service_notify_fn notify;
|
||||
struct onoff_service *srv;
|
||||
onoff_notify_fn notify;
|
||||
struct onoff_manager *srv;
|
||||
};
|
||||
|
||||
static void reset_transit_state(struct transit_state *tsp)
|
||||
|
@ -64,8 +65,8 @@ static void reset_transit_state(struct transit_state *tsp)
|
|||
tsp->srv = NULL;
|
||||
}
|
||||
|
||||
static void run_transit(struct onoff_service *srv,
|
||||
onoff_service_notify_fn notify,
|
||||
static void run_transit(struct onoff_manager *srv,
|
||||
onoff_notify_fn notify,
|
||||
struct transit_state *tsp)
|
||||
{
|
||||
if (tsp->async) {
|
||||
|
@ -99,7 +100,7 @@ static void isr_notify(struct k_timer *timer)
|
|||
}
|
||||
|
||||
struct isr_call_state {
|
||||
struct onoff_service *srv;
|
||||
struct onoff_manager *srv;
|
||||
struct onoff_client *cli;
|
||||
int result;
|
||||
};
|
||||
|
@ -124,15 +125,15 @@ static void isr_reset(struct k_timer *timer)
|
|||
{
|
||||
struct isr_call_state *rsp = k_timer_user_data_get(timer);
|
||||
|
||||
rsp->result = onoff_service_reset(rsp->srv, rsp->cli);
|
||||
rsp->result = onoff_reset(rsp->srv, rsp->cli);
|
||||
k_sem_give(&isr_sync);
|
||||
}
|
||||
|
||||
static struct transit_state start_state = {
|
||||
.tag = "start",
|
||||
};
|
||||
static void start(struct onoff_service *srv,
|
||||
onoff_service_notify_fn notify)
|
||||
static void start(struct onoff_manager *srv,
|
||||
onoff_notify_fn notify)
|
||||
{
|
||||
run_transit(srv, notify, &start_state);
|
||||
}
|
||||
|
@ -140,8 +141,8 @@ static void start(struct onoff_service *srv,
|
|||
static struct transit_state stop_state = {
|
||||
.tag = "stop",
|
||||
};
|
||||
static void stop(struct onoff_service *srv,
|
||||
onoff_service_notify_fn notify)
|
||||
static void stop(struct onoff_manager *srv,
|
||||
onoff_notify_fn notify)
|
||||
{
|
||||
run_transit(srv, notify, &stop_state);
|
||||
}
|
||||
|
@ -149,8 +150,8 @@ static void stop(struct onoff_service *srv,
|
|||
static struct transit_state reset_state = {
|
||||
.tag = "reset",
|
||||
};
|
||||
static void reset(struct onoff_service *srv,
|
||||
onoff_service_notify_fn notify)
|
||||
static void reset(struct onoff_manager *srv,
|
||||
onoff_notify_fn notify)
|
||||
{
|
||||
run_transit(srv, notify, &reset_state);
|
||||
}
|
||||
|
@ -166,39 +167,39 @@ static void clear_transit(void)
|
|||
static void test_service_init_validation(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
const struct onoff_service_transitions null_transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(NULL, NULL, NULL, 0);
|
||||
const struct onoff_service_transitions start_transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, NULL, NULL, 0);
|
||||
const struct onoff_service_transitions stop_transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(NULL, stop, NULL, 0);
|
||||
struct onoff_service_transitions start_stop_transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, NULL, 0);
|
||||
const struct onoff_service_transitions all_transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, reset,
|
||||
ONOFF_SERVICE_START_SLEEPS);
|
||||
struct onoff_manager srv;
|
||||
const struct onoff_transitions null_transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(NULL, NULL, NULL, 0);
|
||||
const struct onoff_transitions start_transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, NULL, NULL, 0);
|
||||
const struct onoff_transitions stop_transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(NULL, stop, NULL, 0);
|
||||
struct onoff_transitions start_stop_transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL, 0);
|
||||
const struct onoff_transitions all_transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, reset,
|
||||
ONOFF_START_SLEEPS);
|
||||
|
||||
clear_transit();
|
||||
|
||||
rc = onoff_service_init(NULL, &null_transitions);
|
||||
rc = onoff_manager_init(NULL, &null_transitions);
|
||||
zassert_equal(rc, -EINVAL,
|
||||
"init null srv %d", rc);
|
||||
|
||||
rc = onoff_service_init(&srv, &null_transitions);
|
||||
rc = onoff_manager_init(&srv, &null_transitions);
|
||||
zassert_equal(rc, -EINVAL,
|
||||
"init null transit %d", rc);
|
||||
|
||||
rc = onoff_service_init(&srv, &start_transitions);
|
||||
rc = onoff_manager_init(&srv, &start_transitions);
|
||||
zassert_equal(rc, -EINVAL,
|
||||
"init null stop %d", rc);
|
||||
|
||||
rc = onoff_service_init(&srv, &stop_transitions);
|
||||
rc = onoff_manager_init(&srv, &stop_transitions);
|
||||
zassert_equal(rc, -EINVAL,
|
||||
"init null start %d", rc);
|
||||
|
||||
start_stop_transitions.flags |= ONOFF_SERVICE_INTERNAL_BASE;
|
||||
rc = onoff_service_init(&srv, &start_stop_transitions);
|
||||
start_stop_transitions.flags |= ONOFF_INTERNAL_BASE;
|
||||
rc = onoff_manager_init(&srv, &start_stop_transitions);
|
||||
zassert_equal(rc, -EINVAL,
|
||||
"init bad flags %d", rc);
|
||||
|
||||
|
@ -206,7 +207,7 @@ static void test_service_init_validation(void)
|
|||
zassert_false(sys_slist_is_empty(&srv.clients),
|
||||
"slist empty");
|
||||
|
||||
rc = onoff_service_init(&srv, &all_transitions);
|
||||
rc = onoff_manager_init(&srv, &all_transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"init good %d", rc);
|
||||
zassert_equal(srv.transitions->start, start,
|
||||
|
@ -215,7 +216,7 @@ static void test_service_init_validation(void)
|
|||
"init stop mismatch");
|
||||
zassert_equal(srv.transitions->reset, reset,
|
||||
"init reset mismatch");
|
||||
zassert_equal(srv.flags, ONOFF_SERVICE_START_SLEEPS,
|
||||
zassert_equal(srv.flags, ONOFF_START_SLEEPS,
|
||||
"init flags mismatch");
|
||||
zassert_equal(srv.refs, 0,
|
||||
"init refs mismatch");
|
||||
|
@ -262,11 +263,11 @@ static void test_client_init_validation(void)
|
|||
static void test_validate_args(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
struct onoff_manager srv;
|
||||
struct k_poll_signal sig;
|
||||
struct onoff_client cli;
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, NULL, 0);
|
||||
const struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL, 0);
|
||||
|
||||
clear_transit();
|
||||
|
||||
|
@ -274,7 +275,7 @@ static void test_validate_args(void)
|
|||
* release, and reset; test it through the request API.
|
||||
*/
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
|
@ -340,30 +341,30 @@ static void test_validate_args(void)
|
|||
static void test_reset(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
struct onoff_manager srv;
|
||||
struct k_poll_signal sig;
|
||||
struct onoff_client cli;
|
||||
unsigned int signalled = 0;
|
||||
int result = 0;
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, NULL, 0);
|
||||
struct onoff_service_transitions transitions_with_reset =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, reset, 0);
|
||||
const struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL, 0);
|
||||
struct onoff_transitions transitions_with_reset =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, reset, 0);
|
||||
|
||||
clear_transit();
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
rc = onoff_service_reset(&srv, &cli);
|
||||
rc = onoff_reset(&srv, &cli);
|
||||
zassert_equal(rc, -ENOTSUP,
|
||||
"reset: %d", rc);
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions_with_reset);
|
||||
rc = onoff_manager_init(&srv, &transitions_with_reset);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
rc = onoff_service_reset(&srv, NULL);
|
||||
rc = onoff_reset(&srv, NULL);
|
||||
zassert_equal(rc, -EINVAL,
|
||||
"rst no cli");
|
||||
|
||||
|
@ -375,11 +376,11 @@ static void test_reset(void)
|
|||
"reset req refs: %u", srv.refs);
|
||||
|
||||
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
reset_state.retval = 57;
|
||||
init_notify_sig(&cli, &sig);
|
||||
rc = onoff_service_reset(&srv, &cli);
|
||||
rc = onoff_reset(&srv, &cli);
|
||||
zassert_equal(rc, -EALREADY,
|
||||
"reset: %d", rc);
|
||||
|
||||
|
@ -390,7 +391,7 @@ static void test_reset(void)
|
|||
"rel trigger: %d", rc);
|
||||
zassert_equal(srv.refs, 0U,
|
||||
"reset req refs: %u", srv.refs);
|
||||
zassert_true(onoff_service_has_error(&srv),
|
||||
zassert_true(onoff_has_error(&srv),
|
||||
"has error");
|
||||
zassert_equal(cli_result(&cli), stop_state.retval,
|
||||
"cli result");
|
||||
|
@ -405,24 +406,24 @@ static void test_reset(void)
|
|||
|
||||
reset_state.retval = -59;
|
||||
init_notify_sig(&cli, &sig);
|
||||
rc = onoff_service_reset(&srv, &cli);
|
||||
rc = onoff_reset(&srv, &cli);
|
||||
zassert_equal(rc, 0U,
|
||||
"reset: %d", rc);
|
||||
zassert_equal(cli_result(&cli), reset_state.retval,
|
||||
"reset result");
|
||||
zassert_equal(srv.refs, 0U,
|
||||
"reset req refs: %u", srv.refs);
|
||||
zassert_true(onoff_service_has_error(&srv),
|
||||
zassert_true(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
reset_state.retval = 62;
|
||||
init_notify_sig(&cli, &sig);
|
||||
rc = onoff_service_reset(&srv, &cli);
|
||||
rc = onoff_reset(&srv, &cli);
|
||||
zassert_equal(rc, 0U,
|
||||
"reset: %d", rc);
|
||||
zassert_equal(cli_result(&cli), reset_state.retval,
|
||||
"reset result");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
signalled = 0;
|
||||
|
@ -435,19 +436,19 @@ static void test_reset(void)
|
|||
|
||||
zassert_equal(srv.refs, 0U,
|
||||
"reset req refs: %u", srv.refs);
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
transitions_with_reset.flags |= ONOFF_SERVICE_RESET_SLEEPS;
|
||||
rc = onoff_service_init(&srv, &transitions_with_reset);
|
||||
transitions_with_reset.flags |= ONOFF_RESET_SLEEPS;
|
||||
rc = onoff_manager_init(&srv, &transitions_with_reset);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
start_state.retval = -23;
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
init_spinwait(&spinwait_cli);
|
||||
rc = onoff_request(&srv, &spinwait_cli);
|
||||
zassert_true(onoff_service_has_error(&srv),
|
||||
zassert_true(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
struct isr_call_state isr_state = {
|
||||
|
@ -474,13 +475,13 @@ static void test_reset(void)
|
|||
static void test_request(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, reset, 0);
|
||||
struct onoff_manager srv;
|
||||
struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, reset, 0);
|
||||
|
||||
clear_transit();
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
|
@ -495,7 +496,7 @@ static void test_request(void)
|
|||
|
||||
/* Can't reset when no error present. */
|
||||
init_spinwait(&spinwait_cli);
|
||||
rc = onoff_service_reset(&srv, &spinwait_cli);
|
||||
rc = onoff_reset(&srv, &spinwait_cli);
|
||||
zassert_equal(rc, -EALREADY,
|
||||
"reset spin client");
|
||||
|
||||
|
@ -517,7 +518,7 @@ static void test_request(void)
|
|||
"error release");
|
||||
zassert_equal(cli_result(&spinwait_cli), stop_state.retval,
|
||||
"error retval");
|
||||
zassert_true(onoff_service_has_error(&srv),
|
||||
zassert_true(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
/* Can't request when error present. */
|
||||
|
@ -537,10 +538,10 @@ static void test_request(void)
|
|||
|
||||
/* Clear the error */
|
||||
init_notify_sig(&cli, &sig);
|
||||
rc = onoff_service_reset(&srv, &cli);
|
||||
rc = onoff_reset(&srv, &cli);
|
||||
zassert_equal(rc, 0,
|
||||
"reset");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
/* Error on start */
|
||||
|
@ -551,20 +552,20 @@ static void test_request(void)
|
|||
"req with error");
|
||||
zassert_equal(cli_result(&spinwait_cli), start_state.retval,
|
||||
"req with error");
|
||||
zassert_true(onoff_service_has_error(&srv),
|
||||
zassert_true(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
/* Clear the error */
|
||||
init_spinwait(&spinwait_cli);
|
||||
rc = onoff_service_reset(&srv, &spinwait_cli);
|
||||
rc = onoff_reset(&srv, &spinwait_cli);
|
||||
zassert_equal(rc, 0,
|
||||
"reset");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
/* Diagnose a no-wait delayed start */
|
||||
transitions.flags |= ONOFF_SERVICE_START_SLEEPS;
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
transitions.flags |= ONOFF_START_SLEEPS;
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
start_state.async = true;
|
||||
|
@ -594,13 +595,13 @@ static void test_request(void)
|
|||
static void test_sync(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, reset, 0);
|
||||
struct onoff_manager srv;
|
||||
const struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, reset, 0);
|
||||
|
||||
clear_transit();
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
|
@ -642,14 +643,15 @@ static void test_sync(void)
|
|||
static void test_async(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
struct onoff_manager srv;
|
||||
struct k_poll_signal sig[2];
|
||||
struct onoff_client cli[2];
|
||||
unsigned int signalled = 0;
|
||||
int result = 0;
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, reset,
|
||||
ONOFF_SERVICE_START_SLEEPS | ONOFF_SERVICE_STOP_SLEEPS);
|
||||
const struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, reset,
|
||||
ONOFF_START_SLEEPS
|
||||
| ONOFF_STOP_SLEEPS);
|
||||
|
||||
clear_transit();
|
||||
start_state.async = true;
|
||||
|
@ -657,7 +659,7 @@ static void test_async(void)
|
|||
stop_state.async = true;
|
||||
stop_state.retval = 17;
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
|
@ -837,19 +839,19 @@ static void test_async(void)
|
|||
static void test_half_sync(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
struct onoff_manager srv;
|
||||
struct k_poll_signal sig;
|
||||
struct onoff_client cli;
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_SERVICE_STOP_SLEEPS);
|
||||
const struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_STOP_SLEEPS);
|
||||
|
||||
clear_transit();
|
||||
start_state.retval = 23;
|
||||
stop_state.async = true;
|
||||
stop_state.retval = 17;
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
|
@ -895,12 +897,13 @@ static void test_half_sync(void)
|
|||
static void test_cancel_request_waits(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
struct onoff_manager srv;
|
||||
struct k_poll_signal sig;
|
||||
struct onoff_client cli;
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_SERVICE_START_SLEEPS | ONOFF_SERVICE_STOP_SLEEPS);
|
||||
const struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_START_SLEEPS
|
||||
| ONOFF_STOP_SLEEPS);
|
||||
|
||||
clear_transit();
|
||||
start_state.async = true;
|
||||
|
@ -908,7 +911,7 @@ static void test_cancel_request_waits(void)
|
|||
stop_state.async = true;
|
||||
stop_state.retval = 31;
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
|
@ -936,7 +939,7 @@ static void test_cancel_request_waits(void)
|
|||
"cancel failed: %d", rc);
|
||||
zassert_equal(cli_result(&cli), -ECANCELED,
|
||||
"cancel notified");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
/* Not allowed to cancel the last pending start.
|
||||
|
@ -944,7 +947,7 @@ static void test_cancel_request_waits(void)
|
|||
rc = onoff_cancel(&srv, &spinwait_cli);
|
||||
zassert_equal(rc, -EWOULDBLOCK,
|
||||
"last cancel", rc);
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
zassert_equal(cli_result(&spinwait_cli), -EAGAIN,
|
||||
"last request");
|
||||
|
@ -952,7 +955,7 @@ static void test_cancel_request_waits(void)
|
|||
notify(&start_state);
|
||||
zassert_equal(cli_result(&spinwait_cli), start_state.retval,
|
||||
"last request");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
|
||||
|
@ -976,7 +979,7 @@ static void test_cancel_request_waits(void)
|
|||
"restart cancel");
|
||||
zassert_equal(cli_result(&spinwait_cli), -ECANCELED,
|
||||
"restart cancel");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
zassert_equal(cli_result(&cli), -EAGAIN,
|
||||
|
@ -985,26 +988,26 @@ static void test_cancel_request_waits(void)
|
|||
notify(&stop_state);
|
||||
zassert_equal(cli_result(&cli), stop_state.retval,
|
||||
"released");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
}
|
||||
|
||||
static void test_cancel_request_ok(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
struct onoff_manager srv;
|
||||
struct k_poll_signal sig;
|
||||
struct onoff_client cli;
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_SERVICE_START_SLEEPS);
|
||||
const struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_START_SLEEPS);
|
||||
|
||||
clear_transit();
|
||||
start_state.async = true;
|
||||
start_state.retval = 14;
|
||||
stop_state.retval = 31;
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
|
@ -1025,11 +1028,11 @@ static void test_cancel_request_ok(void)
|
|||
notify(&start_state);
|
||||
zassert_equal(srv.refs, 1,
|
||||
"refs");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
zassert_equal(cli_result(&cli), start_state.retval,
|
||||
"cancel notified");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
/* You can "cancel" an request that isn't active */
|
||||
|
@ -1047,14 +1050,15 @@ static void test_cancel_request_ok(void)
|
|||
static void test_blocked_restart(void)
|
||||
{
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
struct onoff_manager srv;
|
||||
unsigned int signalled = 0;
|
||||
int result;
|
||||
struct k_poll_signal sig[2];
|
||||
struct onoff_client cli[2];
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_SERVICE_START_SLEEPS | ONOFF_SERVICE_STOP_SLEEPS);
|
||||
const struct onoff_transitions transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_START_SLEEPS
|
||||
| ONOFF_STOP_SLEEPS);
|
||||
|
||||
clear_transit();
|
||||
start_state.async = true;
|
||||
|
@ -1062,7 +1066,7 @@ static void test_blocked_restart(void)
|
|||
stop_state.async = true;
|
||||
stop_state.retval = 31;
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
rc = onoff_manager_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
|
@ -1109,7 +1113,7 @@ static void test_blocked_restart(void)
|
|||
"isr sync");
|
||||
|
||||
/* Fail-to-restart is not an error */
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
k_poll_signal_check(&sig[0], &signalled, &result);
|
||||
|
@ -1127,21 +1131,17 @@ static void test_blocked_restart(void)
|
|||
|
||||
static void test_cancel_release(void)
|
||||
{
|
||||
static const struct onoff_transitions srv_transitions =
|
||||
ONOFF_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_STOP_SLEEPS);
|
||||
struct onoff_manager srv = ONOFF_MANAGER_INITIALIZER(&srv_transitions);
|
||||
int rc;
|
||||
struct onoff_service srv;
|
||||
const struct onoff_service_transitions transitions =
|
||||
ONOFF_SERVICE_TRANSITIONS_INITIALIZER(start, stop, NULL,
|
||||
ONOFF_SERVICE_STOP_SLEEPS);
|
||||
|
||||
clear_transit();
|
||||
start_state.retval = 16;
|
||||
stop_state.async = true;
|
||||
stop_state.retval = 94;
|
||||
|
||||
rc = onoff_service_init(&srv, &transitions);
|
||||
zassert_equal(rc, 0,
|
||||
"service init");
|
||||
|
||||
init_spinwait(&spinwait_cli);
|
||||
rc = onoff_request(&srv, &spinwait_cli);
|
||||
zassert_true(rc > 0,
|
||||
|
@ -1162,13 +1162,13 @@ static void test_cancel_release(void)
|
|||
rc = onoff_cancel(&srv, &spinwait_cli);
|
||||
zassert_equal(rc, -EWOULDBLOCK,
|
||||
"cancel succeeded");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
|
||||
notify(&stop_state);
|
||||
zassert_equal(cli_result(&spinwait_cli), stop_state.retval,
|
||||
"release pending");
|
||||
zassert_false(onoff_service_has_error(&srv),
|
||||
zassert_false(onoff_has_error(&srv),
|
||||
"has error");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue