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 118), then create an
oosmos_sActiveObject
member in your object
(line 54) and then
finally call
oosmos_ActiveObjectInit
(line 66).
pObject |
Pointer to your active object.
|
pActiveObject |
Pointer to the oosmos_sActiveObject object member.
|
pFunction |
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 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
//
|
[GPLv2] |
|
// OOSMOS sw Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
|
|
oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
|
|
return pSwitch;
|
|
}
|
|
|
|
extern sw * swNew(pin * pPin)
|
[...] |
|
{
|
|
sw * pSwitch = swNewDetached(pPin);
|
|
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;
|
|
}
|
|
else {
|
|
return pSwitch->m_State == Closed_State;
|
|
}
|
|
}
|
|
|
|
extern void swRunStateMachine(void * pObject)
|
|
{
|
|
oosmos_POINTER_GUARD(pObject);
|
|
|
|
sw * pSwitch = (sw *) pObject;
|
|
|
|
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 82.
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 97 below.)
|
Type |
The data type of the object. (See line 29 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 23-25 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 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#ifndef toggleMAX
|
|
#define toggleMAX 5
|
|
#endif
|
|
|
|
//===================================
|
[...] |
|
|
|
#include "oosmos.h"
|
|
#include "toggle.h"
|
|
#include "pin.h"
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.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 83 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 90).
|
Type |
The data type of the object. (See line 32 of Interrupt.c .)
|
List |
The address of the array of objects you pre-allocated.
(See line 46.)
|
Count |
The number of objects that have been returned from
oosmos_AllocateVisible .
(See line 47.)
|
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 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
//
|
[GPLv2] |
|
// OOSMOS - Interrupt structure example on Windows
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
|
|
//
|
|
// Demonstrates structure of how to react to interrupts using OOSMOS.
|
|
//
|
|
|
|
typedef struct uartTag uart;
|
|
|
|
struct uartTag
|
struct uartTag {...} |
|
{
|
|
uint8_t m_UartId;
|
|
|
|
oosmos_sQueue m_ReceiveDataQueue;
|
|
uint8_t m_ReceiveDataQueueData[10];
|
|
|
|
oosmos_sActiveObject m_ActiveObject;
|
|
};
|
|
|
|
#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;
|
|
|
|
//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);
|
|
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 36, 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 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
//
|
[GPLv2] |
|
// OOSMOS AnalogMap Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include <stdio.h>
|
[...] |
|
#include <stdint.h>
|
|
#include "oosmos.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 + .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 int32_t Min = 1;
|
|
const int32_t Max = 1000;
|
|
|
|
//
|
|
// Test accurate implementation...
|
|
//
|
|
for (unsigned I = Min; I <= Max; I++) {
|
|
TestAccurate((double) I, (double) Min, (double) Max, 1.0, 25.0);
|
|
}
|
|
|
|
for (unsigned I = 1; I <= ITERATIONS; I++) {
|
|
printf("%d\n", AccurateDistribution[I]);
|
|
}
|
|
|
|
//
|
|
// Test fast implementation...
|
|
//
|
|
for (int32_t I = Min; I <= Max; I++) {
|
|
TestFast(I, Min, Max, 1, 25);
|
|
}
|
|
|
|
for (unsigned 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 thqan speed, use
oosmos_AnalogMapAccurate
.
See example on
line 46, 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 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
//
|
[GPLv2] |
|
// OOSMOS AnalogMap Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include <stdio.h>
|
[...] |
|
#include <stdint.h>
|
|
#include "oosmos.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 + .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 int32_t Min = 1;
|
|
const int32_t Max = 1000;
|
|
|
|
//
|
|
// Test accurate implementation...
|
|
//
|
|
for (unsigned I = Min; I <= Max; I++) {
|
|
TestAccurate((double) I, (double) Min, (double) Max, 1.0, 25.0);
|
|
}
|
|
|
|
for (unsigned I = 1; I <= ITERATIONS; I++) {
|
|
printf("%d\n", AccurateDistribution[I]);
|
|
}
|
|
|
|
//
|
|
// Test fast implementation...
|
|
//
|
|
for (int32_t I = Min; I <= Max; I++) {
|
|
TestFast(I, Min, Max, 1, 25);
|
|
}
|
|
|
|
for (unsigned 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 |
|
//
|
[GPLv2] |
|
// OOSMOS reg Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "reg.h"
|
[...] |
|
#include "oosmos.h"
|
|
#include <stdint.h>
|
|
|
|
struct regTag
|
|
{
|
|
float m_Intercept;
|
|
float m_Slope;
|
|
};
|
|
|
|
static float MeanOfX(const regSample * pSamples, uint32_t Samples)
|
|
{
|
|
float Sum = 0.0f;
|
|
|
|
for (uint32_t SampleIndex = 0; SampleIndex < Samples; SampleIndex++) {
|
|
Sum += pSamples[SampleIndex].X;
|
|
}
|
|
|
|
return Sum / Samples;
|
|
}
|
|
|
|
static float MeanOfY(const regSample * pSamples, uint32_t Samples)
|
|
{
|
|
float Sum = 0.0f;
|
|
|
|
for (uint32_t SampleIndex = 0; SampleIndex < Samples; SampleIndex++) {
|
|
Sum += pSamples[SampleIndex].Y;
|
|
}
|
|
|
|
return Sum / Samples;
|
|
}
|
|
|
|
extern reg * regNew(void)
|
|
{
|
|
static reg Reg[1];
|
|
reg * pReg = &Reg[0];
|
|
|
|
return pReg;
|
|
}
|
|
|
|
extern void regSamples(reg * pReg, const regSample * pSamples, uint32_t Samples)
|
|
{
|
|
const float MeanX = MeanOfX(pSamples, Samples);
|
|
const float MeanY = MeanOfY(pSamples, Samples);
|
|
|
|
float SumXY = 0.0f;
|
|
float SumXX = 0.0f;
|
|
|
|
for (uint32_t SampleIndex = 0; SampleIndex < Samples; SampleIndex++) {
|
|
const regSample * pSample = &pSamples[SampleIndex];
|
|
|
|
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;
|
|
}
|
|
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 122 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 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
//
|
[GPLv2] |
|
// OOSMOS Final Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
//<<<EVENTS
|
|
//>>>EVENTS
|
|
|
|
typedef struct testTag test;
|
|
|
|
struct testTag
|
|
{
|
|
//>>>DECL
|
|
oosmos_sStateMachineNoQueue(ROOT);
|
|
oosmos_sComposite A_State;
|
|
oosmos_sLeaf 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_LeafInit(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 = (test *) 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 168 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
pStateMachine |
The address of the object's state machine.
|
pNameTable |
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 |
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
//
|
[GPLv2] |
|
// OOSMOS Completion Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_Moving_State;
|
|
oosmos_sLeaf Ortho_Region1_Idle_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_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_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_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_Moving_State, Ortho_Region1_State, Ortho_Region1_Moving_State_Code);
|
|
oosmos_LeafInit(pTest, Ortho_Region1_Idle_State, Ortho_Region1_State, Ortho_Region1_Idle_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 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 |
|
296 |
|
//
|
[GPLv2] |
|
// OOSMOS EventDemo example, control object
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include "control.h"
|
|
#include "motor.h"
|
|
#include "pump.h"
|
|
#include "pin.h"
|
|
#include "sw.h"
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.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_Idle_State;
|
|
oosmos_sLeaf Operational_Region2_Pumping_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_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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
//<<<CODE
|
|
|
|
extern control * controlNew(void)
|
|
{
|
|
oosmos_Allocate(pControl, control, 1, NULL);
|
|
|
|
oosmos_sQueue * const pControlEventQueue = &pControl->m_EventQueue;
|
|
|
|
pin * pStopPin = pinNew('s', pinActiveHigh);
|
|
sw * pStopSwitch = swNew(pStopPin);
|
|
swSubscribeCloseEvent(pStopSwitch, pControlEventQueue, evStopPressed, NULL);
|
|
swSubscribeOpenEvent(pStopSwitch, pControlEventQueue, evStopReleased, NULL);
|
|
|
|
pin * pMovePin = pinNew('m', pinActiveHigh);
|
|
sw * pMoveSwitch = swNew(pMovePin);
|
|
swSubscribeCloseEvent(pMoveSwitch, pControlEventQueue, evMovePressed, NULL);
|
|
|
|
pin * pQuitPin = pinNew('q', pinActiveHigh);
|
|
sw * pQuitSwitch = swNew(pQuitPin);
|
|
swSubscribeCloseEvent(pQuitSwitch, pControlEventQueue, evQuitPressed, NULL);
|
|
|
|
pin * pPumpPin = pinNew('p', pinActiveHigh);
|
|
sw * pPumpSwitch = swNew(pPumpPin);
|
|
swSubscribeCloseEvent(pPumpSwitch, pControlEventQueue, evPumpPressed, NULL);
|
|
|
|
pin * pOption1Pin = pinNew('1', pinActiveHigh);
|
|
sw * pOption1Switch = swNew(pOption1Pin);
|
|
swSubscribeCloseEvent(pOption1Switch, pControlEventQueue, evOption1Pressed, NULL);
|
|
|
|
pin * pOption2Pin = pinNew('2', pinActiveHigh);
|
|
sw * pOption2Switch = swNew(pOption2Pin);
|
|
swSubscribeCloseEvent(pOption2Switch, pControlEventQueue, evOption2Pressed, NULL);
|
|
|
|
pin * pUpPin = pinNew('u', pinActiveHigh);
|
|
sw * pUpSwitch = swNew(pUpPin);
|
|
|
|
pin * pDownPin = pinNew('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_Idle_State, Operational_Region2_State, Operational_Region2_Idle_State_Code);
|
|
oosmos_LeafInit(pControl, Operational_Region2_Pumping_State, Operational_Region2_State, Operational_Region2_Pumping_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 61 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 |
|
//
|
[GPLv2] |
|
// OOSMOS Final Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
//<<<EVENTS
|
|
//>>>EVENTS
|
|
|
|
typedef struct testTag test;
|
|
|
|
struct testTag
|
|
{
|
|
//>>>DECL
|
|
oosmos_sStateMachineNoQueue(ROOT);
|
|
oosmos_sComposite A_State;
|
|
oosmos_sLeaf 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_LeafInit(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 = (test *) 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 29 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 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
//
|
[GPLv2] |
|
// OOSMOS DelayMS Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include <stdio.h>
|
|
#include "oosmos.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 29 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_ThreadDelayMS
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 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
//
|
[GPLv2] |
|
// OOSMOS DelaySeconds Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include <stdio.h>
|
|
#include "oosmos.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 29 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 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
//
|
[GPLv2] |
|
// OOSMOS DelayUS Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_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 53 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 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 52 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 |
|
//
|
[...] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_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 73 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 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 126 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 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
//
|
[GPLv2] |
|
// OOSMOS Final Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
//<<<EVENTS
|
|
//>>>EVENTS
|
|
|
|
typedef struct testTag test;
|
|
|
|
struct testTag
|
|
{
|
|
//>>>DECL
|
|
oosmos_sStateMachineNoQueue(ROOT);
|
|
oosmos_sComposite A_State;
|
|
oosmos_sLeaf 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_LeafInit(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 = (test *) 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_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 wrap around 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_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 142 of the code snippet
below for an example.
pStateMachine |
The address of the state machine within the object.
|
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 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
//
|
[GPLv2] |
|
// OOSMOS Final Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
//<<<EVENTS
|
|
//>>>EVENTS
|
|
|
|
typedef struct testTag test;
|
|
|
|
struct testTag
|
|
{
|
|
//>>>DECL
|
|
oosmos_sStateMachineNoQueue(ROOT);
|
|
oosmos_sComposite A_State;
|
|
oosmos_sLeaf 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_LeafInit(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 = (test *) 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 92 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 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_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(Hours) |
|
|
|
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(Hours) |
|
|
|
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(Hours) |
|
|
|
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(Hours) |
|
|
|
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_ObjectThreadInit
Creates an Object Thread.
See line 38 for an
example of the declaration and line 65 for an
example of its creation. See lines
45-59 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 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#ifndef toggleMAX
|
|
#define toggleMAX 5
|
|
#endif
|
|
|
|
//===================================
|
|
|
|
#include "oosmos.h"
|
|
#include "toggle.h"
|
|
#include "pin.h"
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.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_ObjectThreadStart
Starts a previously created Object Thread.
pObject |
Pointer to the object.
|
See Also |
|
oosmos_ObjectThreadStop
Stops an Object Thread. Use
oosmos_ObjectThreadStart
to restart it.
pObject |
Pointer to the object.
|
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 157 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 |
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
//
|
[GPLv2] |
|
// OOSMOS Completion Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_Moving_State;
|
|
oosmos_sLeaf Ortho_Region1_Idle_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_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_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_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_Moving_State, Ortho_Region1_State, Ortho_Region1_Moving_State_Code);
|
|
oosmos_LeafInit(pTest, Ortho_Region1_Idle_State, Ortho_Region1_State, Ortho_Region1_Idle_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 100 of the code snippet
below for an example.
pObject |
The address of the object that contains 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 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
//
|
[GPLv2] |
|
// OOSMOS EnterExit Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 47 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 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#ifndef toggleMAX
|
[...] |
|
#define toggleMAX 5
|
|
#endif
|
|
|
|
//===================================
|
|
|
|
#include "oosmos.h"
|
|
#include "toggle.h"
|
|
#include "pin.h"
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.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 and this is the current active state.
See line 150 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 |
|
314 |
|
315 |
|
316 |
|
317 |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
//
|
[GPLv2] |
|
// OOSMOS Poll Test
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 pointer.
|
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 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
//
|
[GPLv2] |
|
// OOSMOS ThreadEvents Test
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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;
|
|
|
|
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
127 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.
|
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 |
|
//
|
[GPLv2] |
|
// OOSMOS - EventDemo example, motor object
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 248 and 250 in the code snippet below for examples.
pQueue |
Pointer to a oosmos_sQueue item that holds the
meta data for the queue.
|
pQueueData |
A pointer to an array that will hold the data for the queue.
oosmos_QueueConstruct is a macro that requires that
the memory area be an array in order to
properly calculate queue limits.
|
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 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
//
|
[GPLv2] |
|
// OOSMOS uart Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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);
|
|
|
|
oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData);
|
|
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 123 and 138 in the code snippet below for examples.
pQueue |
Pointer to a oosmos_sQueue item that holds the
meta data 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 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
//
|
[GPLv2] |
|
// OOSMOS uart Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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);
|
|
|
|
oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData);
|
|
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
program will loop forever.
See lines 183 and 207 in the code snippet below for examples.
pQueue |
Pointer to a oosmos_sQueue item that holds the
meta data 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 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
//
|
[GPLv2] |
|
// OOSMOS uart Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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);
|
|
|
|
oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData);
|
|
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_RunStateMachine
This API is experimental and may change.
See example on line 222 in
the code snippet.
pStateMachine |
Address of the state machine within the object.
|
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 |
|
//
|
[GPLv2] |
|
// OOSMOS motion Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_sLeaf Active_Region1_Limits_Choice1_State;
|
|
oosmos_sLeaf Active_Region1_Limits_AtLowerLimit_State;
|
|
oosmos_sOrthoRegion Active_Region2_State;
|
|
oosmos_sComposite Active_Region2_Moving_State;
|
|
oosmos_sLeaf Active_Region2_Moving_Up_State;
|
|
oosmos_sLeaf Active_Region2_Moving_Down_State;
|
|
oosmos_sLeaf Active_Region2_Stopped_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_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_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_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_LeafInit(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_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_LeafInit(pMotion, Active_Region2_Stopped_State, Active_Region2_State, Active_Region2_Stopped_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 42 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 |
|
//
|
[GPLv2] |
|
// OOSMOS Blink Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_sComposite
oosmos_sComposite
declares a composite state in
an
OOSMOS
state machine object.
See line 36 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 |
|
//
|
[GPLv2] |
|
// OOSMOS Final Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
//<<<EVENTS
|
|
//>>>EVENTS
|
|
|
|
typedef struct testTag test;
|
|
|
|
struct testTag
|
|
{
|
|
//>>>DECL
|
|
oosmos_sStateMachineNoQueue(ROOT);
|
|
oosmos_sComposite A_State;
|
|
oosmos_sLeaf 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_LeafInit(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 = (test *) 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 principle event structure. It
holds an event code called
Code
and a context pointer
called
pContext
.
See line 47 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 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
//
|
[GPLv2] |
|
// OOSMOS - EventDemo example, motor object
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 40 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 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
//
|
[GPLv2] |
|
// OOSMOS Final Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
//<<<EVENTS
|
|
//>>>EVENTS
|
|
|
|
typedef struct testTag test;
|
|
|
|
struct testTag
|
|
{
|
|
//>>>DECL
|
|
oosmos_sStateMachineNoQueue(ROOT);
|
|
oosmos_sComposite A_State;
|
|
oosmos_sLeaf 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_LeafInit(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 = (test *) 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_sLeaf
oosmos_sLeaf
declares a leaf state in
an
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 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 38 for an
example of the declaration and line 65 for an
example of its creation. See lines
45-59 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 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#ifndef toggleMAX
|
|
#define toggleMAX 5
|
|
#endif
|
|
|
|
//===================================
|
|
|
|
#include "oosmos.h"
|
|
#include "toggle.h"
|
|
#include "pin.h"
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.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 53 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 |
|
//
|
[GPLv2] |
|
// OOSMOS EnterExit Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 54 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 |
|
//
|
[GPLv2] |
|
// OOSMOS EnterExit Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 46.
The other stores data to be sent.
See line 41.
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 |
|
//
|
[GPLv2] |
|
// OOSMOS uart Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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);
|
|
|
|
oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData);
|
|
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 meta data 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 52 in the code snippet
below for an example.
StateMachine |
The name of the state machine. Conventionally, should always
be StateMachine .
|
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 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
//
|
[GPLv2] |
|
// OOSMOS EnterExit Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 37 in the code snippet
below for an example.
StateMachine |
The name of the state machine. Conventionally, should always
be StateMachine .
|
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 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_SubscriberList
is a data type that holds a
list of subscribers interested in the occurrence of a
particular event.
See lines
55 and
56 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 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
//
|
[GPLv2] |
|
// OOSMOS sw Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
|
|
oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
|
|
return pSwitch;
|
|
}
|
|
|
|
extern sw * swNew(pin * pPin)
|
|
{
|
|
sw * pSwitch = swNewDetached(pPin);
|
|
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;
|
|
}
|
|
else {
|
|
return pSwitch->m_State == Closed_State;
|
|
}
|
|
}
|
|
|
|
extern void swRunStateMachine(void * pObject)
|
|
{
|
|
oosmos_POINTER_GUARD(pObject);
|
|
|
|
sw * pSwitch = (sw *) pObject;
|
|
|
|
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_StateMachineInit
oosmos_StateMachineInit
initializes an
oosmos_sStateMachine
object member.
See line 110 of the code snippet
below for an example.
pObject |
The address of the object that contains 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 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
//
|
[GPLv2] |
|
// OOSMOS - EventDemo example, motor object
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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 91 of the code snippet
below for an example.
pObject |
The address of the object that contains 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 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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, 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 52 for an example
of setting the timeout and
line 54 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 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
//
|
[GPLv2] |
|
// OOSMOS StateTimeout Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdint.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, 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 68 for an example
of setting the timeout and
line 70 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 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
//
|
[GPLv2] |
|
// OOSMOS StateTimeout Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdint.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, 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 84 for an example
of setting the timeout and
line 86 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 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
//
|
[GPLv2] |
|
// OOSMOS StateTimeout Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdint.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 meta data
supporting the
oosmos_TimeoutInSeconds
call. See
line 34, line 39 and
line 47 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 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
//
|
[GPLv2] |
|
// OOSMOS TimeoutInSeconds Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
|
#include <stdio.h>
|
|
#include <stdint.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 55 and
68,
84 and 128 in the code snippet below for an example.
pSubscriberList |
Pointer to a oosmos_sSubscriberList member inside an
OOSMOS object.
|
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 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
//
|
[GPLv2] |
|
// OOSMOS sw Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
|
|
oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
|
|
return pSwitch;
|
|
}
|
|
|
|
extern sw * swNew(pin * pPin)
|
[...] |
|
{
|
|
sw * pSwitch = swNewDetached(pPin);
|
|
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;
|
|
}
|
|
else {
|
|
return pSwitch->m_State == Closed_State;
|
|
}
|
|
}
|
|
|
|
extern void swRunStateMachine(void * pObject)
|
|
{
|
|
oosmos_POINTER_GUARD(pObject);
|
|
|
|
sw * pSwitch = (sw *) pObject;
|
|
|
|
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 55 and
68,
84 and 128 in the code snippet below for an example.
pSubscriberList |
Pointer to a oosmos_sSubscriberList member inside an
OOSMOS object.
|
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 |
|
//
|
[GPLv2] |
|
// OOSMOS sw Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
|
|
oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
|
|
return pSwitch;
|
|
}
|
|
|
|
extern sw * swNew(pin * pPin)
|
[...] |
|
{
|
|
sw * pSwitch = swNewDetached(pPin);
|
|
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;
|
|
}
|
|
else {
|
|
return pSwitch->m_State == Closed_State;
|
|
}
|
|
}
|
|
|
|
extern void swRunStateMachine(void * pObject)
|
|
{
|
|
oosmos_POINTER_GUARD(pObject);
|
|
|
|
sw * pSwitch = (sw *) pObject;
|
|
|
|
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 55 and
68,
84 and 128 in the code snippet below for an example.
pSubscriberList |
Pointer to a oosmos_sSubscriberList member inside an
OOSMOS object.
|
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 |
|
//
|
[GPLv2] |
|
// OOSMOS sw Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_ActiveObjectInit(pSwitch, m_ActiveObject, swRunStateMachine);
|
|
|
|
oosmos_SubscriberListInit(pSwitch->m_CloseEvent);
|
|
oosmos_SubscriberListInit(pSwitch->m_OpenEvent);
|
|
|
|
return pSwitch;
|
|
}
|
|
|
|
extern sw * swNew(pin * pPin)
|
[...] |
|
{
|
|
sw * pSwitch = swNewDetached(pPin);
|
|
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;
|
|
}
|
|
else {
|
|
return pSwitch->m_State == Closed_State;
|
|
}
|
|
}
|
|
|
|
extern void swRunStateMachine(void * pObject)
|
|
{
|
|
oosmos_POINTER_GUARD(pObject);
|
|
|
|
sw * pSwitch = (sw *) pObject;
|
|
|
|
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 128 in the code snippet below
for an example.
pSubscriberList |
Pointer to a oosmos_sSubscriberList member inside an
OOSMOS object.
|
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 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
//
|
[GPLv2] |
|
// OOSMOS uart Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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);
|
|
|
|
oosmos_QueueConstruct(&pUART->m_ReceiveDataQueue, pUART->m_ReceiveDataQueueData);
|
|
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 and
oosmos_POLL
event handler.
See line 50 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 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#ifndef toggleMAX
|
[...] |
|
#define toggleMAX 5
|
|
#endif
|
|
|
|
//===================================
|
|
|
|
#include "oosmos.h"
|
|
#include "toggle.h"
|
|
#include "pin.h"
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.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 53 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 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#ifndef toggleMAX
|
[...] |
|
#define toggleMAX 5
|
|
#endif
|
|
|
|
//===================================
|
|
|
|
#include "oosmos.h"
|
|
#include "toggle.h"
|
|
#include "pin.h"
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.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 37 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 |
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 |
|
//
|
[GPLv2] |
|
// OOSMOS ThreadDelaySeconds Test
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
|
|
typedef struct
|
|
{
|
|
oosmos_sObjectThread m_ObjectThread;
|
|
} test;
|
|
|
|
static void Thread(test * pTest, oosmos_sState * pState)
|
|
{
|
|
oosmos_ThreadBegin();
|
|
printf("Wait for 3 seconds...\n");
|
|
|
|
oosmos_ThreadDelaySeconds(3);
|
|
|
|
printf("Done. 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/ThreadDelaySeconds.c
oosmos_ThreadDelayUS
oosmos_ThreadDelayUS
blocks the thread for
the specified number of
Microseconds
.
See line 44 in the code snippet
below for an example.
Milliseconds |
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 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
//
|
[GPLv2] |
|
// OOSMOS ThreadDelayUS Test
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdint.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 and
oosmos_POLL
event handler.
See line 58 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 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#ifndef toggleMAX
|
[...] |
|
#define toggleMAX 5
|
|
#endif
|
|
|
|
//===================================
|
|
|
|
#include "oosmos.h"
|
|
#include "toggle.h"
|
|
#include "pin.h"
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.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 181 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 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
//
|
[GPLv2] |
|
// OOSMOS threadtest Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include "prt.h"
|
|
#include "threadtest.h"
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.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_ThreadEnd();
|
|
}
|
|
|
|
static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
{
|
|
oosmos_ThreadBegin();
|
|
bool TimedOut;
|
|
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;
|
|
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_Action1(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_Action1);
|
|
}
|
|
}
|
|
|
|
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 182 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 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
//
|
[GPLv2] |
|
// OOSMOS threadtest Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include "prt.h"
|
|
#include "threadtest.h"
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.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_ThreadEnd();
|
|
}
|
|
|
|
static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
{
|
|
oosmos_ThreadBegin();
|
|
bool TimedOut;
|
|
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;
|
|
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_Action1(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_Action1);
|
|
}
|
|
}
|
|
|
|
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 113 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 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
//
|
[GPLv2] |
|
// OOSMOS threadtest Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include "prt.h"
|
|
#include "threadtest.h"
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.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_ThreadEnd();
|
|
}
|
|
|
|
static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
[...] |
|
{
|
|
oosmos_ThreadBegin();
|
|
bool TimedOut;
|
|
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;
|
|
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_Action1(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_Action1);
|
|
}
|
|
}
|
|
|
|
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 155 in the code snippet below
for examples.
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 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
//
|
[GPLv2] |
|
// OOSMOS threadtest Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include "prt.h"
|
|
#include "threadtest.h"
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.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_ThreadEnd();
|
|
}
|
|
|
|
static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
{
|
|
oosmos_ThreadBegin();
|
|
bool TimedOut;
|
|
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;
|
|
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_Action1(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_Action1);
|
|
}
|
|
}
|
|
|
|
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 141 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 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
//
|
[GPLv2] |
|
// OOSMOS threadtest Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include "prt.h"
|
|
#include "threadtest.h"
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.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_ThreadEnd();
|
|
}
|
|
|
|
static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
{
|
|
oosmos_ThreadBegin();
|
|
bool TimedOut;
|
|
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;
|
|
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_Action1(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_Action1);
|
|
}
|
|
}
|
|
|
|
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 155 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 condition
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 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
//
|
[GPLv2] |
|
// OOSMOS threadtest Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include "prt.h"
|
|
#include "threadtest.h"
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.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_ThreadEnd();
|
|
}
|
|
|
|
static void WaitCond_TimeoutMS_Thread(threadtest * pThreadTest, oosmos_sState * pState)
|
|
{
|
|
oosmos_ThreadBegin();
|
|
bool TimedOut;
|
|
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;
|
|
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_Action1(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_Action1);
|
|
}
|
|
}
|
|
|
|
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 51 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 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
//
|
[GPLv2] |
|
// OOSMOS threadyieldtest class implementation
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include "prt.h"
|
|
#include "threadyieldtest.h"
|
|
#include <stdlib.h>
|
|
#include <stdbool.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 54 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 |
|
//
|
[GPLv2] |
|
// OOSMOS StateTimeout Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdint.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 47 in the code snippet below
for an example.
pTimeout |
Address of the oosmos_sTimeout meta data 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 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
//
|
[GPLv2] |
|
// OOSMOS TimeoutInMS Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdint.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 39) providing the
address of a
oosmos_sTimeout
object
(line 34), then periodically
check if the timeout has expired using the
oosmos_TimeoutHasExpired
call
(line 47).
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 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
//
|
[GPLv2] |
|
// OOSMOS TimeoutInMS Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdint.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 39) providing the
address of a
oosmos_sTimeout
object
(line 34), then periodically
check if the timeout has expired using the
oosmos_TimeoutHasExpired
call
(line 47).
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 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
//
|
[GPLv2] |
|
// OOSMOS TimeoutInSeconds Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdint.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 39) providing the
address of a
oosmos_sTimeout
object
(line 34), then periodically
check if the timeout has expired using the
oosmos_TimeoutHasExpired
call
(line 47).
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 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
//
|
[GPLv2] |
|
// OOSMOS TimeoutInUS Example
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#include "oosmos.h"
|
[...] |
|
#include <stdio.h>
|
|
#include <stdint.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_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 57.)
Note: In the example, we use the state version of the
toggle
object in the
oosmos/Classes
directory instead of the
Thread
version.
pFromState |
The same pFromState
argument that was passed into the containing state handler.
|
pToState |
pToState is pointer to 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 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
//
|
[GPLv2] |
|
// OOSMOS toggle Class
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_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 lines 51 and 78.)
Note: In the example, we use the state version of the
toggle
object in the
oosmos/Classes
directory instead of the
Thread
version.
pFromState |
The same pFromState
argument that was passed into the containing state handler.
|
pToState |
pToState is pointer to the state we are transitioning to.
|
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 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
//
|
[GPLv2] |
|
// OOSMOS Action Test
|
|
//
|
|
// Copyright (C) 2014-2020 OOSMOS, LLC
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2 of the License ("GPLv2").
|
|
//
|
|
// This software may be used without the GPLv2 restrictions by entering
|
|
// into a commercial license agreement with OOSMOS, LLC.
|
|
// See <https://www.oosmos.com/licensing/>.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#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_Action1(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_Action1);
|
|
}
|
|
}
|
|
|
|
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 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 |