Skip to content

Commit f4a8bd1

Browse files
authored
Update README.md
1 parent 86a71ea commit f4a8bd1

1 file changed

Lines changed: 18 additions & 164 deletions

File tree

README.md

Lines changed: 18 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,29 @@
11
# ArduinoProcessScheduler
2-
An Arduino Object Oriented Cooperative Process Scheduler to Replace Them All
2+
An Cooperative Arduino Object Oriented Cooperative Process Scheduler to Replace Them All
33

44
## Features
55
- Fine Grained Control Over How Often a Process Runs (Periodically, Iterations, or as Often as Possible)
6-
- Exception Handling (wait what?!)
7-
- Atomicity Support
6+
- Interrupt safe (add, disable, destroy, etc.. processes from interrupt routines)
7+
- Process concurrency protection (Guarantees your process to be in a valid state when performing actions on it)
88
- Dynamically Add/Remove and Enable/Disable Processes
9-
- Automatic Process Monitoring Statistics (Automatically calculates % CPU time for service)
10-
- Truly object oriented (a Process is no longer just a callback function like other libraries)
11-
12-
## Basic Usage
13-
There are two classes to worry about: `Scheduler` and `Process`.
14-
15-
### Class `Scheduler`:
16-
A `Scheduler` oversees and manages `Processes`. There should only be one `Scheduler` in your project. Inside of `void loop()`, the scheduler's `run()` method should be repeatedly called.
17-
18-
### Class `Process`:
19-
A service can be thought of as job or a task that needs to be run at certain times. Each Process had be scheduled to run Periodically
20-
Constantly, or Periodically/Constantly with a set number of run iterations.
21-
22-
Each project will have multiple services, here are some examples of `Processes`:
23-
- A Process to handle user input
24-
- A Process to run a basic webserver
25-
- A Process to update a display
26-
27-
`Process` is a base class that should be extended to handle your particular Process (such as the examples mentioned above). The scheduler's will call the following virtual function as an entry point when it is time for you service to run:
28-
```
29-
virtual void service();
30-
```
31-
From here your `service()` routine is expected to be non-blocking, and return from `service()` as soon as possible (that means no long `delay()`'s). Fortunately, since your service routine is a method inside a class, you can store the state of your service in custom class attributes before returning, so you know where you left off when the scheduler calls your Process again. As soon you return from `service()`, control is transferred back to the Scheduler (it will also be transferred back if you raise an Exception--advanced).
32-
33-
Additionally, each Process inherits the following virtual functions which are called by the `Scheduler` at the appropriate times. Note you are guaranteed that only one of these methods will exist in the call stack at once, even if an interrupt fires trying to modify this Process at the same time (such as with `add()`, `destroy()`, `enable()`, or `disable()`). This also includes the `service()` method mentioned above. You do not have to worry about concurrency!
34-
35-
**Thanks to the magic of virtual functions, you don't have to impliment any of these unless your particular Process needs them:**
36-
```
37-
virtual void setup()
38-
virtual void cleanup()
39-
40-
virtual void onEnable()
41-
virtual void onDisable()
42-
43-
virtual void overScheduledHandler(uint32_t behind)
44-
```
45-
46-
#### `setup()`
47-
This method is called by the scheduler when the Process is being added to the scheduling chain with `add()`, it is guaranteed to only be called once when a Process not part of the scheduling chain is being added (`add()`). Keep in mind it will still be called if the Process is removed from the scheduling chain with `destroy()`, then added again with `add()`.
48-
49-
#### `cleanup()`
50-
This is only called once when a `Process` part of the scheduling chain is being removed from the scheduling chain with `destroy()`. This method should undo whatever was done in `setup()`. You are guaranteed it will not be called unless `setup()` was called previously.
51-
52-
#### `onEnable()`
53-
This method is called only once when a disabled task is being enabled with `enable()`.
54-
55-
#### `onDisable()`
56-
This method is called only once when a enabled task is being disabled with `disable()`. You are guaranteed it will not be called unless `onEnable()` was called previously. It should undo whatever `onEnable()` did.
57-
58-
#### `overScheduledHandler(uint32_t behind)`
59-
This method is called if the scheduler can not meet the current set period for the Process and is falling behind. The scheduler will pass in variable `behind` containing how many milliseconds (or microseconds) behind the scheduler is with this task. Inside this method might be a good time increase the period between when this task is run, then call `resetSchedulerWarning()` to clear the warning.
60-
61-
62-
## API
63-
### `Scheduler` Methods:
64-
65-
66-
67-
#### Constructor
68-
```
69-
Scheduler()
70-
```
71-
Create a Scheduler object.
72-
73-
**Returns:** `Scheduler`
74-
___
75-
76-
#### run()
77-
```
78-
run()
79-
```
80-
This method runs one pass through the scheduler. It is the heart of the scheaduler, this method should be called repeatedly inside of `void loop()`
81-
82-
**Returns:** `void`
83-
___
84-
85-
86-
#### getID()
87-
```
88-
getID(Process &service)
89-
```
90-
Get the unique id for the service. Same as `service.getID()`.
91-
92-
**Returns:** `uint8_t`
93-
___
94-
95-
#### isRunningProcess()
96-
```
97-
isRunningProcess(Process &service)
98-
```
99-
Determine if the scheduler is in the middle of running this service. Same as calling `service.isRunningProcess()`
100-
101-
**Returns:** `bool`
102-
___
103-
104-
#### isEnabled()
105-
```
106-
isEnabled(Process &service)
107-
```
108-
Determines if this service is enabled. Same as calling `service.isEnabled()`
109-
110-
**Returns:** `bool`
111-
___
112-
113-
#### getCurrProcess()
114-
```
115-
getCurrProcess()
116-
```
117-
Get pointer to the current service being run by the scheduler. Return NULL if no service being currently run.
118-
119-
**Returns:** `Process*`
120-
___
121-
122-
#### countProcesses()
123-
```
124-
countProcesses(bool enabledOnly = true)
125-
```
126-
Get number of servies in the scheduler's chain. If enabledOnly is true, only the enabled Processes will be counted.
127-
128-
**Returns:** `uint8_t`
129-
___
130-
131-
#### getCurrTS()
132-
```
133-
getCurrTS()
134-
```
135-
Returns the current internal timestamp. Either will be the same as `millis()` or `micros()`
136-
137-
**Returns:** `uint32_t`
138-
___
139-
140-
141-
#### add()
142-
```
143-
add (Process &service))
144-
```
145-
Add the service to the scheduler, same as calling `service.add()`. Note, this will trigger the service's `setup()` method to fire. This method can only fail inside an interrupt routine, particularly when an interrupt interrupts any call to either `add()` or `remove()`. It will also fail if the service is already added.
146-
147-
**Returns:** type `SchedulerAction`, `ACTION_NONE` on failure, `ACTION_SUCCESS` on success.
148-
___
9+
- Easily spawn new processes from within running processes
10+
- Automatic Process Monitoring Statistics (Automatically calculates % CPU time for process)
11+
- Truly object oriented (a Process is no longer just a callback function like other libraries, but its own object)
12+
- Exception Handling (wait what?!)
13+
- Scheduler can automatically terminate stuck processes
14914

150-
#### destroy()
151-
```
152-
destroy (Process &service))
153-
```
154-
Remove the service from the scheduler. Same as calling `service.destroy()`. Note, this will trigger the service's `cleanup()` method to fire. If the service is not disabled, it will first call `disable()`. This method can only fail inside an interrupt routine, particularly when an interrupt interrupts any call to either `add()` or `remove()`. It will first try and QUEUE the request for later, before failing. It will also fail if the service is already destroyed.
15+
## Important Notes
16+
- This is not a preemptive scheduler! However by not being one, processes get to use the entire stack when they run.
17+
- This library was inspired from this [TaskScheduler](https://github.com/arkhipenko/TaskScheduler) library.
15518

156-
**Returns:** type `SchedulerAction`, `ACTION_NONE` on failure, `ACTION_QUEUED` on Queuing it, `ACTION_SUCCESS` on success.
157-
___
19+
## Supported Platfroms
20+
- AVR
21+
- ESP8266 (No exception handling or process timeouts)
15822

159-
#### enable()
160-
```
161-
enable (Process &service))
162-
```
163-
Enable a service, same as calling `service.enable()`. Note, this will trigger the service's `onEnable()` method to fire. This method call will always succeed if it was not called on itself from a method inside of this service. If it was, the scheduler will queue the request. Also, the request will fail if the service is already enabled or is destroyed.
16423

165-
**Returns:** type `SchedulerAction`, `ACTION_NONE` on failure, `ACTION_QUEUED` on Queuing it, `ACTION_SUCCESS` on success.
166-
___
24+
## Usage
25+
See [Wiki](https://github.com/wizard97/ArduinoProcessScheduler/wiki)
16726

168-
#### disable()
169-
```
170-
disable (Process &service))
171-
```
172-
Disable a service, same as calling `service.disable()`. Note, this will trigger the service's `onDisable()` method to fire. This method call will always succeed if it was not called on itself from a method inside of this service. If it was, the scheduler will queue the request. Also, the request will fail if the service is already enabled or is destroyed.
17327

174-
**Returns:** type `SchedulerAction`, `ACTION_NONE` on failure, `ACTION_QUEUED` on Queuing it, `ACTION_SUCCESS` on success.
175-
___
28+
## License
29+
MIT.

0 commit comments

Comments
 (0)