NOTE:
For improved readability, the 'oosmos_' prefix has been suppressed from
the table of contents and from each See Also list.
Important: All of these APIs are available to you to code
by hand, however many of them are generated by the OOSMOS code generator
while parsing your UMLet state chart. We urge you to draw state
charts and generate your code using the OOSMOS code generator.
oosmos_ActiveObjectInit
An active
OOSMOS object is an object that has
reactive behavior but does not have the complexity to warrant
using a full
OOSMOS state machine object.
To establish your object as an active object, you must register it with
OOSMOS like this: create a subroutine for
OOSMOS to call
(line 103), then create an
oosmos_sActiveObject member in your object
(line 39) and then
finally call
oosmos_ActiveObjectInit
(line 61).
pObject |
Pointer to your active object.
|
pActiveObject |
Pointer to the oosmos_sActiveObject object member.
|
pFunc |
Address of the function to call each time through
the OOSMOS main loop.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| //
|
[MIT] |
|
| // OOSMOS sw Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef swMaxSwitches
|
[...] |
|
| #define swMaxSwitches 20
|
|
| #endif
|
|
| |
|
| #ifndef swMaxCloseSubscribers
|
|
| #define swMaxCloseSubscribers 1
|
|
| #endif
|
|
| |
|
| #ifndef swMaxOpenSubscribers
|
|
| #define swMaxOpenSubscribers 1
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "sw.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| |
|
| typedef enum {
|
|
| Unknown_State = 1,
|
|
| Open_State,
|
|
| Closed_State
|
|
| } eStates;
|
|
| |
|
| struct swTag
|
|
| {
|
|
| pin * m_pPin;
|
|
| eStates m_State;
|
|
| |
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| oosmos_sSubscriberList m_CloseEvent[swMaxCloseSubscribers];
|
|
| oosmos_sSubscriberList m_OpenEvent[swMaxOpenSubscribers];
|
|
| };
|
|
| |
|
| extern sw * swNewDetached(pin * pPin)
|
|
| {
|
|
| oosmos_Allocate(pSwitch, sw, swMaxSwitches, NULL);
|
|
| |
|
| pSwitch->m_pPin = pPin;
|
|
| pSwitch->m_State = Unknown_State;
|
|
| |
|
| oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
| oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern sw * swNew(pin * pPin)
|
|
| {
|
|
| sw * pSwitch = swNewDetached(pPin);
|
|
| |
|
| oosmos_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern void swSubscribeCloseEvent(sw * pSwitch, oosmos_sQueue * pQueue, int CloseEventCode, void * pContext)
|
[...] |
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_CloseEvent, pQueue, CloseEventCode, pContext);
|
|
| }
|
|
| |
|
| extern void swSubscribeOpenEvent(sw * pSwitch, oosmos_sQueue * pQueue, int OpenEventCode, void * pContext)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_OpenEvent, pQueue, OpenEventCode, pContext);
|
|
| }
|
|
| |
|
| static eStates PhysicalSwitchState(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| return pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| }
|
|
| |
|
| extern bool swIsOpen(const sw * pSwitch)
|
|
| {
|
|
| return !swIsClosed(pSwitch);
|
|
| }
|
|
| |
|
| extern bool swIsClosed(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| if (pSwitch->m_State == Unknown_State) {
|
|
| return PhysicalSwitchState(pSwitch) == Closed_State;
|
|
| }
|
|
| |
|
| return pSwitch->m_State == Closed_State;
|
|
| }
|
|
| |
|
| extern void swRunStateMachine(sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| switch (pSwitch->m_State) {
|
|
| case Open_State: {
|
|
| if (pinIsOn(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Closed_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_CloseEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Closed_State: {
|
|
| if (pinIsOff(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Open_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_OpenEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Unknown_State: {
|
|
| pSwitch->m_State = pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
oosmos_Allocate
oosmos_Allocate is a macro that returns a pointer to an
unused object from a fixed number of statically preallocated
objects. The static preallocation is done automatically within the
macro.
Once allocated, objects cannot be returned to the pool.
See the example on
line 48.
If you need
dynamic memory, use
malloc in place of this function and then
create a complementary
toggleDelete function and then do a
free to release it.
Pointer |
The name of the variable that will hold the pointer to the
allocated object. You'll use this to initialize your object's members,
including the state machine (if the object has one). You must
return this pointer to the caller. (See toggle.c line 56 below.)
|
Type |
The data type of the object. (See line 14 of toggle.h below.)
|
Elements |
The number of objects to pre-allocate. You can specify a number
here, but it would be better to use the macro technique used in
lines 8-10 of the toggle.c
where you specify a default amount
that can be overridden on the compilation command line.
This is commonly done with most compilers like this:
-D toggleMax=10.
|
pOutOfMemory |
The address of a subroutine to call if all preallocated objects have been
exhausted. See type oosmos_tOutOfMemory for information about
how to implement the called routine.
If NULL, oosmos_Allocate will loop
forever when all objects of this type are exhausted.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef toggle_h
|
[...] |
|
| #define toggle_h
|
|
| |
|
| #include "pin.h"
|
|
| #include <stdint.h>
|
|
| |
|
| typedef struct toggleTag toggle;
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS);
|
|
| |
|
| #endif
|
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 5
|
|
| #endif
|
|
| |
|
| //===================================
|
[...] |
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "toggle.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| oosmos_sObjectThread m_ObjectThread;
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| static void ToggleThread(const toggle * pToggle, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pToggle);
|
|
| oosmos_POINTER_GUARD(pState);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| pinOn(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOnMS);
|
|
| |
|
| pinOff(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOffMS);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| oosmos_ObjectThreadInit(pToggle, m_ObjectThread, ToggleThread, true);
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos_AllocateVisible
oosmos_AllocateVisible is functionally the same
as
oosmos_Allocate but allows the user to allocate
the array of objects
in an outer scope thereby allowing access to that array
by other parts of the implementation of the object.
(See line 66 of the example below.)
Pointer |
The name of the variable that will hold the pointer to the
allocated object. You'll use this to initialize your object's members,
including the state machine (if the object has one). You must
return this pointer to the caller (see line 73).
|
Type |
The data type of the object. (See line 17 of Interrupt.c.)
|
List |
The address of the array of objects you pre-allocated.
(See line 29.)
|
Count |
The number of objects that have been returned from
oosmos_AllocateVisible.
(See line 30.)
|
Elements |
The number of objects to pre-allocate.
|
pOutOfMemory |
The address of a subroutine to call if all preallocated objects have been
exhausted. See type oosmos_tOutOfMemory for information about
how to implement the called routine.
If NULL is specified, oosmos_AllocateVisible will loop
forever when all objects of this type are exhausted.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| //
|
[MIT] |
|
| // OOSMOS - Interrupt structure example on Windows
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //
|
|
| // Demonstrates structure of how to react to interrupts using OOSMOS.
|
|
| //
|
|
| |
|
| typedef struct uartTag uart;
|
|
| |
|
| struct uartTag
|
struct uartTag {...} |
|
| {
|
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| oosmos_sQueue m_ReceiveDataQueue;
|
|
| uint8_t m_UartId;
|
|
| uint8_t m_ReceiveDataQueueData[10];
|
|
| };
|
|
| |
|
| #define MAX_UARTS 5
|
|
| |
|
| static uart UartList[MAX_UARTS];
|
|
| static unsigned UartCount = 0;
|
|
| |
|
| static void ReceiverStateMachine(void * pObject)
|
static void ReceiverStateMachine(...) {...} |
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| uint8_t Byte = 0;
|
|
| |
|
| //DisableInterrupt(pUART);
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| //EnableInterrupt(pUART);
|
|
| |
|
| if (!PopSuccess) {
|
|
| return;
|
|
| }
|
|
| |
|
| printf("Received %d\n", Byte);
|
|
| }
|
|
| |
static void ISR(...) {...} |
|
| static void ISR(const int UartId)
|
|
| {
|
|
| uart * pUART = UartList;
|
|
| |
|
| for (unsigned Count = 0; Count < UartCount; pUART++, Count++) {
|
|
| if (UartId != pUART->m_UartId) {
|
|
| continue;
|
|
| }
|
|
| |
|
| const uint8_t Byte = (uint8_t) UartId;
|
|
| oosmos_QueuePush(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| |
|
| return;
|
|
| }
|
|
| }
|
|
| |
|
| extern uart * uartNew(unsigned UartId)
|
|
| {
|
|
| oosmos_AllocateVisible(pUART, uart, UartList, UartCount, MAX_UARTS, NULL);
|
|
| |
|
| pUART->m_UartId = (uint8_t) UartId;
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData, sizeof(pUART->m_ReceiveDataQueueData), sizeof(uint8_t));
|
|
| oosmos_ActiveObjectInit(pUART, m_ActiveObject, ReceiverStateMachine);
|
|
| |
|
| return pUART;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
extern int main(void) {...} |
|
| (void) uartNew(1);
|
|
| (void) uartNew(3);
|
|
| (void) uartNew(7);
|
|
| |
|
| // Simulate random interrupts...
|
|
| |
|
| ISR(3);
|
|
| oosmos_RunStateMachines();
|
|
| ISR(7);
|
|
| oosmos_RunStateMachines();
|
|
| ISR(1);
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| return 0;
|
|
| }
|
|
| |
|
oosmos/Examples/Interrupt/Windows/Interrupt.c
oosmos_AnalogMapAccurate
Scales a value from a point within one range to the proportionate point in a
different range. This function uses a floating point type to guarantee the
most accurate result. If speed is more important than accuracy, use
oosmos_AnalogMapFast.
See example on
line 21, below.
Value |
The value to be scaled.
|
InMin |
The low end of the source range.
|
InMax |
The high end of the source range.
|
OutMin |
The low end of the target range.
|
OutMax |
The high end of the target range.
|
RETURN |
Returns the scaled number as a floating point value.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| //
|
[MIT] |
|
| // OOSMOS AnalogMap Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| #define ITERATIONS 25
|
|
| |
|
| /*lint -e728 Suppress "Not explicitly initialized" */
|
|
| static int FastDistribution[ITERATIONS+1];
|
|
| /*lint -e728 Suppress "Not explicitly initialized" */
|
|
| static int AccurateDistribution[ITERATIONS+1];
|
|
| |
|
| static void TestAccurate(double Value, double InMin, double InMax, double OutMin, double OutMax)
|
|
| {
|
|
| const double Result = oosmos_AnalogMapAccurate(Value, InMin, InMax, OutMin, OutMax);
|
|
| |
|
| printf("Value:%f, InMin:%f, InMax:%f, OutMin:%f, OutMax:%f, Result:%f\n", Value, InMin, InMax, OutMin, OutMax, Result);
|
|
| |
|
| const long IntResult = (long) (Result + 0.5F);
|
|
| AccurateDistribution[IntResult]++;
|
|
| }
|
|
| |
|
| static void TestFast(int32_t Value, int32_t InMin, int32_t InMax, int32_t OutMin, int32_t OutMax)
|
[...] |
|
| {
|
|
| const int32_t Result = oosmos_AnalogMapFast(Value, InMin, InMax, OutMin, OutMax);
|
|
| printf("Value:%ld, InMin:%ld, InMax:%ld, OutMin:%ld, OutMax:%ld, Result:%ld\n",
|
|
| (long) Value, (long) InMin, (long) InMax, (long) OutMin, (long) OutMax, (long) Result);
|
|
| |
|
| FastDistribution[Result]++;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| const uint32_t Min = 1;
|
|
| const uint32_t Max = 1000;
|
|
| |
|
| //
|
|
| // Test accurate implementation...
|
|
| //
|
|
| for (uint32_t I = Min; I <= Max; I++) {
|
|
| TestAccurate((double) I, (double) Min, (double) Max, 1.0, 25.0);
|
|
| }
|
|
| |
|
| for (uint32_t I = 1; I <= ITERATIONS; I++) {
|
|
| printf("%d\n", AccurateDistribution[I]);
|
|
| }
|
|
| |
|
| //
|
|
| // Test fast implementation...
|
|
| //
|
|
| for (uint32_t I = Min; I <= Max; I++) {
|
|
| TestFast(I, Min, Max, 1, 25);
|
|
| }
|
|
| |
|
| for (uint32_t I = 1; I <= ITERATIONS; I++) {
|
|
| printf("%d\n", FastDistribution[I]);
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/AnalogMap/Windows/AnalogMap.c
oosmos_AnalogMapFast
Scales a value from a point within one range to the proportionate point in a
different range. This function uses a long integral data type
in order to calculate the result quickly. If accuracy is more important than speed, use
oosmos_AnalogMapAccurate.
See example on
line 31, below.
| 1 |
| 2 |
| 3 |
| |
|
| int32_t oosmos_AnalogMapFast(int32_t Value, int32_t InMin, int32_t InMax, int32_t OutMin, int32_t OutMax); |
|
| |
|
Prototype
Value |
The value to be scaled.
|
InMin |
The low end of the source range.
|
InMax |
The high end of the source range.
|
OutMin |
The low end of the target range.
|
OutMax |
The high end of the target range.
|
RETURN |
Returns the scaled number as a long integral value.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| //
|
[MIT] |
|
| // OOSMOS AnalogMap Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| #define ITERATIONS 25
|
|
| |
|
| /*lint -e728 Suppress "Not explicitly initialized" */
|
|
| static int FastDistribution[ITERATIONS+1];
|
|
| /*lint -e728 Suppress "Not explicitly initialized" */
|
|
| static int AccurateDistribution[ITERATIONS+1];
|
|
| |
|
| static void TestAccurate(double Value, double InMin, double InMax, double OutMin, double OutMax)
|
|
| {
|
|
| const double Result = oosmos_AnalogMapAccurate(Value, InMin, InMax, OutMin, OutMax);
|
|
| |
|
| printf("Value:%f, InMin:%f, InMax:%f, OutMin:%f, OutMax:%f, Result:%f\n", Value, InMin, InMax, OutMin, OutMax, Result);
|
|
| |
|
| const long IntResult = (long) (Result + 0.5F);
|
|
| AccurateDistribution[IntResult]++;
|
|
| }
|
|
| |
|
| static void TestFast(int32_t Value, int32_t InMin, int32_t InMax, int32_t OutMin, int32_t OutMax)
|
|
| {
|
|
| const int32_t Result = oosmos_AnalogMapFast(Value, InMin, InMax, OutMin, OutMax);
|
|
| printf("Value:%ld, InMin:%ld, InMax:%ld, OutMin:%ld, OutMax:%ld, Result:%ld\n",
|
|
| (long) Value, (long) InMin, (long) InMax, (long) OutMin, (long) OutMax, (long) Result);
|
|
| |
|
| FastDistribution[Result]++;
|
|
| }
|
|
| |
|
| extern int main(void)
|
[...] |
|
| {
|
|
| const uint32_t Min = 1;
|
|
| const uint32_t Max = 1000;
|
|
| |
|
| //
|
|
| // Test accurate implementation...
|
|
| //
|
|
| for (uint32_t I = Min; I <= Max; I++) {
|
|
| TestAccurate((double) I, (double) Min, (double) Max, 1.0, 25.0);
|
|
| }
|
|
| |
|
| for (uint32_t I = 1; I <= ITERATIONS; I++) {
|
|
| printf("%d\n", AccurateDistribution[I]);
|
|
| }
|
|
| |
|
| //
|
|
| // Test fast implementation...
|
|
| //
|
|
| for (uint32_t I = Min; I <= Max; I++) {
|
|
| TestFast(I, Min, Max, 1, 25);
|
|
| }
|
|
| |
|
| for (uint32_t I = 1; I <= ITERATIONS; I++) {
|
|
| printf("%d\n", FastDistribution[I]);
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/AnalogMap/Windows/AnalogMap.c
oosmos_ASSERT
oosmos_ASSERT works just like the standard C assert,
but instead of aborting the program (which doesn't mean
much on an embedded system), it will loop endlessly.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| //
|
[MIT] |
|
| // OOSMOS reg Class - Linear regression
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "reg.h"
|
[...] |
|
| #include "oosmos.h"
|
|
| #include <stdint.h>
|
|
| #include <string.h>
|
|
| |
|
| #ifndef regMax
|
|
| #define regMax 1
|
|
| #endif
|
|
| |
|
| struct regTag
|
|
| {
|
|
| float m_Intercept;
|
|
| float m_Slope;
|
|
| |
|
| regSample* m_SampleFIFO;
|
|
| size_t m_SampleCount;
|
|
| size_t m_MaxSamples;
|
|
| size_t m_StartIndex;
|
|
| };
|
|
| |
|
| extern reg* regNew(regSample* sampleBuffer, size_t MaxSamples)
|
|
| {
|
|
| oosmos_Allocate(pReg, reg, regMax, NULL);
|
|
| |
|
| pReg->m_SampleFIFO = sampleBuffer;
|
|
| pReg->m_MaxSamples = MaxSamples;
|
|
| pReg->m_SampleCount = 0;
|
|
| pReg->m_StartIndex = 0;
|
|
| return pReg;
|
|
| }
|
|
| |
|
| extern void regPushSample(reg* pReg, const float X, const float Y)
|
|
| {
|
|
| const size_t InsertIndex = (pReg->m_StartIndex + pReg->m_SampleCount) % pReg->m_MaxSamples;
|
|
| |
|
| pReg->m_SampleFIFO[InsertIndex].X = X;
|
|
| pReg->m_SampleFIFO[InsertIndex].Y = Y;
|
|
| |
|
| if (pReg->m_SampleCount < pReg->m_MaxSamples) {
|
|
| pReg->m_SampleCount++;
|
|
| }
|
|
| else {
|
|
| pReg->m_StartIndex = (pReg->m_StartIndex + 1) % pReg->m_MaxSamples;
|
|
| }
|
|
| }
|
|
| |
|
| static float MeanOfX(const reg* pReg)
|
|
| {
|
|
| float sum = 0.0f;
|
|
| |
|
| for (size_t i = 0; i < pReg->m_SampleCount; i++) {
|
|
| size_t index = (pReg->m_StartIndex + i) % pReg->m_MaxSamples;
|
|
| sum += pReg->m_SampleFIFO[index].X;
|
|
| }
|
|
| |
|
| return sum / pReg->m_SampleCount;
|
|
| }
|
|
| |
|
| static float MeanOfY(const reg* pReg)
|
|
| {
|
|
| float sum = 0.0f;
|
|
| |
|
| for (size_t i = 0; i < pReg->m_SampleCount; i++) {
|
|
| size_t index = (pReg->m_StartIndex + i) % pReg->m_MaxSamples;
|
|
| sum += pReg->m_SampleFIFO[index].Y;
|
|
| }
|
|
| |
|
| return sum / pReg->m_SampleCount;
|
|
| }
|
|
| |
|
| extern void regCalculateRegression(reg* pReg)
|
|
| {
|
|
| const float meanX = MeanOfX(pReg);
|
|
| const float meanY = MeanOfY(pReg);
|
|
| |
|
| float sumXY = 0.0f;
|
|
| float sumXX = 0.0f;
|
|
| |
|
| for (size_t i = 0; i < pReg->m_SampleCount; i++) {
|
|
| size_t index = (pReg->m_StartIndex + i) % pReg->m_MaxSamples;
|
|
| const regSample* pSample = &pReg->m_SampleFIFO[index];
|
|
| |
|
| const float xiMinusMeanX = pSample->X - meanX;
|
|
| const float yiMinusMeanY = pSample->Y - meanY;
|
|
| |
|
| sumXY += xiMinusMeanX * yiMinusMeanY;
|
|
| sumXX += xiMinusMeanX * xiMinusMeanX;
|
|
| }
|
|
| |
|
| oosmos_ASSERT(sumXX > 0.0f);
|
|
| |
|
| pReg->m_Slope = sumXY / sumXX;
|
|
| pReg->m_Intercept = meanY - pReg->m_Slope * meanX;
|
|
| }
|
|
| |
[...] |
|
| extern float regPredictY(const reg* pReg, float X)
|
|
| {
|
|
| return pReg->m_Slope * X + pReg->m_Intercept;
|
|
| }
|
|
| |
|
| extern float regSlope(const reg* pReg)
|
|
| {
|
|
| return pReg->m_Slope;
|
|
| }
|
|
| |
|
| extern size_t regGetSampleCount(const reg* pReg)
|
|
| {
|
|
| return pReg->m_SampleCount;
|
|
| }
|
|
| |
|
| extern void regClearSamples(reg* pReg)
|
|
| {
|
|
| pReg->m_SampleCount = 0;
|
|
| }
|
|
| |
|
| extern void regIterateSamples(const reg* pReg, void (*pCallback)(const size_t SampleNumber, const regSample* pSample))
|
|
| {
|
|
| for (size_t i = 0; i < pReg->m_SampleCount; i++) {
|
|
| const size_t index = (pReg->m_StartIndex + i) % pReg->m_MaxSamples;
|
|
| pCallback(i +1 , &pReg->m_SampleFIFO[index]);
|
|
| }
|
|
| }
|
|
| |
|
oosmos_ChoiceInit
oosmos_ChoiceInit initializes an
oosmos_sChoice state. A choice pseudostate
branches to one of several target states based on guard
conditions that are evaluated when the choice state is entered.
| 1 |
| 2 |
| 3 |
| |
|
| void oosmos_ChoiceInit(pObject, ChoiceState, ParentState, pCode); |
|
| |
|
Prototype
pObject |
The address of the object that contains the state machine.
|
ChoiceState |
The name of the choice state.
|
ParentState |
The name of the parent state.
|
pCode |
The address of the event code function.
|
See Also |
|
oosmos_ClockSpeedInMHz
oosmos_ClockSpeedInMHz tells
OOSMOS
the speed of the processor as configured externally. This call
only applies to the
PIC32 architecture.
oosmos_COMPLETE
oosmos_COMPLETE is one of the six predefined event macros.
This event is generated when
the final states within all orthogonal regions have been entered.
See
The User's Guide for
more information.
oosmos_CompositeInit
oosmos_CompositeInit initializes an
oosmos_sComposite state.
See line 107 of the code snippet
below for an example.
pObject |
The address of the object that contains the state machine.
|
CompositeState |
The name of the composite state.
|
ParentState |
The name of the parent state.
|
DefaultState |
The name of the default state.
|
pCode |
Pointer to event handler function.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| //
|
[MIT] |
|
| // OOSMOS Final Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sComposite A_State;
|
|
| oosmos_sChoice A_Choice1_State;
|
|
| oosmos_sLeaf A_Left_State;
|
|
| oosmos_sLeaf A_Right_State;
|
|
| oosmos_sFinal A_Final1_State;
|
|
| oosmos_sLeaf B_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| static bool IsLeft(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static void Default(void)
|
|
| {
|
|
| printf("In Default\n");
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool A_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_DEFAULT: {
|
|
| Default();
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, B_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Choice1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| if (oosmos_EventCode(pEvent) == oosmos_ENTER) {
|
|
| if (IsLeft()) {
|
|
| return oosmos_Transition(pTest, pState, A_Left_State);
|
|
| }
|
|
| else {
|
|
| return oosmos_Transition(pTest, pState, A_Right_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Left_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Right_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, A_State);
|
|
| oosmos_CompositeInit(pTest, A_State, ROOT, A_Choice1_State, A_State_Code);
|
|
| oosmos_ChoiceInit(pTest, A_Choice1_State, A_State, A_Choice1_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Left_State, A_State, A_Left_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Right_State, A_State, A_Right_State_Code);
|
|
| oosmos_FinalInit(pTest, A_Final1_State, A_State, NULL);
|
|
| oosmos_LeafInit(pTest, B_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
[...] |
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->B_State)) {
|
|
| printf("SUCCESS.\n");
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos/Examples/Basic/Windows/Final.c
oosmos_Days2Hours
oosmos_Days2Hours is a macro that converts days to hours.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Days2Hours(Days) |
|
| |
|
Macro
See Also |
Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Days2Minutes
oosmos_Days2Minutes is a macro that converts days to minutes.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Days2Minutes(Days) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Days2MS
oosmos_Days2MS is a macro that converts days to milliseconds.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Days2MS(Days) |
|
| |
|
Macro
See Also |
Days2Hours, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Days2Seconds
oosmos_Days2Seconds is a macro that converts days to seconds.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Days2Seconds(Days) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Days2US
oosmos_Days2US is a macro that converts days to microseconds.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Days2US(Days) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Debug
A call to
oosmos_Debug is generated by the
OOSMOS code generator when the
debug
option is specified in your
.json generator
configuration file.
oosmos_Debug enables debug
output indicating when transitions are made
into and out of states and when events occur.
See line 153 in the code snippet
below for an example.
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 |
| 16 |
| 17 |
| 18 |
| 19 |
| 20 |
| 21 |
| 22 |
| 23 |
| 24 |
| |
|
| Completion.c: ==> Ortho_State |
|
| Completion.c: ==> Ortho_Region2_Idle_State |
|
| Completion.c: ==> Ortho_Region1_Idle_State |
|
| Completion.c: EVENT: evA (1) |
|
| Completion.c: Ortho_Region1_Idle_State --> |
|
| Completion.c: --> Ortho_Region1_Moving_State |
|
| Completion.c: EVENT: evB (2) |
|
| Completion.c: Ortho_Region2_Idle_State --> |
|
| Completion.c: --> Ortho_Region2_Moving_State |
|
| Completion.c: EVENT: evStop (3) |
|
| Completion.c: Ortho_Region2_Moving_State --> |
|
| Completion.c: --> Ortho_Region2_Final2_State |
|
| Completion.c: Ortho_Region1_Moving_State --> |
|
| Completion.c: --> Ortho_Region1_Final1_State |
|
| Completion.c: ((( Ortho_State Complete ))) |
|
| Completion.c: Ortho_Region2_Final2_State --> |
|
| Completion.c: Ortho_Region1_Final1_State --> |
|
| Completion.c: Ortho_State --> |
|
| Completion.c: --> Complete_State |
|
| |
|
| --Goal State Achieved-- |
|
| SUCCESS |
|
| |
|
Output from running Completion.exe
pObject |
The address of the object that contains the state machine.
|
pEventName |
This argument specifies the address of a function
that returns the string representation of an event code.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| //
|
[MIT] |
|
| // OOSMOS Completion Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evA = 1,
|
|
| evB = 2,
|
|
| evStop = 3
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evA: return "evA";
|
|
| case evB: return "evB";
|
|
| case evStop: return "evStop";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Ortho_State;
|
|
| oosmos_sOrthoRegion Ortho_Region1_State;
|
|
| oosmos_sLeaf Ortho_Region1_Idle_State;
|
|
| oosmos_sLeaf Ortho_Region1_Moving_State;
|
|
| oosmos_sFinal Ortho_Region1_Final1_State;
|
|
| oosmos_sOrthoRegion Ortho_Region2_State;
|
|
| oosmos_sLeaf Ortho_Region2_Idle_State;
|
|
| oosmos_sLeaf Ortho_Region2_Moving_State;
|
|
| oosmos_sFinal Ortho_Region2_Final2_State;
|
|
| oosmos_sLeaf Complete_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Ortho_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Complete_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region1_Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evA: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_Region1_Moving_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region1_Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStop: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_Region1_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region2_Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evB: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_Region2_Moving_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region2_Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStop: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_Region2_Final2_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Complete_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| printf("\n--Goal State Achieved--\n");
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pTest, ROOT, NULL, Ortho_State);
|
|
| oosmos_OrthoInit(pTest, Ortho_State, ROOT, Ortho_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, Ortho_Region1_State, Ortho_State, Ortho_Region1_Idle_State, NULL);
|
|
| oosmos_LeafInit(pTest, Ortho_Region1_Idle_State, Ortho_Region1_State, Ortho_Region1_Idle_State_Code);
|
|
| oosmos_LeafInit(pTest, Ortho_Region1_Moving_State, Ortho_Region1_State, Ortho_Region1_Moving_State_Code);
|
|
| oosmos_FinalInit(pTest, Ortho_Region1_Final1_State, Ortho_Region1_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Ortho_Region2_State, Ortho_State, Ortho_Region2_Idle_State, NULL);
|
|
| oosmos_LeafInit(pTest, Ortho_Region2_Idle_State, Ortho_Region2_State, Ortho_Region2_Idle_State_Code);
|
|
| oosmos_LeafInit(pTest, Ortho_Region2_Moving_State, Ortho_Region2_State, Ortho_Region2_Moving_State_Code);
|
|
| oosmos_FinalInit(pTest, Ortho_Region2_Final2_State, Ortho_Region2_State, NULL);
|
|
| oosmos_LeafInit(pTest, Complete_State, ROOT, Complete_State_Code);
|
|
| |
|
| oosmos_Debug(pTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| static void QueueEvent(const test * pTest, int EventCode)
|
[...] |
|
| {
|
|
| oosmos_PushEventCode(pTest, EventCode);
|
|
| oosmos_RunStateMachines();
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| QueueEvent(pTest, evA);
|
|
| QueueEvent(pTest, evB);
|
|
| QueueEvent(pTest, evStop);
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Complete_State)) {
|
|
| printf("SUCCESS\n");
|
|
| } else {
|
|
| printf("FAILURE\n");
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Ortho/Windows/Completion.c
oosmos_DebugPrint
oosmos_DebugPrint
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| 273 |
|
| 274 |
|
| 275 |
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| //
|
[MIT] |
|
| // OOSMOS EventDemo example, control object
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "control.h"
|
[...] |
|
| |
|
| #include "motor.h"
|
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "pump.h"
|
|
| #include "sw.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| #include <stdlib.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evMovePressed = 1,
|
|
| evOption1Pressed = 2,
|
|
| evOption2Pressed = 3,
|
|
| evPumpPressed = 4,
|
|
| evQuitPressed = 5,
|
|
| evStopPressed = 6,
|
|
| evStopReleased = 7
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evMovePressed: return "evMovePressed";
|
|
| case evOption1Pressed: return "evOption1Pressed";
|
|
| case evOption2Pressed: return "evOption2Pressed";
|
|
| case evPumpPressed: return "evPumpPressed";
|
|
| case evQuitPressed: return "evQuitPressed";
|
|
| case evStopPressed: return "evStopPressed";
|
|
| case evStopReleased: return "evStopReleased";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Event;
|
|
| } uEvents;
|
|
| |
|
| struct controlTag
|
|
| {
|
|
| motor * m_pMotor;
|
|
| pump * m_pPump;
|
|
| bool m_Option1;
|
|
| bool m_Option2;
|
|
| |
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sLeaf StartingUp_State;
|
|
| oosmos_sOrtho Operational_State;
|
|
| oosmos_sOrthoRegion Operational_Region1_State;
|
|
| oosmos_sLeaf Operational_Region1_Moving_State;
|
|
| oosmos_sLeaf Operational_Region1_Idle_State;
|
|
| oosmos_sOrthoRegion Operational_Region2_State;
|
|
| oosmos_sLeaf Operational_Region2_Pumping_State;
|
|
| oosmos_sLeaf Operational_Region2_Idle_State;
|
|
| oosmos_sLeaf StopPressed_State;
|
|
| oosmos_sLeaf Terminated_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| static void ToggleOption1(control * pControl)
|
|
| {
|
|
| pControl->m_Option1 = !(pControl->m_Option1);
|
|
| oosmos_DebugPrint("Option1: %d\n", pControl->m_Option1);
|
|
| }
|
|
| |
|
| static void ToggleOption2(control * pControl)
|
|
| {
|
|
| pControl->m_Option2 = !(pControl->m_Option2);
|
|
| oosmos_DebugPrint("Option2: %d\n", pControl->m_Option1);
|
|
| }
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool StartingUp_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| control * pControl = (control *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutSeconds(pState, (uint32_t) 1);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pControl, pState, Operational_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Operational_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| control * pControl = (control *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStopPressed: {
|
|
| return oosmos_Transition(pControl, pState, StopPressed_State);
|
|
| }
|
|
| case evQuitPressed: {
|
|
| return oosmos_Transition(pControl, pState, Terminated_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool StopPressed_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| control * pControl = (control *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evOption1Pressed: {
|
|
| ToggleOption1(pControl);
|
|
| return true;
|
|
| }
|
|
| case evOption2Pressed: {
|
|
| ToggleOption2(pControl);
|
|
| return true;
|
|
| }
|
|
| case evStopReleased: {
|
|
| return oosmos_Transition(pControl, pState, Operational_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Operational_Region1_Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| control * pControl = (control *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| motorOn(pControl->m_pMotor);
|
|
| return true;
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| motorOff(pControl->m_pMotor);
|
|
| return true;
|
|
| }
|
|
| case evMovePressed: {
|
|
| return oosmos_Transition(pControl, pState, Operational_Region1_Idle_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Operational_Region1_Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| control * pControl = (control *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evMovePressed: {
|
|
| return oosmos_Transition(pControl, pState, Operational_Region1_Moving_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Terminated_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| exit(1);
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static bool Operational_Region2_Pumping_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| control * pControl = (control *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pumpOn(pControl->m_pPump);
|
|
| return true;
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pumpOff(pControl->m_pPump);
|
|
| return true;
|
|
| }
|
|
| case evPumpPressed: {
|
|
| return oosmos_Transition(pControl, pState, Operational_Region2_Idle_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Operational_Region2_Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| control * pControl = (control *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evPumpPressed: {
|
|
| return oosmos_Transition(pControl, pState, Operational_Region2_Pumping_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern control * controlNew(void)
|
|
| {
|
|
| oosmos_Allocate(pControl, control, 1, NULL);
|
|
| |
|
| oosmos_sQueue * const pControlEventQueue = &pControl->m_EventQueue;
|
|
| |
|
| pin * pStopPin = pinNew_Key('s', pinActiveHigh);
|
|
| sw * pStopSwitch = swNew(pStopPin);
|
|
| swSubscribeCloseEvent(pStopSwitch, pControlEventQueue, evStopPressed, NULL);
|
|
| swSubscribeOpenEvent(pStopSwitch, pControlEventQueue, evStopReleased, NULL);
|
|
| |
|
| pin * pMovePin = pinNew_Key('m', pinActiveHigh);
|
|
| sw * pMoveSwitch = swNew(pMovePin);
|
|
| swSubscribeCloseEvent(pMoveSwitch, pControlEventQueue, evMovePressed, NULL);
|
|
| |
|
| pin * pQuitPin = pinNew_Key('q', pinActiveHigh);
|
|
| sw * pQuitSwitch = swNew(pQuitPin);
|
|
| swSubscribeCloseEvent(pQuitSwitch, pControlEventQueue, evQuitPressed, NULL);
|
|
| |
|
| pin * pPumpPin = pinNew_Key('p', pinActiveHigh);
|
|
| sw * pPumpSwitch = swNew(pPumpPin);
|
|
| swSubscribeCloseEvent(pPumpSwitch, pControlEventQueue, evPumpPressed, NULL);
|
|
| |
|
| pin * pOption1Pin = pinNew_Key('1', pinActiveHigh);
|
|
| sw * pOption1Switch = swNew(pOption1Pin);
|
|
| swSubscribeCloseEvent(pOption1Switch, pControlEventQueue, evOption1Pressed, NULL);
|
|
| |
|
| pin * pOption2Pin = pinNew_Key('2', pinActiveHigh);
|
|
| sw * pOption2Switch = swNew(pOption2Pin);
|
|
| swSubscribeCloseEvent(pOption2Switch, pControlEventQueue, evOption2Pressed, NULL);
|
|
| |
|
| pin * pUpPin = pinNew_Key('u', pinActiveHigh);
|
|
| sw * pUpSwitch = swNew(pUpPin);
|
|
| |
|
| pin * pDownPin = pinNew_Key('d', pinActiveHigh);
|
|
| sw * pDownSwitch = swNew(pDownPin);
|
|
| |
|
| pControl->m_pMotor = motorNew();
|
|
| pControl->m_pPump = pumpNew(pUpSwitch, pDownSwitch);
|
|
| pControl->m_Option1 = false;
|
|
| pControl->m_Option2 = false;
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pControl, ROOT, NULL, StartingUp_State);
|
|
| oosmos_LeafInit(pControl, StartingUp_State, ROOT, StartingUp_State_Code);
|
|
| oosmos_OrthoInit(pControl, Operational_State, ROOT, Operational_State_Code);
|
|
| oosmos_OrthoRegionInit(pControl, Operational_Region1_State, Operational_State, Operational_Region1_Idle_State, NULL);
|
|
| oosmos_LeafInit(pControl, Operational_Region1_Moving_State, Operational_Region1_State, Operational_Region1_Moving_State_Code);
|
|
| oosmos_LeafInit(pControl, Operational_Region1_Idle_State, Operational_Region1_State, Operational_Region1_Idle_State_Code);
|
|
| oosmos_OrthoRegionInit(pControl, Operational_Region2_State, Operational_State, Operational_Region2_Idle_State, NULL);
|
|
| oosmos_LeafInit(pControl, Operational_Region2_Pumping_State, Operational_Region2_State, Operational_Region2_Pumping_State_Code);
|
|
| oosmos_LeafInit(pControl, Operational_Region2_Idle_State, Operational_Region2_State, Operational_Region2_Idle_State_Code);
|
|
| oosmos_LeafInit(pControl, StopPressed_State, ROOT, StopPressed_State_Code);
|
|
| oosmos_LeafInit(pControl, Terminated_State, ROOT, Terminated_State_Code);
|
|
| |
|
| oosmos_Debug(pControl, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pControl;
|
|
| }
|
|
oosmos/Examples/EventDemo/Windows/control.c
oosmos_DEFAULT
oosmos_DEFAULT is one of the six predefined event macros.
This event is sent to the
state once, before the state is entered, to allow the user the
opportunity to execute initialization code.
See line 46 in the code snippet below
for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| //
|
[MIT] |
|
| // OOSMOS Final Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sComposite A_State;
|
|
| oosmos_sChoice A_Choice1_State;
|
|
| oosmos_sLeaf A_Left_State;
|
|
| oosmos_sLeaf A_Right_State;
|
|
| oosmos_sFinal A_Final1_State;
|
|
| oosmos_sLeaf B_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| static bool IsLeft(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static void Default(void)
|
|
| {
|
|
| printf("In Default\n");
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool A_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_DEFAULT: {
|
|
| Default();
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, B_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
[...] |
|
| static bool A_Choice1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| if (oosmos_EventCode(pEvent) == oosmos_ENTER) {
|
|
| if (IsLeft()) {
|
|
| return oosmos_Transition(pTest, pState, A_Left_State);
|
|
| }
|
|
| else {
|
|
| return oosmos_Transition(pTest, pState, A_Right_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Left_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Right_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, A_State);
|
|
| oosmos_CompositeInit(pTest, A_State, ROOT, A_Choice1_State, A_State_Code);
|
|
| oosmos_ChoiceInit(pTest, A_Choice1_State, A_State, A_Choice1_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Left_State, A_State, A_Left_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Right_State, A_State, A_Right_State_Code);
|
|
| oosmos_FinalInit(pTest, A_Final1_State, A_State, NULL);
|
|
| oosmos_LeafInit(pTest, B_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->B_State)) {
|
|
| printf("SUCCESS.\n");
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos/Examples/Basic/Windows/Final.c
oosmos_DelayMS
oosmos_DelayMS suspends all processing for a specified number of
milliseconds.
oosmos_DelayMS is a thread blocker, not an
object blocker. If you want to suspend only the current object,
use the
oosmos_TimeoutInMS or
oosmos_ThreadDelayMS (inside of a thread group) instead. See
line 14 of the snippet below for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| //
|
[MIT] |
|
| // OOSMOS DelayMS Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
|
| #include <stdio.h>
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| for (unsigned LoopCount = 1; LoopCount <= 5; LoopCount++) {
|
|
| oosmos_DelayMS(500);
|
|
| printf("Work...\n");
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos_DelaySeconds
oosmos_DelaySeconds suspends all processing for a specified number of seconds.
See
line 14 of the snippet below for an example.
oosmos_DelaySeconds is a thread blocker, not an
object blocker. If you want to suspend only the current object,
use the
oosmos_TimeoutInSeconds or
oosmos_ThreadDelaySeconds inside of a thread group instead.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| //
|
[MIT] |
|
| // OOSMOS DelaySeconds Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
|
| #include <stdio.h>
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| for (unsigned LoopCount = 1; LoopCount <= 5; LoopCount++) {
|
|
| oosmos_DelaySeconds(1);
|
|
| printf("Work...\n");
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos_DelayUS
oosmos_DelayUS suspends all processing for a specified
number of microseconds. See
line 14 of the snippet below for an example.
If you want to suspend only the current object,
use the
oosmos_TimeoutInUS instead.
Note that
oosmos_DelayUS is not implemented on Windows.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| //
|
[MIT] |
|
| // OOSMOS DelayUS Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include <stdio.h>
|
|
| #include "oosmos.h"
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| for (unsigned LoopCount = 1; LoopCount <= 5; LoopCount++) {
|
|
| oosmos_DelayUS(1000 * 1000);
|
|
| printf("Work...\n");
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos_Divide_Integral_Rounded
oosmos_Divide_Integral_Rounded is a macro that is used internally by the
time unit conversion APIs, but it is externalized for your use.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_EMPTY_EVENT
oosmos_EMPTY_EVENT is a macro that initializes an
oosmos_sEvent structure to the empty event: event
code
oosmos_NOP (
0) and a
NULL
context pointer. Useful for initializing a user-defined event
structure whose first member is an
oosmos_sEvent.
oosmos_EndProgram
oosmos_EndProgram exits the program on platforms where that
makes sense, like Windows and Linux. On other platforms,
it is implemented as an endless loop, effectively stopping
the program.
oosmos_ENTER
oosmos_ENTER is one of the six predefined event macros. This event is generated
when the state is being entered. See line 38 in
the code snippet below for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "toggle.h"
|
|
| #include "pin.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stddef.h>
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 4
|
|
| #endif
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Off_State;
|
|
| oosmos_sLeaf On_State;
|
|
| //<<<DECL
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Off_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOffMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, On_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool On_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
[...] |
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pinOn(pToggle->m_pPin);
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOnMS);
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pinOff(pToggle->m_pPin);
|
|
| return true;
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, Off_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pToggle, ROOT, NULL, On_State);
|
|
| oosmos_LeafInit(pToggle, Off_State, ROOT, Off_State_Code);
|
|
| oosmos_LeafInit(pToggle, On_State, ROOT, On_State_Code);
|
|
| //<<<INIT
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle_state.c (State machine version)
oosmos_EventCode
oosmos_EventCode is a macro that accesses the event code from within an OOSMOS event
structure to improve readability of the generated code.
See line 37 for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| //
|
[...] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "toggle.h"
|
|
| #include "pin.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stddef.h>
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 4
|
|
| #endif
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Off_State;
|
|
| oosmos_sLeaf On_State;
|
|
| //<<<DECL
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Off_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOffMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, On_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
[...] |
|
| static bool On_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pinOn(pToggle->m_pPin);
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOnMS);
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pinOff(pToggle->m_pPin);
|
|
| return true;
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, Off_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pToggle, ROOT, NULL, On_State);
|
|
| oosmos_LeafInit(pToggle, Off_State, ROOT, Off_State_Code);
|
|
| oosmos_LeafInit(pToggle, On_State, ROOT, On_State_Code);
|
|
| //<<<INIT
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle_state.c (State machine version)
oosmos_EventQueue
oosmos_EventQueue is a macro that returns the address
of the object's event queue. Useful when subscribing the object
to events published by another object.
pObject |
The address of the object that contains the event queue.
|
RETURN |
The address of the object's oosmos_sQueue event queue.
|
See Also |
|
oosmos_EXIT
oosmos_EXIT is one of the six predefined event macros. This event is generated
when the state is being exited as part of a transition to another state.
See line 58 in
the code snippet below for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "toggle.h"
|
|
| #include "pin.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stddef.h>
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 4
|
|
| #endif
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Off_State;
|
|
| oosmos_sLeaf On_State;
|
|
| //<<<DECL
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Off_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOffMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, On_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool On_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pinOn(pToggle->m_pPin);
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOnMS);
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pinOff(pToggle->m_pPin);
|
|
| return true;
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, Off_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
[...] |
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pToggle, ROOT, NULL, On_State);
|
|
| oosmos_LeafInit(pToggle, Off_State, ROOT, Off_State_Code);
|
|
| oosmos_LeafInit(pToggle, On_State, ROOT, On_State_Code);
|
|
| //<<<INIT
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle_state.c (State machine version)
oosmos_FinalInit
Initializes a Final state. See line 111 for an example.
pObject |
Pointer to the object that holds the state machine.
|
StateName |
State name of the Final element.
|
Parent |
The name of this state's parent state.
|
pCode |
Pointer to event handler function. NULL if there is no function to call.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| //
|
[MIT] |
|
| // OOSMOS Final Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sComposite A_State;
|
|
| oosmos_sChoice A_Choice1_State;
|
|
| oosmos_sLeaf A_Left_State;
|
|
| oosmos_sLeaf A_Right_State;
|
|
| oosmos_sFinal A_Final1_State;
|
|
| oosmos_sLeaf B_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| static bool IsLeft(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static void Default(void)
|
|
| {
|
|
| printf("In Default\n");
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool A_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_DEFAULT: {
|
|
| Default();
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, B_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Choice1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| if (oosmos_EventCode(pEvent) == oosmos_ENTER) {
|
|
| if (IsLeft()) {
|
|
| return oosmos_Transition(pTest, pState, A_Left_State);
|
|
| }
|
|
| else {
|
|
| return oosmos_Transition(pTest, pState, A_Right_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Left_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Right_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, A_State);
|
|
| oosmos_CompositeInit(pTest, A_State, ROOT, A_Choice1_State, A_State_Code);
|
|
| oosmos_ChoiceInit(pTest, A_Choice1_State, A_State, A_Choice1_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Left_State, A_State, A_Left_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Right_State, A_State, A_Right_State_Code);
|
|
| oosmos_FinalInit(pTest, A_Final1_State, A_State, NULL);
|
|
| oosmos_LeafInit(pTest, B_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
[...] |
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->B_State)) {
|
|
| printf("SUCCESS.\n");
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos/Examples/Basic/Windows/Final.c
oosmos_FOREVER
oosmos_FOREVER loops forever. Useful to stop a
program once a problem has been programmatically identified.
oosmos_GetClockSpeedInMHz
oosmos_GetClockSpeedInMHz returns the processor
speed previously established with
oosmos_ClockSpeedInMHz. This call
only applies to the
PIC32 architecture.
| 1 |
| 2 |
| 3 |
| |
|
| uint32_t oosmos_GetClockSpeedInMHz(void); |
|
| |
|
Prototype
oosmos_GetCurrentEvent
oosmos_GetCurrentEvent is a macro that returns the
address of the event that is currently being delivered to the
state machine. Useful for accessing the members of a complex
(user-defined) event, for example after an
oosmos_ThreadWaitEvent call.
pState |
The same pState
argument that was passed into the containing state handler.
|
RETURN |
The address of the event currently being delivered.
|
See Also |
|
oosmos_GetFreeRunningUS
oosmos_GetFreeRunningUS returns the number of microseconds
since program start. Returning a
uint32_t, the maximum number
of microseconds that can be represented is 4,294,967,295, which is a little over 1 hour.
Therefore, this value will wrap around to 0 about once an hour. The OOSMOS timeout
capabilities handle the wraparound correctly, as does the
accum class.
| 1 |
| 2 |
| 3 |
| |
|
| uint32_t oosmos_GetFreeRunningUS(void) |
|
| |
|
Prototype
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_HexDump
oosmos_HexDump prints a hex dump of a memory area
using
oosmos_DebugPrint. Only available when
oosmos_DEBUG is defined.
| 1 |
| 2 |
| 3 |
| |
|
| void oosmos_HexDump(const void * pBuffer, size_t TotalBytes); |
|
| |
|
Prototype
pBuffer |
The address of the memory area to dump.
|
TotalBytes |
The number of bytes to dump.
|
See Also |
|
oosmos_HistoryInit
oosmos_HistoryInit initializes an
oosmos_sHistory state. When the parent composite
state is exited, the history pseudostate remembers which
substate was active; a later transition to the history
pseudostate resumes at that remembered substate. Shallow
history remembers only the immediate substate, while deep
history remembers the full nested state configuration.
| 1 |
| 2 |
| 3 |
| |
|
| void oosmos_HistoryInit(pObject, HistoryState, ParentState, Type); |
|
| |
|
Prototype
pObject |
The address of the object that contains the state machine.
|
HistoryState |
The name of the history state.
|
ParentState |
The name of the parent state.
|
Type |
The kind of history to track:
OOSMOS_HistoryShallowType or
OOSMOS_HistoryDeepType.
|
See Also |
|
oosmos_Hours2Days_Rounded
oosmos_Hours2Days_Rounded is a macro that converts hours to days with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Hours2Days_Rounded(Hours) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Hours2Days_Truncated
oosmos_Hours2Days_Truncated is a macro that converts hours to days with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Hours2Days_Truncated(Hours) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Hours2Minutes
oosmos_Hours2Minutes is a macro that converts hours to minutes.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Hours2Minutes(Hours) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Hours2MS
oosmos_Hours2MS is a macro that converts hours to milliseconds.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Hours2MS(Hours) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Hours2Seconds
oosmos_Hours2Seconds is a macro that converts hours to seconds.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Hours2Seconds(Hours) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Hours2US
oosmos_Hours2US is a macro that converts hours to microseconds.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Hours2US(Hours) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_IsInState
oosmos_IsInState returns
true if
the object is in state
pState or any of its
substates,
false otherwise.
See line 127 of the code snippet
below for an example.
pObject |
The address of the object that contains the state machine.
|
pState |
The address of the state within the current object.
|
RETURN |
Returns true if the object
is in the state specified by pState
or any of its subordinate states, false
otherwise.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| //
|
[MIT] |
|
| // OOSMOS Final Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sComposite A_State;
|
|
| oosmos_sChoice A_Choice1_State;
|
|
| oosmos_sLeaf A_Left_State;
|
|
| oosmos_sLeaf A_Right_State;
|
|
| oosmos_sFinal A_Final1_State;
|
|
| oosmos_sLeaf B_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| static bool IsLeft(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static void Default(void)
|
|
| {
|
|
| printf("In Default\n");
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool A_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_DEFAULT: {
|
|
| Default();
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, B_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Choice1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| if (oosmos_EventCode(pEvent) == oosmos_ENTER) {
|
|
| if (IsLeft()) {
|
|
| return oosmos_Transition(pTest, pState, A_Left_State);
|
|
| }
|
|
| else {
|
|
| return oosmos_Transition(pTest, pState, A_Right_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Left_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Right_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, A_State);
|
|
| oosmos_CompositeInit(pTest, A_State, ROOT, A_Choice1_State, A_State_Code);
|
|
| oosmos_ChoiceInit(pTest, A_Choice1_State, A_State, A_Choice1_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Left_State, A_State, A_Left_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Right_State, A_State, A_Right_State_Code);
|
|
| oosmos_FinalInit(pTest, A_Final1_State, A_State, NULL);
|
|
| oosmos_LeafInit(pTest, B_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->B_State)) {
|
|
| printf("SUCCESS.\n");
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos/Examples/Basic/Windows/Final.c
oosmos_LeafInit
oosmos_LeafInit initializes an
oosmos_sLeaf state.
See line 77 in the code snippet
below for an example.
pObject |
The address of the object that contains the state machine.
|
LeafState |
The name of the leaf state.
|
ParentState |
The name of the parent state.
|
pCode |
The address of the event code function or NULL.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "toggle.h"
|
|
| #include "pin.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stddef.h>
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 4
|
|
| #endif
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Off_State;
|
|
| oosmos_sLeaf On_State;
|
|
| //<<<DECL
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Off_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOffMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, On_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool On_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pinOn(pToggle->m_pPin);
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOnMS);
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pinOff(pToggle->m_pPin);
|
|
| return true;
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, Off_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pToggle, ROOT, NULL, On_State);
|
|
| oosmos_LeafInit(pToggle, Off_State, ROOT, Off_State_Code);
|
|
| oosmos_LeafInit(pToggle, On_State, ROOT, On_State_Code);
|
|
| //<<<INIT
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle_state.c
oosmos_Max
oosmos_Max is a macro that returns the larger of two values.
oosmos_Min
oosmos_Min is a macro that returns the smaller of two values.
oosmos_Minutes2Days_Rounded
oosmos_Minutes2Days_Rounded is a macro that converts minutes to days with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Minutes2Days_Rounded(Minutes) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Minutes2Days_Truncated
oosmos_Minutes2Days_Truncated is a macro that converts minutes to days with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Minutes2Days_Truncated(Minutes) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Minutes2Hours_Rounded
oosmos_Minutes2Hours_Rounded is a macro that converts minutes to hours with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Minutes2Hours_Truncated
oosmos_Minutes2Hours_Truncated is a macro that converts minutes to hours with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Minutes2MS
oosmos_Minutes2MS is a macro that converts minutes to milliseconds.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Minutes2Seconds
oosmos_Minutes2Seconds is a macro that converts minutes to seconds.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Minutes2US
oosmos_Minutes2US is a macro that converts minutes to microseconds.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2Days_Rounded
oosmos_MS2Days_Rounded is a macro that converts milliseconds to days with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_MS2Days_Rounded(Milliseconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2Days_Truncated
oosmos_MS2Days_Truncated is a macro that converts milliseconds to days with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_MS2Days_Truncated(Milliseconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2Hours_Rounded
oosmos_MS2Hours_Rounded is a macro that converts milliseconds to hours with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_MS2Hours_Rounded(Milliseconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2Hours_Truncated
oosmos_MS2Hours_Truncated is a macro that converts milliseconds to hours with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_MS2Hours_Truncated(Milliseconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2Minutes_Rounded
oosmos_MS2Minutes_Rounded is a macro that converts milliseconds to minutes with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2Minutes_Truncated
oosmos_MS2Minutes_Truncated is a macro that converts milliseconds to minutes with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2Seconds_Rounded
oosmos_MS2Seconds_Rounded is a macro that converts milliseconds
to seconds with the result being rounded for better precision.
If speed is more important than accuracy, see the truncated version of this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2Seconds_Truncated
oosmos_MS2Seconds_Truncated is a macro that converts milliseconds to seconds with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_MS2US
oosmos_MS2US is a macro that converts milliseconds to microseconds.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_NOP
oosmos_NOP is the reserved "no event" event
code (
0).
OOSMOS uses it internally to
mark empty events and initialized subscriber list entries.
Because event code
0 is reserved, user-defined
event codes must start at
1.
oosmos_ObjectThreadInit
Creates an Object Thread.
See line 23 for an
example of the declaration and line 50 for an
example of its creation. See lines
30-44 for the thread itself.
pObject |
Pointer to the object.
|
ObjectThread |
The name of the object member of type oosmos_sObjectThread.
|
pFunc |
The thread function.
|
bRunning |
Indicates whether the thread should start right away. If false,
then use oosmos_ObjectThreadStart() and
oosmos_ObjectThreadStop() to start and stop the thread.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 5
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "toggle.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| oosmos_sObjectThread m_ObjectThread;
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| static void ToggleThread(const toggle * pToggle, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pToggle);
|
|
| oosmos_POINTER_GUARD(pState);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| pinOn(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOnMS);
|
|
| |
|
| pinOff(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOffMS);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| oosmos_ObjectThreadInit(pToggle, m_ObjectThread, ToggleThread, true);
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos_ObjectThreadRestart
Restarts an Object Thread from its first statement, whether the
thread is currently running or stopped.
pObjectThread |
Pointer to the oosmos_sObjectThread object member.
|
See Also |
|
oosmos_ObjectThreadStart
Starts a previously created Object Thread.
pObjectThread |
Pointer to the oosmos_sObjectThread object member.
|
See Also |
|
oosmos_ObjectThreadStop
Stops an Object Thread. Use
oosmos_ObjectThreadStart
to restart it.
pObjectThread |
Pointer to the oosmos_sObjectThread object member.
|
See Also |
|
oosmos_ORTHO
oosmos_ORTHO is a preprocessor macro that, when defined,
compiles in all the
OOSMOS orthogonal state machine features.
The default is
#undef which will compile the smallest
possible footprint. Of course if you use orthogonal states in
any object in your build, you will have to
#define it
during compilation.
You can either define it on the compilation command
line (usually
-Doosmos_ORTHO),
or add a
#define oosmos_ORTHO at the top of
both
oosmos.h and
oosmos.c.
oosmos_OrthoInit
oosmos_OrthoInit initializes an
oosmos_sOrtho state.
See line 142 of the code snippet below for an example.
pObject |
The address of the object that contains the state machine.
|
OrthoState |
The name of the Ortho state.
|
ParentState |
The name of the parent state.
|
pCode |
The address of the event code function or NULL.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| //
|
[MIT] |
|
| // OOSMOS Completion Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evA = 1,
|
|
| evB = 2,
|
|
| evStop = 3
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evA: return "evA";
|
|
| case evB: return "evB";
|
|
| case evStop: return "evStop";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Ortho_State;
|
|
| oosmos_sOrthoRegion Ortho_Region1_State;
|
|
| oosmos_sLeaf Ortho_Region1_Idle_State;
|
|
| oosmos_sLeaf Ortho_Region1_Moving_State;
|
|
| oosmos_sFinal Ortho_Region1_Final1_State;
|
|
| oosmos_sOrthoRegion Ortho_Region2_State;
|
|
| oosmos_sLeaf Ortho_Region2_Idle_State;
|
|
| oosmos_sLeaf Ortho_Region2_Moving_State;
|
|
| oosmos_sFinal Ortho_Region2_Final2_State;
|
|
| oosmos_sLeaf Complete_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Ortho_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Complete_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region1_Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evA: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_Region1_Moving_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region1_Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStop: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_Region1_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region2_Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evB: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_Region2_Moving_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region2_Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStop: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_Region2_Final2_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Complete_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| printf("\n--Goal State Achieved--\n");
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pTest, ROOT, NULL, Ortho_State);
|
|
| oosmos_OrthoInit(pTest, Ortho_State, ROOT, Ortho_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, Ortho_Region1_State, Ortho_State, Ortho_Region1_Idle_State, NULL);
|
|
| oosmos_LeafInit(pTest, Ortho_Region1_Idle_State, Ortho_Region1_State, Ortho_Region1_Idle_State_Code);
|
|
| oosmos_LeafInit(pTest, Ortho_Region1_Moving_State, Ortho_Region1_State, Ortho_Region1_Moving_State_Code);
|
|
| oosmos_FinalInit(pTest, Ortho_Region1_Final1_State, Ortho_Region1_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Ortho_Region2_State, Ortho_State, Ortho_Region2_Idle_State, NULL);
|
|
| oosmos_LeafInit(pTest, Ortho_Region2_Idle_State, Ortho_Region2_State, Ortho_Region2_Idle_State_Code);
|
|
| oosmos_LeafInit(pTest, Ortho_Region2_Moving_State, Ortho_Region2_State, Ortho_Region2_Moving_State_Code);
|
|
| oosmos_FinalInit(pTest, Ortho_Region2_Final2_State, Ortho_Region2_State, NULL);
|
|
| oosmos_LeafInit(pTest, Complete_State, ROOT, Complete_State_Code);
|
|
| |
|
| oosmos_Debug(pTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| static void QueueEvent(const test * pTest, int EventCode)
|
[...] |
|
| {
|
|
| oosmos_PushEventCode(pTest, EventCode);
|
|
| oosmos_RunStateMachines();
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| QueueEvent(pTest, evA);
|
|
| QueueEvent(pTest, evB);
|
|
| QueueEvent(pTest, evStop);
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Complete_State)) {
|
|
| printf("SUCCESS\n");
|
|
| } else {
|
|
| printf("FAILURE\n");
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Ortho/Windows/Completion.c
oosmos_OrthoRegionInit
oosmos_OrthoRegionInit initializes an
oosmos_sOrthoRegion state.
See line 85 of the code snippet
below for an example.
pObject |
The address of the object that contains the state machine.
|
OrthoState |
The name of the ortho state.
|
ParentState |
The name of the parent state.
|
DefaultState |
The name of the default state.
|
pCode |
The address of the event code function or NULL.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| //
|
[MIT] |
|
| // OOSMOS EnterExit Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evTweak = 1
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evTweak: return "evTweak";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Active_State;
|
|
| oosmos_sOrthoRegion Active_Region1_State;
|
|
| oosmos_sLeaf Active_Region1_Moving_State;
|
|
| oosmos_sOrthoRegion Active_Region2_State;
|
|
| oosmos_sComposite Active_Region2_Outer_State;
|
|
| oosmos_sLeaf Active_Region2_Outer_Inner_State;
|
|
| oosmos_sOrthoRegion Active_Region3_State;
|
|
| oosmos_sLeaf Active_Region3_Leaf_State;
|
|
| oosmos_sLeaf Active_Region3_Running_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Active_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evTweak: {
|
|
| return oosmos_Transition(pTest, pState, Active_Region2_Outer_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region3_Leaf_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Active_Region3_Running_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pTest, ROOT, NULL, Active_State);
|
|
| oosmos_OrthoInit(pTest, Active_State, ROOT, Active_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region1_State, Active_State, Active_Region1_Moving_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region1_Moving_State, Active_Region1_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region2_State, Active_State, Active_Region2_Outer_State, NULL);
|
|
| oosmos_CompositeInit(pTest, Active_Region2_Outer_State, Active_Region2_State, Active_Region2_Outer_Inner_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region2_Outer_Inner_State, Active_Region2_Outer_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region3_State, Active_State, Active_Region3_Leaf_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region3_Leaf_State, Active_Region3_State, Active_Region3_Leaf_State_Code);
|
|
| oosmos_LeafInit(pTest, Active_Region3_Running_State, Active_Region3_State, NULL);
|
|
| |
|
| oosmos_Debug(pTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| static void QueueEventRoutine(const test * pTest, int EventCode)
|
[...] |
|
| {
|
|
| oosmos_PushEventCode(pTest, EventCode);
|
|
| oosmos_RunStateMachines();
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| QueueEventRoutine(pTest, evTweak);
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Active_Region2_Outer_Inner_State)) {
|
|
| printf("SUCCESS\n");
|
|
| } else {
|
|
| printf("FAILURE\n");
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Ortho/Windows/EnterExit.c
oosmos_POINTER_GUARD
oosmos_POINTER_GUARD guarantees that the passed argument is not NULL.
See line 32 in
the code snippet below for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef toggleMAX
|
[...] |
|
| #define toggleMAX 5
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "toggle.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| oosmos_sObjectThread m_ObjectThread;
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| static void ToggleThread(const toggle * pToggle, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pToggle);
|
|
| oosmos_POINTER_GUARD(pState);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| pinOn(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOnMS);
|
|
| |
|
| pinOff(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOffMS);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
[...] |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| oosmos_ObjectThreadInit(pToggle, m_ObjectThread, ToggleThread, true);
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle.c (thread version)
oosmos_POLL
oosmos_POLL is one of the six predefined event macros. This event is generated
each time the state machine is executed while this state is the currently active state.
See line 135 in
the code snippet below for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| 273 |
|
| 274 |
|
| 275 |
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
|
| 283 |
|
| 284 |
|
| 285 |
|
| 286 |
|
| 287 |
|
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
|
| 294 |
|
| 295 |
|
| 296 |
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 |
|
| 302 |
|
| 303 |
|
| 304 |
|
| 305 |
|
| 306 |
|
| 307 |
|
| 308 |
|
| 309 |
|
| 310 |
|
| 311 |
|
| 312 |
|
| 313 |
|
| //
|
[MIT] |
|
| // OOSMOS Poll Test
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| const unsigned TargetCount = 3;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf TestingNullTransitionWithoutPoll_State;
|
|
| oosmos_sOrtho Ortho_State;
|
|
| oosmos_sOrthoRegion Ortho_Region1_State;
|
|
| oosmos_sComposite Ortho_Region1_A1_State;
|
|
| oosmos_sComposite Ortho_Region1_A1_B1_State;
|
|
| oosmos_sLeaf Ortho_Region1_A1_B1_C1_State;
|
|
| oosmos_sOrthoRegion Ortho_Region2_State;
|
|
| oosmos_sComposite Ortho_Region2_A2_State;
|
|
| oosmos_sComposite Ortho_Region2_A2_B2_State;
|
|
| oosmos_sLeaf Ortho_Region2_A2_B2_C2_State;
|
|
| oosmos_sLeaf TestNullTransitionWithPoll_State;
|
|
| oosmos_sLeaf Done_State;
|
|
| //<<<DECL
|
|
| |
|
| unsigned m_Ortho;
|
|
| |
|
| unsigned m_A1_Count;
|
|
| unsigned m_B1_Count;
|
|
| unsigned m_C1_Count;
|
|
| |
|
| unsigned m_A2_Count;
|
|
| unsigned m_B2_Count;
|
|
| unsigned m_C2_Count;
|
|
| };
|
|
| |
|
| static bool CheckCounts(const test * pTest)
|
|
| {
|
|
| return pTest->m_Ortho > TargetCount &&
|
|
| pTest->m_A1_Count > TargetCount && pTest->m_B1_Count > TargetCount && pTest->m_C1_Count > TargetCount &&
|
|
| pTest->m_A2_Count > TargetCount && pTest->m_B2_Count > TargetCount && pTest->m_C2_Count > TargetCount;
|
|
| }
|
|
| |
|
| static void TestNullThread(test * pTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_UNUSED(pTest);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| printf("DELAY 50ms\n");
|
|
| oosmos_ThreadDelayMS(50);
|
|
| |
|
| printf("DELAY 100ms\n");
|
|
| oosmos_ThreadDelayMS(100);
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void OrthoPoll(test * pTest)
|
|
| {
|
|
| printf("Poll Ortho\n");
|
|
| pTest->m_Ortho++;
|
|
| }
|
|
| |
|
| static void A1Thread(test * pTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| printf("Poll A1: %u\n", pTest->m_A1_Count);
|
|
| pTest->m_A1_Count++;
|
|
| oosmos_ThreadDelayMS(20);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void B1Poll(test * pTest)
|
|
| {
|
|
| printf("Poll B1: %u\n", pTest->m_B1_Count);
|
|
| pTest->m_B1_Count++;
|
|
| }
|
|
| |
|
| static void C1Poll(test * pTest)
|
|
| {
|
|
| printf("Poll C1: %u\n", pTest->m_C1_Count);
|
|
| pTest->m_C1_Count++;
|
|
| }
|
|
| |
|
| static void A2Poll(test * pTest)
|
|
| {
|
|
| printf("Poll A2: %u\n", pTest->m_A2_Count);
|
|
| pTest->m_A2_Count++;
|
|
| }
|
|
| |
|
| static void B2Poll(test * pTest)
|
|
| {
|
|
| printf("Poll B2: %u\n", pTest->m_B2_Count);
|
|
| pTest->m_B2_Count++;
|
|
| }
|
|
| |
|
| static void C2Poll(test * pTest)
|
|
| {
|
|
| printf("Poll C2: %u\n", pTest->m_C2_Count);
|
|
| pTest->m_C2_Count++;
|
|
| }
|
|
| |
|
| |
|
| //>>>CODE
|
|
| static bool TestingNullTransitionWithoutPoll_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Ortho_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| OrthoPoll(pTest);
|
|
| if (CheckCounts(pTest)) {
|
|
| return oosmos_Transition(pTest, pState, TestNullTransitionWithPoll_State);
|
|
| }
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region1_A1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
[...] |
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| A1Thread(pTest, pState);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region1_A1_B1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| B1Poll(pTest);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region1_A1_B1_C1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| C1Poll(pTest);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region2_A2_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| A2Poll(pTest);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region2_A2_B2_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| B2Poll(pTest);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static bool Ortho_Region2_A2_B2_C2_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| C2Poll(pTest);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static bool TestNullTransitionWithPoll_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| TestNullThread(pTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Done_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Done_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| printf("SUCCESS!\nTerminating program.\n");
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, TestingNullTransitionWithoutPoll_State);
|
|
| oosmos_LeafInit(pTest, TestingNullTransitionWithoutPoll_State, ROOT, TestingNullTransitionWithoutPoll_State_Code);
|
|
| oosmos_OrthoInit(pTest, Ortho_State, ROOT, Ortho_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, Ortho_Region1_State, Ortho_State, Ortho_Region1_A1_State, NULL);
|
|
| oosmos_CompositeInit(pTest, Ortho_Region1_A1_State, Ortho_Region1_State, Ortho_Region1_A1_B1_State, Ortho_Region1_A1_State_Code);
|
|
| oosmos_CompositeInit(pTest, Ortho_Region1_A1_B1_State, Ortho_Region1_A1_State, Ortho_Region1_A1_B1_C1_State, Ortho_Region1_A1_B1_State_Code);
|
|
| oosmos_LeafInit(pTest, Ortho_Region1_A1_B1_C1_State, Ortho_Region1_A1_B1_State, Ortho_Region1_A1_B1_C1_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, Ortho_Region2_State, Ortho_State, Ortho_Region2_A2_State, NULL);
|
|
| oosmos_CompositeInit(pTest, Ortho_Region2_A2_State, Ortho_Region2_State, Ortho_Region2_A2_B2_State, Ortho_Region2_A2_State_Code);
|
|
| oosmos_CompositeInit(pTest, Ortho_Region2_A2_B2_State, Ortho_Region2_A2_State, Ortho_Region2_A2_B2_C2_State, Ortho_Region2_A2_B2_State_Code);
|
|
| oosmos_LeafInit(pTest, Ortho_Region2_A2_B2_C2_State, Ortho_Region2_A2_B2_State, Ortho_Region2_A2_B2_C2_State_Code);
|
|
| oosmos_LeafInit(pTest, TestNullTransitionWithPoll_State, ROOT, TestNullTransitionWithPoll_State_Code);
|
|
| oosmos_LeafInit(pTest, Done_State, ROOT, Done_State_Code);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| pTest->m_Ortho = 0;
|
|
| |
|
| pTest->m_A1_Count = 0;
|
|
| pTest->m_B1_Count = 0;
|
|
| pTest->m_C1_Count = 0;
|
|
| |
|
| pTest->m_A2_Count = 0;
|
|
| pTest->m_B2_Count = 0;
|
|
| pTest->m_C2_Count = 0;
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| (void) testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| printf("---\n");
|
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos/Tests/Poll.c (thread version)
oosmos_PushEvent
Allows you to push a complex event onto the object's event queue. Useful for
pushing complex events. That is, events that hold more than
just an event code.
pObject |
Pointer to the object.
|
Event |
Event object to push onto the object's event queue.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| //
|
[MIT] |
|
| // OOSMOS ThreadEvents Test
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evTestEvent = 1
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evTestEvent: return "evTestEvent";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct {
|
|
| oosmos_sEvent Event;
|
|
| unsigned Value;
|
|
| } sTestEvent;
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Event;
|
|
| sTestEvent TestEvent;
|
|
| } uEvents;
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho A1_State;
|
|
| oosmos_sOrthoRegion A1_Region1_State;
|
|
| oosmos_sLeaf A1_Region1_B1_State;
|
|
| oosmos_sOrthoRegion A1_Region2_State;
|
|
| oosmos_sLeaf A1_Region2_EventDriver_State;
|
|
| oosmos_sLeaf Done_State;
|
|
| //<<<DECL
|
|
| |
|
| };
|
|
| |
|
| static void A1Thread(oosmos_sState * pState)
|
|
| {
|
|
| const sTestEvent * pTestEvent = NULL;
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| oosmos_ThreadWaitEvent(evTestEvent);
|
|
| pTestEvent = (sTestEvent *) oosmos_GetCurrentEvent(pState);
|
|
| printf("ThreadA1: Received evTestEvent, Value %u %s\n", pTestEvent->Value, pTestEvent->Value == 998 ? "SUCCESS" : "FAILURE");
|
|
| |
|
| oosmos_ThreadWaitEvent(evTestEvent);
|
|
| pTestEvent = (sTestEvent *) oosmos_GetCurrentEvent(pState);
|
|
| printf("ThreadA1: Received evTestEvent, Value %u %s\n", pTestEvent->Value, pTestEvent->Value == 999 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void EventDriverThread(const test * pTest, oosmos_sState * pState)
|
|
| {
|
|
| static const sTestEvent TestEvent998 = { { evTestEvent, NULL }, 998 };
|
|
| static const sTestEvent TestEvent999 = { { evTestEvent, NULL }, 999 };
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| printf("EventDriverThread: Enter\n");
|
|
| oosmos_ThreadDelayMS(1000);
|
|
| |
|
| printf("EventDriverThread: Push 998\n");
|
|
| oosmos_PushEvent(pTest, TestEvent998);
|
|
| |
|
| printf("EventDriverThread: Push 999\n");
|
|
| oosmos_PushEvent(pTest, TestEvent999);
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool A1_Region1_B1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| A1Thread(pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Done_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Done_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static bool A1_Region2_EventDriver_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| EventDriverThread(pTest, pState);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pTest, ROOT, NULL, A1_State);
|
|
| oosmos_OrthoInit(pTest, A1_State, ROOT, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, A1_Region1_State, A1_State, A1_Region1_B1_State, NULL);
|
|
| oosmos_LeafInit(pTest, A1_Region1_B1_State, A1_Region1_State, A1_Region1_B1_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, A1_Region2_State, A1_State, A1_Region2_EventDriver_State, NULL);
|
|
| oosmos_LeafInit(pTest, A1_Region2_EventDriver_State, A1_Region2_State, A1_Region2_EventDriver_State_Code);
|
|
| oosmos_LeafInit(pTest, Done_State, ROOT, Done_State_Code);
|
|
| |
|
| oosmos_Debug(pTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| (void) testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos/Tests/ThreadEvents.c
oosmos_PushEventCode
oosmos_PushEventCode sends an event to an
OOSMOS
object. (It actually pushes the event to the object's event queue.) If the
event is handled by the current state or any of its parent states,
then the appropriate action is taken in that state. If the current
active state (or its parents) do not handle the event, it will
be popped from the queue and no action will take place.
See line
112 for an example.
pObject |
Pointer to the object that will react to the event.
|
EventCode |
The event code to send. Will always be an event defined inside the
implementation's .c file.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| //
|
[MIT] |
|
| // OOSMOS - EventDemo example, motor object
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "motor.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evStart = 1,
|
|
| evStop = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evStart: return "evStart";
|
|
| case evStop: return "evStop";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Event;
|
|
| } uEvents;
|
|
| |
|
| struct motorTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sLeaf Idle_State;
|
|
| oosmos_sLeaf Moving_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| #ifndef motorMAX
|
|
| #define motorMAX 3
|
|
| #endif
|
|
| |
|
| static void MovingThread(oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| printf("motor: MOVING...\n");
|
|
| oosmos_ThreadDelayMS(500);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motor * pMotor = (motor *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStart: {
|
|
| return oosmos_Transition(pMotor, pState, Moving_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motor * pMotor = (motor *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| MovingThread(pState);
|
|
| return true;
|
|
| }
|
|
| case evStop: {
|
|
| return oosmos_Transition(pMotor, pState, Idle_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern motor * motorNew(void)
|
|
| {
|
|
| oosmos_Allocate(pMotor, motor, motorMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pMotor, ROOT, NULL, Idle_State);
|
|
| oosmos_LeafInit(pMotor, Idle_State, ROOT, Idle_State_Code);
|
|
| oosmos_LeafInit(pMotor, Moving_State, ROOT, Moving_State_Code);
|
|
| |
|
| oosmos_Debug(pMotor, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pMotor;
|
|
| }
|
|
| |
|
| extern void motorOn(const motor * pMotor)
|
|
| {
|
|
| oosmos_PushEventCode(pMotor, evStart);
|
|
| }
|
|
| |
|
| extern void motorOff(const motor * pMotor)
|
|
| {
|
|
| oosmos_PushEventCode(pMotor, evStop);
|
|
| }
|
|
oosmos/Examples/EventDemo/Windows/motor.c
oosmos_QueueConstruct
Constructs a queue of type
oosmos_sQueue.
See lines 233 and 235 in the code snippet below for examples.
pQueue |
Pointer to a oosmos_sQueue item that holds the
metadata for the queue.
|
pQueueData |
A pointer to an array that will hold the data for the queue.
|
QueueDataSize |
The total size, in bytes, of the queue data array. Typically
specified as sizeof(QueueData). Must not be zero.
|
QueueElementSize |
The size, in bytes, of one element of the queue. Typically
specified as sizeof(QueueData[0]).
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| //
|
[MIT] |
|
| // OOSMOS uart Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "uart.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| #include <stdarg.h>
|
|
| |
|
| typedef enum
|
|
| {
|
|
| sendAwaitingCharToSend_State,
|
|
| sendAwaitingReady_State,
|
|
| sendAwaitingComplete_State
|
|
| } eSendStates;
|
|
| |
|
| struct uartTag
|
|
| {
|
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| |
|
| oosmos_sQueue m_SendDataQueue;
|
|
| uint8_t m_SendDataQueueData[200];
|
|
| eSendStates m_SendState;
|
|
| uint8_t m_CharToSend;
|
|
| |
|
| oosmos_sQueue m_ReceiveDataQueue;
|
|
| uint8_t m_ReceiveDataQueueData[10];
|
|
| oosmos_sSubscriberList m_ReceivedByteEventSubscribers[1];
|
|
| |
|
| uint8_t m_PlibUartID;
|
|
| uint8_t m_UartModule;
|
|
| };
|
|
| |
|
| #if defined _UART6
|
|
| #define MaxUARTS 6
|
|
| #elif defined _UART5
|
|
| #define MaxUARTS 5
|
|
| #elif defined _UART4
|
|
| #define MaxUARTS 4
|
|
| #elif defined _UART3
|
|
| #define MaxUARTS 3
|
|
| #elif defined _UART2
|
|
| #define MaxUARTS 2
|
|
| #elif defined _UART1
|
|
| #define MaxUARTS 1
|
|
| #endif
|
|
| |
|
| static uart UartList[MaxUARTS];
|
|
| static unsigned UartCount;
|
|
| |
|
| static const unsigned UartIndex_to_PlibUartId[] =
|
|
| {
|
|
| #ifdef _UART1
|
|
| UART1,
|
|
| #endif
|
|
| #ifdef _UART2
|
|
| UART2,
|
|
| #endif
|
|
| #ifdef _UART3
|
|
| UART3,
|
|
| #endif
|
|
| #ifdef _UART4
|
|
| UART4,
|
|
| #endif
|
|
| #ifdef _UART5
|
|
| UART5,
|
|
| #endif
|
|
| #ifdef _UART6
|
|
| UART6,
|
|
| #endif
|
|
| };
|
|
| |
|
| static void EnableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_ENABLED);
|
|
| }
|
|
| |
|
| static void DisableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_DISABLED);
|
|
| }
|
|
| |
|
| static uint16_t GetPriorityBits(const unsigned PriorityNumber)
|
|
| {
|
|
| switch (PriorityNumber) {
|
|
| case 1: return INT_PRIORITY_LEVEL_1;
|
|
| case 2: return INT_PRIORITY_LEVEL_2;
|
|
| case 3: return INT_PRIORITY_LEVEL_3;
|
|
| case 4: return INT_PRIORITY_LEVEL_4;
|
|
| case 5: return INT_PRIORITY_LEVEL_5;
|
|
| case 6: return INT_PRIORITY_LEVEL_6;
|
|
| case 7: return INT_PRIORITY_LEVEL_7;
|
|
| default: oosmos_FOREVER();
|
|
| }
|
|
| }
|
|
| |
|
| static void RunReceiverStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| uint8_t Byte;
|
|
| |
|
| DisableInterrupt(pUART);
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| EnableInterrupt(pUART);
|
|
| |
|
| if (PopSuccess) {
|
|
| uart_sReceivedByteEvent ReceivedByteEvent = { oosmos_EMPTY_EVENT, Byte };
|
|
| oosmos_SubscriberListNotifyWithArgs(pUART->m_ReceivedByteEventSubscribers, ReceivedByteEvent);
|
|
| }
|
|
| }
|
|
| |
|
| static void RunSenderStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| |
|
| switch (pUART->m_SendState) {
|
|
| case sendAwaitingCharToSend_State: {
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_SendDataQueue, &pUART->m_CharToSend, sizeof(pUART->m_CharToSend));
|
|
| |
|
| if (PopSuccess)
|
|
| pUART->m_SendState = sendAwaitingReady_State;
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingReady_State: {
|
|
| if (UARTTransmitterIsReady(pUART->m_PlibUartID)) {
|
|
| UARTSendDataByte(pUART->m_PlibUartID, pUART->m_CharToSend);
|
|
| pUART->m_SendState = sendAwaitingComplete_State;
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingComplete_State: {
|
|
| if (UARTTransmissionHasCompleted(pUART->m_PlibUartID))
|
|
| pUART->m_SendState = sendAwaitingCharToSend_State;
|
|
| |
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
| |
|
| static void RunStateMachine(void * pObject)
|
|
| {
|
|
| RunSenderStateMachine(pObject);
|
|
| RunReceiverStateMachine(pObject);
|
|
| }
|
|
| |
|
| static void ISR(const unsigned UartModule)
|
|
| {
|
|
| uart * pUART = UartList;
|
|
| |
|
| for (unsigned Count = 1; Count <= UartCount; pUART++, Count++) {
|
|
| if (UartModule <= pUART->m_UartModule) {
|
|
| break;
|
|
| }
|
|
| }
|
|
| |
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| if (INTGetFlag(INT_SOURCE_UART_RX(PlibUartId))) {
|
|
| while (UARTReceivedDataIsAvailable(PlibUartId)) {
|
|
| const uint8_t Byte = UARTGetDataByte(PlibUartId);
|
|
| oosmos_QueuePush(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| }
|
|
| |
|
| INTClearFlag(INT_SOURCE_UART_RX(PlibUartId));
|
|
| }
|
|
| }
|
|
| |
|
| static uint32_t GetPeripheralClock(void)
|
|
| {
|
|
| return (oosmos_GetClockSpeedInMHz()*1000000) / (1 << OSCCONbits.PBDIV);
|
|
| }
|
|
| |
|
| extern void uartPrintf(uart * pUART, const char * pFormat, ...)
|
|
| {
|
|
| char Buffer[100];
|
|
| va_list ArgList;
|
|
| |
|
| va_start(ArgList, pFormat);
|
|
| vsprintf(Buffer, pFormat, ArgList);
|
|
| uartSendString(pUART, Buffer);
|
|
| }
|
|
| |
|
| extern void uartSendChar(uart * pUART, const char Char)
|
|
| {
|
|
| oosmos_QueuePush(&pUART->m_SendDataQueue, &Char, sizeof(Char));
|
|
| }
|
|
| |
|
| extern void uartSendString(uart * pUART, const char * pString)
|
|
| {
|
|
| uint8_t Char;
|
|
| |
|
| while (Char = *pString++, Char) {
|
|
| uartSendChar(pUART, Char);
|
|
| }
|
|
| }
|
|
| |
|
| extern void uartStart(uart * pUART)
|
|
| {
|
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| UARTEnable(PlibUartId, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
|
|
| EnableInterrupt(pUART);
|
|
| }
|
|
| |
|
| //
|
|
| // 'UartModule' is 1, 2, etc.
|
|
| //
|
|
| extern uart * uartNew(const unsigned UartModule, const unsigned BaudRate)
|
|
| {
|
|
| oosmos_AllocateVisible(pUART, uart, UartList, UartCount, MaxUARTS, NULL);
|
|
| |
|
| pUART->m_UartModule = UartModule;
|
|
| |
|
| const unsigned PlibUartID = UartIndex_to_PlibUartId[UartModule-1];
|
|
| pUART->m_PlibUartID = PlibUartID;
|
|
| |
|
| UARTConfigure(PlibUartID, UART_ENABLE_PINS_TX_RX_ONLY);
|
|
| UARTSetFifoMode(PlibUartID, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
|
|
| UARTSetLineControl(PlibUartID, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
|
|
| UARTSetDataRate(PlibUartID, GetPeripheralClock(), BaudRate);
|
|
| |
|
| const unsigned Priority = 1;
|
|
| INTSetVectorPriority(INT_VECTOR_UART(PlibUartID), GetPriorityBits(Priority));
|
|
| INTSetVectorSubPriority(INT_VECTOR_UART(PlibUartID), INT_SUB_PRIORITY_LEVEL_0);
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_SendDataQueue, pUART->m_SendDataQueueData, sizeof(pUART->m_SendDataQueueData), sizeof(uint8_t));
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData, sizeof(pUART->m_ReceiveDataQueueData), sizeof(uint8_t));
|
|
| oosmos_SubscriberListInit(pUART->m_ReceivedByteEventSubscribers);
|
|
| |
|
| oosmos_ActiveObjectInit(pUART, m_ActiveObject, RunStateMachine);
|
|
| |
|
| return pUART;
|
|
| }
|
|
| |
[...] |
|
| extern void uartSubscribe(uart * pUART, oosmos_sQueue * pQueue, const int EventCode, void * pContext)
|
|
| {
|
|
| oosmos_SubscriberListAdd(pUART->m_ReceivedByteEventSubscribers, pQueue, EventCode, pContext);
|
|
| }
|
|
| |
|
| #define uartVector(N) void __ISR(_UART_##N##_VECTOR) IntUart##N##Handler() { ISR(N); }
|
|
| |
|
| #ifdef _UART1
|
|
| uartVector(1)
|
|
| #endif
|
|
| |
|
| #ifdef _UART2
|
|
| uartVector(2)
|
|
| #endif
|
|
| |
|
| #ifdef _UART3
|
|
| uartVector(3)
|
|
| #endif
|
|
| |
|
| #ifdef _UART4
|
|
| uartVector(4)
|
|
| #endif
|
|
| |
|
| #ifdef _UART5
|
|
| uartVector(5)
|
|
| #endif
|
|
| |
|
| #ifdef _UART6
|
|
| uartVector(6)
|
|
| #endif
|
|
oosmos/Classes/PIC32/uart.c
oosmos_QueuePop
If the queue is not empty,
oosmos_QueuePop
will pop an element off the queue and copy it into an item
that you allocate.
See lines 108 and 123 in the code snippet below for examples.
pQueue |
Pointer to a oosmos_sQueue item that holds the
metadata for the queue.
|
pPoppedItem |
A pointer to an item of ElementSize size
into which the queue item will be popped.
|
ElementSize |
Size of one element of the queue.
|
RETURN |
Returns true if an item was popped
off the queue, false otherwise.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| //
|
[MIT] |
|
| // OOSMOS uart Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "uart.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| #include <stdarg.h>
|
|
| |
|
| typedef enum
|
|
| {
|
|
| sendAwaitingCharToSend_State,
|
|
| sendAwaitingReady_State,
|
|
| sendAwaitingComplete_State
|
|
| } eSendStates;
|
|
| |
|
| struct uartTag
|
|
| {
|
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| |
|
| oosmos_sQueue m_SendDataQueue;
|
|
| uint8_t m_SendDataQueueData[200];
|
|
| eSendStates m_SendState;
|
|
| uint8_t m_CharToSend;
|
|
| |
|
| oosmos_sQueue m_ReceiveDataQueue;
|
|
| uint8_t m_ReceiveDataQueueData[10];
|
|
| oosmos_sSubscriberList m_ReceivedByteEventSubscribers[1];
|
|
| |
|
| uint8_t m_PlibUartID;
|
|
| uint8_t m_UartModule;
|
|
| };
|
|
| |
|
| #if defined _UART6
|
|
| #define MaxUARTS 6
|
|
| #elif defined _UART5
|
|
| #define MaxUARTS 5
|
|
| #elif defined _UART4
|
|
| #define MaxUARTS 4
|
|
| #elif defined _UART3
|
|
| #define MaxUARTS 3
|
|
| #elif defined _UART2
|
|
| #define MaxUARTS 2
|
|
| #elif defined _UART1
|
|
| #define MaxUARTS 1
|
|
| #endif
|
|
| |
|
| static uart UartList[MaxUARTS];
|
|
| static unsigned UartCount;
|
|
| |
|
| static const unsigned UartIndex_to_PlibUartId[] =
|
|
| {
|
|
| #ifdef _UART1
|
|
| UART1,
|
|
| #endif
|
|
| #ifdef _UART2
|
|
| UART2,
|
|
| #endif
|
|
| #ifdef _UART3
|
|
| UART3,
|
|
| #endif
|
|
| #ifdef _UART4
|
|
| UART4,
|
|
| #endif
|
|
| #ifdef _UART5
|
|
| UART5,
|
|
| #endif
|
|
| #ifdef _UART6
|
|
| UART6,
|
|
| #endif
|
|
| };
|
|
| |
|
| static void EnableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_ENABLED);
|
|
| }
|
|
| |
|
| static void DisableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_DISABLED);
|
|
| }
|
|
| |
|
| static uint16_t GetPriorityBits(const unsigned PriorityNumber)
|
|
| {
|
|
| switch (PriorityNumber) {
|
|
| case 1: return INT_PRIORITY_LEVEL_1;
|
|
| case 2: return INT_PRIORITY_LEVEL_2;
|
|
| case 3: return INT_PRIORITY_LEVEL_3;
|
|
| case 4: return INT_PRIORITY_LEVEL_4;
|
|
| case 5: return INT_PRIORITY_LEVEL_5;
|
|
| case 6: return INT_PRIORITY_LEVEL_6;
|
|
| case 7: return INT_PRIORITY_LEVEL_7;
|
|
| default: oosmos_FOREVER();
|
|
| }
|
|
| }
|
|
| |
|
| static void RunReceiverStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| uint8_t Byte;
|
|
| |
|
| DisableInterrupt(pUART);
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| EnableInterrupt(pUART);
|
|
| |
|
| if (PopSuccess) {
|
|
| uart_sReceivedByteEvent ReceivedByteEvent = { oosmos_EMPTY_EVENT, Byte };
|
|
| oosmos_SubscriberListNotifyWithArgs(pUART->m_ReceivedByteEventSubscribers, ReceivedByteEvent);
|
|
| }
|
|
| }
|
|
| |
|
| static void RunSenderStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| |
|
| switch (pUART->m_SendState) {
|
|
| case sendAwaitingCharToSend_State: {
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_SendDataQueue, &pUART->m_CharToSend, sizeof(pUART->m_CharToSend));
|
|
| |
|
| if (PopSuccess)
|
|
| pUART->m_SendState = sendAwaitingReady_State;
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingReady_State: {
|
|
| if (UARTTransmitterIsReady(pUART->m_PlibUartID)) {
|
|
| UARTSendDataByte(pUART->m_PlibUartID, pUART->m_CharToSend);
|
|
| pUART->m_SendState = sendAwaitingComplete_State;
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingComplete_State: {
|
|
| if (UARTTransmissionHasCompleted(pUART->m_PlibUartID))
|
|
| pUART->m_SendState = sendAwaitingCharToSend_State;
|
|
| |
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
| |
|
| static void RunStateMachine(void * pObject)
|
[...] |
|
| {
|
|
| RunSenderStateMachine(pObject);
|
|
| RunReceiverStateMachine(pObject);
|
|
| }
|
|
| |
|
| static void ISR(const unsigned UartModule)
|
|
| {
|
|
| uart * pUART = UartList;
|
|
| |
|
| for (unsigned Count = 1; Count <= UartCount; pUART++, Count++) {
|
|
| if (UartModule <= pUART->m_UartModule) {
|
|
| break;
|
|
| }
|
|
| }
|
|
| |
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| if (INTGetFlag(INT_SOURCE_UART_RX(PlibUartId))) {
|
|
| while (UARTReceivedDataIsAvailable(PlibUartId)) {
|
|
| const uint8_t Byte = UARTGetDataByte(PlibUartId);
|
|
| oosmos_QueuePush(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| }
|
|
| |
|
| INTClearFlag(INT_SOURCE_UART_RX(PlibUartId));
|
|
| }
|
|
| }
|
|
| |
|
| static uint32_t GetPeripheralClock(void)
|
|
| {
|
|
| return (oosmos_GetClockSpeedInMHz()*1000000) / (1 << OSCCONbits.PBDIV);
|
|
| }
|
|
| |
|
| extern void uartPrintf(uart * pUART, const char * pFormat, ...)
|
|
| {
|
|
| char Buffer[100];
|
|
| va_list ArgList;
|
|
| |
|
| va_start(ArgList, pFormat);
|
|
| vsprintf(Buffer, pFormat, ArgList);
|
|
| uartSendString(pUART, Buffer);
|
|
| }
|
|
| |
|
| extern void uartSendChar(uart * pUART, const char Char)
|
|
| {
|
|
| oosmos_QueuePush(&pUART->m_SendDataQueue, &Char, sizeof(Char));
|
|
| }
|
|
| |
|
| extern void uartSendString(uart * pUART, const char * pString)
|
|
| {
|
|
| uint8_t Char;
|
|
| |
|
| while (Char = *pString++, Char) {
|
|
| uartSendChar(pUART, Char);
|
|
| }
|
|
| }
|
|
| |
|
| extern void uartStart(uart * pUART)
|
|
| {
|
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| UARTEnable(PlibUartId, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
|
|
| EnableInterrupt(pUART);
|
|
| }
|
|
| |
|
| //
|
|
| // 'UartModule' is 1, 2, etc.
|
|
| //
|
|
| extern uart * uartNew(const unsigned UartModule, const unsigned BaudRate)
|
|
| {
|
|
| oosmos_AllocateVisible(pUART, uart, UartList, UartCount, MaxUARTS, NULL);
|
|
| |
|
| pUART->m_UartModule = UartModule;
|
|
| |
|
| const unsigned PlibUartID = UartIndex_to_PlibUartId[UartModule-1];
|
|
| pUART->m_PlibUartID = PlibUartID;
|
|
| |
|
| UARTConfigure(PlibUartID, UART_ENABLE_PINS_TX_RX_ONLY);
|
|
| UARTSetFifoMode(PlibUartID, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
|
|
| UARTSetLineControl(PlibUartID, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
|
|
| UARTSetDataRate(PlibUartID, GetPeripheralClock(), BaudRate);
|
|
| |
|
| const unsigned Priority = 1;
|
|
| INTSetVectorPriority(INT_VECTOR_UART(PlibUartID), GetPriorityBits(Priority));
|
|
| INTSetVectorSubPriority(INT_VECTOR_UART(PlibUartID), INT_SUB_PRIORITY_LEVEL_0);
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_SendDataQueue, pUART->m_SendDataQueueData, sizeof(pUART->m_SendDataQueueData), sizeof(uint8_t));
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData, sizeof(pUART->m_ReceiveDataQueueData), sizeof(uint8_t));
|
|
| oosmos_SubscriberListInit(pUART->m_ReceivedByteEventSubscribers);
|
|
| |
|
| oosmos_ActiveObjectInit(pUART, m_ActiveObject, RunStateMachine);
|
|
| |
|
| return pUART;
|
|
| }
|
|
| |
|
| extern void uartSubscribe(uart * pUART, oosmos_sQueue * pQueue, const int EventCode, void * pContext)
|
|
| {
|
|
| oosmos_SubscriberListAdd(pUART->m_ReceivedByteEventSubscribers, pQueue, EventCode, pContext);
|
|
| }
|
|
| |
|
| #define uartVector(N) void __ISR(_UART_##N##_VECTOR) IntUart##N##Handler() { ISR(N); }
|
|
| |
|
| #ifdef _UART1
|
|
| uartVector(1)
|
|
| #endif
|
|
| |
|
| #ifdef _UART2
|
|
| uartVector(2)
|
|
| #endif
|
|
| |
|
| #ifdef _UART3
|
|
| uartVector(3)
|
|
| #endif
|
|
| |
|
| #ifdef _UART4
|
|
| uartVector(4)
|
|
| #endif
|
|
| |
|
| #ifdef _UART5
|
|
| uartVector(5)
|
|
| #endif
|
|
| |
|
| #ifdef _UART6
|
|
| uartVector(6)
|
|
| #endif
|
|
oosmos/Classes/PIC32/uart.c
oosmos_QueuePush
Pushes a single item of size
ElementSize onto
the queue specified by
pQueue.
If the queue is already full at the time of this call, the
new item is tossed. Use
oosmos_QueueSetBehaviorFunc
to be notified when the queue is full and to control which
item is tossed.
See lines 168 and 192 in the code snippet below for examples.
pQueue |
Pointer to a oosmos_sQueue item that holds the
metadata for the queue.
|
pItemToPush |
A pointer to an item of ElementSize size
that will be pushed (i.e. copied) onto the queue.
|
ElementSize |
Size of one element of the queue.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| //
|
[MIT] |
|
| // OOSMOS uart Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "uart.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| #include <stdarg.h>
|
|
| |
|
| typedef enum
|
|
| {
|
|
| sendAwaitingCharToSend_State,
|
|
| sendAwaitingReady_State,
|
|
| sendAwaitingComplete_State
|
|
| } eSendStates;
|
|
| |
|
| struct uartTag
|
|
| {
|
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| |
|
| oosmos_sQueue m_SendDataQueue;
|
|
| uint8_t m_SendDataQueueData[200];
|
|
| eSendStates m_SendState;
|
|
| uint8_t m_CharToSend;
|
|
| |
|
| oosmos_sQueue m_ReceiveDataQueue;
|
|
| uint8_t m_ReceiveDataQueueData[10];
|
|
| oosmos_sSubscriberList m_ReceivedByteEventSubscribers[1];
|
|
| |
|
| uint8_t m_PlibUartID;
|
|
| uint8_t m_UartModule;
|
|
| };
|
|
| |
|
| #if defined _UART6
|
|
| #define MaxUARTS 6
|
|
| #elif defined _UART5
|
|
| #define MaxUARTS 5
|
|
| #elif defined _UART4
|
|
| #define MaxUARTS 4
|
|
| #elif defined _UART3
|
|
| #define MaxUARTS 3
|
|
| #elif defined _UART2
|
|
| #define MaxUARTS 2
|
|
| #elif defined _UART1
|
|
| #define MaxUARTS 1
|
|
| #endif
|
|
| |
|
| static uart UartList[MaxUARTS];
|
|
| static unsigned UartCount;
|
|
| |
|
| static const unsigned UartIndex_to_PlibUartId[] =
|
|
| {
|
|
| #ifdef _UART1
|
|
| UART1,
|
|
| #endif
|
|
| #ifdef _UART2
|
|
| UART2,
|
|
| #endif
|
|
| #ifdef _UART3
|
|
| UART3,
|
|
| #endif
|
|
| #ifdef _UART4
|
|
| UART4,
|
|
| #endif
|
|
| #ifdef _UART5
|
|
| UART5,
|
|
| #endif
|
|
| #ifdef _UART6
|
|
| UART6,
|
|
| #endif
|
|
| };
|
|
| |
|
| static void EnableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_ENABLED);
|
|
| }
|
|
| |
|
| static void DisableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_DISABLED);
|
|
| }
|
|
| |
|
| static uint16_t GetPriorityBits(const unsigned PriorityNumber)
|
|
| {
|
|
| switch (PriorityNumber) {
|
|
| case 1: return INT_PRIORITY_LEVEL_1;
|
|
| case 2: return INT_PRIORITY_LEVEL_2;
|
|
| case 3: return INT_PRIORITY_LEVEL_3;
|
|
| case 4: return INT_PRIORITY_LEVEL_4;
|
|
| case 5: return INT_PRIORITY_LEVEL_5;
|
|
| case 6: return INT_PRIORITY_LEVEL_6;
|
|
| case 7: return INT_PRIORITY_LEVEL_7;
|
|
| default: oosmos_FOREVER();
|
|
| }
|
|
| }
|
|
| |
|
| static void RunReceiverStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| uint8_t Byte;
|
|
| |
|
| DisableInterrupt(pUART);
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| EnableInterrupt(pUART);
|
|
| |
|
| if (PopSuccess) {
|
|
| uart_sReceivedByteEvent ReceivedByteEvent = { oosmos_EMPTY_EVENT, Byte };
|
|
| oosmos_SubscriberListNotifyWithArgs(pUART->m_ReceivedByteEventSubscribers, ReceivedByteEvent);
|
|
| }
|
|
| }
|
|
| |
|
| static void RunSenderStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| |
|
| switch (pUART->m_SendState) {
|
|
| case sendAwaitingCharToSend_State: {
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_SendDataQueue, &pUART->m_CharToSend, sizeof(pUART->m_CharToSend));
|
|
| |
|
| if (PopSuccess)
|
|
| pUART->m_SendState = sendAwaitingReady_State;
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingReady_State: {
|
|
| if (UARTTransmitterIsReady(pUART->m_PlibUartID)) {
|
|
| UARTSendDataByte(pUART->m_PlibUartID, pUART->m_CharToSend);
|
|
| pUART->m_SendState = sendAwaitingComplete_State;
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingComplete_State: {
|
|
| if (UARTTransmissionHasCompleted(pUART->m_PlibUartID))
|
|
| pUART->m_SendState = sendAwaitingCharToSend_State;
|
|
| |
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
| |
|
| static void RunStateMachine(void * pObject)
|
|
| {
|
|
| RunSenderStateMachine(pObject);
|
|
| RunReceiverStateMachine(pObject);
|
|
| }
|
|
| |
|
| static void ISR(const unsigned UartModule)
|
|
| {
|
|
| uart * pUART = UartList;
|
|
| |
|
| for (unsigned Count = 1; Count <= UartCount; pUART++, Count++) {
|
|
| if (UartModule <= pUART->m_UartModule) {
|
|
| break;
|
|
| }
|
|
| }
|
|
| |
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| if (INTGetFlag(INT_SOURCE_UART_RX(PlibUartId))) {
|
|
| while (UARTReceivedDataIsAvailable(PlibUartId)) {
|
|
| const uint8_t Byte = UARTGetDataByte(PlibUartId);
|
|
| oosmos_QueuePush(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| }
|
|
| |
|
| INTClearFlag(INT_SOURCE_UART_RX(PlibUartId));
|
|
| }
|
|
| }
|
|
| |
[...] |
|
| static uint32_t GetPeripheralClock(void)
|
|
| {
|
|
| return (oosmos_GetClockSpeedInMHz()*1000000) / (1 << OSCCONbits.PBDIV);
|
|
| }
|
|
| |
|
| extern void uartPrintf(uart * pUART, const char * pFormat, ...)
|
|
| {
|
|
| char Buffer[100];
|
|
| va_list ArgList;
|
|
| |
|
| va_start(ArgList, pFormat);
|
|
| vsprintf(Buffer, pFormat, ArgList);
|
|
| uartSendString(pUART, Buffer);
|
|
| }
|
|
| |
|
| extern void uartSendChar(uart * pUART, const char Char)
|
|
| {
|
|
| oosmos_QueuePush(&pUART->m_SendDataQueue, &Char, sizeof(Char));
|
|
| }
|
|
| |
[...] |
|
| extern void uartSendString(uart * pUART, const char * pString)
|
|
| {
|
|
| uint8_t Char;
|
|
| |
|
| while (Char = *pString++, Char) {
|
|
| uartSendChar(pUART, Char);
|
|
| }
|
|
| }
|
|
| |
|
| extern void uartStart(uart * pUART)
|
|
| {
|
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| UARTEnable(PlibUartId, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
|
|
| EnableInterrupt(pUART);
|
|
| }
|
|
| |
|
| //
|
|
| // 'UartModule' is 1, 2, etc.
|
|
| //
|
|
| extern uart * uartNew(const unsigned UartModule, const unsigned BaudRate)
|
|
| {
|
|
| oosmos_AllocateVisible(pUART, uart, UartList, UartCount, MaxUARTS, NULL);
|
|
| |
|
| pUART->m_UartModule = UartModule;
|
|
| |
|
| const unsigned PlibUartID = UartIndex_to_PlibUartId[UartModule-1];
|
|
| pUART->m_PlibUartID = PlibUartID;
|
|
| |
|
| UARTConfigure(PlibUartID, UART_ENABLE_PINS_TX_RX_ONLY);
|
|
| UARTSetFifoMode(PlibUartID, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
|
|
| UARTSetLineControl(PlibUartID, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
|
|
| UARTSetDataRate(PlibUartID, GetPeripheralClock(), BaudRate);
|
|
| |
|
| const unsigned Priority = 1;
|
|
| INTSetVectorPriority(INT_VECTOR_UART(PlibUartID), GetPriorityBits(Priority));
|
|
| INTSetVectorSubPriority(INT_VECTOR_UART(PlibUartID), INT_SUB_PRIORITY_LEVEL_0);
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_SendDataQueue, pUART->m_SendDataQueueData, sizeof(pUART->m_SendDataQueueData), sizeof(uint8_t));
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData, sizeof(pUART->m_ReceiveDataQueueData), sizeof(uint8_t));
|
|
| oosmos_SubscriberListInit(pUART->m_ReceivedByteEventSubscribers);
|
|
| |
|
| oosmos_ActiveObjectInit(pUART, m_ActiveObject, RunStateMachine);
|
|
| |
|
| return pUART;
|
|
| }
|
|
| |
|
| extern void uartSubscribe(uart * pUART, oosmos_sQueue * pQueue, const int EventCode, void * pContext)
|
|
| {
|
|
| oosmos_SubscriberListAdd(pUART->m_ReceivedByteEventSubscribers, pQueue, EventCode, pContext);
|
|
| }
|
|
| |
|
| #define uartVector(N) void __ISR(_UART_##N##_VECTOR) IntUart##N##Handler() { ISR(N); }
|
|
| |
|
| #ifdef _UART1
|
|
| uartVector(1)
|
|
| #endif
|
|
| |
|
| #ifdef _UART2
|
|
| uartVector(2)
|
|
| #endif
|
|
| |
|
| #ifdef _UART3
|
|
| uartVector(3)
|
|
| #endif
|
|
| |
|
| #ifdef _UART4
|
|
| uartVector(4)
|
|
| #endif
|
|
| |
|
| #ifdef _UART5
|
|
| uartVector(5)
|
|
| #endif
|
|
| |
|
| #ifdef _UART6
|
|
| uartVector(6)
|
|
| #endif
|
|
oosmos/Classes/PIC32/uart.c
oosmos_QueueSetBehaviorFunc
Allows you to specify a function to call when the specified queue is full.
If no function is set, the new element is tossed
(
oosmos_QueueFull_TossNew).
| 1 |
| 2 |
| 3 |
| |
|
| void oosmos_QueueSetBehaviorFunc(oosmos_sQueue * pQueue, oosmos_eQueueFullBehavior (*pCallback)(void *), void * pContext); |
|
| |
|
Prototype
pQueue |
Pointer to a oosmos_sQueue item that holds the
metadata for the queue.
|
pCallback |
Address of function to call when the specified queue is full. In this function,
you can report the issue or attempt to recover from it. Your function can return one of two
values to instruct OOSMOS what to do:
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| |
|
| typedef enum { |
|
| oosmos_QueueFull_TossNew = 1, |
|
| oosmos_QueueFull_TossOld |
|
| } oosmos_eQueueFullBehavior; |
|
| |
|
Prototype
|
pContext |
A pointer to caller context information that will be passed to the
callback function. Can be NULL.
|
See Also |
|
oosmos_RunStateMachine
oosmos_RunStateMachine runs a single
OOSMOS state machine object one time.
See example on line 207 in
the code snippet.
pObject |
The address of the object that contains the state machine.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| //
|
[MIT] |
|
| // OOSMOS motion Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evDownCommand = 1,
|
|
| evLowerLimitSwitchClosed = 2,
|
|
| evLowerLimitSwitchOpen = 3,
|
|
| evStopCommand = 4,
|
|
| evUpCommand = 5,
|
|
| evUpperLimitSwitchClosed = 6,
|
|
| evUpperLimitSwitchOpen = 7
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evDownCommand: return "evDownCommand";
|
|
| case evLowerLimitSwitchClosed: return "evLowerLimitSwitchClosed";
|
|
| case evLowerLimitSwitchOpen: return "evLowerLimitSwitchOpen";
|
|
| case evStopCommand: return "evStopCommand";
|
|
| case evUpCommand: return "evUpCommand";
|
|
| case evUpperLimitSwitchClosed: return "evUpperLimitSwitchClosed";
|
|
| case evUpperLimitSwitchOpen: return "evUpperLimitSwitchOpen";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct motionTag motion;
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct motionTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Active_State;
|
|
| oosmos_sOrthoRegion Active_Region1_State;
|
|
| oosmos_sComposite Active_Region1_Limits_State;
|
|
| oosmos_sLeaf Active_Region1_Limits_AtUpperLimit_State;
|
|
| oosmos_sLeaf Active_Region1_Limits_InBounds_State;
|
|
| oosmos_sChoice Active_Region1_Limits_Choice1_State;
|
|
| oosmos_sLeaf Active_Region1_Limits_AtLowerLimit_State;
|
|
| oosmos_sOrthoRegion Active_Region2_State;
|
|
| oosmos_sLeaf Active_Region2_Stopped_State;
|
|
| oosmos_sComposite Active_Region2_Moving_State;
|
|
| oosmos_sLeaf Active_Region2_Moving_Up_State;
|
|
| oosmos_sLeaf Active_Region2_Moving_Down_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| static int Failures = 0;
|
|
| |
|
| static bool IsUpperLimitSwitchOpen(void) {
|
|
| return true;
|
|
| }
|
|
| |
|
| static bool IsLowerLimitSwitchOpen(void) {
|
|
| return false;
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool Active_Region1_Limits_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motion * pMotion = (motion *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evUpperLimitSwitchOpen: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region1_Limits_AtUpperLimit_State);
|
|
| }
|
|
| case evUpperLimitSwitchClosed: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region1_Limits_InBounds_State);
|
|
| }
|
|
| case evLowerLimitSwitchClosed: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region1_Limits_InBounds_State);
|
|
| }
|
|
| case evLowerLimitSwitchOpen: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region1_Limits_AtLowerLimit_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region1_Limits_Choice1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motion * pMotion = (motion *) pObject;
|
|
| |
|
| if (oosmos_EventCode(pEvent) == oosmos_ENTER) {
|
|
| if (IsUpperLimitSwitchOpen()) {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region1_Limits_AtUpperLimit_State);
|
|
| }
|
|
| else if (IsLowerLimitSwitchOpen()) {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region1_Limits_AtLowerLimit_State);
|
|
| }
|
|
| else {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region1_Limits_InBounds_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region2_Stopped_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motion * pMotion = (motion *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evUpCommand: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region2_Moving_Up_State);
|
|
| }
|
|
| case evDownCommand: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region2_Moving_Down_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region2_Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motion * pMotion = (motion *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStopCommand: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region2_Stopped_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region2_Moving_Up_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motion * pMotion = (motion *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evDownCommand: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region2_Moving_Down_State);
|
|
| }
|
|
| case evUpperLimitSwitchOpen: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region2_Stopped_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region2_Moving_Down_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motion * pMotion = (motion *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evUpCommand: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region2_Moving_Up_State);
|
|
| }
|
|
| case evLowerLimitSwitchOpen: {
|
|
| return oosmos_Transition(pMotion, pState, Active_Region2_Stopped_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static motion * motionNew(void)
|
|
| {
|
|
| oosmos_Allocate(pMotion, motion, 2, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pMotion, ROOT, NULL, Active_State);
|
|
| oosmos_OrthoInit(pMotion, Active_State, ROOT, NULL);
|
|
| oosmos_OrthoRegionInit(pMotion, Active_Region1_State, Active_State, Active_Region1_Limits_State, NULL);
|
|
| oosmos_CompositeInit(pMotion, Active_Region1_Limits_State, Active_Region1_State, Active_Region1_Limits_Choice1_State, Active_Region1_Limits_State_Code);
|
|
| oosmos_LeafInit(pMotion, Active_Region1_Limits_AtUpperLimit_State, Active_Region1_Limits_State, NULL);
|
|
| oosmos_LeafInit(pMotion, Active_Region1_Limits_InBounds_State, Active_Region1_Limits_State, NULL);
|
|
| oosmos_ChoiceInit(pMotion, Active_Region1_Limits_Choice1_State, Active_Region1_Limits_State, Active_Region1_Limits_Choice1_State_Code);
|
|
| oosmos_LeafInit(pMotion, Active_Region1_Limits_AtLowerLimit_State, Active_Region1_Limits_State, NULL);
|
|
| oosmos_OrthoRegionInit(pMotion, Active_Region2_State, Active_State, Active_Region2_Stopped_State, NULL);
|
|
| oosmos_LeafInit(pMotion, Active_Region2_Stopped_State, Active_Region2_State, Active_Region2_Stopped_State_Code);
|
|
| oosmos_CompositeInit(pMotion, Active_Region2_Moving_State, Active_Region2_State, Active_Region2_Moving_Up_State, Active_Region2_Moving_State_Code);
|
|
| oosmos_LeafInit(pMotion, Active_Region2_Moving_Up_State, Active_Region2_Moving_State, Active_Region2_Moving_Up_State_Code);
|
|
| oosmos_LeafInit(pMotion, Active_Region2_Moving_Down_State, Active_Region2_Moving_State, Active_Region2_Moving_Down_State_Code);
|
|
| |
|
| oosmos_Debug(pMotion, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pMotion;
|
|
| }
|
|
| |
|
| static void QueueEvent(motion * pMotion, int EventCode)
|
|
| {
|
|
| oosmos_PushEventCode(pMotion, EventCode);
|
|
| oosmos_RunStateMachine(pMotion);
|
|
| }
|
|
| |
|
| static void TestState(const motion * pMotion, const void * pState)
|
[...] |
|
| {
|
|
| if (!oosmos_IsInState(pMotion, pState)) {
|
|
| printf("FAILURE.\n");
|
|
| Failures += 1;
|
|
| }
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| motion * pMotion = motionNew();
|
|
| |
|
| QueueEvent(pMotion, evUpCommand);
|
|
| TestState(pMotion, &pMotion->Active_Region2_Moving_Up_State);
|
|
| |
|
| QueueEvent(pMotion, evUpperLimitSwitchOpen);
|
|
| TestState(pMotion, &pMotion->Active_Region2_Stopped_State);
|
|
| TestState(pMotion, &pMotion->Active_Region1_Limits_AtUpperLimit_State);
|
|
| |
|
| QueueEvent(pMotion, evDownCommand);
|
|
| TestState(pMotion, &pMotion->Active_Region2_Moving_Down_State);
|
|
| |
|
| QueueEvent(pMotion, evLowerLimitSwitchClosed);
|
|
| TestState(pMotion, &pMotion->Active_Region1_Limits_InBounds_State);
|
|
| |
|
| QueueEvent(pMotion, evUpCommand);
|
|
| TestState(pMotion, &pMotion->Active_Region2_Moving_Up_State);
|
|
| |
|
| QueueEvent(pMotion, evStopCommand);
|
|
| TestState(pMotion, &pMotion->Active_Region2_Stopped_State);
|
|
| |
|
| if (Failures > 0) {
|
|
| printf("%d FAILURES\n", Failures);
|
|
| }
|
|
| else {
|
|
| printf("\n");
|
|
| printf("SUCCESS!\n");
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Ortho/Windows/Motion.c
oosmos_RunStateMachines
oosmos_RunStateMachines runs all
OOSMOS state machine objects
as well as all registered Active Objects
(see
oosmos_ActiveObjectInit.)
See line 27 in the code snippet
below for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| //
|
[MIT] |
|
| // OOSMOS Blink Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "toggle.h"
|
|
| |
|
| static void SetupToggle(int Pin, int OnTimeMS, int OffTimeMS)
|
|
| {
|
|
| pin * pPin = pinNew(Pin, pinOut, pinActiveHigh);
|
|
| toggleNew(pPin, OnTimeMS, OffTimeMS);
|
|
| }
|
|
| |
|
| extern void setup()
|
|
| {
|
|
| SetupToggle(13, 50, 500);
|
|
| SetupToggle(12, 2000, 2000);
|
|
| SetupToggle(11, 50, 1500);
|
|
| }
|
|
| |
|
| extern void loop()
|
|
| {
|
|
| oosmos_RunStateMachines();
|
|
| }
|
|
oosmos/Examples/Blink/Arduino/BlinkExample/BlinkExample.ino
oosmos_sActiveObject
oosmos_sChoice
oosmos_sChoice declares a choice pseudostate in
an
OOSMOS state machine object.
oosmos_sComposite
oosmos_sComposite declares a composite state in
an
OOSMOS state machine object.
See line 21 in the code snippet below for
an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| //
|
[MIT] |
|
| // OOSMOS Final Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sComposite A_State;
|
|
| oosmos_sChoice A_Choice1_State;
|
|
| oosmos_sLeaf A_Left_State;
|
|
| oosmos_sLeaf A_Right_State;
|
|
| oosmos_sFinal A_Final1_State;
|
|
| oosmos_sLeaf B_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| static bool IsLeft(void)
|
[...] |
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static void Default(void)
|
|
| {
|
|
| printf("In Default\n");
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool A_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_DEFAULT: {
|
|
| Default();
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, B_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Choice1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| if (oosmos_EventCode(pEvent) == oosmos_ENTER) {
|
|
| if (IsLeft()) {
|
|
| return oosmos_Transition(pTest, pState, A_Left_State);
|
|
| }
|
|
| else {
|
|
| return oosmos_Transition(pTest, pState, A_Right_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Left_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Right_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, A_State);
|
|
| oosmos_CompositeInit(pTest, A_State, ROOT, A_Choice1_State, A_State_Code);
|
|
| oosmos_ChoiceInit(pTest, A_Choice1_State, A_State, A_Choice1_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Left_State, A_State, A_Left_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Right_State, A_State, A_Right_State_Code);
|
|
| oosmos_FinalInit(pTest, A_Final1_State, A_State, NULL);
|
|
| oosmos_LeafInit(pTest, B_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->B_State)) {
|
|
| printf("SUCCESS.\n");
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos/Examples/Basic/Windows/Final.c
oosmos_Seconds2Days_Rounded
oosmos_Seconds2Days_Rounded is a macro that converts seconds to days with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Seconds2Days_Rounded(Seconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Seconds2Days_Truncated
oosmos_Seconds2Days_Truncated is a macro that converts seconds to days with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Seconds2Days_Truncated(Seconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Seconds2Hours_Rounded
oosmos_Seconds2Hours_Rounded is a macro that converts seconds to hours with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Seconds2Hours_Truncated
oosmos_Seconds2Hours_Truncated is a macro that converts seconds to hours with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Seconds2Minutes_Rounded
oosmos_Seconds2Minutes_Rounded is a macro that converts seconds to minutes with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Seconds2Minutes_Rounded(Seconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Seconds2Minutes_Truncated
oosmos_Seconds2Minutes_Truncated is a macro that converts seconds to minutes with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_Seconds2Minutes_Truncated(Seconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Seconds2MS
oosmos_Seconds2MS is a macro that converts seconds to milliseconds.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_Seconds2US
oosmos_Seconds2US is a macro that converts seconds to microseconds.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_sEvent
oosmos_sEvent is the principal event structure. It
holds an event code called
Code and a context pointer
called
pContext.
See line 32 for an example of use.
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| |
|
| typedef struct |
|
| { |
|
| int m_Code; |
|
| void * m_pContext; |
|
| } oosmos_sEvent; |
|
| |
|
oosmos_sEvent Data Type
Code |
Member m_Code holds the event code to be delivered.
|
pContext |
Member m_pContext is a user-defined pointer to help the
notified entity determine the context of the action.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| //
|
[MIT] |
|
| // OOSMOS - EventDemo example, motor object
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "motor.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
[Code Generated by OOSMOS] |
|
| evStart = 1,
|
|
| evStop = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evStart: return "evStart";
|
|
| case evStop: return "evStop";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Event;
|
|
| } uEvents;
|
|
| |
|
| struct motorTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
[Code Generated by OOSMOS] |
|
| oosmos_sLeaf Idle_State;
|
|
| oosmos_sLeaf Moving_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| #ifndef motorMAX
|
|
| #define motorMAX 3
|
|
| #endif
|
|
| |
|
| static void MovingThread(oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| printf("motor: MOVING...\n");
|
|
| oosmos_ThreadDelayMS(500);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
[Code Generated by OOSMOS] |
|
| {
|
|
| motor * pMotor = (motor *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStart: {
|
|
| return oosmos_Transition(pMotor, pState, Moving_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motor * pMotor = (motor *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| MovingThread(pState);
|
|
| return true;
|
|
| }
|
|
| case evStop: {
|
|
| return oosmos_Transition(pMotor, pState, Idle_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern motor * motorNew(void)
|
|
| {
|
|
| oosmos_Allocate(pMotor, motor, motorMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pMotor, ROOT, NULL, Idle_State);
|
[Code Generated by OOSMOS] |
|
| oosmos_LeafInit(pMotor, Idle_State, ROOT, Idle_State_Code);
|
|
| oosmos_LeafInit(pMotor, Moving_State, ROOT, Moving_State_Code);
|
|
| |
|
| oosmos_Debug(pMotor, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pMotor;
|
|
| }
|
|
| |
|
| extern void motorOn(const motor * pMotor)
|
[...] |
|
| {
|
|
| oosmos_PushEventCode(pMotor, evStart);
|
|
| }
|
|
| |
|
| extern void motorOff(const motor * pMotor)
|
|
| {
|
|
| oosmos_PushEventCode(pMotor, evStop);
|
|
| }
|
|
oosmos/Examples/EventDemo/Windows/motor.c
oosmos_sFinal
oosmos_sFinal declares a final state in
your
OOSMOS state machine object.
See line 25 in the code snippet for
an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| //
|
[MIT] |
|
| // OOSMOS Final Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sComposite A_State;
|
|
| oosmos_sChoice A_Choice1_State;
|
|
| oosmos_sLeaf A_Left_State;
|
|
| oosmos_sLeaf A_Right_State;
|
|
| oosmos_sFinal A_Final1_State;
|
|
| oosmos_sLeaf B_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| static bool IsLeft(void)
|
[...] |
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static void Default(void)
|
|
| {
|
|
| printf("In Default\n");
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool A_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_DEFAULT: {
|
|
| Default();
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, B_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Choice1_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| if (oosmos_EventCode(pEvent) == oosmos_ENTER) {
|
|
| if (IsLeft()) {
|
|
| return oosmos_Transition(pTest, pState, A_Left_State);
|
|
| }
|
|
| else {
|
|
| return oosmos_Transition(pTest, pState, A_Right_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Left_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_Right_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, A_State);
|
|
| oosmos_CompositeInit(pTest, A_State, ROOT, A_Choice1_State, A_State_Code);
|
|
| oosmos_ChoiceInit(pTest, A_Choice1_State, A_State, A_Choice1_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Left_State, A_State, A_Left_State_Code);
|
|
| oosmos_LeafInit(pTest, A_Right_State, A_State, A_Right_State_Code);
|
|
| oosmos_FinalInit(pTest, A_Final1_State, A_State, NULL);
|
|
| oosmos_LeafInit(pTest, B_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->B_State)) {
|
|
| printf("SUCCESS.\n");
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos/Examples/Basic/Windows/Final.c
oosmos_sHistory
oosmos_sHistory declares a history pseudostate
(shallow or deep) in an
OOSMOS state machine object.
oosmos_sLeaf
oosmos_sLeaf declares a leaf state in
an
OOSMOS state machine object.
See line 23 in the code snippet below for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "toggle.h"
|
|
| #include "pin.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stddef.h>
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 4
|
|
| #endif
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Off_State;
|
|
| oosmos_sLeaf On_State;
|
|
| //<<<DECL
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool Off_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOffMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, On_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool On_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pinOn(pToggle->m_pPin);
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOnMS);
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pinOff(pToggle->m_pPin);
|
|
| return true;
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, Off_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pToggle, ROOT, NULL, On_State);
|
|
| oosmos_LeafInit(pToggle, Off_State, ROOT, Off_State_Code);
|
|
| oosmos_LeafInit(pToggle, On_State, ROOT, On_State_Code);
|
|
| //<<<INIT
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle_state.c
oosmos_sObjectThread
Type that declares an Object Thread inside an OOSMOS object.
See line 23 for an
example of the declaration and line 50 for an
example of its creation. See lines
30-44 for the thread itself.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 5
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "toggle.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| oosmos_sObjectThread m_ObjectThread;
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| static void ToggleThread(const toggle * pToggle, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pToggle);
|
|
| oosmos_POINTER_GUARD(pState);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| pinOn(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOnMS);
|
|
| |
|
| pinOff(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOffMS);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| oosmos_ObjectThreadInit(pToggle, m_ObjectThread, ToggleThread, true);
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos_sOrtho
Declares an orthogonal state in
your
OOSMOS state machine object.
See line 38 in the code snippet below for
an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| //
|
[MIT] |
|
| // OOSMOS EnterExit Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evTweak = 1
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evTweak: return "evTweak";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Active_State;
|
|
| oosmos_sOrthoRegion Active_Region1_State;
|
|
| oosmos_sLeaf Active_Region1_Moving_State;
|
|
| oosmos_sOrthoRegion Active_Region2_State;
|
|
| oosmos_sComposite Active_Region2_Outer_State;
|
|
| oosmos_sLeaf Active_Region2_Outer_Inner_State;
|
|
| oosmos_sOrthoRegion Active_Region3_State;
|
|
| oosmos_sLeaf Active_Region3_Leaf_State;
|
|
| oosmos_sLeaf Active_Region3_Running_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool Active_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evTweak: {
|
|
| return oosmos_Transition(pTest, pState, Active_Region2_Outer_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region3_Leaf_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Active_Region3_Running_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pTest, ROOT, NULL, Active_State);
|
|
| oosmos_OrthoInit(pTest, Active_State, ROOT, Active_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region1_State, Active_State, Active_Region1_Moving_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region1_Moving_State, Active_Region1_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region2_State, Active_State, Active_Region2_Outer_State, NULL);
|
|
| oosmos_CompositeInit(pTest, Active_Region2_Outer_State, Active_Region2_State, Active_Region2_Outer_Inner_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region2_Outer_Inner_State, Active_Region2_Outer_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region3_State, Active_State, Active_Region3_Leaf_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region3_Leaf_State, Active_Region3_State, Active_Region3_Leaf_State_Code);
|
|
| oosmos_LeafInit(pTest, Active_Region3_Running_State, Active_Region3_State, NULL);
|
|
| |
|
| oosmos_Debug(pTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| static void QueueEventRoutine(const test * pTest, int EventCode)
|
|
| {
|
|
| oosmos_PushEventCode(pTest, EventCode);
|
|
| oosmos_RunStateMachines();
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| QueueEventRoutine(pTest, evTweak);
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Active_Region2_Outer_Inner_State)) {
|
|
| printf("SUCCESS\n");
|
|
| } else {
|
|
| printf("FAILURE\n");
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Ortho/Windows/EnterExit.c
oosmos_sOrthoRegion
oosmos_sOrthoRegion declares an orthogonal region
state in
your
OOSMOS state machine object.
See line 39 in the code snippet below for
an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| //
|
[MIT] |
|
| // OOSMOS EnterExit Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evTweak = 1
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evTweak: return "evTweak";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Active_State;
|
|
| oosmos_sOrthoRegion Active_Region1_State;
|
|
| oosmos_sLeaf Active_Region1_Moving_State;
|
|
| oosmos_sOrthoRegion Active_Region2_State;
|
|
| oosmos_sComposite Active_Region2_Outer_State;
|
|
| oosmos_sLeaf Active_Region2_Outer_Inner_State;
|
|
| oosmos_sOrthoRegion Active_Region3_State;
|
|
| oosmos_sLeaf Active_Region3_Leaf_State;
|
|
| oosmos_sLeaf Active_Region3_Running_State;
|
|
| //<<<DECL
|
|
| };
|
[...] |
|
| |
|
| //>>>CODE
|
|
| static bool Active_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evTweak: {
|
|
| return oosmos_Transition(pTest, pState, Active_Region2_Outer_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region3_Leaf_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Active_Region3_Running_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pTest, ROOT, NULL, Active_State);
|
|
| oosmos_OrthoInit(pTest, Active_State, ROOT, Active_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region1_State, Active_State, Active_Region1_Moving_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region1_Moving_State, Active_Region1_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region2_State, Active_State, Active_Region2_Outer_State, NULL);
|
|
| oosmos_CompositeInit(pTest, Active_Region2_Outer_State, Active_Region2_State, Active_Region2_Outer_Inner_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region2_Outer_Inner_State, Active_Region2_Outer_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region3_State, Active_State, Active_Region3_Leaf_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region3_Leaf_State, Active_Region3_State, Active_Region3_Leaf_State_Code);
|
|
| oosmos_LeafInit(pTest, Active_Region3_Running_State, Active_Region3_State, NULL);
|
|
| |
|
| oosmos_Debug(pTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| static void QueueEventRoutine(const test * pTest, int EventCode)
|
|
| {
|
|
| oosmos_PushEventCode(pTest, EventCode);
|
|
| oosmos_RunStateMachines();
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| QueueEventRoutine(pTest, evTweak);
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Active_Region2_Outer_Inner_State)) {
|
|
| printf("SUCCESS\n");
|
|
| } else {
|
|
| printf("FAILURE\n");
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Ortho/Windows/EnterExit.c
oosmos_sQueue
OOSMOS has a generalized queue mechanism
that serves two purposes:
- To hold events. A state machine object
can have a queue onto
which events are queued to be handled by the
current state. If the event is not handled
by the current state or any of its
parent states, the event is thrown away.
- To hold work. An object then periodically
checks the queue for work to be done. In this
way, the queue mechanism supports a server model.
Study the
uart example below. Note that there is no
state machine in this object. There are, however, two work queues. One
that stores data received from the UART that is pushed onto the
queue in an interrupt service routine (
ISR).
See line 31.
The other stores data to be sent.
See line 26.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| //
|
[MIT] |
|
| // OOSMOS uart Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "uart.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| #include <stdarg.h>
|
|
| |
|
| typedef enum
|
|
| {
|
|
| sendAwaitingCharToSend_State,
|
|
| sendAwaitingReady_State,
|
|
| sendAwaitingComplete_State
|
|
| } eSendStates;
|
|
| |
|
| struct uartTag
|
|
| {
|
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| |
|
| oosmos_sQueue m_SendDataQueue;
|
|
| uint8_t m_SendDataQueueData[200];
|
|
| eSendStates m_SendState;
|
|
| uint8_t m_CharToSend;
|
|
| |
|
| oosmos_sQueue m_ReceiveDataQueue;
|
|
| uint8_t m_ReceiveDataQueueData[10];
|
|
| oosmos_sSubscriberList m_ReceivedByteEventSubscribers[1];
|
|
| |
|
| uint8_t m_PlibUartID;
|
|
| uint8_t m_UartModule;
|
|
| };
|
|
| |
|
| #if defined _UART6
|
[...] |
|
| #define MaxUARTS 6
|
|
| #elif defined _UART5
|
|
| #define MaxUARTS 5
|
|
| #elif defined _UART4
|
|
| #define MaxUARTS 4
|
|
| #elif defined _UART3
|
|
| #define MaxUARTS 3
|
|
| #elif defined _UART2
|
|
| #define MaxUARTS 2
|
|
| #elif defined _UART1
|
|
| #define MaxUARTS 1
|
|
| #endif
|
|
| |
|
| static uart UartList[MaxUARTS];
|
|
| static unsigned UartCount;
|
|
| |
|
| static const unsigned UartIndex_to_PlibUartId[] =
|
|
| {
|
|
| #ifdef _UART1
|
|
| UART1,
|
|
| #endif
|
|
| #ifdef _UART2
|
|
| UART2,
|
|
| #endif
|
|
| #ifdef _UART3
|
|
| UART3,
|
|
| #endif
|
|
| #ifdef _UART4
|
|
| UART4,
|
|
| #endif
|
|
| #ifdef _UART5
|
|
| UART5,
|
|
| #endif
|
|
| #ifdef _UART6
|
|
| UART6,
|
|
| #endif
|
|
| };
|
|
| |
|
| static void EnableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_ENABLED);
|
|
| }
|
|
| |
|
| static void DisableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_DISABLED);
|
|
| }
|
|
| |
|
| static uint16_t GetPriorityBits(const unsigned PriorityNumber)
|
|
| {
|
|
| switch (PriorityNumber) {
|
|
| case 1: return INT_PRIORITY_LEVEL_1;
|
|
| case 2: return INT_PRIORITY_LEVEL_2;
|
|
| case 3: return INT_PRIORITY_LEVEL_3;
|
|
| case 4: return INT_PRIORITY_LEVEL_4;
|
|
| case 5: return INT_PRIORITY_LEVEL_5;
|
|
| case 6: return INT_PRIORITY_LEVEL_6;
|
|
| case 7: return INT_PRIORITY_LEVEL_7;
|
|
| default: oosmos_FOREVER();
|
|
| }
|
|
| }
|
|
| |
|
| static void RunReceiverStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| uint8_t Byte;
|
|
| |
|
| DisableInterrupt(pUART);
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| EnableInterrupt(pUART);
|
|
| |
|
| if (PopSuccess) {
|
|
| uart_sReceivedByteEvent ReceivedByteEvent = { oosmos_EMPTY_EVENT, Byte };
|
|
| oosmos_SubscriberListNotifyWithArgs(pUART->m_ReceivedByteEventSubscribers, ReceivedByteEvent);
|
|
| }
|
|
| }
|
|
| |
|
| static void RunSenderStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| |
|
| switch (pUART->m_SendState) {
|
|
| case sendAwaitingCharToSend_State: {
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_SendDataQueue, &pUART->m_CharToSend, sizeof(pUART->m_CharToSend));
|
|
| |
|
| if (PopSuccess)
|
|
| pUART->m_SendState = sendAwaitingReady_State;
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingReady_State: {
|
|
| if (UARTTransmitterIsReady(pUART->m_PlibUartID)) {
|
|
| UARTSendDataByte(pUART->m_PlibUartID, pUART->m_CharToSend);
|
|
| pUART->m_SendState = sendAwaitingComplete_State;
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingComplete_State: {
|
|
| if (UARTTransmissionHasCompleted(pUART->m_PlibUartID))
|
|
| pUART->m_SendState = sendAwaitingCharToSend_State;
|
|
| |
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
| |
|
| static void RunStateMachine(void * pObject)
|
|
| {
|
|
| RunSenderStateMachine(pObject);
|
|
| RunReceiverStateMachine(pObject);
|
|
| }
|
|
| |
|
| static void ISR(const unsigned UartModule)
|
|
| {
|
|
| uart * pUART = UartList;
|
|
| |
|
| for (unsigned Count = 1; Count <= UartCount; pUART++, Count++) {
|
|
| if (UartModule <= pUART->m_UartModule) {
|
|
| break;
|
|
| }
|
|
| }
|
|
| |
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| if (INTGetFlag(INT_SOURCE_UART_RX(PlibUartId))) {
|
|
| while (UARTReceivedDataIsAvailable(PlibUartId)) {
|
|
| const uint8_t Byte = UARTGetDataByte(PlibUartId);
|
|
| oosmos_QueuePush(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| }
|
|
| |
|
| INTClearFlag(INT_SOURCE_UART_RX(PlibUartId));
|
|
| }
|
|
| }
|
|
| |
|
| static uint32_t GetPeripheralClock(void)
|
|
| {
|
|
| return (oosmos_GetClockSpeedInMHz()*1000000) / (1 << OSCCONbits.PBDIV);
|
|
| }
|
|
| |
|
| extern void uartPrintf(uart * pUART, const char * pFormat, ...)
|
|
| {
|
|
| char Buffer[100];
|
|
| va_list ArgList;
|
|
| |
|
| va_start(ArgList, pFormat);
|
|
| vsprintf(Buffer, pFormat, ArgList);
|
|
| uartSendString(pUART, Buffer);
|
|
| }
|
|
| |
|
| extern void uartSendChar(uart * pUART, const char Char)
|
|
| {
|
|
| oosmos_QueuePush(&pUART->m_SendDataQueue, &Char, sizeof(Char));
|
|
| }
|
|
| |
|
| extern void uartSendString(uart * pUART, const char * pString)
|
|
| {
|
|
| uint8_t Char;
|
|
| |
|
| while (Char = *pString++, Char) {
|
|
| uartSendChar(pUART, Char);
|
|
| }
|
|
| }
|
|
| |
|
| extern void uartStart(uart * pUART)
|
|
| {
|
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| UARTEnable(PlibUartId, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
|
|
| EnableInterrupt(pUART);
|
|
| }
|
|
| |
|
| //
|
|
| // 'UartModule' is 1, 2, etc.
|
|
| //
|
|
| extern uart * uartNew(const unsigned UartModule, const unsigned BaudRate)
|
|
| {
|
|
| oosmos_AllocateVisible(pUART, uart, UartList, UartCount, MaxUARTS, NULL);
|
|
| |
|
| pUART->m_UartModule = UartModule;
|
|
| |
|
| const unsigned PlibUartID = UartIndex_to_PlibUartId[UartModule-1];
|
|
| pUART->m_PlibUartID = PlibUartID;
|
|
| |
|
| UARTConfigure(PlibUartID, UART_ENABLE_PINS_TX_RX_ONLY);
|
|
| UARTSetFifoMode(PlibUartID, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
|
|
| UARTSetLineControl(PlibUartID, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
|
|
| UARTSetDataRate(PlibUartID, GetPeripheralClock(), BaudRate);
|
|
| |
|
| const unsigned Priority = 1;
|
|
| INTSetVectorPriority(INT_VECTOR_UART(PlibUartID), GetPriorityBits(Priority));
|
|
| INTSetVectorSubPriority(INT_VECTOR_UART(PlibUartID), INT_SUB_PRIORITY_LEVEL_0);
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_SendDataQueue, pUART->m_SendDataQueueData, sizeof(pUART->m_SendDataQueueData), sizeof(uint8_t));
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData, sizeof(pUART->m_ReceiveDataQueueData), sizeof(uint8_t));
|
|
| oosmos_SubscriberListInit(pUART->m_ReceivedByteEventSubscribers);
|
|
| |
|
| oosmos_ActiveObjectInit(pUART, m_ActiveObject, RunStateMachine);
|
|
| |
|
| return pUART;
|
|
| }
|
|
| |
|
| extern void uartSubscribe(uart * pUART, oosmos_sQueue * pQueue, const int EventCode, void * pContext)
|
|
| {
|
|
| oosmos_SubscriberListAdd(pUART->m_ReceivedByteEventSubscribers, pQueue, EventCode, pContext);
|
|
| }
|
|
| |
|
| #define uartVector(N) void __ISR(_UART_##N##_VECTOR) IntUart##N##Handler() { ISR(N); }
|
|
| |
|
| #ifdef _UART1
|
|
| uartVector(1)
|
|
| #endif
|
|
| |
|
| #ifdef _UART2
|
|
| uartVector(2)
|
|
| #endif
|
|
| |
|
| #ifdef _UART3
|
|
| uartVector(3)
|
|
| #endif
|
|
| |
|
| #ifdef _UART4
|
|
| uartVector(4)
|
|
| #endif
|
|
| |
|
| #ifdef _UART5
|
|
| uartVector(5)
|
|
| #endif
|
|
| |
|
| #ifdef _UART6
|
|
| uartVector(6)
|
|
| #endif
|
|
oosmos/Classes/PIC32/uart.c
oosmos_sState
oosmos_sState is a data type that holds state metadata and is never used directly - only contained by
other OOSMOS state types.
oosmos_sStateMachine
oosmos_sStateMachine declares the
state machine in your
OOSMOS object. It also
preallocates the object's event queue.
See line 37 in the code snippet
below for an example.
StateMachine |
The name of the state machine. Must always
be ROOT: the OOSMOS object macros
(oosmos_PushEventCode, oosmos_IsInState,
oosmos_RunStateMachine, etc.) refer to the state
machine member by that name.
|
EventType |
Datatype of elements queued to the event queue. Can be a
union of other types.
|
MaxEvents |
The maximum number of elements that the event queue can hold.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| //
|
[MIT] |
|
| // OOSMOS EnterExit Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evTweak = 1
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evTweak: return "evTweak";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Active_State;
|
|
| oosmos_sOrthoRegion Active_Region1_State;
|
|
| oosmos_sLeaf Active_Region1_Moving_State;
|
|
| oosmos_sOrthoRegion Active_Region2_State;
|
|
| oosmos_sComposite Active_Region2_Outer_State;
|
|
| oosmos_sLeaf Active_Region2_Outer_Inner_State;
|
|
| oosmos_sOrthoRegion Active_Region3_State;
|
|
| oosmos_sLeaf Active_Region3_Leaf_State;
|
|
| oosmos_sLeaf Active_Region3_Running_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool Active_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evTweak: {
|
|
| return oosmos_Transition(pTest, pState, Active_Region2_Outer_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Active_Region3_Leaf_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Active_Region3_Running_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pTest, ROOT, NULL, Active_State);
|
|
| oosmos_OrthoInit(pTest, Active_State, ROOT, Active_State_Code);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region1_State, Active_State, Active_Region1_Moving_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region1_Moving_State, Active_Region1_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region2_State, Active_State, Active_Region2_Outer_State, NULL);
|
|
| oosmos_CompositeInit(pTest, Active_Region2_Outer_State, Active_Region2_State, Active_Region2_Outer_Inner_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region2_Outer_Inner_State, Active_Region2_Outer_State, NULL);
|
|
| oosmos_OrthoRegionInit(pTest, Active_Region3_State, Active_State, Active_Region3_Leaf_State, NULL);
|
|
| oosmos_LeafInit(pTest, Active_Region3_Leaf_State, Active_Region3_State, Active_Region3_Leaf_State_Code);
|
|
| oosmos_LeafInit(pTest, Active_Region3_Running_State, Active_Region3_State, NULL);
|
|
| |
|
| oosmos_Debug(pTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| static void QueueEventRoutine(const test * pTest, int EventCode)
|
|
| {
|
|
| oosmos_PushEventCode(pTest, EventCode);
|
|
| oosmos_RunStateMachines();
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| QueueEventRoutine(pTest, evTweak);
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Active_Region2_Outer_Inner_State)) {
|
|
| printf("SUCCESS\n");
|
|
| } else {
|
|
| printf("FAILURE\n");
|
|
| }
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Ortho/Windows/EnterExit.c
oosmos_sStateMachineNoQueue
oosmos_sStateMachineNoQueue declares the
state machine
in
your
OOSMOS object. Use this form when
your object will not accept events.
See line 22 in the code snippet
below for an example.
StateMachine |
The name of the state machine. Must always
be ROOT: the OOSMOS object macros
(oosmos_PushEventCode, oosmos_IsInState,
oosmos_RunStateMachine, etc.) refer to the state
machine member by that name.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "toggle.h"
|
|
| #include "pin.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stddef.h>
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 4
|
|
| #endif
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Off_State;
|
|
| oosmos_sLeaf On_State;
|
|
| //<<<DECL
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool Off_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOffMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, On_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool On_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pinOn(pToggle->m_pPin);
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOnMS);
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pinOff(pToggle->m_pPin);
|
|
| return true;
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, Off_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pToggle, ROOT, NULL, On_State);
|
|
| oosmos_LeafInit(pToggle, Off_State, ROOT, Off_State_Code);
|
|
| oosmos_LeafInit(pToggle, On_State, ROOT, On_State_Code);
|
|
| //<<<INIT
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle_state.c
oosmos_sSubscriberList
oosmos_sSubscriberList is a data type that holds a
list of subscribers interested in the occurrence of a
particular event.
See lines
40 and
41 of the code snippet below for examples.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| //
|
[MIT] |
|
| // OOSMOS sw Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef swMaxSwitches
|
[...] |
|
| #define swMaxSwitches 20
|
|
| #endif
|
|
| |
|
| #ifndef swMaxCloseSubscribers
|
|
| #define swMaxCloseSubscribers 1
|
|
| #endif
|
|
| |
|
| #ifndef swMaxOpenSubscribers
|
|
| #define swMaxOpenSubscribers 1
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "sw.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| |
|
| typedef enum {
|
|
| Unknown_State = 1,
|
|
| Open_State,
|
|
| Closed_State
|
|
| } eStates;
|
|
| |
|
| struct swTag
|
|
| {
|
|
| pin * m_pPin;
|
|
| eStates m_State;
|
|
| |
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| oosmos_sSubscriberList m_CloseEvent[swMaxCloseSubscribers];
|
|
| oosmos_sSubscriberList m_OpenEvent[swMaxOpenSubscribers];
|
|
| };
|
|
| |
|
| extern sw * swNewDetached(pin * pPin)
|
[...] |
|
| {
|
|
| oosmos_Allocate(pSwitch, sw, swMaxSwitches, NULL);
|
|
| |
|
| pSwitch->m_pPin = pPin;
|
|
| pSwitch->m_State = Unknown_State;
|
|
| |
|
| oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
| oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern sw * swNew(pin * pPin)
|
|
| {
|
|
| sw * pSwitch = swNewDetached(pPin);
|
|
| |
|
| oosmos_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern void swSubscribeCloseEvent(sw * pSwitch, oosmos_sQueue * pQueue, int CloseEventCode, void * pContext)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_CloseEvent, pQueue, CloseEventCode, pContext);
|
|
| }
|
|
| |
|
| extern void swSubscribeOpenEvent(sw * pSwitch, oosmos_sQueue * pQueue, int OpenEventCode, void * pContext)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_OpenEvent, pQueue, OpenEventCode, pContext);
|
|
| }
|
|
| |
|
| static eStates PhysicalSwitchState(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| return pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| }
|
|
| |
|
| extern bool swIsOpen(const sw * pSwitch)
|
|
| {
|
|
| return !swIsClosed(pSwitch);
|
|
| }
|
|
| |
|
| extern bool swIsClosed(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| if (pSwitch->m_State == Unknown_State) {
|
|
| return PhysicalSwitchState(pSwitch) == Closed_State;
|
|
| }
|
|
| |
|
| return pSwitch->m_State == Closed_State;
|
|
| }
|
|
| |
|
| extern void swRunStateMachine(sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| switch (pSwitch->m_State) {
|
|
| case Open_State: {
|
|
| if (pinIsOn(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Closed_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_CloseEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Closed_State: {
|
|
| if (pinIsOff(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Open_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_OpenEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Unknown_State: {
|
|
| pSwitch->m_State = pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
oosmos_StateMachineDetach
oosmos_StateMachineDetach detaches the object's
state machine from the list of state machines run by
oosmos_RunStateMachines. Useful when an object
reaches its end of life, for example upon entry to a final state.
| 1 |
| 2 |
| 3 |
| |
|
| void oosmos_StateMachineDetach(pObject, StateMachine); |
|
| |
|
Prototype
pObject |
The address of the object that contains the state machine.
|
StateMachine |
The name of the state machine. Must always be ROOT.
|
See Also |
|
oosmos_StateMachineInit
oosmos_StateMachineInit initializes an
oosmos_sStateMachine object member.
See line 95 of the code snippet
below for an example.
pObject |
The address of the object that contains the state machine.
|
StateMachine |
The name of the state machine.
|
ParentState |
The name of the parent state. Must always be NULL. This
argument exists for overall state machine initialization readability.
|
DefaultState |
The name of the default state.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| //
|
[MIT] |
|
| // OOSMOS - EventDemo example, motor object
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "motor.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evStart = 1,
|
|
| evStop = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evStart: return "evStart";
|
|
| case evStop: return "evStop";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Event;
|
|
| } uEvents;
|
|
| |
|
| struct motorTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sLeaf Idle_State;
|
|
| oosmos_sLeaf Moving_State;
|
|
| //<<<DECL
|
|
| };
|
|
| |
|
| #ifndef motorMAX
|
|
| #define motorMAX 3
|
|
| #endif
|
|
| |
|
| static void MovingThread(oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| printf("motor: MOVING...\n");
|
|
| oosmos_ThreadDelayMS(500);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool Idle_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motor * pMotor = (motor *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evStart: {
|
|
| return oosmos_Transition(pMotor, pState, Moving_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Moving_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| motor * pMotor = (motor *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| MovingThread(pState);
|
|
| return true;
|
|
| }
|
|
| case evStop: {
|
|
| return oosmos_Transition(pMotor, pState, Idle_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern motor * motorNew(void)
|
|
| {
|
|
| oosmos_Allocate(pMotor, motor, motorMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pMotor, ROOT, NULL, Idle_State);
|
|
| oosmos_LeafInit(pMotor, Idle_State, ROOT, Idle_State_Code);
|
|
| oosmos_LeafInit(pMotor, Moving_State, ROOT, Moving_State_Code);
|
|
| |
|
| oosmos_Debug(pMotor, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pMotor;
|
|
| }
|
|
| |
|
| extern void motorOn(const motor * pMotor)
|
[...] |
|
| {
|
|
| oosmos_PushEventCode(pMotor, evStart);
|
|
| }
|
|
| |
|
| extern void motorOff(const motor * pMotor)
|
|
| {
|
|
| oosmos_PushEventCode(pMotor, evStop);
|
|
| }
|
|
oosmos/Examples/EventDemo/Windows/motor.c
oosmos_StateMachineInitNoQueue
oosmos_StateMachineInitNoQueue initializes an
oosmos_sStateMachineNoQueue object member.
See line 76 of the code snippet
below for an example.
pObject |
The address of the object that contains the state machine.
|
StateMachine |
The name of the state machine.
|
ParentState |
The name of the parent state. Must always be NULL. This
argument exists for overall state machine initialization readability.
|
DefaultState |
The name of the default state.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "toggle.h"
|
|
| #include "pin.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stddef.h>
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 4
|
|
| #endif
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Off_State;
|
|
| oosmos_sLeaf On_State;
|
|
| //<<<DECL
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Off_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOffMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, On_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool On_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pinOn(pToggle->m_pPin);
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOnMS);
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pinOff(pToggle->m_pPin);
|
|
| return true;
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, Off_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pToggle, ROOT, NULL, On_State);
|
|
| oosmos_LeafInit(pToggle, Off_State, ROOT, Off_State_Code);
|
|
| oosmos_LeafInit(pToggle, On_State, ROOT, On_State_Code);
|
|
| //<<<INIT
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle_state.c
oosmos_StateTimeoutMS
oosmos_StateTimeoutMS is used to set a state's
timeout value. If another event or condition does not
transition you out of the current state before the
number of milliseconds in your timeout value elapses, then an
oosmos_TIMEOUT event will be delivered to
the current state's event handler.
You will typically set your state's timeout value upon
entry to the state in the
oosmos_ENTER
event action.
See
StateTimeout.c, below,
line 37 for an example
of setting the timeout and
line 39 for an example of an
oosmos_TIMEOUT event handler.
pState |
The same pState
argument that was passed into the containing state handler.
|
Milliseconds |
The timeout value in milliseconds.
|
RETURN |
Always returns true.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| //
|
[MIT] |
|
| // OOSMOS StateTimeout Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf MS_State;
|
|
| oosmos_sLeaf Seconds_State;
|
|
| oosmos_sLeaf US_State;
|
|
| oosmos_sLeaf Done_State;
|
|
| //<<<DECL
|
|
| unsigned m_TimeMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool MS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pTest->m_TimeMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, Seconds_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Seconds_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
[...] |
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutSeconds(pState, (uint32_t) 1);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, US_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool US_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutUS(pState, (uint32_t) 100000);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, Done_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, MS_State);
|
|
| oosmos_LeafInit(pTest, MS_State, ROOT, MS_State_Code);
|
|
| oosmos_LeafInit(pTest, Seconds_State, ROOT, Seconds_State_Code);
|
|
| oosmos_LeafInit(pTest, US_State, ROOT, US_State_Code);
|
|
| oosmos_LeafInit(pTest, Done_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| pTest->m_TimeMS = 1000;
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Done_State)) {
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/StateTimeout.c
oosmos_StateTimeoutSeconds
oosmos_StateTimeoutSeconds is used to set a state's
timeout value. If another event or condition does not
transition you out of the current state before the
number of seconds in your timeout value elapses, then an
oosmos_TIMEOUT event will be delivered to
the current state's event handler.
You will typically set your state's timeout value upon
entry to the state in the
oosmos_ENTER
event action.
See
StateTimeout.c, below,
line 53 for an example
of setting the timeout and
line 55 for an example of an
oosmos_TIMEOUT event handler.
pState |
The same pState
argument that was passed into the containing state handler.
|
Seconds |
The timeout value in seconds.
|
RETURN |
Always returns true.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| //
|
[MIT] |
|
| // OOSMOS StateTimeout Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf MS_State;
|
|
| oosmos_sLeaf Seconds_State;
|
|
| oosmos_sLeaf US_State;
|
|
| oosmos_sLeaf Done_State;
|
|
| //<<<DECL
|
|
| unsigned m_TimeMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool MS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pTest->m_TimeMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, Seconds_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Seconds_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutSeconds(pState, (uint32_t) 1);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, US_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool US_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
[...] |
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutUS(pState, (uint32_t) 100000);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, Done_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, MS_State);
|
|
| oosmos_LeafInit(pTest, MS_State, ROOT, MS_State_Code);
|
|
| oosmos_LeafInit(pTest, Seconds_State, ROOT, Seconds_State_Code);
|
|
| oosmos_LeafInit(pTest, US_State, ROOT, US_State_Code);
|
|
| oosmos_LeafInit(pTest, Done_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| pTest->m_TimeMS = 1000;
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Done_State)) {
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/StateTimeout.c
oosmos_StateTimeoutUS
oosmos_StateTimeoutUS is used to set a state's
timeout value. If another event or condition does not
transition you out of the current state before the
number of microseconds in your timeout value elapses, then an
oosmos_TIMEOUT event will be delivered to
the current state's event handler.
You will typically set your state's timeout value upon
entry to the state in the
oosmos_ENTER
event action.
See
StateTimeout.c, below,
line 69 for an example
of setting the timeout and
line 71 for an example of an
oosmos_TIMEOUT event handler.
pState |
The same pState
argument that was passed into the containing state handler.
|
Microseconds |
The timeout value in microseconds.
|
RETURN |
Always returns true.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| //
|
[MIT] |
|
| // OOSMOS StateTimeout Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf MS_State;
|
|
| oosmos_sLeaf Seconds_State;
|
|
| oosmos_sLeaf US_State;
|
|
| oosmos_sLeaf Done_State;
|
|
| //<<<DECL
|
|
| unsigned m_TimeMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool MS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pTest->m_TimeMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, Seconds_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Seconds_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutSeconds(pState, (uint32_t) 1);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, US_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool US_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutUS(pState, (uint32_t) 100000);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, Done_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
[...] |
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, MS_State);
|
|
| oosmos_LeafInit(pTest, MS_State, ROOT, MS_State_Code);
|
|
| oosmos_LeafInit(pTest, Seconds_State, ROOT, Seconds_State_Code);
|
|
| oosmos_LeafInit(pTest, US_State, ROOT, US_State_Code);
|
|
| oosmos_LeafInit(pTest, Done_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| pTest->m_TimeMS = 1000;
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Done_State)) {
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/StateTimeout.c
oosmos_sTimeout
oosmos_sTimeout is a data type that holds timeout metadata
supporting the
oosmos_TimeoutInSeconds call. See
line 19, line 24 and
line 32 in the snippet for an example of use.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| //
|
[MIT] |
|
| // OOSMOS TimeoutInSeconds Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| static const uint32_t WaitTimeSeconds = 2;
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| //
|
|
| // Allocate a Timeout object.
|
|
| //
|
|
| oosmos_sTimeout Timeout;
|
|
| |
|
| //
|
|
| // Set timeout.
|
|
| //
|
|
| oosmos_TimeoutInSeconds(&Timeout, WaitTimeSeconds);
|
|
| |
|
| printf("Waiting for %lu seconds...\n", (unsigned long) WaitTimeSeconds);
|
|
| |
|
| for (;;) {
|
|
| //
|
|
| // Check if the time has expired.
|
|
| //
|
|
| if (oosmos_TimeoutHasExpired(&Timeout)) {
|
|
| break;
|
|
| }
|
|
| |
|
| //
|
|
| // Be polite. Prevent 100% CPU usage on multi-tasked
|
|
| // machines (e.g. Windows or Linux).
|
|
| //
|
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/TimeoutInSeconds.c
oosmos_SubscriberListAdd
Publishers notify subscribers of events that occur within the publisher's
object.
oosmos_SubscriberListAdd is called within
the publisher's implementation file to add a subscriber to the list
of subscribers interested in the occurrence of a particular event.
See lines 40 and
51,
70 and 111 in the code snippet below for an example.
SubscriberList |
The oosmos_sSubscriberList array member inside an
OOSMOS object. Must be the array itself, not a
pointer to it — the macro computes the number of elements
from the array.
|
pNotifyQueue |
Points to the queue of the subscriber onto which published events
will be pushed.
|
EventCode |
When the associated event occurs within a publisher, the publisher
should post this event code to the subscriber's event queue.
Note that the event code is defined within the subscriber's
object, not the publisher's.
|
pContext |
A pointer to some type of context information that a notified
subscriber can use in any way. Can be NULL.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| //
|
[MIT] |
|
| // OOSMOS sw Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef swMaxSwitches
|
[...] |
|
| #define swMaxSwitches 20
|
|
| #endif
|
|
| |
|
| #ifndef swMaxCloseSubscribers
|
|
| #define swMaxCloseSubscribers 1
|
|
| #endif
|
|
| |
|
| #ifndef swMaxOpenSubscribers
|
|
| #define swMaxOpenSubscribers 1
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "sw.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| |
|
| typedef enum {
|
|
| Unknown_State = 1,
|
|
| Open_State,
|
|
| Closed_State
|
|
| } eStates;
|
|
| |
|
| struct swTag
|
|
| {
|
|
| pin * m_pPin;
|
|
| eStates m_State;
|
|
| |
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| oosmos_sSubscriberList m_CloseEvent[swMaxCloseSubscribers];
|
|
| oosmos_sSubscriberList m_OpenEvent[swMaxOpenSubscribers];
|
|
| };
|
|
| |
|
| extern sw * swNewDetached(pin * pPin)
|
|
| {
|
|
| oosmos_Allocate(pSwitch, sw, swMaxSwitches, NULL);
|
|
| |
|
| pSwitch->m_pPin = pPin;
|
|
| pSwitch->m_State = Unknown_State;
|
|
| |
|
| oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
| oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern sw * swNew(pin * pPin)
|
[...] |
|
| {
|
|
| sw * pSwitch = swNewDetached(pPin);
|
|
| |
|
| oosmos_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern void swSubscribeCloseEvent(sw * pSwitch, oosmos_sQueue * pQueue, int CloseEventCode, void * pContext)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_CloseEvent, pQueue, CloseEventCode, pContext);
|
|
| }
|
|
| |
|
| extern void swSubscribeOpenEvent(sw * pSwitch, oosmos_sQueue * pQueue, int OpenEventCode, void * pContext)
|
[...] |
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_OpenEvent, pQueue, OpenEventCode, pContext);
|
|
| }
|
|
| |
|
| static eStates PhysicalSwitchState(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| return pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| }
|
|
| |
|
| extern bool swIsOpen(const sw * pSwitch)
|
|
| {
|
|
| return !swIsClosed(pSwitch);
|
|
| }
|
|
| |
|
| extern bool swIsClosed(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| if (pSwitch->m_State == Unknown_State) {
|
|
| return PhysicalSwitchState(pSwitch) == Closed_State;
|
|
| }
|
|
| |
|
| return pSwitch->m_State == Closed_State;
|
|
| }
|
|
| |
|
| extern void swRunStateMachine(sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| switch (pSwitch->m_State) {
|
|
| case Open_State: {
|
|
| if (pinIsOn(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Closed_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_CloseEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Closed_State: {
|
|
| if (pinIsOff(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Open_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_OpenEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Unknown_State: {
|
|
| pSwitch->m_State = pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
oosmos_SubscriberListInit
oosmos_SubscriberListInit initializes a subscriber
list. Subscriber lists are stored within the publisher's object.
See lines 40 and
51,
70 and 111 in the code snippet below for an example.
SubscriberList |
The oosmos_sSubscriberList array member inside an
OOSMOS object. Must be the array itself, not a
pointer to it — the macro computes the number of elements
from the array.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| //
|
[MIT] |
|
| // OOSMOS sw Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef swMaxSwitches
|
[...] |
|
| #define swMaxSwitches 20
|
|
| #endif
|
|
| |
|
| #ifndef swMaxCloseSubscribers
|
|
| #define swMaxCloseSubscribers 1
|
|
| #endif
|
|
| |
|
| #ifndef swMaxOpenSubscribers
|
|
| #define swMaxOpenSubscribers 1
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "sw.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| |
|
| typedef enum {
|
|
| Unknown_State = 1,
|
|
| Open_State,
|
|
| Closed_State
|
|
| } eStates;
|
|
| |
|
| struct swTag
|
|
| {
|
|
| pin * m_pPin;
|
|
| eStates m_State;
|
|
| |
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| oosmos_sSubscriberList m_CloseEvent[swMaxCloseSubscribers];
|
|
| oosmos_sSubscriberList m_OpenEvent[swMaxOpenSubscribers];
|
|
| };
|
|
| |
|
| extern sw * swNewDetached(pin * pPin)
|
|
| {
|
|
| oosmos_Allocate(pSwitch, sw, swMaxSwitches, NULL);
|
|
| |
|
| pSwitch->m_pPin = pPin;
|
|
| pSwitch->m_State = Unknown_State;
|
|
| |
|
| oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
| oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern sw * swNew(pin * pPin)
|
[...] |
|
| {
|
|
| sw * pSwitch = swNewDetached(pPin);
|
|
| |
|
| oosmos_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern void swSubscribeCloseEvent(sw * pSwitch, oosmos_sQueue * pQueue, int CloseEventCode, void * pContext)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_CloseEvent, pQueue, CloseEventCode, pContext);
|
|
| }
|
|
| |
|
| extern void swSubscribeOpenEvent(sw * pSwitch, oosmos_sQueue * pQueue, int OpenEventCode, void * pContext)
|
[...] |
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_OpenEvent, pQueue, OpenEventCode, pContext);
|
|
| }
|
|
| |
|
| static eStates PhysicalSwitchState(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| return pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| }
|
|
| |
|
| extern bool swIsOpen(const sw * pSwitch)
|
|
| {
|
|
| return !swIsClosed(pSwitch);
|
|
| }
|
|
| |
|
| extern bool swIsClosed(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| if (pSwitch->m_State == Unknown_State) {
|
|
| return PhysicalSwitchState(pSwitch) == Closed_State;
|
|
| }
|
|
| |
|
| return pSwitch->m_State == Closed_State;
|
|
| }
|
|
| |
|
| extern void swRunStateMachine(sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| switch (pSwitch->m_State) {
|
|
| case Open_State: {
|
|
| if (pinIsOn(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Closed_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_CloseEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Closed_State: {
|
|
| if (pinIsOff(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Open_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_OpenEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Unknown_State: {
|
|
| pSwitch->m_State = pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
oosmos_SubscriberListNotify
Called by a publisher,
oosmos_SubscriberListNotify
notifies all subscribers of the occurrence of an event.
See lines 40 and
51,
70 and 111 in the code snippet below for an example.
SubscriberList |
The oosmos_sSubscriberList array member inside an
OOSMOS object. Must be the array itself, not a
pointer to it — the macro computes the number of elements
from the array.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| //
|
[MIT] |
|
| // OOSMOS sw Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef swMaxSwitches
|
[...] |
|
| #define swMaxSwitches 20
|
|
| #endif
|
|
| |
|
| #ifndef swMaxCloseSubscribers
|
|
| #define swMaxCloseSubscribers 1
|
|
| #endif
|
|
| |
|
| #ifndef swMaxOpenSubscribers
|
|
| #define swMaxOpenSubscribers 1
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "sw.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| |
|
| typedef enum {
|
|
| Unknown_State = 1,
|
|
| Open_State,
|
|
| Closed_State
|
|
| } eStates;
|
|
| |
|
| struct swTag
|
|
| {
|
|
| pin * m_pPin;
|
|
| eStates m_State;
|
|
| |
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| oosmos_sSubscriberList m_CloseEvent[swMaxCloseSubscribers];
|
|
| oosmos_sSubscriberList m_OpenEvent[swMaxOpenSubscribers];
|
|
| };
|
|
| |
|
| extern sw * swNewDetached(pin * pPin)
|
|
| {
|
|
| oosmos_Allocate(pSwitch, sw, swMaxSwitches, NULL);
|
|
| |
|
| pSwitch->m_pPin = pPin;
|
|
| pSwitch->m_State = Unknown_State;
|
|
| |
|
| oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
| oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern sw * swNew(pin * pPin)
|
[...] |
|
| {
|
|
| sw * pSwitch = swNewDetached(pPin);
|
|
| |
|
| oosmos_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
| |
|
| return pSwitch;
|
|
| }
|
|
| |
|
| extern void swSubscribeCloseEvent(sw * pSwitch, oosmos_sQueue * pQueue, int CloseEventCode, void * pContext)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_CloseEvent, pQueue, CloseEventCode, pContext);
|
|
| }
|
|
| |
|
| extern void swSubscribeOpenEvent(sw * pSwitch, oosmos_sQueue * pQueue, int OpenEventCode, void * pContext)
|
[...] |
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| oosmos_SubscriberListAdd(pSwitch->m_OpenEvent, pQueue, OpenEventCode, pContext);
|
|
| }
|
|
| |
|
| static eStates PhysicalSwitchState(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| return pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| }
|
|
| |
|
| extern bool swIsOpen(const sw * pSwitch)
|
|
| {
|
|
| return !swIsClosed(pSwitch);
|
|
| }
|
|
| |
|
| extern bool swIsClosed(const sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| if (pSwitch->m_State == Unknown_State) {
|
|
| return PhysicalSwitchState(pSwitch) == Closed_State;
|
|
| }
|
|
| |
|
| return pSwitch->m_State == Closed_State;
|
|
| }
|
|
| |
|
| extern void swRunStateMachine(sw * pSwitch)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pSwitch);
|
|
| |
|
| switch (pSwitch->m_State) {
|
|
| case Open_State: {
|
|
| if (pinIsOn(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Closed_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_CloseEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Closed_State: {
|
|
| if (pinIsOff(pSwitch->m_pPin)) {
|
|
| pSwitch->m_State = Open_State;
|
|
| oosmos_SubscriberListNotify(pSwitch->m_OpenEvent);
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case Unknown_State: {
|
|
| pSwitch->m_State = pinIsOn(pSwitch->m_pPin) ? Closed_State : Open_State;
|
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
oosmos_SubscriberListNotifyWithArgs
Called by a publisher,
oosmos_SubscriberListNotifyWithArgs
notifies all subscribers of the occurrence of an event and passes
additional arguments that the subscriber can use.
See line 113 in the code snippet below
for an example.
SubscriberList |
The oosmos_sSubscriberList array member inside an
OOSMOS object. Must be the array itself, not a
pointer to it — the macro computes the number of elements
from the array.
|
Event |
The event to publish, passed by name, not by address — the
macro takes the event's address and size itself. Can be a
user-defined event structure whose first member is an
oosmos_sEvent.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| //
|
[MIT] |
|
| // OOSMOS uart Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "uart.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| #include <stdarg.h>
|
|
| |
|
| typedef enum
|
|
| {
|
|
| sendAwaitingCharToSend_State,
|
|
| sendAwaitingReady_State,
|
|
| sendAwaitingComplete_State
|
|
| } eSendStates;
|
|
| |
|
| struct uartTag
|
|
| {
|
|
| oosmos_sActiveObject m_ActiveObject;
|
|
| |
|
| oosmos_sQueue m_SendDataQueue;
|
|
| uint8_t m_SendDataQueueData[200];
|
|
| eSendStates m_SendState;
|
|
| uint8_t m_CharToSend;
|
|
| |
|
| oosmos_sQueue m_ReceiveDataQueue;
|
|
| uint8_t m_ReceiveDataQueueData[10];
|
|
| oosmos_sSubscriberList m_ReceivedByteEventSubscribers[1];
|
|
| |
|
| uint8_t m_PlibUartID;
|
|
| uint8_t m_UartModule;
|
|
| };
|
|
| |
|
| #if defined _UART6
|
|
| #define MaxUARTS 6
|
|
| #elif defined _UART5
|
|
| #define MaxUARTS 5
|
|
| #elif defined _UART4
|
|
| #define MaxUARTS 4
|
|
| #elif defined _UART3
|
|
| #define MaxUARTS 3
|
|
| #elif defined _UART2
|
|
| #define MaxUARTS 2
|
|
| #elif defined _UART1
|
|
| #define MaxUARTS 1
|
|
| #endif
|
|
| |
|
| static uart UartList[MaxUARTS];
|
|
| static unsigned UartCount;
|
|
| |
|
| static const unsigned UartIndex_to_PlibUartId[] =
|
|
| {
|
|
| #ifdef _UART1
|
|
| UART1,
|
|
| #endif
|
|
| #ifdef _UART2
|
|
| UART2,
|
|
| #endif
|
|
| #ifdef _UART3
|
|
| UART3,
|
|
| #endif
|
|
| #ifdef _UART4
|
|
| UART4,
|
|
| #endif
|
|
| #ifdef _UART5
|
|
| UART5,
|
|
| #endif
|
|
| #ifdef _UART6
|
|
| UART6,
|
|
| #endif
|
|
| };
|
|
| |
|
| static void EnableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_ENABLED);
|
|
| }
|
|
| |
|
| static void DisableInterrupt(uart * pUART)
|
|
| {
|
|
| INTEnable(INT_SOURCE_UART_RX(pUART->m_PlibUartID), INT_DISABLED);
|
|
| }
|
|
| |
|
| static uint16_t GetPriorityBits(const unsigned PriorityNumber)
|
|
| {
|
|
| switch (PriorityNumber) {
|
|
| case 1: return INT_PRIORITY_LEVEL_1;
|
|
| case 2: return INT_PRIORITY_LEVEL_2;
|
|
| case 3: return INT_PRIORITY_LEVEL_3;
|
|
| case 4: return INT_PRIORITY_LEVEL_4;
|
|
| case 5: return INT_PRIORITY_LEVEL_5;
|
|
| case 6: return INT_PRIORITY_LEVEL_6;
|
|
| case 7: return INT_PRIORITY_LEVEL_7;
|
|
| default: oosmos_FOREVER();
|
|
| }
|
|
| }
|
|
| |
|
| static void RunReceiverStateMachine(void * pObject)
|
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| uint8_t Byte;
|
|
| |
|
| DisableInterrupt(pUART);
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| EnableInterrupt(pUART);
|
|
| |
|
| if (PopSuccess) {
|
|
| uart_sReceivedByteEvent ReceivedByteEvent = { oosmos_EMPTY_EVENT, Byte };
|
|
| oosmos_SubscriberListNotifyWithArgs(pUART->m_ReceivedByteEventSubscribers, ReceivedByteEvent);
|
|
| }
|
|
| }
|
|
| |
|
| static void RunSenderStateMachine(void * pObject)
|
[...] |
|
| {
|
|
| uart * pUART = (uart *) pObject;
|
|
| |
|
| switch (pUART->m_SendState) {
|
|
| case sendAwaitingCharToSend_State: {
|
|
| const bool PopSuccess = oosmos_QueuePop(&pUART->m_SendDataQueue, &pUART->m_CharToSend, sizeof(pUART->m_CharToSend));
|
|
| |
|
| if (PopSuccess)
|
|
| pUART->m_SendState = sendAwaitingReady_State;
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingReady_State: {
|
|
| if (UARTTransmitterIsReady(pUART->m_PlibUartID)) {
|
|
| UARTSendDataByte(pUART->m_PlibUartID, pUART->m_CharToSend);
|
|
| pUART->m_SendState = sendAwaitingComplete_State;
|
|
| }
|
|
| |
|
| break;
|
|
| }
|
|
| case sendAwaitingComplete_State: {
|
|
| if (UARTTransmissionHasCompleted(pUART->m_PlibUartID))
|
|
| pUART->m_SendState = sendAwaitingCharToSend_State;
|
|
| |
|
| break;
|
|
| }
|
|
| }
|
|
| }
|
|
| |
|
| static void RunStateMachine(void * pObject)
|
|
| {
|
|
| RunSenderStateMachine(pObject);
|
|
| RunReceiverStateMachine(pObject);
|
|
| }
|
|
| |
|
| static void ISR(const unsigned UartModule)
|
|
| {
|
|
| uart * pUART = UartList;
|
|
| |
|
| for (unsigned Count = 1; Count <= UartCount; pUART++, Count++) {
|
|
| if (UartModule <= pUART->m_UartModule) {
|
|
| break;
|
|
| }
|
|
| }
|
|
| |
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| if (INTGetFlag(INT_SOURCE_UART_RX(PlibUartId))) {
|
|
| while (UARTReceivedDataIsAvailable(PlibUartId)) {
|
|
| const uint8_t Byte = UARTGetDataByte(PlibUartId);
|
|
| oosmos_QueuePush(&pUART->m_ReceiveDataQueue, &Byte, sizeof(Byte));
|
|
| }
|
|
| |
|
| INTClearFlag(INT_SOURCE_UART_RX(PlibUartId));
|
|
| }
|
|
| }
|
|
| |
|
| static uint32_t GetPeripheralClock(void)
|
|
| {
|
|
| return (oosmos_GetClockSpeedInMHz()*1000000) / (1 << OSCCONbits.PBDIV);
|
|
| }
|
|
| |
|
| extern void uartPrintf(uart * pUART, const char * pFormat, ...)
|
|
| {
|
|
| char Buffer[100];
|
|
| va_list ArgList;
|
|
| |
|
| va_start(ArgList, pFormat);
|
|
| vsprintf(Buffer, pFormat, ArgList);
|
|
| uartSendString(pUART, Buffer);
|
|
| }
|
|
| |
|
| extern void uartSendChar(uart * pUART, const char Char)
|
|
| {
|
|
| oosmos_QueuePush(&pUART->m_SendDataQueue, &Char, sizeof(Char));
|
|
| }
|
|
| |
|
| extern void uartSendString(uart * pUART, const char * pString)
|
|
| {
|
|
| uint8_t Char;
|
|
| |
|
| while (Char = *pString++, Char) {
|
|
| uartSendChar(pUART, Char);
|
|
| }
|
|
| }
|
|
| |
|
| extern void uartStart(uart * pUART)
|
|
| {
|
|
| const unsigned PlibUartId = pUART->m_PlibUartID;
|
|
| |
|
| UARTEnable(PlibUartId, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
|
|
| EnableInterrupt(pUART);
|
|
| }
|
|
| |
|
| //
|
|
| // 'UartModule' is 1, 2, etc.
|
|
| //
|
|
| extern uart * uartNew(const unsigned UartModule, const unsigned BaudRate)
|
|
| {
|
|
| oosmos_AllocateVisible(pUART, uart, UartList, UartCount, MaxUARTS, NULL);
|
|
| |
|
| pUART->m_UartModule = UartModule;
|
|
| |
|
| const unsigned PlibUartID = UartIndex_to_PlibUartId[UartModule-1];
|
|
| pUART->m_PlibUartID = PlibUartID;
|
|
| |
|
| UARTConfigure(PlibUartID, UART_ENABLE_PINS_TX_RX_ONLY);
|
|
| UARTSetFifoMode(PlibUartID, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
|
|
| UARTSetLineControl(PlibUartID, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
|
|
| UARTSetDataRate(PlibUartID, GetPeripheralClock(), BaudRate);
|
|
| |
|
| const unsigned Priority = 1;
|
|
| INTSetVectorPriority(INT_VECTOR_UART(PlibUartID), GetPriorityBits(Priority));
|
|
| INTSetVectorSubPriority(INT_VECTOR_UART(PlibUartID), INT_SUB_PRIORITY_LEVEL_0);
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_SendDataQueue, pUART->m_SendDataQueueData, sizeof(pUART->m_SendDataQueueData), sizeof(uint8_t));
|
|
| |
|
| oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData, sizeof(pUART->m_ReceiveDataQueueData), sizeof(uint8_t));
|
|
| oosmos_SubscriberListInit(pUART->m_ReceivedByteEventSubscribers);
|
|
| |
|
| oosmos_ActiveObjectInit(pUART, m_ActiveObject, RunStateMachine);
|
|
| |
|
| return pUART;
|
|
| }
|
|
| |
|
| extern void uartSubscribe(uart * pUART, oosmos_sQueue * pQueue, const int EventCode, void * pContext)
|
|
| {
|
|
| oosmos_SubscriberListAdd(pUART->m_ReceivedByteEventSubscribers, pQueue, EventCode, pContext);
|
|
| }
|
|
| |
|
| #define uartVector(N) void __ISR(_UART_##N##_VECTOR) IntUart##N##Handler() { ISR(N); }
|
|
| |
|
| #ifdef _UART1
|
|
| uartVector(1)
|
|
| #endif
|
|
| |
|
| #ifdef _UART2
|
|
| uartVector(2)
|
|
| #endif
|
|
| |
|
| #ifdef _UART3
|
|
| uartVector(3)
|
|
| #endif
|
|
| |
|
| #ifdef _UART4
|
|
| uartVector(4)
|
|
| #endif
|
|
| |
|
| #ifdef _UART5
|
|
| uartVector(5)
|
|
| #endif
|
|
| |
|
| #ifdef _UART6
|
|
| uartVector(6)
|
|
| #endif
|
|
oosmos/Classes/PIC32/uart.c
oosmos_ThreadBegin
oosmos_ThreadBegin and
oosmos_ThreadEnd bracket
OOSMOS Thread calls within an
oosmos_POLL event handler.
See line 35 in the code
snippet below for an example.
See Also |
ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef toggleMAX
|
[...] |
|
| #define toggleMAX 5
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "toggle.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| oosmos_sObjectThread m_ObjectThread;
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| static void ToggleThread(const toggle * pToggle, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pToggle);
|
|
| oosmos_POINTER_GUARD(pState);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| pinOn(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOnMS);
|
|
| |
|
| pinOff(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOffMS);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
[...] |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| oosmos_ObjectThreadInit(pToggle, m_ObjectThread, ToggleThread, true);
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos_ThreadDelayMS
oosmos_ThreadDelayMS blocks the thread for
the specified number of
Milliseconds.
See line 38 in the code snippet
below for an example.
Milliseconds |
The number of milliseconds to block the thread.
|
See Also |
ThreadBegin, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef toggleMAX
|
[...] |
|
| #define toggleMAX 5
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "toggle.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| oosmos_sObjectThread m_ObjectThread;
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| static void ToggleThread(const toggle * pToggle, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pToggle);
|
|
| oosmos_POINTER_GUARD(pState);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| pinOn(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOnMS);
|
|
| |
|
| pinOff(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOffMS);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
[...] |
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| oosmos_ObjectThreadInit(pToggle, m_ObjectThread, ToggleThread, true);
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos_ThreadDelaySeconds
oosmos_ThreadDelaySeconds blocks the thread for
the specified number of
Seconds.
See line 24 in the code snippet
below for an example.
Seconds |
The number of seconds to block the thread.
|
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
oosmos/Tests/ThreadDelaySeconds.c
oosmos_ThreadDelayUS
oosmos_ThreadDelayUS blocks the thread for
the specified number of
Microseconds.
See line 29 in the code snippet
below for an example.
Microseconds |
The number of microseconds to block the thread.
|
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| //
|
[MIT] |
|
| // OOSMOS ThreadDelayUS Test
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| typedef struct
|
|
| {
|
|
| oosmos_sObjectThread m_ObjectThread;
|
|
| unsigned I;
|
|
| uint32_t Before;
|
|
| uint32_t After;
|
|
| uint32_t Diff;
|
|
| } test;
|
|
| |
|
| static void Thread(test * pTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| printf("Starting Thread\n");
|
|
| |
|
| pTest->Before = oosmos_GetFreeRunningUS();
|
|
| |
|
| for (pTest->I = 1; pTest->I <= 5; pTest->I++) {
|
|
| oosmos_ThreadDelayUS(1000);
|
|
| }
|
|
| |
|
| pTest->After = oosmos_GetFreeRunningUS();
|
|
| |
|
| pTest->Diff = pTest->After - pTest->Before;
|
|
| |
|
| printf("Diff: %u %u %u\n", (unsigned) pTest->Diff, (unsigned) pTest->Before, (unsigned) pTest->After);
|
|
| |
|
| if (pTest->Diff >= 5000 && pTest->Diff <= 5100) {
|
|
| printf("Success\n");
|
|
| }
|
|
| else {
|
|
| printf("Failed\n");
|
|
| }
|
|
| |
|
| printf("Press CNTL-C to exit.\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| extern int main(void)
|
[...] |
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| oosmos_ObjectThreadInit(pTest, m_ObjectThread, Thread, true);
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| }
|
|
| }
|
|
oosmos/Tests/ThreadDelayUS.c
oosmos_ThreadEnd
oosmos_ThreadBegin and
oosmos_ThreadEnd bracket
OOSMOS Thread calls within an
oosmos_POLL event handler.
See line 43 in the code snippet
below for an example.
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #ifndef toggleMAX
|
[...] |
|
| #define toggleMAX 5
|
|
| #endif
|
|
| |
|
| //===================================
|
|
| |
|
| #include "oosmos.h"
|
|
| #include "pin.h"
|
|
| #include "toggle.h"
|
|
| #include <stdbool.h>
|
|
| #include <stddef.h>
|
|
| #include <stdint.h>
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| oosmos_sObjectThread m_ObjectThread;
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| static void ToggleThread(const toggle * pToggle, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_POINTER_GUARD(pToggle);
|
|
| oosmos_POINTER_GUARD(pState);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| for (;;) {
|
|
| pinOn(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOnMS);
|
|
| |
|
| pinOff(pToggle->m_pPin);
|
|
| oosmos_ThreadDelayMS(pToggle->m_TimeOffMS);
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
[...] |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| oosmos_ObjectThreadInit(pToggle, m_ObjectThread, ToggleThread, true);
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos_ThreadExit
oosmos_ThreadExit exits the thread. If there is an
oosmos_ThreadFinally() function between the
oosmos_ThreadExit and the
oosmos_ThreadEnd, the
code in the
Finally block will be executed prior to
exiting the thread.
See line 167 in the code snippet
below for an example.
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| 273 |
|
| 274 |
|
| 275 |
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
|
| 283 |
|
| 284 |
|
| 285 |
|
| 286 |
|
| 287 |
|
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
|
| 294 |
|
| 295 |
|
| 296 |
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 |
|
| 302 |
|
| 303 |
|
| 304 |
|
| 305 |
|
| 306 |
|
| 307 |
|
| 308 |
|
| 309 |
|
| 310 |
|
| 311 |
|
| 312 |
|
| 313 |
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
|
| 319 |
|
| 320 |
|
| 321 |
|
| 322 |
|
| 323 |
|
| 324 |
|
| 325 |
|
| 326 |
|
| 327 |
|
| 328 |
|
| 329 |
|
| 330 |
|
| 331 |
|
| 332 |
|
| 333 |
|
| 334 |
|
| 335 |
|
| 336 |
|
| 337 |
|
| 338 |
|
| 339 |
|
| 340 |
|
| 341 |
|
| 342 |
|
| 343 |
|
| 344 |
|
| 345 |
|
| 346 |
|
| 347 |
|
| 348 |
|
| 349 |
|
| 350 |
|
| 351 |
|
| 352 |
|
| 353 |
|
| 354 |
|
| 355 |
|
| 356 |
|
| 357 |
|
| 358 |
|
| 359 |
|
| 360 |
|
| 361 |
|
| //
|
[MIT] |
|
| // OOSMOS threadtest Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "prt.h"
|
|
| #include "threadtest.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| #include <stdlib.h>
|
|
| |
|
| //
|
|
| // Adjust this in order to preallocate all 'threadtest' objects.
|
|
| // Use 1 for a memory constrained environment.
|
|
| //
|
|
| #ifndef MAX_THREADTEST
|
|
| #define MAX_THREADTEST 10
|
|
| #endif
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evDone = 1,
|
|
| evPrint = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evDone: return "evDone";
|
|
| case evPrint: return "evPrint";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct threadtestTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Running_State;
|
|
| oosmos_sOrthoRegion Running_Region1_State;
|
|
| oosmos_sLeaf Running_Region1_DelayMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExit_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExitFinally_State;
|
|
| oosmos_sLeaf Running_Region1_Exiting_State;
|
|
| oosmos_sOrthoRegion Running_Region2_State;
|
|
| oosmos_sLeaf Running_Region2_Printing_State;
|
|
| //<<<DECL
|
|
| unsigned m_WC_Timeout_Successes;
|
|
| unsigned m_WE_Timeout_Successes;
|
|
| |
|
| unsigned m_ThreadExitCount;
|
|
| };
|
|
| |
|
| static bool ConditionRandom(int Range)
|
|
| {
|
|
| return rand() % Range == 0;
|
|
| }
|
|
| |
|
| static bool ConditionTrue(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static bool ConditionFalse(void)
|
|
| {
|
|
| return false;
|
|
| }
|
|
| |
|
| static void DelayMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadDelayMS...\n");
|
|
| oosmos_ThreadDelayMS(3000);
|
|
| prtFormatted("ThreadDelayMS SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitCond...\n");
|
|
| oosmos_ThreadWaitCond(ConditionRandom(2));
|
|
| prtFormatted("ThreadWaitCond SUCCESS\n\n");
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WC_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitCond_TimeoutMS...\n");
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionTrue(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionFalse(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitCond_TimeoutMS %s\n\n", pThreadTest->m_WC_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitEvent...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent(evDone);
|
|
| prtFormatted("ThreadWaitEvent SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WE_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitEvent_TimeoutMS...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitEvent_TimeoutMS %s\n\n", pThreadTest->m_WE_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExit_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| prtFormatted("ThreadExit SUCCESS\n");
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExitFinally_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadFinally();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| |
|
| if (pThreadTest->m_ThreadExitCount == 2) {
|
|
| prtFormatted("ThreadExitFinally SUCCESS\n");
|
|
| } else {
|
|
| prtFormatted("ThreadExitFinally FAILURE\n");
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool Running_Region1_DelayMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| DelayMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExit_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExit_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExit_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExitFinally_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExitFinally_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExitFinally_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_Exiting_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_Exiting_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static void OOSMOS_Action_2e6a8ac5(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| printf("Printing...\n");
|
|
| oosmos_PushEventCode(pThreadTest, evDone);
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| oosmos_UNUSED(pEvent);
|
|
| }
|
|
| |
|
| static bool Running_Region2_Printing_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evPrint: {
|
|
| return oosmos_TransitionAction(pThreadTest, pState, Running_Region2_Printing_State, pEvent, OOSMOS_Action_2e6a8ac5);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern threadtest * threadtestNew(void)
|
|
| {
|
|
| oosmos_Allocate(pThreadTest, threadtest, MAX_THREADTEST, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pThreadTest, ROOT, NULL, Running_State);
|
|
| oosmos_OrthoInit(pThreadTest, Running_State, ROOT, NULL);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region1_State, Running_State, Running_Region1_DelayMS_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_DelayMS_State, Running_Region1_State, Running_Region1_DelayMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_State, Running_Region1_State, Running_Region1_WaitCond_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitCond_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_State, Running_Region1_State, Running_Region1_WaitEvent_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitEvent_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExit_State, Running_Region1_State, Running_Region1_ThreadExit_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExitFinally_State, Running_Region1_State, Running_Region1_ThreadExitFinally_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_Exiting_State, Running_Region1_State, Running_Region1_Exiting_State_Code);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region2_State, Running_State, Running_Region2_Printing_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region2_Printing_State, Running_Region2_State, Running_Region2_Printing_State_Code);
|
|
| |
|
| oosmos_Debug(pThreadTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pThreadTest;
|
|
| }
|
|
oosmos/Classes/Tests/threadtest.c
oosmos_ThreadFinally
oosmos_ThreadFinally is an optional construct
that begins a section of code to be executed
before exiting the
Thread block.
oosmos_ThreadFinally and its code must be placed
immediately before the
oosmos_ThreadEnd.
See
threadtest.c, below,
line 168 for an example.
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| 273 |
|
| 274 |
|
| 275 |
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
|
| 283 |
|
| 284 |
|
| 285 |
|
| 286 |
|
| 287 |
|
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
|
| 294 |
|
| 295 |
|
| 296 |
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 |
|
| 302 |
|
| 303 |
|
| 304 |
|
| 305 |
|
| 306 |
|
| 307 |
|
| 308 |
|
| 309 |
|
| 310 |
|
| 311 |
|
| 312 |
|
| 313 |
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
|
| 319 |
|
| 320 |
|
| 321 |
|
| 322 |
|
| 323 |
|
| 324 |
|
| 325 |
|
| 326 |
|
| 327 |
|
| 328 |
|
| 329 |
|
| 330 |
|
| 331 |
|
| 332 |
|
| 333 |
|
| 334 |
|
| 335 |
|
| 336 |
|
| 337 |
|
| 338 |
|
| 339 |
|
| 340 |
|
| 341 |
|
| 342 |
|
| 343 |
|
| 344 |
|
| 345 |
|
| 346 |
|
| 347 |
|
| 348 |
|
| 349 |
|
| 350 |
|
| 351 |
|
| 352 |
|
| 353 |
|
| 354 |
|
| 355 |
|
| 356 |
|
| 357 |
|
| 358 |
|
| 359 |
|
| 360 |
|
| 361 |
|
| //
|
[MIT] |
|
| // OOSMOS threadtest Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "prt.h"
|
|
| #include "threadtest.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| #include <stdlib.h>
|
|
| |
|
| //
|
|
| // Adjust this in order to preallocate all 'threadtest' objects.
|
|
| // Use 1 for a memory constrained environment.
|
|
| //
|
|
| #ifndef MAX_THREADTEST
|
|
| #define MAX_THREADTEST 10
|
|
| #endif
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evDone = 1,
|
|
| evPrint = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evDone: return "evDone";
|
|
| case evPrint: return "evPrint";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct threadtestTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Running_State;
|
|
| oosmos_sOrthoRegion Running_Region1_State;
|
|
| oosmos_sLeaf Running_Region1_DelayMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExit_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExitFinally_State;
|
|
| oosmos_sLeaf Running_Region1_Exiting_State;
|
|
| oosmos_sOrthoRegion Running_Region2_State;
|
|
| oosmos_sLeaf Running_Region2_Printing_State;
|
|
| //<<<DECL
|
|
| unsigned m_WC_Timeout_Successes;
|
|
| unsigned m_WE_Timeout_Successes;
|
|
| |
|
| unsigned m_ThreadExitCount;
|
|
| };
|
|
| |
|
| static bool ConditionRandom(int Range)
|
|
| {
|
|
| return rand() % Range == 0;
|
|
| }
|
|
| |
|
| static bool ConditionTrue(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static bool ConditionFalse(void)
|
|
| {
|
|
| return false;
|
|
| }
|
|
| |
|
| static void DelayMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadDelayMS...\n");
|
|
| oosmos_ThreadDelayMS(3000);
|
|
| prtFormatted("ThreadDelayMS SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitCond...\n");
|
|
| oosmos_ThreadWaitCond(ConditionRandom(2));
|
|
| prtFormatted("ThreadWaitCond SUCCESS\n\n");
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WC_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitCond_TimeoutMS...\n");
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionTrue(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionFalse(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitCond_TimeoutMS %s\n\n", pThreadTest->m_WC_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitEvent...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent(evDone);
|
|
| prtFormatted("ThreadWaitEvent SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WE_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitEvent_TimeoutMS...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitEvent_TimeoutMS %s\n\n", pThreadTest->m_WE_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExit_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| prtFormatted("ThreadExit SUCCESS\n");
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExitFinally_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadFinally();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| |
|
| if (pThreadTest->m_ThreadExitCount == 2) {
|
|
| prtFormatted("ThreadExitFinally SUCCESS\n");
|
|
| } else {
|
|
| prtFormatted("ThreadExitFinally FAILURE\n");
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool Running_Region1_DelayMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| DelayMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExit_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExit_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExit_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExitFinally_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExitFinally_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExitFinally_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_Exiting_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_Exiting_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static void OOSMOS_Action_2e6a8ac5(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| printf("Printing...\n");
|
|
| oosmos_PushEventCode(pThreadTest, evDone);
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| oosmos_UNUSED(pEvent);
|
|
| }
|
|
| |
|
| static bool Running_Region2_Printing_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evPrint: {
|
|
| return oosmos_TransitionAction(pThreadTest, pState, Running_Region2_Printing_State, pEvent, OOSMOS_Action_2e6a8ac5);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern threadtest * threadtestNew(void)
|
|
| {
|
|
| oosmos_Allocate(pThreadTest, threadtest, MAX_THREADTEST, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pThreadTest, ROOT, NULL, Running_State);
|
|
| oosmos_OrthoInit(pThreadTest, Running_State, ROOT, NULL);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region1_State, Running_State, Running_Region1_DelayMS_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_DelayMS_State, Running_Region1_State, Running_Region1_DelayMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_State, Running_Region1_State, Running_Region1_WaitCond_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitCond_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_State, Running_Region1_State, Running_Region1_WaitEvent_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitEvent_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExit_State, Running_Region1_State, Running_Region1_ThreadExit_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExitFinally_State, Running_Region1_State, Running_Region1_ThreadExitFinally_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_Exiting_State, Running_Region1_State, Running_Region1_Exiting_State_Code);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region2_State, Running_State, Running_Region2_Printing_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region2_Printing_State, Running_Region2_State, Running_Region2_Printing_State_Code);
|
|
| |
|
| oosmos_Debug(pThreadTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pThreadTest;
|
|
| }
|
|
oosmos/Classes/Tests/threadtest.c
oosmos_ThreadWaitCond
oosmos_ThreadWaitCond effectively blocks
execution
of this object until a condition is met.
See line 98 in the code snippet below
for an example.
This form of
oosmos_ThreadWaitCond does
not accept a timeout, so you must be certain that the condition
will be met eventually. There are other forms of
oosmos_ThreadWaitCond that do accept a timeout value.
Condition |
When this condition is false, OOSMOS
returns from the function to run other objects and then re-enters
this statement to check
the condition again. It keeps doing this until
the condition is true, and then
execution continues to the next statement.
|
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| 273 |
|
| 274 |
|
| 275 |
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
|
| 283 |
|
| 284 |
|
| 285 |
|
| 286 |
|
| 287 |
|
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
|
| 294 |
|
| 295 |
|
| 296 |
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 |
|
| 302 |
|
| 303 |
|
| 304 |
|
| 305 |
|
| 306 |
|
| 307 |
|
| 308 |
|
| 309 |
|
| 310 |
|
| 311 |
|
| 312 |
|
| 313 |
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
|
| 319 |
|
| 320 |
|
| 321 |
|
| 322 |
|
| 323 |
|
| 324 |
|
| 325 |
|
| 326 |
|
| 327 |
|
| 328 |
|
| 329 |
|
| 330 |
|
| 331 |
|
| 332 |
|
| 333 |
|
| 334 |
|
| 335 |
|
| 336 |
|
| 337 |
|
| 338 |
|
| 339 |
|
| 340 |
|
| 341 |
|
| 342 |
|
| 343 |
|
| 344 |
|
| 345 |
|
| 346 |
|
| 347 |
|
| 348 |
|
| 349 |
|
| 350 |
|
| 351 |
|
| 352 |
|
| 353 |
|
| 354 |
|
| 355 |
|
| 356 |
|
| 357 |
|
| 358 |
|
| 359 |
|
| 360 |
|
| 361 |
|
| //
|
[MIT] |
|
| // OOSMOS threadtest Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "prt.h"
|
|
| #include "threadtest.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| #include <stdlib.h>
|
|
| |
|
| //
|
|
| // Adjust this in order to preallocate all 'threadtest' objects.
|
|
| // Use 1 for a memory constrained environment.
|
|
| //
|
|
| #ifndef MAX_THREADTEST
|
|
| #define MAX_THREADTEST 10
|
|
| #endif
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evDone = 1,
|
|
| evPrint = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evDone: return "evDone";
|
|
| case evPrint: return "evPrint";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct threadtestTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Running_State;
|
|
| oosmos_sOrthoRegion Running_Region1_State;
|
|
| oosmos_sLeaf Running_Region1_DelayMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExit_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExitFinally_State;
|
|
| oosmos_sLeaf Running_Region1_Exiting_State;
|
|
| oosmos_sOrthoRegion Running_Region2_State;
|
|
| oosmos_sLeaf Running_Region2_Printing_State;
|
|
| //<<<DECL
|
|
| unsigned m_WC_Timeout_Successes;
|
|
| unsigned m_WE_Timeout_Successes;
|
|
| |
|
| unsigned m_ThreadExitCount;
|
|
| };
|
|
| |
|
| static bool ConditionRandom(int Range)
|
|
| {
|
|
| return rand() % Range == 0;
|
|
| }
|
|
| |
|
| static bool ConditionTrue(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static bool ConditionFalse(void)
|
|
| {
|
|
| return false;
|
|
| }
|
|
| |
|
| static void DelayMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadDelayMS...\n");
|
|
| oosmos_ThreadDelayMS(3000);
|
|
| prtFormatted("ThreadDelayMS SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitCond...\n");
|
|
| oosmos_ThreadWaitCond(ConditionRandom(2));
|
|
| prtFormatted("ThreadWaitCond SUCCESS\n\n");
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
[...] |
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WC_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitCond_TimeoutMS...\n");
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionTrue(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionFalse(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitCond_TimeoutMS %s\n\n", pThreadTest->m_WC_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitEvent...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent(evDone);
|
|
| prtFormatted("ThreadWaitEvent SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WE_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitEvent_TimeoutMS...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitEvent_TimeoutMS %s\n\n", pThreadTest->m_WE_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExit_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| prtFormatted("ThreadExit SUCCESS\n");
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExitFinally_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadFinally();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| |
|
| if (pThreadTest->m_ThreadExitCount == 2) {
|
|
| prtFormatted("ThreadExitFinally SUCCESS\n");
|
|
| } else {
|
|
| prtFormatted("ThreadExitFinally FAILURE\n");
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool Running_Region1_DelayMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| DelayMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExit_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExit_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExit_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExitFinally_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExitFinally_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExitFinally_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_Exiting_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_Exiting_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static void OOSMOS_Action_2e6a8ac5(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| printf("Printing...\n");
|
|
| oosmos_PushEventCode(pThreadTest, evDone);
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| oosmos_UNUSED(pEvent);
|
|
| }
|
|
| |
|
| static bool Running_Region2_Printing_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evPrint: {
|
|
| return oosmos_TransitionAction(pThreadTest, pState, Running_Region2_Printing_State, pEvent, OOSMOS_Action_2e6a8ac5);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern threadtest * threadtestNew(void)
|
|
| {
|
|
| oosmos_Allocate(pThreadTest, threadtest, MAX_THREADTEST, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pThreadTest, ROOT, NULL, Running_State);
|
|
| oosmos_OrthoInit(pThreadTest, Running_State, ROOT, NULL);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region1_State, Running_State, Running_Region1_DelayMS_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_DelayMS_State, Running_Region1_State, Running_Region1_DelayMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_State, Running_Region1_State, Running_Region1_WaitCond_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitCond_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_State, Running_Region1_State, Running_Region1_WaitEvent_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitEvent_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExit_State, Running_Region1_State, Running_Region1_ThreadExit_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExitFinally_State, Running_Region1_State, Running_Region1_ThreadExitFinally_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_Exiting_State, Running_Region1_State, Running_Region1_Exiting_State_Code);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region2_State, Running_State, Running_Region2_Printing_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region2_Printing_State, Running_Region2_State, Running_Region2_Printing_State_Code);
|
|
| |
|
| oosmos_Debug(pThreadTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pThreadTest;
|
|
| }
|
|
oosmos/Classes/Tests/threadtest.c
oosmos_ThreadWaitCond_TimeoutMS
oosmos_ThreadWaitCond_TimeoutMS effectively blocks
execution
of this object until a condition is met or
a timeout expires.
See line 141 in the code snippet below
for an example.
Condition |
When this condition is false, OOSMOS
returns from the function to run other objects and then re-enters
this statement to check
the condition again. It keeps doing this until
the condition is true and then
execution continues to the next statement.
|
TimeoutMS |
The timeout value in milliseconds.
|
pTimeoutStatus |
The address of a bool variable that will indicate whether
the timeout expired first (true) or the condition
occurred first (false).
|
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| 273 |
|
| 274 |
|
| 275 |
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
|
| 283 |
|
| 284 |
|
| 285 |
|
| 286 |
|
| 287 |
|
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
|
| 294 |
|
| 295 |
|
| 296 |
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 |
|
| 302 |
|
| 303 |
|
| 304 |
|
| 305 |
|
| 306 |
|
| 307 |
|
| 308 |
|
| 309 |
|
| 310 |
|
| 311 |
|
| 312 |
|
| 313 |
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
|
| 319 |
|
| 320 |
|
| 321 |
|
| 322 |
|
| 323 |
|
| 324 |
|
| 325 |
|
| 326 |
|
| 327 |
|
| 328 |
|
| 329 |
|
| 330 |
|
| 331 |
|
| 332 |
|
| 333 |
|
| 334 |
|
| 335 |
|
| 336 |
|
| 337 |
|
| 338 |
|
| 339 |
|
| 340 |
|
| 341 |
|
| 342 |
|
| 343 |
|
| 344 |
|
| 345 |
|
| 346 |
|
| 347 |
|
| 348 |
|
| 349 |
|
| 350 |
|
| 351 |
|
| 352 |
|
| 353 |
|
| 354 |
|
| 355 |
|
| 356 |
|
| 357 |
|
| 358 |
|
| 359 |
|
| 360 |
|
| 361 |
|
| //
|
[MIT] |
|
| // OOSMOS threadtest Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "prt.h"
|
|
| #include "threadtest.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| #include <stdlib.h>
|
|
| |
|
| //
|
|
| // Adjust this in order to preallocate all 'threadtest' objects.
|
|
| // Use 1 for a memory constrained environment.
|
|
| //
|
|
| #ifndef MAX_THREADTEST
|
|
| #define MAX_THREADTEST 10
|
|
| #endif
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evDone = 1,
|
|
| evPrint = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evDone: return "evDone";
|
|
| case evPrint: return "evPrint";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct threadtestTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Running_State;
|
|
| oosmos_sOrthoRegion Running_Region1_State;
|
|
| oosmos_sLeaf Running_Region1_DelayMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExit_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExitFinally_State;
|
|
| oosmos_sLeaf Running_Region1_Exiting_State;
|
|
| oosmos_sOrthoRegion Running_Region2_State;
|
|
| oosmos_sLeaf Running_Region2_Printing_State;
|
|
| //<<<DECL
|
|
| unsigned m_WC_Timeout_Successes;
|
|
| unsigned m_WE_Timeout_Successes;
|
|
| |
|
| unsigned m_ThreadExitCount;
|
|
| };
|
|
| |
|
| static bool ConditionRandom(int Range)
|
|
| {
|
|
| return rand() % Range == 0;
|
|
| }
|
|
| |
|
| static bool ConditionTrue(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static bool ConditionFalse(void)
|
|
| {
|
|
| return false;
|
|
| }
|
|
| |
|
| static void DelayMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadDelayMS...\n");
|
|
| oosmos_ThreadDelayMS(3000);
|
|
| prtFormatted("ThreadDelayMS SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitCond...\n");
|
|
| oosmos_ThreadWaitCond(ConditionRandom(2));
|
|
| prtFormatted("ThreadWaitCond SUCCESS\n\n");
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WC_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitCond_TimeoutMS...\n");
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionTrue(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionFalse(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitCond_TimeoutMS %s\n\n", pThreadTest->m_WC_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitEvent...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent(evDone);
|
|
| prtFormatted("ThreadWaitEvent SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WE_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitEvent_TimeoutMS...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitEvent_TimeoutMS %s\n\n", pThreadTest->m_WE_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExit_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
[...] |
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| prtFormatted("ThreadExit SUCCESS\n");
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExitFinally_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadFinally();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| |
|
| if (pThreadTest->m_ThreadExitCount == 2) {
|
|
| prtFormatted("ThreadExitFinally SUCCESS\n");
|
|
| } else {
|
|
| prtFormatted("ThreadExitFinally FAILURE\n");
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool Running_Region1_DelayMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| DelayMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExit_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExit_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExit_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExitFinally_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExitFinally_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExitFinally_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_Exiting_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_Exiting_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static void OOSMOS_Action_2e6a8ac5(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| printf("Printing...\n");
|
|
| oosmos_PushEventCode(pThreadTest, evDone);
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| oosmos_UNUSED(pEvent);
|
|
| }
|
|
| |
|
| static bool Running_Region2_Printing_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evPrint: {
|
|
| return oosmos_TransitionAction(pThreadTest, pState, Running_Region2_Printing_State, pEvent, OOSMOS_Action_2e6a8ac5);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern threadtest * threadtestNew(void)
|
|
| {
|
|
| oosmos_Allocate(pThreadTest, threadtest, MAX_THREADTEST, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pThreadTest, ROOT, NULL, Running_State);
|
|
| oosmos_OrthoInit(pThreadTest, Running_State, ROOT, NULL);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region1_State, Running_State, Running_Region1_DelayMS_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_DelayMS_State, Running_Region1_State, Running_Region1_DelayMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_State, Running_Region1_State, Running_Region1_WaitCond_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitCond_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_State, Running_Region1_State, Running_Region1_WaitEvent_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitEvent_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExit_State, Running_Region1_State, Running_Region1_ThreadExit_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExitFinally_State, Running_Region1_State, Running_Region1_ThreadExitFinally_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_Exiting_State, Running_Region1_State, Running_Region1_Exiting_State_Code);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region2_State, Running_State, Running_Region2_Printing_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region2_Printing_State, Running_Region2_State, Running_Region2_Printing_State_Code);
|
|
| |
|
| oosmos_Debug(pThreadTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pThreadTest;
|
|
| }
|
|
oosmos/Classes/Tests/threadtest.c
oosmos_ThreadWaitEvent
oosmos_ThreadWaitEvent effectively blocks
execution
of this object until the
specified event is received.
See line 127 in the code snippet below
for an example.
This form of
oosmos_ThreadWaitEvent does
not accept a timeout, so you should be certain that the event
will be received eventually. There are other forms of
oosmos_ThreadWaitEvent that do accept a timeout value.
WaitEventCode |
The event code that must be received before execution can continue.
|
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent_TimeoutMS, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| 273 |
|
| 274 |
|
| 275 |
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
|
| 283 |
|
| 284 |
|
| 285 |
|
| 286 |
|
| 287 |
|
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
|
| 294 |
|
| 295 |
|
| 296 |
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 |
|
| 302 |
|
| 303 |
|
| 304 |
|
| 305 |
|
| 306 |
|
| 307 |
|
| 308 |
|
| 309 |
|
| 310 |
|
| 311 |
|
| 312 |
|
| 313 |
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
|
| 319 |
|
| 320 |
|
| 321 |
|
| 322 |
|
| 323 |
|
| 324 |
|
| 325 |
|
| 326 |
|
| 327 |
|
| 328 |
|
| 329 |
|
| 330 |
|
| 331 |
|
| 332 |
|
| 333 |
|
| 334 |
|
| 335 |
|
| 336 |
|
| 337 |
|
| 338 |
|
| 339 |
|
| 340 |
|
| 341 |
|
| 342 |
|
| 343 |
|
| 344 |
|
| 345 |
|
| 346 |
|
| 347 |
|
| 348 |
|
| 349 |
|
| 350 |
|
| 351 |
|
| 352 |
|
| 353 |
|
| 354 |
|
| 355 |
|
| 356 |
|
| 357 |
|
| 358 |
|
| 359 |
|
| 360 |
|
| 361 |
|
| //
|
[MIT] |
|
| // OOSMOS threadtest Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "prt.h"
|
|
| #include "threadtest.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| #include <stdlib.h>
|
|
| |
|
| //
|
|
| // Adjust this in order to preallocate all 'threadtest' objects.
|
|
| // Use 1 for a memory constrained environment.
|
|
| //
|
|
| #ifndef MAX_THREADTEST
|
|
| #define MAX_THREADTEST 10
|
|
| #endif
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evDone = 1,
|
|
| evPrint = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evDone: return "evDone";
|
|
| case evPrint: return "evPrint";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct threadtestTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Running_State;
|
|
| oosmos_sOrthoRegion Running_Region1_State;
|
|
| oosmos_sLeaf Running_Region1_DelayMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExit_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExitFinally_State;
|
|
| oosmos_sLeaf Running_Region1_Exiting_State;
|
|
| oosmos_sOrthoRegion Running_Region2_State;
|
|
| oosmos_sLeaf Running_Region2_Printing_State;
|
|
| //<<<DECL
|
|
| unsigned m_WC_Timeout_Successes;
|
|
| unsigned m_WE_Timeout_Successes;
|
|
| |
|
| unsigned m_ThreadExitCount;
|
|
| };
|
|
| |
|
| static bool ConditionRandom(int Range)
|
|
| {
|
|
| return rand() % Range == 0;
|
|
| }
|
|
| |
|
| static bool ConditionTrue(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static bool ConditionFalse(void)
|
|
| {
|
|
| return false;
|
|
| }
|
|
| |
|
| static void DelayMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadDelayMS...\n");
|
|
| oosmos_ThreadDelayMS(3000);
|
|
| prtFormatted("ThreadDelayMS SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitCond...\n");
|
|
| oosmos_ThreadWaitCond(ConditionRandom(2));
|
|
| prtFormatted("ThreadWaitCond SUCCESS\n\n");
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WC_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitCond_TimeoutMS...\n");
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionTrue(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionFalse(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitCond_TimeoutMS %s\n\n", pThreadTest->m_WC_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitEvent...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent(evDone);
|
|
| prtFormatted("ThreadWaitEvent SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
[...] |
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WE_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitEvent_TimeoutMS...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitEvent_TimeoutMS %s\n\n", pThreadTest->m_WE_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExit_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| prtFormatted("ThreadExit SUCCESS\n");
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExitFinally_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadFinally();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| |
|
| if (pThreadTest->m_ThreadExitCount == 2) {
|
|
| prtFormatted("ThreadExitFinally SUCCESS\n");
|
|
| } else {
|
|
| prtFormatted("ThreadExitFinally FAILURE\n");
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool Running_Region1_DelayMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| DelayMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExit_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExit_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExit_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExitFinally_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExitFinally_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExitFinally_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_Exiting_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_Exiting_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static void OOSMOS_Action_2e6a8ac5(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| printf("Printing...\n");
|
|
| oosmos_PushEventCode(pThreadTest, evDone);
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| oosmos_UNUSED(pEvent);
|
|
| }
|
|
| |
|
| static bool Running_Region2_Printing_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evPrint: {
|
|
| return oosmos_TransitionAction(pThreadTest, pState, Running_Region2_Printing_State, pEvent, OOSMOS_Action_2e6a8ac5);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern threadtest * threadtestNew(void)
|
|
| {
|
|
| oosmos_Allocate(pThreadTest, threadtest, MAX_THREADTEST, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pThreadTest, ROOT, NULL, Running_State);
|
|
| oosmos_OrthoInit(pThreadTest, Running_State, ROOT, NULL);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region1_State, Running_State, Running_Region1_DelayMS_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_DelayMS_State, Running_Region1_State, Running_Region1_DelayMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_State, Running_Region1_State, Running_Region1_WaitCond_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitCond_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_State, Running_Region1_State, Running_Region1_WaitEvent_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitEvent_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExit_State, Running_Region1_State, Running_Region1_ThreadExit_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExitFinally_State, Running_Region1_State, Running_Region1_ThreadExitFinally_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_Exiting_State, Running_Region1_State, Running_Region1_Exiting_State_Code);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region2_State, Running_State, Running_Region2_Printing_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region2_Printing_State, Running_Region2_State, Running_Region2_Printing_State_Code);
|
|
| |
|
| oosmos_Debug(pThreadTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pThreadTest;
|
|
| }
|
|
oosmos/Classes/Tests/threadtest.c
oosmos_ThreadWaitEvent_TimeoutMS
oosmos_ThreadWaitEvent_TimeoutMS effectively blocks
execution
of this object until a condition is met or
a timeout expires.
See line 141 in the code snippet below
for an example.
WaitEventCode |
The event code that must be received before execution can
continue.
|
TimeoutMS |
The timeout value in milliseconds.
|
pTimeoutStatus |
The address of a bool variable that will indicate whether
the timeout expired first (true) or the event
occurred first (false).
|
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadYield |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| 166 |
|
| 167 |
|
| 168 |
|
| 169 |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 |
|
| 174 |
|
| 175 |
|
| 176 |
|
| 177 |
|
| 178 |
|
| 179 |
|
| 180 |
|
| 181 |
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
|
| 186 |
|
| 187 |
|
| 188 |
|
| 189 |
|
| 190 |
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 |
|
| 195 |
|
| 196 |
|
| 197 |
|
| 198 |
|
| 199 |
|
| 200 |
|
| 201 |
|
| 202 |
|
| 203 |
|
| 204 |
|
| 205 |
|
| 206 |
|
| 207 |
|
| 208 |
|
| 209 |
|
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
|
| 215 |
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
|
| 226 |
|
| 227 |
|
| 228 |
|
| 229 |
|
| 230 |
|
| 231 |
|
| 232 |
|
| 233 |
|
| 234 |
|
| 235 |
|
| 236 |
|
| 237 |
|
| 238 |
|
| 239 |
|
| 240 |
|
| 241 |
|
| 242 |
|
| 243 |
|
| 244 |
|
| 245 |
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 |
|
| 250 |
|
| 251 |
|
| 252 |
|
| 253 |
|
| 254 |
|
| 255 |
|
| 256 |
|
| 257 |
|
| 258 |
|
| 259 |
|
| 260 |
|
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
|
| 265 |
|
| 266 |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 |
|
| 271 |
|
| 272 |
|
| 273 |
|
| 274 |
|
| 275 |
|
| 276 |
|
| 277 |
|
| 278 |
|
| 279 |
|
| 280 |
|
| 281 |
|
| 282 |
|
| 283 |
|
| 284 |
|
| 285 |
|
| 286 |
|
| 287 |
|
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
|
| 294 |
|
| 295 |
|
| 296 |
|
| 297 |
|
| 298 |
|
| 299 |
|
| 300 |
|
| 301 |
|
| 302 |
|
| 303 |
|
| 304 |
|
| 305 |
|
| 306 |
|
| 307 |
|
| 308 |
|
| 309 |
|
| 310 |
|
| 311 |
|
| 312 |
|
| 313 |
|
| 314 |
|
| 315 |
|
| 316 |
|
| 317 |
|
| 318 |
|
| 319 |
|
| 320 |
|
| 321 |
|
| 322 |
|
| 323 |
|
| 324 |
|
| 325 |
|
| 326 |
|
| 327 |
|
| 328 |
|
| 329 |
|
| 330 |
|
| 331 |
|
| 332 |
|
| 333 |
|
| 334 |
|
| 335 |
|
| 336 |
|
| 337 |
|
| 338 |
|
| 339 |
|
| 340 |
|
| 341 |
|
| 342 |
|
| 343 |
|
| 344 |
|
| 345 |
|
| 346 |
|
| 347 |
|
| 348 |
|
| 349 |
|
| 350 |
|
| 351 |
|
| 352 |
|
| 353 |
|
| 354 |
|
| 355 |
|
| 356 |
|
| 357 |
|
| 358 |
|
| 359 |
|
| 360 |
|
| 361 |
|
| //
|
[MIT] |
|
| // OOSMOS threadtest Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "prt.h"
|
|
| #include "threadtest.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| #include <stdlib.h>
|
|
| |
|
| //
|
|
| // Adjust this in order to preallocate all 'threadtest' objects.
|
|
| // Use 1 for a memory constrained environment.
|
|
| //
|
|
| #ifndef MAX_THREADTEST
|
|
| #define MAX_THREADTEST 10
|
|
| #endif
|
|
| |
|
| //>>>EVENTS
|
|
| enum {
|
|
| evDone = 1,
|
|
| evPrint = 2
|
|
| };
|
|
| |
|
| #ifdef oosmos_DEBUG
|
|
| static const char * OOSMOS_EventNames(int EventCode)
|
|
| {
|
|
| switch (EventCode) {
|
|
| case evDone: return "evDone";
|
|
| case evPrint: return "evPrint";
|
|
| default: return "";
|
|
| }
|
|
| }
|
|
| #endif
|
|
| //<<<EVENTS
|
|
| |
|
| typedef union {
|
|
| oosmos_sEvent Base;
|
|
| } uEvents;
|
|
| |
|
| struct threadtestTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachine(ROOT, uEvents, 3);
|
|
| oosmos_sOrtho Running_State;
|
|
| oosmos_sOrthoRegion Running_Region1_State;
|
|
| oosmos_sLeaf Running_Region1_DelayMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_State;
|
|
| oosmos_sLeaf Running_Region1_WaitCond_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_State;
|
|
| oosmos_sLeaf Running_Region1_WaitEvent_TimeoutMS_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExit_State;
|
|
| oosmos_sLeaf Running_Region1_ThreadExitFinally_State;
|
|
| oosmos_sLeaf Running_Region1_Exiting_State;
|
|
| oosmos_sOrthoRegion Running_Region2_State;
|
|
| oosmos_sLeaf Running_Region2_Printing_State;
|
|
| //<<<DECL
|
|
| unsigned m_WC_Timeout_Successes;
|
|
| unsigned m_WE_Timeout_Successes;
|
|
| |
|
| unsigned m_ThreadExitCount;
|
|
| };
|
|
| |
|
| static bool ConditionRandom(int Range)
|
|
| {
|
|
| return rand() % Range == 0;
|
|
| }
|
|
| |
|
| static bool ConditionTrue(void)
|
|
| {
|
|
| return true;
|
|
| }
|
|
| |
|
| static bool ConditionFalse(void)
|
|
| {
|
|
| return false;
|
|
| }
|
|
| |
|
| static void DelayMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| |
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadDelayMS...\n");
|
|
| oosmos_ThreadDelayMS(3000);
|
|
| prtFormatted("ThreadDelayMS SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitCond...\n");
|
|
| oosmos_ThreadWaitCond(ConditionRandom(2));
|
|
| prtFormatted("ThreadWaitCond SUCCESS\n\n");
|
|
| oosmos_UNUSED(pThreadTest);
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WC_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitCond_TimeoutMS...\n");
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionTrue(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitCond_TimeoutMS(ConditionFalse(), 100, &TimedOut);
|
|
| pThreadTest->m_WC_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitCond_TimeoutMS %s\n\n", pThreadTest->m_WC_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| prtFormatted("ThreadWaitEvent...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent(evDone);
|
|
| prtFormatted("ThreadWaitEvent SUCCESS\n\n");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void WaitEvent_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| bool TimedOut = false;
|
|
| pThreadTest->m_WE_Timeout_Successes = 0;
|
|
| |
|
| prtFormatted("ThreadWaitEvent_TimeoutMS...\n");
|
|
| |
|
| oosmos_PushEventCode(pThreadTest, evPrint);
|
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == false);
|
|
| |
|
| oosmos_ThreadWaitEvent_TimeoutMS(evPrint, 100, &TimedOut);
|
|
| pThreadTest->m_WE_Timeout_Successes += (TimedOut == true);
|
|
| prtFormatted("ThreadWaitEvent_TimeoutMS %s\n\n", pThreadTest->m_WE_Timeout_Successes == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExit_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
[...] |
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| prtFormatted("ThreadExit SUCCESS\n");
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| static void ThreadExitFinally_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| pThreadTest->m_ThreadExitCount = 0;
|
|
| oosmos_ThreadYield();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| oosmos_ThreadExit();
|
|
| oosmos_ThreadFinally();
|
|
| pThreadTest->m_ThreadExitCount++;
|
|
| |
|
| if (pThreadTest->m_ThreadExitCount == 2) {
|
|
| prtFormatted("ThreadExitFinally SUCCESS\n");
|
|
| } else {
|
|
| prtFormatted("ThreadExitFinally FAILURE\n");
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
|
| static bool Running_Region1_DelayMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| DelayMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitCond_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitCond_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitCond_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_WaitEvent_TimeoutMS_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_WaitEvent_TimeoutMS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| WaitEvent_TimeoutMS_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExit_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExit_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExit_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_ThreadExitFinally_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_ThreadExitFinally_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| ThreadExitFinally_Thread(pThreadTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadTest, pState, Running_Region1_Exiting_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Running_Region1_Exiting_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| |
|
| static void OOSMOS_Action_2e6a8ac5(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| printf("Printing...\n");
|
|
| oosmos_PushEventCode(pThreadTest, evDone);
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| oosmos_UNUSED(pEvent);
|
|
| }
|
|
| |
|
| static bool Running_Region2_Printing_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadtest * pThreadTest = (threadtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case evPrint: {
|
|
| return oosmos_TransitionAction(pThreadTest, pState, Running_Region2_Printing_State, pEvent, OOSMOS_Action_2e6a8ac5);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern threadtest * threadtestNew(void)
|
|
| {
|
|
| oosmos_Allocate(pThreadTest, threadtest, MAX_THREADTEST, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInit(pThreadTest, ROOT, NULL, Running_State);
|
|
| oosmos_OrthoInit(pThreadTest, Running_State, ROOT, NULL);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region1_State, Running_State, Running_Region1_DelayMS_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_DelayMS_State, Running_Region1_State, Running_Region1_DelayMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_State, Running_Region1_State, Running_Region1_WaitCond_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitCond_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitCond_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_State, Running_Region1_State, Running_Region1_WaitEvent_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_WaitEvent_TimeoutMS_State, Running_Region1_State, Running_Region1_WaitEvent_TimeoutMS_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExit_State, Running_Region1_State, Running_Region1_ThreadExit_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_ThreadExitFinally_State, Running_Region1_State, Running_Region1_ThreadExitFinally_State_Code);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region1_Exiting_State, Running_Region1_State, Running_Region1_Exiting_State_Code);
|
|
| oosmos_OrthoRegionInit(pThreadTest, Running_Region2_State, Running_State, Running_Region2_Printing_State, NULL);
|
|
| oosmos_LeafInit(pThreadTest, Running_Region2_Printing_State, Running_Region2_State, Running_Region2_Printing_State_Code);
|
|
| |
|
| oosmos_Debug(pThreadTest, OOSMOS_EventNames);
|
|
| //<<<INIT
|
|
| |
|
| return pThreadTest;
|
|
| }
|
|
oosmos/Classes/Tests/threadtest.c
oosmos_ThreadYield
If you have a loop that will use a lot of CPU time,
it could hold up execution of other
OOSMOS
objects in the system, you can use the
oosmos_ThreadYield
call to relinquish control occasionally in your loop.
See line 36 in the code snippet
below for an example. In this example, we relinquish control
every time through the loop, but you could use the
C
modulo operator (
%) to relinquish every
N
iterations through the loop.
See Also |
ThreadBegin, ThreadDelayMS, ThreadDelaySeconds, ThreadDelayUS, ThreadEnd, ThreadExit, ThreadFinally, ThreadWaitCond, ThreadWaitCond_TimeoutMS, ThreadWaitEvent, ThreadWaitEvent_TimeoutMS |
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| //
|
[MIT] |
|
| // OOSMOS threadyieldtest class implementation
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "prt.h"
|
|
| #include "threadyieldtest.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdlib.h>
|
|
| |
|
| #ifndef MAX_THREAD
|
|
| #define MAX_THREAD 2
|
|
| #endif
|
|
| |
|
| struct threadyieldtestTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Running_State;
|
|
| oosmos_sLeaf Done_State;
|
|
| //<<<DECL
|
|
| |
|
| const char * m_pID;
|
|
| unsigned m_Count;
|
|
| unsigned m_Iterations;
|
|
| };
|
|
| |
|
| static void Thread(threadyieldtest * pThreadYieldTest, oosmos_sState * pState)
|
|
| {
|
|
| oosmos_ThreadBegin();
|
|
| for (pThreadYieldTest->m_Count = 1; pThreadYieldTest->m_Count <= pThreadYieldTest->m_Iterations; pThreadYieldTest->m_Count++) {
|
|
| prtFormatted("Test threadyieldtest, '%s'...\n", pThreadYieldTest->m_pID);
|
|
| oosmos_ThreadYield();
|
|
| }
|
|
| oosmos_ThreadEnd();
|
|
| }
|
|
| |
|
| //>>>CODE
|
[...] |
|
| static bool Running_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadyieldtest * pThreadYieldTest = (threadyieldtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_POLL: {
|
|
| Thread(pThreadYieldTest, pState);
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pThreadYieldTest, pState, Done_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Done_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| threadyieldtest * pThreadYieldTest = (threadyieldtest *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| prtFormatted("Test threadyieldtest, '%s' DONE.\n", pThreadYieldTest->m_pID);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern threadyieldtest * threadyieldtestNew(const char * pID, unsigned Iterations)
|
|
| {
|
|
| oosmos_Allocate(pThreadYieldTest, threadyieldtest, MAX_THREAD, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pThreadYieldTest, ROOT, NULL, Running_State);
|
|
| oosmos_LeafInit(pThreadYieldTest, Running_State, ROOT, Running_State_Code);
|
|
| oosmos_LeafInit(pThreadYieldTest, Done_State, ROOT, Done_State_Code);
|
|
| |
|
| oosmos_Debug(pThreadYieldTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| pThreadYieldTest->m_pID = pID;
|
|
| pThreadYieldTest->m_Iterations = Iterations;
|
|
| |
|
| return pThreadYieldTest;
|
|
| }
|
|
oosmos/Classes/Tests/threadyieldtest.c
oosmos_TIMEOUT
oosmos_TIMEOUT is one of the six predefined event macros. This event is generated
if a timeout for this state has been previously established and that timeout has expired.
To establish a timeout, use one of
oosmos_StateTimeoutMS,
oosmos_StateTimeoutSeconds or
oosmos_StateTimeoutUS.
See line 39 in the code snippet below
for an example.
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| //
|
[MIT] |
|
| // OOSMOS StateTimeout Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| //<<<EVENTS
|
|
| //>>>EVENTS
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf MS_State;
|
|
| oosmos_sLeaf Seconds_State;
|
|
| oosmos_sLeaf US_State;
|
|
| oosmos_sLeaf Done_State;
|
|
| //<<<DECL
|
|
| unsigned m_TimeMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool MS_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pTest->m_TimeMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, Seconds_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Seconds_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
[...] |
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutSeconds(pState, (uint32_t) 1);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, US_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool US_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutUS(pState, (uint32_t) 100000);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pTest, pState, Done_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, MS_State);
|
|
| oosmos_LeafInit(pTest, MS_State, ROOT, MS_State_Code);
|
|
| oosmos_LeafInit(pTest, Seconds_State, ROOT, Seconds_State_Code);
|
|
| oosmos_LeafInit(pTest, US_State, ROOT, US_State_Code);
|
|
| oosmos_LeafInit(pTest, Done_State, ROOT, NULL);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| pTest->m_TimeMS = 1000;
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| test * pTest = testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| |
|
| if (oosmos_IsInState(pTest, &pTest->Done_State)) {
|
|
| break;
|
|
| }
|
|
| |
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/StateTimeout.c
oosmos_TimeoutHasExpired
oosmos_TimeoutHasExpired checks to see if a previously
established timeout has expired.
See line 32 in the code snippet below
for an example.
pTimeout |
Address of the oosmos_sTimeout metadata item.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| //
|
[MIT] |
|
| // OOSMOS TimeoutInMS Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| static const uint32_t WaitTimeMS = 1000;
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| //
|
|
| // Allocate a Timeout object.
|
|
| //
|
|
| oosmos_sTimeout Timeout;
|
|
| |
|
| //
|
|
| // Set timeout.
|
|
| //
|
|
| oosmos_TimeoutInMS(&Timeout, WaitTimeMS);
|
|
| |
|
| printf("Waiting for %lu milliseconds...\n", (unsigned long) WaitTimeMS);
|
|
| |
|
| for (;;) {
|
|
| //
|
|
| // Check if the time has expired.
|
|
| //
|
|
| if (oosmos_TimeoutHasExpired(&Timeout)) {
|
|
| break;
|
|
| }
|
|
| |
|
| //
|
|
| // Be polite. Prevent 100% CPU usage on multi-tasked
|
|
| // machines (e.g. Windows or Linux).
|
|
| //
|
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/TimeoutInMS.c
oosmos_TimeoutInMS
oosmos_TimeoutInMS is the low-level timeout
mechanism used by the state machine engine. It is provided
to give your program the flexibility to have timeout capability
without having to add a state machine to your object.
To use it, first execute the
oosmos_TimeoutInMS
call (line 24) providing the
address of a
oosmos_sTimeout object
(line 19), then periodically
check if the timeout has expired using the
oosmos_TimeoutHasExpired call
(line 32).
pTimeout |
Address of the oosmos_sTimeout item.
|
Milliseconds |
Number of milliseconds before timeout.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| //
|
[MIT] |
|
| // OOSMOS TimeoutInMS Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| static const uint32_t WaitTimeMS = 1000;
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| //
|
|
| // Allocate a Timeout object.
|
|
| //
|
|
| oosmos_sTimeout Timeout;
|
|
| |
|
| //
|
|
| // Set timeout.
|
|
| //
|
|
| oosmos_TimeoutInMS(&Timeout, WaitTimeMS);
|
|
| |
|
| printf("Waiting for %lu milliseconds...\n", (unsigned long) WaitTimeMS);
|
|
| |
|
| for (;;) {
|
|
| //
|
|
| // Check if the time has expired.
|
|
| //
|
|
| if (oosmos_TimeoutHasExpired(&Timeout)) {
|
|
| break;
|
|
| }
|
|
| |
|
| //
|
|
| // Be polite. Prevent 100% CPU usage on multi-tasked
|
|
| // machines (e.g. Windows or Linux).
|
|
| //
|
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/TimeoutInMS.c
oosmos_TimeoutInSeconds
oosmos_TimeoutInSeconds is the low-level timeout
mechanism used by the state machine engine. It is provided
to give your program the flexibility to have timeout capability
without having to add a state machine to your object.
To use it, first execute the
oosmos_TimeoutInSeconds
call (line 24) providing the
address of a
oosmos_sTimeout object
(line 19), then periodically
check if the timeout has expired using the
oosmos_TimeoutHasExpired call
(line 32).
pTimeout |
Address of the oosmos_sTimeout item.
|
Seconds |
Number of seconds before timeout.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| //
|
[MIT] |
|
| // OOSMOS TimeoutInSeconds Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| static const uint32_t WaitTimeSeconds = 2;
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| //
|
|
| // Allocate a Timeout object.
|
|
| //
|
|
| oosmos_sTimeout Timeout;
|
|
| |
|
| //
|
|
| // Set timeout.
|
|
| //
|
|
| oosmos_TimeoutInSeconds(&Timeout, WaitTimeSeconds);
|
|
| |
|
| printf("Waiting for %lu seconds...\n", (unsigned long) WaitTimeSeconds);
|
|
| |
|
| for (;;) {
|
|
| //
|
|
| // Check if the time has expired.
|
|
| //
|
|
| if (oosmos_TimeoutHasExpired(&Timeout)) {
|
|
| break;
|
|
| }
|
|
| |
|
| //
|
|
| // Be polite. Prevent 100% CPU usage on multi-tasked
|
|
| // machines (e.g. Windows or Linux).
|
|
| //
|
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/TimeoutInSeconds.c
oosmos_TimeoutInUS
oosmos_TimeoutInUS is the low-level timeout
mechanism used by the state machine engine. It is provided
to give your program the flexibility to have timeout capability
without having to add a state machine to your object.
To use it, first execute the
oosmos_TimeoutInUS
call (line 24) providing the
address of a
oosmos_sTimeout object
(line 19), then periodically
check if the timeout has expired using the
oosmos_TimeoutHasExpired call
(line 32).
pTimeout |
Address of the oosmos_sTimeout item.
|
Microseconds |
Number of microseconds before timeout.
|
See Also |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| //
|
[MIT] |
|
| // OOSMOS TimeoutInUS Example
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdint.h>
|
|
| #include <stdio.h>
|
|
| |
|
| static const uint32_t WaitTimeUS = oosmos_Seconds2US(2);
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| //
|
|
| // Allocate a Timeout object.
|
|
| //
|
|
| oosmos_sTimeout Timeout;
|
|
| |
|
| //
|
|
| // Set timeout.
|
|
| //
|
|
| oosmos_TimeoutInUS(&Timeout, WaitTimeUS);
|
|
| |
|
| printf("Waiting for %lu microseconds...\n", (unsigned long) WaitTimeUS);
|
|
| |
|
| for (;;) {
|
|
| //
|
|
| // Check if the time has expired.
|
|
| //
|
|
| if (oosmos_TimeoutHasExpired(&Timeout)) {
|
|
| break;
|
|
| }
|
|
| |
|
| //
|
|
| // Be polite. Prevent 100% CPU usage on multi-tasked
|
|
| // machines (e.g. Windows or Linux).
|
|
| //
|
|
| oosmos_DelayMS(75);
|
|
| }
|
|
| |
|
| printf("SUCCESS\n");
|
|
| |
|
| return 0;
|
|
| }
|
|
oosmos/Examples/Basic/Windows/TimeoutInUS.c
oosmos_TimestampMS
oosmos_TimestampMS returns the number of milliseconds
since program start.
OOSMOS uses it to timestamp
debug output.
| 1 |
| 2 |
| 3 |
| |
|
| uint32_t oosmos_TimestampMS(void); |
|
| |
|
Prototype
oosmos_Transition
oosmos_Transition causes a transition from the current
state to the specified target state. During this transition
process, we execute all the nested
oosmos_EXIT event handlers
as we exit the from states and then execute all the
oosmos_ENTER event handlers as we enter into
all the (possibly nested) states to the
target state. (See line 42.)
Note: In the example, we use the state version of the
toggle
object in the
oosmos/Classes directory instead of the
Thread version.
pObject |
The address of the object that contains the state machine.
|
pFromState |
The same pState
argument that was passed into the containing state handler.
|
ToState |
The name of the state we are transitioning to.
|
RETURN |
Always returns true.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| //
|
[MIT] |
|
| // OOSMOS toggle Class
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include "toggle.h"
|
|
| #include "pin.h"
|
|
| #include <stdbool.h>
|
|
| #include <stdint.h>
|
|
| #include <stddef.h>
|
|
| |
|
| #ifndef toggleMAX
|
|
| #define toggleMAX 4
|
|
| #endif
|
|
| |
|
| struct toggleTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sLeaf Off_State;
|
|
| oosmos_sLeaf On_State;
|
|
| //<<<DECL
|
|
| |
|
| pin * m_pPin;
|
|
| uint32_t m_TimeOnMS;
|
|
| uint32_t m_TimeOffMS;
|
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static bool Off_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOffMS);
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, On_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
[...] |
|
| static bool On_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| toggle * pToggle = (toggle *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| pinOn(pToggle->m_pPin);
|
|
| return oosmos_StateTimeoutMS(pState, (uint32_t) pToggle->m_TimeOnMS);
|
|
| }
|
|
| case oosmos_EXIT: {
|
|
| pinOff(pToggle->m_pPin);
|
|
| return true;
|
|
| }
|
|
| case oosmos_TIMEOUT: {
|
|
| return oosmos_Transition(pToggle, pState, Off_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS)
|
|
| {
|
|
| oosmos_Allocate(pToggle, toggle, toggleMAX, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pToggle, ROOT, NULL, On_State);
|
|
| oosmos_LeafInit(pToggle, Off_State, ROOT, Off_State_Code);
|
|
| oosmos_LeafInit(pToggle, On_State, ROOT, On_State_Code);
|
|
| //<<<INIT
|
|
| |
|
| pToggle->m_pPin = pPin;
|
|
| pToggle->m_TimeOnMS = TimeOnMS;
|
|
| pToggle->m_TimeOffMS = TimeOffMS;
|
|
| |
|
| return pToggle;
|
|
| }
|
|
oosmos/Classes/toggle_state.c
oosmos_TransitionAction
oosmos_TransitionAction causes a transition from the current
state to the specified target state, executing an action function
along the way. During this transition
process, we execute all the nested
oosmos_EXIT event handlers
as we exit the from states, then call the action function, and then execute all the
oosmos_ENTER event handlers as we enter into
all the (possibly nested) states to the
target state. (See lines 36 and 63.)
pObject |
The address of the object that contains the state machine.
|
pFromState |
The same pState
argument that was passed into the containing state handler.
|
ToState |
The name of the state we are transitioning to.
|
pEvent |
The same pEvent
argument that was passed into the containing state handler. It is
passed through to the action function.
|
pActionFunction |
pActionFunction is a pointer to a function to call after all oosmos_EXIT and before
all oosmos_ENTER events are triggered.
|
RETURN |
Always returns true.
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
|
| 15 |
|
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
|
| 27 |
|
| 28 |
|
| 29 |
|
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
|
| 47 |
|
| 48 |
|
| 49 |
|
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
|
| 69 |
|
| 70 |
|
| 71 |
|
| 72 |
|
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 |
|
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
|
| 89 |
|
| 90 |
|
| 91 |
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
|
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
|
| 107 |
|
| 108 |
|
| 109 |
|
| 110 |
|
| 111 |
|
| 112 |
|
| 113 |
|
| 114 |
|
| 115 |
|
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
|
| 122 |
|
| 123 |
|
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 |
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
|
| 145 |
|
| 146 |
|
| 147 |
|
| 148 |
|
| 149 |
|
| 150 |
|
| 151 |
|
| 152 |
|
| 153 |
|
| 154 |
|
| 155 |
|
| 156 |
|
| 157 |
|
| 158 |
|
| 159 |
|
| 160 |
|
| 161 |
|
| 162 |
|
| 163 |
|
| 164 |
|
| 165 |
|
| //
|
[MIT] |
|
| // OOSMOS Action Test
|
|
| //
|
|
| // Copyright (c) 2014-2026 OOSMOS, LLC
|
|
| // SPDX-License-Identifier: MIT
|
|
| //
|
|
| |
|
| #include "oosmos.h"
|
[...] |
|
| #include <stdbool.h>
|
|
| #include <stdio.h>
|
|
| |
|
| //>>>EVENTS
|
|
| //<<<EVENTS
|
|
| |
|
| typedef struct testTag test;
|
|
| |
|
| static unsigned Count;
|
|
| static unsigned ActionCount;
|
|
| |
|
| struct testTag
|
|
| {
|
|
| //>>>DECL
|
|
| oosmos_sStateMachineNoQueue(ROOT);
|
|
| oosmos_sComposite A_State;
|
|
| oosmos_sLeaf A_AA_State;
|
|
| oosmos_sFinal A_Final1_State;
|
|
| oosmos_sComposite B_State;
|
|
| oosmos_sLeaf B_BB_State;
|
|
| oosmos_sFinal B_Final2_State;
|
|
| oosmos_sLeaf Exiting_State;
|
|
| //<<<DECL
|
|
| |
|
| };
|
|
| |
|
| //>>>CODE
|
|
| static void OOSMOS_Action_97af96b2(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| printf("Count: %u\n", Count);
|
|
| ActionCount = Count;
|
|
| printf("%s\n", oosmos_IsInState(pTest, &pTest->ROOT) ? "SUCCESS" : "FAILURE");
|
|
| |
|
| oosmos_UNUSED(pState);
|
|
| oosmos_UNUSED(pEvent);
|
|
| }
|
|
| |
|
| static bool A_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_EXIT: {
|
|
| Count++;
|
|
| return true;
|
|
| }
|
|
| case oosmos_DEFAULT: {
|
|
| Count = 0;
|
|
| printf("INITIAL\n");
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_TransitionAction(pTest, pState, B_State, pEvent, OOSMOS_Action_97af96b2);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool A_AA_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
[...] |
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_EXIT: {
|
|
| Count++;
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, A_Final1_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool B_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| Count++;
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, Exiting_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool B_BB_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| test * pTest = (test *) pObject;
|
|
| |
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| Count++;
|
|
| return true;
|
|
| }
|
|
| case oosmos_COMPLETE: {
|
|
| return oosmos_Transition(pTest, pState, B_Final2_State);
|
|
| }
|
|
| }
|
|
| |
|
| return false;
|
|
| }
|
|
| |
|
| static bool Exiting_State_Code(void * pObject, oosmos_sState * pState, const oosmos_sEvent * pEvent)
|
|
| {
|
|
| switch (oosmos_EventCode(pEvent)) {
|
|
| case oosmos_ENTER: {
|
|
| printf("%s\n", ActionCount == 2 ? "SUCCESS" : "FAILURE");
|
|
| oosmos_EndProgram(1);
|
|
| return true;
|
|
| }
|
|
| }
|
|
| |
|
| oosmos_UNUSED(pObject);
|
|
| oosmos_UNUSED(pState);
|
|
| return false;
|
|
| }
|
|
| //<<<CODE
|
|
| |
|
| static test * testNew(void)
|
|
| {
|
|
| oosmos_Allocate(pTest, test, 1, NULL);
|
|
| |
|
| //>>>INIT
|
|
| oosmos_StateMachineInitNoQueue(pTest, ROOT, NULL, A_State);
|
|
| oosmos_CompositeInit(pTest, A_State, ROOT, A_AA_State, A_State_Code);
|
|
| oosmos_LeafInit(pTest, A_AA_State, A_State, A_AA_State_Code);
|
|
| oosmos_FinalInit(pTest, A_Final1_State, A_State, NULL);
|
|
| oosmos_CompositeInit(pTest, B_State, ROOT, B_BB_State, B_State_Code);
|
|
| oosmos_LeafInit(pTest, B_BB_State, B_State, B_BB_State_Code);
|
|
| oosmos_FinalInit(pTest, B_Final2_State, B_State, NULL);
|
|
| oosmos_LeafInit(pTest, Exiting_State, ROOT, Exiting_State_Code);
|
|
| |
|
| oosmos_Debug(pTest, NULL);
|
|
| //<<<INIT
|
|
| |
|
| return pTest;
|
|
| }
|
|
| |
|
| extern int main(void)
|
|
| {
|
|
| (void) testNew();
|
|
| |
|
| for (;;) {
|
|
| oosmos_RunStateMachines();
|
|
| oosmos_DelayMS(1);
|
|
| }
|
|
| }
|
|
oosmos_UNUSED
oosmos_UNUSED assures that a reference is made to a function argument.
Prevents compiler or LINT messages. Usually used by the OOSMOS code generator.
oosmos_US2Days_Rounded
oosmos_US2Days_Rounded is a macro that converts microseconds to days with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_US2Days_Rounded(Microseconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_US2Days_Truncated
oosmos_US2Days_Truncated is a macro that converts microseconds to days with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_US2Days_Truncated(Microseconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_US2Hours_Rounded
oosmos_US2Hours_Rounded is a macro that converts microseconds to hours with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_US2Hours_Rounded(Microseconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_US2Hours_Truncated
oosmos_US2Hours_Truncated is a macro that converts microseconds to hours with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
| 1 |
| 2 |
| 3 |
| |
|
| oosmos_US2Hours_Truncated(Microseconds) |
|
| |
|
Macro
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_US2Minutes_Rounded
oosmos_US2Minutes_Rounded is a macro that converts microseconds to minutes with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_US2Minutes_Truncated
oosmos_US2Minutes_Truncated is a macro that converts microseconds to minutes with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_US2MS_Rounded
oosmos_US2MS_Rounded is a macro that converts microseconds to milliseconds with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_US2MS_Truncated
oosmos_US2MS_Truncated is a macro that converts microseconds to milliseconds with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded, US2Seconds_Truncated |
oosmos_US2Seconds_Rounded
oosmos_US2Seconds_Rounded is a macro that converts microseconds to seconds with the result being
rounded for better precision. If speed is more important than accuracy, see the truncated version
of this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Truncated |
oosmos_US2Seconds_Truncated
oosmos_US2Seconds_Truncated is a macro that converts microseconds to seconds with the result being
truncated due to default integral division behavior. If precision is important, see the rounded version of
this macro.
See Also |
Days2Hours, Days2MS, Days2Minutes, Days2Seconds, Days2US, Divide_Integral_Rounded, Hours2Days_Rounded, Hours2Days_Truncated, Hours2MS, Hours2Minutes, Hours2Seconds, Hours2US, MS2Days_Rounded, MS2Days_Truncated, MS2Hours_Rounded, MS2Hours_Truncated, MS2Minutes_Rounded, MS2Minutes_Truncated, MS2Seconds_Rounded, MS2Seconds_Truncated, MS2US, Minutes2Days_Rounded, Minutes2Days_Truncated, Minutes2Hours_Rounded, Minutes2Hours_Truncated, Minutes2MS, Minutes2Seconds, Minutes2US, Seconds2Days_Rounded, Seconds2Days_Truncated, Seconds2Hours_Rounded, Seconds2Hours_Truncated, Seconds2MS, Seconds2Minutes_Rounded, Seconds2Minutes_Truncated, Seconds2US, US2Days_Rounded, US2Days_Truncated, US2Hours_Rounded, US2Hours_Truncated, US2MS_Rounded, US2MS_Truncated, US2Minutes_Rounded, US2Minutes_Truncated, US2Seconds_Rounded |