Skip to content

Commit 43ba1c0

Browse files
committed
README.md updates
1 parent 863f31b commit 43ba1c0

File tree

2 files changed

+30
-26
lines changed

2 files changed

+30
-26
lines changed

doc/tick_sources.md

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
# Scheduler tick sources
22

33
## Configuration
4-
Tick source is selected by (un)defining values `portUSE_WDTO` and `portUSE_TIMER0` in file `FreeRTOSVariant.h`. Default in Arduino_FreeRTOS is Watchdog timer (WDT), it contains all code needed for this and works out-of-the-box.
4+
Tick source is selected by (un)defining values `portUSE_WDTO` and `portUSE_TIMER0` in file `FreeRTOSVariant.h`. Default in Arduino_FreeRTOS is Watchdog timer (WDT), it contains all code needed for this and works out-of-the-box.
55

6-
For alternative tick source, pieces of code must be provided by the application. Arduino_FreeRTOS expects you to provide function `void prvSetupTimerInterrupt(void)` responsible for the initialization of your tick source. This function is called after the Arduino's initialization and before the FreeRTOS scheduler is launched.
6+
For alternative tick source, pieces of code must be provided by the application. Arduino_FreeRTOS expects you to provide function `void prvSetupTimerInterrupt(void)` responsible for the initialisation of your tick source. This function is called after the Arduino's initialisation and before the FreeRTOS scheduler is launched.
77

88
NOTE: Reconfiguring Timer0 for FreeRTOS will break Arduino `millis()` and `micros()`, as these functions rely on Timer0. Functions relying on these Arduino features need to be overridden.
99

10-
11-
1210
## WDT (default)
1311
Time slices can be selected from 15ms up to 500ms. Slower time slicing can allow the Arduino MCU to sleep for longer, without the complexity of a Tickless idle.
1412

@@ -30,21 +28,23 @@ The frequency of the Watchdog Oscillator is voltage and temperature dependent as
3028
Timing consistency may vary as much as 20% between two devices in same setup due to individual device differences, or between a prototype and production device due to setup differences.
3129

3230
## Alternative tick sources
33-
For applications requiring high precision timing, the Ticks can be sourced from a hardware timer or external clock.
31+
For applications requiring high precision timing, the Ticks can be sourced from a hardware timer or external clock.
32+
33+
First, you switch it in `FreeRTOSVariant.h` header by removing or undefining `portUSE_WDTO` and defining `portUSE_TIMER0`.
3434

