FreeRTOScpp
Loading...
Searching...
No Matches
MutexCPP.h
Go to the documentation of this file.
1/**
2 * @file MutexCPP.h
3 * @brief FreeRTOS Mutex Wrapper
4 *
5 * This file contains a set of lightweight wrappers for mutexes using FreeRTOS
6 *
7 * @copyright (c) 2007-2024 Richard Damon
8 * @author Richard Damon <richard.damon@gmail.com>
9 * @parblock
10 * MIT License:
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this software and associated documentation files (the "Software"), to deal
14 * in the Software without restriction, including without limitation the rights
15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 * copies of the Software, and to permit persons to whom the Software is
17 * furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 * THE SOFTWARE.
29 *
30 * It is requested (but not required by license) that any bugs found or
31 * improvements made be shared, preferably to the author.
32 * @endparblock
33 *
34 * @ingroup FreeRTOSCpp
35 */
36
37#ifndef MUTEXCPP_H
38#define MUTEXCPP_H
39
40#include "FreeRTOScpp.h"
41
42#include "Lock.h"
43#include "semphr.h"
44
45#if FREERTOSCPP_USE_NAMESPACE
46namespace FreeRTOScpp {
47#endif
48
49/**
50 * @brief Mutex Wrapper.
51 *
52 * A Mutex is a basic synchronization primitive allowing mutual exclusion to be
53 * handled which also implements priority inheritance. Note, the basic mutex is
54 * NOT recursive, ie if a Task has taken the Mutex, it must not try to take it
55 * again before giving it. If you need this, use a RecurviseMutex.
56 *
57 * The usage of a Mutex is similar to a semaphore, but the task that takes the
58 * Mutex is also supposed to be the Task that eventually gives it back. It also
59 * doesn't normally make sense for an ISR to use a Mutex, so no _ISR routines
60 * have been made available.
61 *
62 * Example Usage:
63 * @code
64 * RecursiveMutex mutex("MyMutex");
65 *
66 * // In some other task
67 * mutex.take();
68 * ... // some code that needs mutual exclusion
69 * mutex.give();
70 * @endcode
71 *
72 * @ingroup FreeRTOSCpp
73 */
74
75class Mutex : public Lockable {
76public:
77 /**
78 * @brief Constructor.
79 * @param name Name to give mutex, used for Debug Registry if setup
80 */
81 Mutex(char const* name) {
82#if( configSUPPORT_STATIC_ALLOCATION == 1 )
83 mutexHandle = xSemaphoreCreateMutexStatic(&mutexBuffer);
84#else
85 mutexHandle = xSemaphoreCreateMutex();
86#endif
87#if configQUEUE_REGISTRY_SIZE > 0
88 vQueueAddToRegistry(mutexHandle, name);
89#endif
90 }
91 /**
92 * @brief Destructor.
93 *
94 * Deletes the semaphore.
95 */
97 vSemaphoreDelete(mutexHandle);
98 }
99
100 bool take(TickType_t wait = portMAX_DELAY) override {
101 return xSemaphoreTake(mutexHandle, wait);
102 }
103#if FREERTOSCPP_USE_CHRONO
104 bool take(Time_ms wait) {
105 return xSemaphoreTake(mutexHandle, ms2ticks(wait));
106 }
107#endif
108
109 bool give() override {
110 return xSemaphoreGive(mutexHandle);
111 }
112private:
113 SemaphoreHandle_t mutexHandle;
114#if __cplusplus < 201101L
115 Mutex(Mutex const&); ///< We are not copyable.
116 void operator =(Mutex const&); ///< We are not assignable.
117#else
118 Mutex(Mutex const&) = delete; ///< We are not copyable.
119 void operator =(Mutex const&) = delete; ///< We are not assignable.
120#endif // __cplusplus
121#if( configSUPPORT_STATIC_ALLOCATION == 1 )
122 StaticSemaphore_t mutexBuffer;
123#endif
124
125};
126
127#if configUSE_RECURSIVE_MUTEXES > 0
128/**
129 * @brief Recursive Mutex Wrapper.
130 *
131 * A RecursiveMutex adds the ability to nest takes, so that if you have taken the
132 * RecursiveMutex and take it again, this works and requires you to give the
133 * RecursiveMutex back as many times as it was taken before it is released.
134 *
135 * One very common application for this is for messages to the user on a console.
136 * Generally, you don't want pieces of a message interrupted by pieces of other
137 * messages, so message output routines use a mutex on the console port.
138 * These routines often use lower level routines that also want to make sure their
139 * output isn't interspersed, so each level takes the RecursiveMutex at their start
140 * and releases it at the end. Being a RecursiveMutex this works.
141 *
142 * Example Usage:
143 * @code
144 * RecursiveMutex mutex("MyMutex");
145 *
146 * // In some other task
147 * mutex.take();
148 * ...
149 * // possible in a recursive call or call to lower level routine.
150 * mutex.take();
151 * ...
152 * mutex.give();
153 * ...
154 * mutex.give();
155 *
156 * @endcode
157 * @ingroup FreeRTOSCpp
158 */
159
161public:
162 RecursiveMutex(char const* name = nullptr) {
163#if( configSUPPORT_STATIC_ALLOCATION == 1 )
164 mutexHandle = xSemaphoreCreateRecursiveMutexStatic(&mutexBuffer);
165#else
166 mutexHandle = xSemaphoreCreateRecursiveMutex();
167#endif
168#if configQUEUE_REGISTRY_SIZE > 0
169 if(name)
170 vQueueAddToRegistry(mutexHandle, name);
171#endif
172 }
174 vSemaphoreDelete(mutexHandle);
175 }
176
177 bool take(TickType_t wait = portMAX_DELAY) override {
178 return xSemaphoreTakeRecursive(mutexHandle, wait);
179 }
180 bool give() override {
181 return xSemaphoreGiveRecursive(mutexHandle);
182 }
183
184private:
185 SemaphoreHandle_t mutexHandle;
186#if __cplusplus < 201101L
187 RecursiveMutex(RecursiveMutex const&); ///< We are not copyable.
188 void operator =(RecursiveMutex const&); ///< We are not assignable.
189#else
190 RecursiveMutex(RecursiveMutex const&) = delete; ///< We are not copyable.
191 void operator =(RecursiveMutex const&) = delete; ///< We are not assignable.
192#endif // __cplusplus
193#if( configSUPPORT_STATIC_ALLOCATION == 1 )
194 StaticSemaphore_t mutexBuffer;
195#endif
196};
197#endif // configUSE_RECURSIVE_MUTEXES
198
199#if FREERTOSCPP_USE_NAMESPACE
200} // namespace FreeRTOScpp
201#endif
202
203#endif // MUTEXCPP_H
FreeRTOS Wrapper.
FreeRTOS Lock wrapper.
A Base class to provide block based locking capability.
Definition Lock.h:58
Mutex Wrapper.
Definition MutexCPP.h:75
Mutex(char const *name)
Constructor.
Definition MutexCPP.h:81
bool take(TickType_t wait=portMAX_DELAY) override
Definition MutexCPP.h:100
~Mutex()
Destructor.
Definition MutexCPP.h:96
Mutex(Mutex const &)=delete
We are not copyable.
SemaphoreHandle_t mutexHandle
Definition MutexCPP.h:113
bool give() override
Definition MutexCPP.h:109
Recursive Mutex Wrapper.
Definition MutexCPP.h:160
RecursiveMutex(RecursiveMutex const &)=delete
We are not copyable.
bool take(TickType_t wait=portMAX_DELAY) override
Definition MutexCPP.h:177
~RecursiveMutex()
Definition MutexCPP.h:173
SemaphoreHandle_t mutexHandle
Definition MutexCPP.h:185
RecursiveMutex(char const *name=nullptr)
Definition MutexCPP.h:162
bool give() override
Definition MutexCPP.h:180
Definition FreeRTOScpp.h:74