diff options
author | Jett Rink <jettrink@chromium.org> | 2019-08-02 16:20:50 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-08-20 15:53:16 +0000 |
commit | 2a7996a3caf25d358164a48e80723758e8be1fd1 (patch) | |
tree | a6dd0682b7ab1c3cc408450137e5f10988cf9da7 /include/usb_sm.h | |
parent | a1aea89ae15c85d56f52976289a329e7c58bc8f6 (diff) | |
download | chrome-ec-2a7996a3caf25d358164a48e80723758e8be1fd1.tar.gz |
usb: update state machine framework
- OBJ is renamed to context (CTX) for current and last state
- State definition now includes its parent (no need for the boiler
plate function that takes in a signal)
- The init_state, set_state, and exe_state have been re-written to take
advantages of new state machine definition. I had to add more logic to
handle hierarchical states fully.
- Explicitly create the USB states at the bottom of the file with all
of the statics. Don't need to use macros (even though I did suggest them)
- Use NULL when we do_nothing instead of calling into a function
- Created a "private" enum in the C file that lists all of the states
in the file, that we can use to refer to a state (it is also the
index into the states array for that state).
- Changed prototype of state function to return void, since we aren't
really using the return value and it cleans up a lot of return 0 that
aren't needed.
- Add const to int port since we can and should
- Moves struct definition to implementation file only to keep
implementation details private. We can access data through accessor if
needed.
BRANCH=none
BUG=none
TEST=all unit tests passes
Change-Id: I482a63e08f7d63022d5102b891a2fac0b0faa46f
Signed-off-by: Jett Rink <jettrink@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1733744
Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'include/usb_sm.h')
-rw-r--r-- | include/usb_sm.h | 155 |
1 files changed, 37 insertions, 118 deletions
diff --git a/include/usb_sm.h b/include/usb_sm.h index e57cd0b873..f9f10b439f 100644 --- a/include/usb_sm.h +++ b/include/usb_sm.h @@ -8,142 +8,61 @@ #ifndef __CROS_EC_USB_SM_H #define __CROS_EC_USB_SM_H -#define DECLARE_SM_FUNC_(prefix, name, run, exit) \ - DECLARE_SM_FUNC_##run(prefix, name); \ - DECLARE_SM_FUNC_##exit(prefix, name) - -#define DECLARE_SM_FUNC_WITH_RUN(prefix, name) static int \ - prefix##_##name##_run(int port) - -#define DECLARE_SM_FUNC_WITH_EXIT(prefix, name) static int \ - prefix##_##name##_exit(int port) - -#define DECLARE_SM_FUNC_NOOP(prefix, name) - -#define DECLARE_SM_SIG_RUN(prefix, name, run) DECLARE_SM_##run(prefix, name) -#define DECLARE_SM_WITH_RUN(prefix, name) prefix##_##name##_run - -#define DECLARE_SM_SIG_EXIT(prefix, name, exit) DECLARE_SM_##exit(prefix, name) -#define DECLARE_SM_WITH_EXIT(prefix, name) prefix##_##name##_exit - -#define DECLARE_SM_NOOP(prefix, name) sm_do_nothing +/* Function pointer that implements a portion of a usb state */ +typedef void (*state_execution)(const int port); /* - * Helper macro for the declaration of states. - * - * @param prefix - prefix of state function name - * @param name - name of state - * @param run - if WITH_RUN, generates a run state function name - * if NOOP, generates a do nothing function name - * @param exit - if WITH_EXIT, generates an exit state function name - * if NOOP, generates a do nothing function name - * - * EXAMPLE: - * - * DECLARE_STATE(tc, test, WITH_RUN, WITH_EXIT); generates the following: + * General usb state that can be used in multiple state machines. * - * static unsigned int tc_test(int port, enum sm_signal sig); - * static unsigned int tc_test_entry(int port); - * static unsigned int tc_test_run(int port); - * static unsigned int tc_test_exit(int port); - * static const state_sig tc_test_sig[] = { - * tc_test_entry, - * tc_test_run, - * tc_test_exit, - * sm_get_super_state }; - * - * DECLARE_STATE(tc, test, NOOP, NOOP); generates the following: - * - * static unsigned int tc_test(int port, enum sm_signal sig); - * static unsigned int tc_test_entry(int port); - * static const state_sig tc_test_sig[] = { - * tc_test_entry, - * sm_do_nothing, - * sm_do_nothing, - * sm_get_super_state }; + * entry - Optional method that will be run when this state is entered + * run - Optional method that will be run repeatedly during state machine loop + * exit - Optional method that will be run when this state exists + * parent- Optional parent usb_state that contains common entry/run/exit + * implementation between various usb state. All parent entry/run + * functions will before any child entry/run functions. All parent exit + * functions will run after any child exit functions. */ -#define DECLARE_STATE(prefix, name, run, exit) \ -static int prefix##_##name(int port, enum sm_signal sig); \ -static int prefix##_##name##_entry(int port); \ -DECLARE_SM_FUNC_(prefix, name, run, exit); \ -static const state_sig prefix##_##name##_sig[] = { \ -prefix##_##name##_entry, \ -DECLARE_SM_SIG_RUN(prefix, name, run), \ -DECLARE_SM_SIG_EXIT(prefix, name, exit), \ -sm_get_super_state \ -} +struct usb_state { + const state_execution entry; + const state_execution run; + const state_execution exit; + const struct usb_state *parent; +}; + +typedef const struct usb_state *usb_state_ptr; -#define SM_OBJ(smo) ((struct sm_obj *)&smo) -#define SM_SUPER(r, sig, s) ((((r) == 0) || ((sig) == SM_ENTRY_SIG) || \ - ((sig) == SM_EXIT_SIG)) ? 0 : ((uintptr_t)(s))) -#define SM_RUN_SUPER 1 +/* Defines the current context of the usb statemachine. */ +struct sm_ctx { + usb_state_ptr current; + usb_state_ptr previous; + /* We use intptr_t type to accommodate host tests ptr size variance */ + intptr_t internal[2]; +}; /* Local state machine states */ enum sm_local_state { - SM_INIT, + SM_INIT = 0, /* Ensure static variables initialize to SM_INIT */ SM_RUN, - SM_PAUSED -}; - -/* State Machine signals */ -enum sm_signal { - SM_ENTRY_SIG = 0, - SM_RUN_SIG, - SM_EXIT_SIG, - SM_SUPER_SIG, + SM_PAUSED, }; -typedef int (*state_sig)(int port); -typedef int (*sm_state)(int port, enum sm_signal sig); - -struct sm_obj { - sm_state task_state; - sm_state last_state; -}; - -/** - * Initialize a State Machine - * - * @param port USB-C port number - * @param obj State machine object - * @param target Initial state of state machine - */ -void sm_init_state(int port, struct sm_obj *obj, sm_state target); - -/** - * Changes a state machines state - * - * @param port USB-C port number - * @param obj State machine object - * @param target State to transition to - * @return 0 - */ -int sm_set_state(int port, struct sm_obj *obj, sm_state target); - -/** - * Runs a state machine - * - * @param port USB-C port number - * @param obj State machine object - * @param sig State machine signal - */ -void sm_run_state_machine(int port, struct sm_obj *obj, enum sm_signal sig); - /** - * Substitute this function for states that do not implement a - * run or exit state. + * Changes a state machines state. This handles exiting the previous state and + * entering the target state. A common parent state will not exited nor be + * re-entered. * - * @param port USB-C port number - * @return 0 + * @param port USB-C port number + * @param ctx State machine context + * @param new_state State to transition to (NULL is valid and exits all states) */ -int sm_do_nothing(int port); +void set_state(int port, struct sm_ctx *ctx, usb_state_ptr new_state); /** - * Called by the state machine framework to execute a states super state. + * Runs one iteration of a state machine (including any parent states) * * @param port USB-C port number - * @return RUN_SUPER + * @param ctx State machine context */ -int sm_get_super_state(int port); +void exe_state(int port, struct sm_ctx *ctx); #endif /* __CROS_EC_USB_SM_H */ |