OOSMOS
object is an object that has
reactive behavior but does not have the complexity to warrant
using a full OOSMOS
state machine object.
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).
1 | |
---|---|
2 | |
3 | |
void oosmos_ActiveObjectInit(void * pObject, oosmos_sActiveObject * pActiveObject, oosmos_tActiveObjectFunc pFunc); | |
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 | |
---|---|
22 | |
23 | |
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 | |
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] | |
[...] | |
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 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
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.
malloc
in place of this function and then
create a complementary toggleDelete
function and then do a
free
to release it.
1 | |
---|---|
2 | |
3 | |
Type * oosmos_Allocate(Pointer, Type, Elements, pOutOfMemory); | |
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 | |
---|---|
22 | |
23 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
[GPLv2] | |
[...] | |
typedef struct toggleTag toggle; | |
extern toggle * toggleNew(pin * pPin, uint32_t TimeOnMS, uint32_t TimeOffMS); | |
#endif |
1 | |
---|---|
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
[GPLv2] | |
#ifndef toggleMAX | |
#define toggleMAX 5 | |
#endif | |
[...] |
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.)
1 | |
---|---|
2 | |
3 | |
Type * oosmos_AllocateVisible(Pointer, Type, List, Count, Elements, pOutOfMemory); | |
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 | |
---|---|
22 | |
23 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
64 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
[GPLv2] | |
[...] | |
// | |
// Demonstrates structure of how to react to interrupts using OOSMOS. | |
// | |
typedef struct uartTag uart; | |
struct uartTag {...} | |
#define MAX_UARTS 5 | |
static uart UartList[MAX_UARTS]; | |
static unsigned UartCount = 0; | |
static void ReceiverStateMachine(...) {...} | |
static void ISR(...) {...} | |
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) {...} |
oosmos_AnalogMapFast
.
1 | |
---|---|
2 | |
3 | |
double oosmos_AnalogMapAccurate(double Value, double InMin, double InMax, double OutMin, double OutMax); | |
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 | |
---|---|
22 | |
23 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
[GPLv2] | |
[...] | |
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]++; | |
} | |
[...] |
oosmos_AnalogMapAccurate
.
1 | |
---|---|
2 | |
3 | |
int32_t oosmos_AnalogMapFast(int32_t Value, int32_t InMin, int32_t InMax, int32_t OutMin, int32_t OutMax)); | |
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 | |
---|---|
22 | |
23 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
[GPLv2] | |
[...] | |
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]++; | |
} | |
[...] |
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 | |
---|---|
22 | |
23 | |
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 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
oosmos_ClockSpeedInMHz
tells OOSMOS
the speed of the processor as configured externally. This call
only applies to the PIC32
architecture.
1 | |
---|---|
2 | |
3 | |
void oosmos_ClockSpeedInMHz(uint32_t ClockSpeedMHz); | |
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
initializes an
oosmos_sComposite
state.
1 | |
---|---|
2 | |
3 | |
void oosmos_CompositeInit(pObject, CompositeState, ParentState, DefaultState, pCode); | |
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 | |
---|---|
22 | |
23 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
oosmos_Days2Hours
is a macro that converts days to hours.
1 | |
---|---|
2 | |
3 | |
oosmos_Days2Hours(Days) | |
oosmos_Days2Minutes
is a macro that converts days to minutes.
1 | |
---|---|
2 | |
3 | |
oosmos_Days2Minutes(Days) | |
oosmos_Days2MS
is a macro that converts days to milliseconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Days2MS(Days) | |
oosmos_Days2Seconds
is a macro that converts days to seconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Days2Seconds(Days) | |
oosmos_Days2US
is a macro that converts days to microseconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Days2US(Days) | |
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 | |
oosmos_Debug(oosmos_sStateMachine * pStateMachine, const char * (*pNameTable)(int)); | |
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 | |
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 | |
---|---|
22 | |
23 | |
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 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
oosmos_DebugPrint
1 | |
---|---|
22 | |
23 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
[GPLv2] | |
[...] | |
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); | |
} | |
[...] |
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 | |
---|---|
22 | |
23 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
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 | |
void oosmos_DelayMS(uint32_t Milliseconds); | |
See Also |
1 | |
---|---|
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
[GPLv2] | |
#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
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 | |
void oosmos_DelaySeconds(uint32_t Seconds); | |
See Also |
1 | |
---|---|
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
[GPLv2] | |
#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
suspends all processing for a specified
number of microseconds. See
line 29 of the snippet below for an example.
oosmos_TimeoutInUS
instead.
oosmos_DelayUS
is not implemented on Windows.
1 | |
---|---|
2 | |
3 | |
void oosmos_DelayUS(uint32_t Microseconds); | |
See Also |
1 | |
---|---|
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
[GPLv2] | |
#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
is a macro that is used internally by the
time unit conversion APIs, but it is externalized for your use.
1 | |
---|---|
2 | |
3 | |
oosmos_Divide_Integral_Rounded(Dividend, Divisor) | |
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
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 | |
---|---|
22 | |
23 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
[GPLv2] | |
[...] | |
//>>>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; | |
} | |
[...] |
oosmos_EventCode
is a macro that accesses the event code from within an OOSMOS event
structure to improve readability of the generated code.
See Also |
1 | |
---|---|
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
[...] | |
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; | |
} | |
[...] |
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 | |
---|---|
22 | |
23 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
1 | |
---|---|
2 | |
3 | |
void oosmos_FinalInit(pObject, StateName, Parent, pCode); | |
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 | |
---|---|
22 | |
23 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
oosmos_FOREVER
loops forever. Useful to stop a
program once a problem has been programmatically identified.
See Also |
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) | |
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) | |
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) | |
oosmos_Hours2Minutes
is a macro that converts hours to minutes.
1 | |
---|---|
2 | |
3 | |
oosmos_Hours2Minutes(Hours) | |
oosmos_Hours2MS
is a macro that converts hours to milliseconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Hours2MS(Hours) | |
oosmos_Hours2Seconds
is a macro that converts hours to seconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Hours2Seconds(Hours) | |
oosmos_Hours2US
is a macro that converts hours to microseconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Hours2US(Hours) | |
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.
1 | |
---|---|
2 | |
3 | |
bool oosmos_IsInState(const oosmos_sStateMachine * pStateMachine, const oosmos_sState * pState); | |
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 | |
---|---|
22 | |
23 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
[GPLv2] | |
[...] | |
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_LeafInit
initializes an
oosmos_sLeaf
state.
1 | |
---|---|
2 | |
3 | |
void oosmos_LeafInit(pObject, LeafState, ParentState, pCode); | |
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 | |
---|---|
22 | |
23 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
[GPLv2] | |
[...] | |
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_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) | |
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) | |
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.
1 | |
---|---|
2 | |
3 | |
oosmos_Minutes2Hours_Rounded(Minutes) | |
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.
1 | |
---|---|
2 | |
3 | |
oosmos_Minutes2Hours_Truncated(Minutes) | |
oosmos_Minutes2MS
is a macro that converts minutes to milliseconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Minutes2MS(Minutes) | |
oosmos_Minutes2Seconds
is a macro that converts minutes to seconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Minutes2Seconds(Minutes) | |
oosmos_Minutes2US
is a macro that converts minutes to microseconds.
1 | |
---|---|
2 | |
3 | |
oosmos_Minutes2US(Minutes) | |
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) | |
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) | |
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) | |
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) | |
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.
1 | |
---|---|
2 | |
3 | |
oosmos_MS2Minutes_Rounded(Milliseconds) | |
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.
1 | |
---|---|
2 | |
3 | |
oosmos_MS2Minutes_Truncated(Milliseconds) | |
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.
1 | |
---|---|
2 | |
3 | |
oosmos_MS2Seconds_Rounded(Milliseconds) | |
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.
1 | |
---|---|
2 | |
3 | |
oosmos_MS2Seconds_Truncated(Milliseconds) | |
oosmos_MS2US
is a macro that converts milliseconds to microseconds.
1 | |
---|---|
2 | |
3 | |
oosmos_MS2US(Milliseconds) | |
1 | |
---|---|
2 | |
3 | |
void oosmos_ObjectThreadInit(pObject, pObjectThread, pFunc, bRunning); | |
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 | |
---|---|
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] | |
#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; | |
} |
1 | |
---|---|
2 | |
3 | |
void oosmos_ObjectThreadStart(oosmos_ObjectThread * pObject); | |
pObject |
Pointer to the object.
|
See Also |
oosmos_ObjectThreadStart
to restart it.
1 | |
---|---|
2 | |
3 | |
void oosmos_ObjectThreadStop(oosmos_ObjectThread * pObject); | |
pObject |
Pointer to the object.
|
See Also |
oosmos_ORTHO
is a preprocessor macro that, when defined,
compiles in all the OOSMOS
orthogonal state machine features.
#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.
-Doosmos_ORTHO
),
or add a #define
oosmos_ORTHO
at the top of
both oosmos.h
and oosmos.c
.
See Also |
oosmos_OrthoInit
initializes an
oosmos_sOrtho
state.
1 | |
---|---|
2 | |
3 | |
void oosmos_OrthoInit(pObject, OrthoState, ParentState, pCode) | |
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 | |
---|---|
22 | |
23 | |
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 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
oosmos_OrthoRegionInit
initializes an
oosmos_sOrthoRegion
state.
1 | |
---|---|
2 | |
3 | |
void oosmos_OrthoRegionInit(pObject, LeafState, ParentState, DefaultState, pCode); | |
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 | |
---|---|
22 | |
23 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
oosmos_POINTER_GUARD
guarantees that the passed argument is not NULL.
See line 47 in
the code snippet below for an example.
1 | |
---|---|
22 | |
23 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
[GPLv2] | |
[...] | |
}; | |
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(); | |
} | |
[...] |
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 | |
---|---|
22 | |
23 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
[GPLv2] | |
[...] | |
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; | |
} | |
[...] |
1 | |
---|---|
2 | |
3 | |
oosmos_PushEvent(pObject, Event) | |
pObject |
Pointer to the object pointer.
|
Event |
Event object to push onto the object's event queue.
|
See Also |
1 | |
---|---|
22 | |
23 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
[GPLv2] | |
[...] | |
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(); | |
} | |
[...] |
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.
1 | |
---|---|
2 | |
3 | |
bool oosmos_PushEventCode(void * pObject, int EventCode); | |
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 | |
---|---|
22 | |
23 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
[GPLv2] | |
[...] | |
oosmos_PushEventCode(pMotor, evStart); | |
} | |
extern void motorOff(const motor * pMotor) | |
{ | |
oosmos_PushEventCode(pMotor, evStop); | |
} |
oosmos_sQueue
.
1 | |
---|---|
2 | |
3 | |
bool oosmos_QueueConstruct(oosmos_sQueue * pQueue, void * pQueueData); | |
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 | |
---|---|
22 | |
23 | |
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 | |
[GPLv2] | |
[...] | |
} | |
// | |
// '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; | |
} | |
[...] |
oosmos_QueuePop
will pop an element off the queue and copy it into an item
that you allocate.
1 | |
---|---|
2 | |
3 | |
bool oosmos_QueuePop(oosmos_sQueue * pQueue, void * pPoppedItem, size_t ElementSize); | |
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 | |
---|---|
22 | |
23 | |
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 | |
[GPLv2] | |
[...] | |
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; | |
} | |
} | |
} | |
[...] |
ElementSize
onto
the queue specified by pQueue
.
1 | |
---|---|
2 | |
3 | |
void oosmos_QueuePush(oosmos_sQueue * pQueue, const void * pItemToPush, size_t ElementSize); | |
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 | |
---|---|
22 | |
23 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
203 | |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
[GPLv2] | |
[...] | |
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)); | |
} | |
} | |
[...] | |
} | |
extern void uartSendChar(uart * pUART, const char Char) | |
{ | |
oosmos_QueuePush(&pUART->m_SendDataQueue, &Char, sizeof(Char)); | |
} | |
[...] |
1 | |
---|---|
2 | |
3 | |
void oosmos_RunStateMachine(oosmos_sStateMachine * pStateMachine); | |
pStateMachine |
Address of the state machine within the object.
|
See Also |
1 | |
---|---|
22 | |
23 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
[GPLv2] | |
[...] | |
static void QueueEvent(motion * pMotion, int EventCode) | |
{ | |
oosmos_PushEventCode(pMotion, EventCode); | |
oosmos_RunStateMachine(pMotion); | |
} | |
[...] |
oosmos_RunStateMachines
runs all
OOSMOS
state machine objects
as well as all registered Active Objects
(see oosmos_ActiveObjectInit.)
1 | |
---|---|
2 | |
3 | |
void oosmos_RunStateMachines(); | |
1 | |
---|---|
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
[GPLv2] | |
#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_sComposite
declares a composite state in
an OOSMOS
state machine object.
1 | |
---|---|
22 | |
23 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
[GPLv2] | |
[...] | |
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 | |
}; | |
[...] |