You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This example will blink builtin LED and read analog data.
10
-
Additionally this example demonstrates usage of task handle, simply by deleting the analog
11
-
read task after 10 seconds from main loop by calling the function `vTaskDelete`.
9
+
This example will blink the built-in LED and read analog data.
10
+
Additionally, this example demonstrates the usage of the task handle, simply by deleting the analog
11
+
read task after 10 seconds from the main loop by calling the function `vTaskDelete`.
12
12
13
13
### Theory:
14
-
A task is simply a function which runs when the operating system (FreeeRTOS) sees fit.
14
+
A task is simply a function that runs when the operating system (FreeeRTOS) sees fit.
15
15
This task can have an infinite loop inside if you want to do some work periodically for the entirety of the program run.
16
-
This however can create a problem - no other task will ever run and also the Watch Dog will trigger and your program will restart.
17
-
A nice behaving tasks knows when it is useless to keep the processor for itself and gives it away for other tasks to be used.
18
-
This can be achieved by many ways, but the simplest is calling`delay(milliseconds)`.
19
-
During that delay any other task may run and do it's job.
20
-
When the delay runs out the Operating System gives the processor to the task which can continue.
21
-
For other ways to yield the CPU in task please see other examples in this folder.
22
-
It is also worth mentioning that two or more tasks running the exact same function will run them with separated stack, so if you want to run the same code (could be differentiated by the argument) there is no need to have multiple copies of the same function.
23
-
24
-
**Task creation has few parameters you should understand:**
16
+
This, however, can create a problem - no other task will ever run and also the Watch Dog will trigger and your program will restart.
17
+
A nice behaving tasks know when it is useless to keep the processor for itself and give it away for other tasks to be used.
18
+
This can be achieved in many ways, but the simplest is called`delay(`milliseconds)`.
19
+
During that delay, any other task may run and do its job.
20
+
When the delay runs out the Operating System gives the processor the task which can continue.
21
+
For other ways to yield the CPU in a task please see other examples in this folder.
22
+
It is also worth mentioning that two or more tasks running the same function will run them with separate stacks, so if you want to run the same code (which could be differentiated by the argument) there is no need to have multiple copies of the same function.
23
+
24
+
**Task creation has a few parameters you should understand:**
25
25
```
26
26
xTaskCreate(TaskFunction_t pxTaskCode,
27
27
const char * const pcName,
@@ -31,12 +31,12 @@ It is also worth mentioning that two or more tasks running the exact same functi
31
31
TaskHandle_t * const pxCreatedTask )
32
32
```
33
33
-**pxTaskCode** is the name of your function which will run as a task
34
-
-**pcName** is a string of humanreadable description for your task
35
-
-**usStackDepth** is number of words (word = 4B) available to the task. If you see error similar to this "Debug exception reason: Stack canary watchpoint triggered (Task Blink)" you should increase it
36
-
-**pvParameters** is a parameter which will be passed to the task function - it must be explicitly converted to (void*) and in your function explicitly converted back to the intended data type.
37
-
-**uxPriority** is number from 0 to configMAX_PRIORITIES which determines how the FreeRTOS will allow the tasks to run. 0 is lowest priority.
38
-
-**pxCreatedTask** task handle is basically a pointer to the task which allows you to manipulate with the task - delete it, suspend and resume.
39
-
If you don't need to do anything special with you task, simply pass NULL for this parameter.
34
+
-**pcName** is a string of human-readable descriptions for your task
35
+
-**usStackDepth** is the number of words (word = 4B) available to the task. If you see an error similar to this "Debug exception reason: Stack canary watchpoint triggered (Task Blink)" you should increase it
36
+
-**pvParameters** is a parameter that will be passed to the task function - it must be explicitly converted to (void*) and in your function explicitly converted back to the intended data type.
37
+
-**uxPriority** is a number from 0 to configMAX_PRIORITIES which determines how the FreeRTOS will allow the tasks to run. 0 is the lowest priority.
38
+
-**pxCreatedTask** task handle is a pointer to the task which allows you to manipulate the task - delete it, suspend and resume.
39
+
If you don't need to do anything special with your task, simply pass NULL for this parameter.
40
40
You can read more about task control here: https://www.freertos.org/a00112.html
41
41
42
42
# Supported Targets
@@ -45,10 +45,10 @@ This example supports all SoCs.
45
45
46
46
### Hardware Connection
47
47
48
-
If your board does not have built in LED, please connect one to the pin specified by the `LED_BUILTIN` in code (you can also change the number and connect it on pin you desire).
48
+
If your board does not have a built-in LED, please connect one to the pin specified by the `LED_BUILTIN` in the code (you can also change the number and connect it to the pin you desire).
49
49
50
-
Optionally you can connect analog element to pin ? such as variable resistor, or analog input such as audio signal, or any signal generator. However if the pin is left unconnected it will receive background noise and you will also see change in the signal when the pin is touched by finger.
51
-
Please refer to the ESP-IDF ADC documentation for specific SoC for info which pins are available:
50
+
Optionally you can connect the analog element to the pin. such as a variable resistor, analog input such as an audio signal, or any signal generator. However, if the pin is left unconnected it will receive background noise and you will also see a change in the signal when the pin is touched by a finger.
51
+
Please refer to the ESP-IDF ADC documentation for specific SoC for info on which pins are available:
Copy file name to clipboardExpand all lines: libraries/MultiThreading/examples/Mutex/README.md
+22-27Lines changed: 22 additions & 27 deletions
Original file line number
Diff line number
Diff line change
@@ -1,40 +1,35 @@
1
1
# Mutex
2
2
3
-
This example demonstrates basic usage of FreeRTOS Mutually Exclusive Locks (Mutex) for securing access to shared resources in multithreading.
4
-
Please refer to other examples in this folder to better understand usage of tasks.
5
-
It is also advised to read documentation on FreeRTOS web pages:
3
+
This example demonstrates the basic usage of FreeRTOS Mutually Exclusive Locks (Mutex) for securing access to shared resources in multi-threading.
4
+
Please refer to other examples in this folder to better understand the usage of tasks.
5
+
It is also advised to read the documentation on FreeRTOS web pages:
6
6
https://www.freertos.org/a00106.html
7
7
8
-
This example creates 2 task with same implementation - they write into shared
9
-
variable and then read it and check if it is the same as what they have written.
10
-
In single thread programming like on Arduino this is of no concern and will be always ok, however when multi threading is used the tasks execution is switched by the FreeRTOS and the value can be rewritten from other task before reading again.
11
-
The tasks print write and read operation - each in their own column for better reading. Task 0 is on the left and Task 1 is on the right.
8
+
This example creates 2 tasks with the same implementation - they write into a shared variable and then read it and check if it is the same as what they have written.
9
+
In single-thread programming like on Arduino this is of no concern and will be always ok, however when multi-threading is used the execution of the task is switched by the FreeRTOS and the value can be rewritten from another task before reading again.
10
+
The tasks print write and read operation - each in their column for better reading. Task 0 is on the left and Task 1 is on the right.
12
11
Watch the writes and read in secure mode when using the mutex (default) as the results are as you would expect them.
13
-
Then try to comment the USE_MUTEX and watch again - there will be a lots of mismatches!
12
+
Then try to comment the USE_MUTEX and watch again - there will be a lot of mismatches!
14
13
15
14
### Theory:
16
15
Mutex is a specialized version of Semaphore (please see the Semaphore example for more info).
17
-
In essence the mutex is a variable whose value determines if the mutes is taken (locked) or given (unlocked).
18
-
When two or more processes access the same resource (variable, peripheral, etc) it might happen, for example
19
-
that when one task starts to read a variable and the operating system (FreeRTOS) will schedule execution of another task
16
+
In essence, the mutex is a variable whose value determines if the mute is taken (locked) or given (unlocked).
17
+
When two or more processes access the same resource (variable, peripheral, etc) it might happen, for example, that when one task starts to read a variable and the operating system (FreeRTOS) will schedule the execution of another task
20
18
which will write to this variable and when the previous task runs again it will read something different.
21
19
22
20
Mutexes and binary semaphores are very similar but have some subtle differences:
23
-
Mutexes include a priority inheritance mechanism, binary semaphores do not.
24
-
This makes binary semaphores the better choice for implementing
25
-
synchronisation (between tasks or between tasks and an interrupt), and mutexes the better
21
+
Mutexes include a priority inheritance mechanism, whereas binary semaphores do not.
22
+
This makes binary semaphores the better choice for implementing synchronization (between tasks or between tasks and an interrupt), and mutexes the better
26
23
choice for implementing simple mutual exclusion.
24
+
What is priority inheritance?
25
+
If a low-priority task holds the Mutex but gets interrupted by a Higher priority task, which
26
+
then tries to take the Mutex, the low-priority task will temporarily ‘inherit’ the high priority so a middle-priority task can't block the low-priority task, and thus also block the high priority task.
27
+
Semaphores don't have the logic to handle this, in part because Semaphores aren't 'owned' by the task that takes them.
27
28
28
-
Wha is priority inheritance?
29
-
If a low priority task holds the Mutex, but gets interrupted by a Higher priority task, which
30
-
then tries to take the Mutex, the low priority task will temporarily ‘inherit’ the high priority so a middle
31
-
priority task can't block the low priority task, and thus also block the high priority task.
32
-
Semaphores don't have logic to handle this, in part because Semaphores aren't 'owned' by the task that takes them.
29
+
A mutex can also be recursive - if a task that holds the mutex takes it again, it will succeed, and the mutex will be released
30
+
for other tasks only when it is given the same number of times that it was taken.
33
31
34
-
Mutex can also be recursive - if a task that holds the mutex takes it again, it will succeed, and the mutex will be released
35
-
for other tasks only when it is given the same number of time which it was taken.
36
-
37
-
You can check the danger by commenting the definition of USE_MUTEX which will disable the mutex and present the danger of concurrent access.
32
+
You can check the danger by commenting on the definition of USE_MUTEX which will disable the mutex and present the danger of concurrent access.
38
33
39
34
40
35
# Supported Targets
@@ -43,9 +38,9 @@ This example supports all ESP32 SoCs.
43
38
44
39
## How to Use Example
45
40
46
-
Flash and observe serial output.
41
+
Flash and observe the serial output.
47
42
48
-
Comment the `USE_MUTEX` definition, save and flash again and observe the behavior of unprotected access to shared variable.
43
+
Comment the `USE_MUTEX` definition, save and flash again and observe the behavior of unprotected access to the shared variable.
49
44
50
45
* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide).
51
46
@@ -62,7 +57,7 @@ To get more information about the Espressif boards see [Espressif Development Ki
62
57
63
58
## Example Log Output
64
59
65
-
Expected output of shared variable protected by mutex demonstrates mutually exclusive acces from tasks - the do not interrupt each other and do not rewrite the value before the other task has read it back.
60
+
The expected output of shared variables protected by mutex demonstrates mutually exclusive access from tasks - they do not interrupt each other and do not rewrite the value before the other task has read it back.
66
61
67
62
```
68
63
Task 0 | Task 1
@@ -77,7 +72,7 @@ Expected output of shared variable protected by mutex demonstrates mutually excl
77
72
282 <- 267 |
78
73
```
79
74
80
-
Output of unprotected access to shared variable - ot happens often that a task is interrupted after writing and before reading the other task write a different value - a corruption occurred!
75
+
The output of unprotected access to shared variable - it happens often that a task is interrupted after writing and before reading the other task write a different value - a corruption occurred!
0 commit comments