/***************************************************************************** * Active Object pattern implementation based on uC/OS-II (uC/AO) * * Q u a n t u m L e a P s * ------------------------ * Modern Embedded Software * * Copyright (C) 2020 Quantum Leaps, LLC. All rights reserved. * * SPDX-License-Identifier: APACHE-2.0 * * This software is distributed by Quantum Leaps, LLC under the terms of * Apache License Version 2.0, which is the same license used for uC/OS-II RTOS. * The text of the license is available at: www.apache.org/licenses/LICENSE-2.0. * * Contact information: * * *****************************************************************************/ #ifndef UC_AO_H #define UC_AO_H #include "ucos_ii.h" /* uC/OS-II API, port and compile-time configuration */ #include "qassert.h" /* embedded-systems-friendly assertions (DbC) */ /*---------------------------------------------------------------------------*/ /* Event facilities... */ typedef uint16_t Signal; /* event signal */ enum ReservedSignals { INIT_SIG, /* dispatched to AO before entering event-loop */ ENTRY_SIG, /* for triggering the entry action in a state */ EXIT_SIG, /* for triggering the exit action from a state */ USER_SIG /* first signal available to the users */ }; /* Event base class */ typedef struct { Signal sig; /* event signal */ /* event parameters added in subclasses of Event */ } Event; /*---------------------------------------------------------------------------*/ /* Hierarchical State Machine facilities... */ typedef struct Hsm Hsm; /* forward declaration */ typedef enum { TRAN_STATUS, HANDLED_STATUS, IGNORED_STATUS, INIT_STATUS, SUPER_STATUS } State; typedef State (*StateHandler)(Hsm * const me, Event const * const e); #define TRAN(target_) (((Hsm *)me)->state = (StateHandler)(target_), TRAN_STATUS) #define SUPER(super_) (((Hsm *)me)->temp = (StateHandler)(super_), SUPER_STATUS) struct Hsm { StateHandler state; /* the "state variable" */ StateHandler temp; /* temporary state to traverse state hierarchy */ }; void Hsm_ctor(Hsm * const me, StateHandler initial); void Hsm_init(Hsm * const me, Event const * const e); void Hsm_dispatch(Hsm * const me, Event const * const e); State Hsm_top(Hsm * const me, Event const * const e); /*---------------------------------------------------------------------------*/ /* Actvie Object facilities... */ typedef struct Active Active; /* forward declaration */ /* Active Object base class */ struct Active { Hsm super; /* inherit Hsm */ INT8U thread; /* private thread (the unique uC/OS-II task priority) */ OS_EVENT *queue; /* private message queue */ /* active object data added in subclasses of Active */ }; void Active_ctor(Active * const me, StateHandler initial); void Active_start(Active * const me, uint8_t prio, /* priority (1-based) */ Event **queueSto, uint32_t queueLen, void *stackSto, uint32_t stackSize, uint16_t opt); void Active_post(Active * const me, Event const * const e); /*---------------------------------------------------------------------------*/ /* Time Event facilities... */ /* Time Event class */ typedef struct { Event super; /* inherit Event */ Active *act; /* the AO that requested this TimeEvent */ uint32_t timeout; /* timeout counter; 0 means not armed */ uint32_t interval; /* interval for periodic TimeEvent, 0 means one-shot */ } TimeEvent; void TimeEvent_ctor(TimeEvent * const me, Signal sig, Active *act); void TimeEvent_arm(TimeEvent * const me, uint32_t timeout, uint32_t interval); void TimeEvent_disarm(TimeEvent * const me); /* static (i.e., class-wide) operation */ void TimeEvent_tick(void); #endif /* UC_AO_H */