35-
First, you switch it in `FreeRTOSVariant.h` header by removing or undefining `portUSE_WDTO` and defining `portUSE_TIMER0`.
3635
```cpp
3736
#undef portUSE_WDTO
3837
#define portUSE_TIMER0
3938
#define portTICK_PERIOD_MS 16
4039
```
4140
42-
Next, in your app you provide two pieces of code: the initialization function and the ISR hook. Their implementation depends of what is your tick source.
41+
Next, in your app you provide two pieces of code: the initialisation function and the ISR hook. Their implementation depends of what is your tick source.
4342
4443
4544
## Hardware timer Timer0
46-
### Timer initialization function
47-
_NOTE: This code snippet is verified to work on Atmega2560. Full code avaialable [here](./tick_sources_timer0.cpp)._
45+
### Timer initialisation function
46+
_NOTE: This code snippet is verified to work on Atmega2560. Full code available [here](./tick_sources_timer0.cpp)._
47+
4848
```cpp
4949
// Formula for the frequency is:
5050
// f = F_CPU / (PRESCALER * (1 + COUNTER_TOP)
@@ -79,10 +79,10 @@ void prvSetupTimerInterrupt( void )
7979
TCCR0A = NO_PWM | MODE_CTC_TCCR0A;
8080
TCCR0B = MODE_CTC_TCCR0B | PRESCALER_1024;
8181
OCR0A = TICK_PERIOD_16MS;
82-
82+
8383
// Prevent missing the top and going into a possibly long wait until wrapping around:
8484
TCNT0 = 0;
85-
85+
8686
// At this point the global interrupt flag is NOT YET enabled,
8787
// so you're NOT starting to get the ISR calls until FreeRTOS enables it just before launching the scheduler.
8888
TIMSK0 = INTERRUPT_AT_TOP;
@@ -93,6 +93,7 @@ Though Timer0 is given as example here, any timer can be used. A 16-bit timer (e
9393

9494
### ISR hook
9595
For **preemptive** scheduler use `naked` attribute to reduce the call overhead:
96+
9697
```cpp
9798
ISR(TIMER0_COMPA_vect, ISR_NAKED) __attribute__ ((hot, flatten));
9899
ISR(TIMER0_COMPA_vect) {
@@ -105,6 +106,7 @@ The context is saved at the start of `portSchedulerTick()`, then the tick count
105106
106107
107108
For **cooperative** scheduler, the context is not saved because no switching is intended; therefore `naked` attribute cannot be applied because cooperative `portSchedulerTick()` dirties the context.
109+
108110
```cpp
109111
ISR(TIMER0_COMPA_vect) __attribute__ ((hot, flatten));
110112
ISR(TIMER0_COMPA_vect) {
@@ -125,6 +127,7 @@ Attributes `hot` and `flatten` help inlining all the code found inside your ISR
125127
_NOTE: This code snippet was not verified on actual MCU._
126128
127129
Assuming the external clock is connected to data pin 21 (function INT0):
130+
128131
```cpp
129132
// For register EICRA:
130133
#define TICK_ON_RISING_EDGE_D21 (1 << ISC01) | (1 << ISC00)
@@ -140,15 +143,16 @@ void prvSetupTimerInterrupt( void )
140143
// At this point the global interrupt flag is NOT YET enabled,
141144
// so you're NOT starting to get the ISR calls until FreeRTOS enables it just before launching the scheduler.
142145
EIMSK = TICK_INPUT_PIN_D21;
143-
144-
// Configure the pin
145-
pinMode(21, INPUT);
146+
147+
// Configure the pin
148+
pinMode(21, INPUT);
146149
}
147150
```
148151

149152

150153
### ISR hook
151-
Similar to Timer0 ISR, for **preemptive** scheduler:
154+
Similar to Timer0 ISR, for **preemptive** scheduler:
155+
152156
```cpp
153157
ISR(INT0_vect, ISR_NAKED) __attribute__ ((hot, flatten));
154158
ISR(INT0_vect) {
@@ -165,23 +169,22 @@ ISR(INT0_vect) {
165169
}
166170
```
167171

168-
169-
170172
## Performance considerations
171173
When selecting the duration for the time slice, the following should be kept in mind.
172174

173175
### Granularity
174-
Note that Timer resolution (or granularity) is affected by integer math division and the time slice selected. For example, trying to measure 50ms using a 120ms time slice won't work.
176+
Note that Timer resolution (or granularity) is affected by integer maths division and the time slice selected. For example, trying to measure 50ms using a 120ms time slice won't work.
175177

176178
### Context switching
177-
In preemptive mode, tasks which are actively executing (i.e., those not waiting for a semaphore or queue) might be switched every time tick, depending on their priority. Switching the context involves pushing all CPU's registers of old task and poping all registers of new task. The shorter your time slice is, the bigger of overhead this becomes.
179+
In preemptive mode, tasks which are actively executing (i.e., those not waiting for a semaphore or queue) might be switched every time tick, depending on their priority. Switching the context involves pushing all CPU's registers of old task and popping all registers of new task. The shorter your time slice is, the bigger of overhead this becomes.
178180

179181
In cooperative mode, context overhead is not a factor.
180182

181183
### Calculations
182-
On MCUs lacking the hardware division operation like AVR, a special care should be taken to avoid division operations. Where unavoidable, operations with divisor of power of 2 work best because they are performed with bitwise shifting, whereas an arbitrary value results in a software division operation taking ~200 clock cycles (for a uint16 operand).
184+
On MCUs lacking the hardware division operation like AVR, a special care should be taken to avoid division operations. Where unavoidable, operations with divisor of power of 2 work best because they are performed with bitwise shifting, whereas an arbitrary value results in a software division operation taking ~200 clock cycles (for a `uint16_t` operand).
183185

184186
You might encounter a division when calculating delays, e.g. converting milliseconds to ticks:
187+
185188
```cpp
186189
TickType_t ticks = delay_millis / portTICK_PERIOD_MS
187190
```

readme.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Over the past few years freeRTOS development has become increasingly 32-bit orie
2121
FreeRTOS has a multitude of configuration options, which can be specified from within the FreeRTOSConfig.h file.
2222
To keep commonality with all of the Arduino hardware options, some sensible defaults have been selected. Feel free to change these defaults as you gain experience with FreeRTOS.
2323

24-
Normally, the AVR Watchdog Timer is used to generate 15ms time slices (Ticks). For applications requiring high precision timing, the Ticks can be sourced from a hardware timer or external clock. See chapter [Scheduler Tick Sources](./doc/tick_sources.md) for the configuration details.
24+
Normally, the AVR Watchdog Timer is used to generate 15ms time slices (Ticks). For applications requiring high precision timing, the Ticks can be sourced from a hardware timer or external clock. See chapter [Scheduler Tick Sources](./doc/tick_sources.md) for the configuration details.f
2525

2626
Tasks that finish before their allocated time will hand execution back to the Scheduler.
2727

@@ -97,11 +97,12 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
9797
<!-- markdownlint-disable -->
9898
<table>
9999
<tr>
100-
<td align="center"><a href="https://feilipu.me/"><img src="https://avatars2.githubusercontent.com/u/3955592" width="100px;" alt=""/><br /><sub><b>Phillip Stevens</b></sub></a><br /><a title="Maintenance">🚧</a><a title="Code">💻</a><a title="Reviewed Pull Requests">👀</a></td>
101-
<td align="center"><a href="https://www.blackleg.es/"><img src="https://avatars1.githubusercontent.com/u/4323228" width="100px;" alt=""/><br /><sub><b>Hector Espert</b></sub></a><br /><a title="Code">💻</a></td>
102-
<td align="center"><a href="https://github.com/Floessie"><img src="https://avatars1.githubusercontent.com/u/10133457" width="100px;" alt=""/><br /><sub><b>Floessie</b></sub></a><br /><a title="Code">💻</a></td>
103-
<td align="center"><a href="https://github.com/Derekduke"><img src="https://avatars2.githubusercontent.com/u/30068270" width="100px;" alt=""/><br /><sub><b>Derekduke</b></sub></a><br /><a title="Code">💻</a></td>
104-
<td align="center"><a href="https://github.com/balaji"><img src="https://avatars2.githubusercontent.com/u/29356302" width="100px;" alt=""/><br /><sub><b>Balaji.V</b></sub></a><br /><a title="Code">💻</a></td>
100+
<td align="center"><a href="https://feilipu.me/"><img src="https://avatars.githubusercontent.com/u/3955592" width="100px;" alt=""/><br /><sub><b>Phillip Stevens</b></sub></a><br /><a title="Maintenance">🚧</a><a title="Code">💻</a><a title="Reviewed Pull Requests">👀</a></td>
101+
<td align="center"><a href="https://www.blackleg.es/"><img src="https://avatars.githubusercontent.com/u/4323228" width="100px;" alt=""/><br /><sub><b>Hector Espert</b></sub></a><br /><a title="Code">💻</a></td>
102+
<td align="center"><a href="https://github.com/Floessie"><img src="https://avatars.githubusercontent.com/u/10133457" width="100px;" alt=""/><br /><sub><b>Floessie</b></sub></a><br /><a title="Code">💻</a></td>
103+
<td align="center"><a href="https://github.com/Derekduke"><img src="https://avatars.githubusercontent.com/u/30068270" width="100px;" alt=""/><br /><sub><b>Derekduke</b></sub></a><br /><a title="Code">💻</a></td>
104+
<td align="center"><a href="https://github.com/balaji"><img src="https://avatars.githubusercontent.com/u/29356302" width="100px;" alt=""/><br /><sub><b>Balaji.V</b></sub></a><br /><a title="Code">💻</a></td>
105+
<td align="center"><a href="https://github.com/neboskreb"><img src="https://avatars.githubusercontent.com/u/35344069" width="100px;" alt=""/><br /><sub><b>John Y. Pazekha</b></sub></a><br /><a title="Code">💻</a></td>
105106
</tr>
106107
</table>
107108

0 commit comments

Comments
 (0)