Open FFBoard
Open source force feedback firmware
cthread.cpp
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * Copyright (c) 2017, Michael Becker (michael.f.becker@gmail.com)
4 *
5 * This file is part of the FreeRTOS Add-ons project.
6 *
7 * Source Code:
8 * https://github.com/michaelbecker/freertos-addons
9 *
10 * Project Page:
11 * http://michaelbecker.github.io/freertos-addons/
12 *
13 * On-line Documentation:
14 * http://michaelbecker.github.io/freertos-addons/docs/html/index.html
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files
18 * (the "Software"), to deal in the Software without restriction, including
19 * without limitation the rights to use, copy, modify, merge, publish,
20 * distribute, sublicense, and/or sell copies of the Software, and to
21 * permit persons to whom the Software is furnished to do so,subject to the
22 * following conditions:
23 *
24 * + The above copyright notice and this permission notice shall be included
25 * in all copies or substantial portions of the Software.
26 * + Credit is appreciated, but not required, if you find this project
27 * useful enough to include in your application, product, device, etc.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
30 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
32 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
33 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
34 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
35 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 *
37 ***************************************************************************/
38
39
40#include <cstring>
41#include "thread.hpp"
42
43
44using namespace cpp_freertos;
45
46
47volatile bool Thread::SchedulerActive = false;
48MutexStandard Thread::StartGuardLock;
49
50
51//
52// We want to use C++ strings. This is the default.
53//
54#ifndef CPP_FREERTOS_NO_CPP_STRINGS
55
56Thread::Thread( const std::string pcName,
57 uint16_t usStackDepth,
58 UBaseType_t uxPriority)
59 : Name(pcName),
60 StackDepth(usStackDepth),
61 Priority(uxPriority),
62 ThreadStarted(false)
63{
64#if (INCLUDE_vTaskDelayUntil == 1)
66#endif
67}
68
69
70Thread::Thread( uint16_t usStackDepth,
71 UBaseType_t uxPriority)
72 : Name("Default"),
73 StackDepth(usStackDepth),
74 Priority(uxPriority),
75 ThreadStarted(false)
76{
77#if (INCLUDE_vTaskDelayUntil == 1)
79#endif
80}
81
82//
83// We do not want to use C++ strings. Fall back to character arrays.
84//
85#else
86
87Thread::Thread( const char *pcName,
88 uint16_t usStackDepth,
89 UBaseType_t uxPriority)
90 : StackDepth(usStackDepth),
91 Priority(uxPriority),
92 ThreadStarted(false)
93{
94 for (int i = 0; i < configMAX_TASK_NAME_LEN - 1; i++) {
95 Name[i] = *pcName;
96 if (*pcName == 0)
97 break;
98 pcName++;
99 }
100 Name[configMAX_TASK_NAME_LEN - 1] = 0;
101
102#if (INCLUDE_vTaskDelayUntil == 1)
103 delayUntilInitialized = false;
104#endif
105}
106
107
108Thread::Thread( uint16_t usStackDepth,
109 UBaseType_t uxPriority)
110 : StackDepth(usStackDepth),
111 Priority(uxPriority),
112 ThreadStarted(false)
113{
114 memset(Name, 0, sizeof(Name));
115#if (INCLUDE_vTaskDelayUntil == 1)
116 delayUntilInitialized = false;
117#endif
118}
119
120#endif
121
122
124{
125 //
126 // If the Scheduler is on, we need to lock before checking
127 // the ThreadStarted variable. We'll leverage the LockGuard
128 // pattern, so we can create the guard and just forget it.
129 // Leaving scope, including the return, will automatically
130 // unlock it.
131 //
132 if (SchedulerActive) {
133
135
136 if (ThreadStarted)
137 return false;
138 else
139 ThreadStarted = true;
140 }
141 //
142 // If the Scheduler isn't running, just check it.
143 //
144 else {
145
146 if (ThreadStarted)
147 return false;
148 else
149 ThreadStarted = true;
150 }
151
152#ifndef CPP_FREERTOS_NO_CPP_STRINGS
153
154 BaseType_t rc = xTaskCreate(TaskFunctionAdapter,
155 Name.c_str(),
157 this,
158 Priority,
159 &handle);
160#else
161
162 BaseType_t rc = xTaskCreate(TaskFunctionAdapter,
163 Name,
165 this,
166 Priority,
167 &handle);
168#endif
169
170 return rc != pdPASS ? false : true;
171}
172
173
174#if (INCLUDE_vTaskDelete == 1)
175
176//
177// Deliberately empty. If this is needed, it will be overloaded.
178//
180{
181}
182
183
185{
186 vTaskDelete(handle);
187 handle = (TaskHandle_t)-1;
188}
189
190#else
191
193{
194 configASSERT( ! "Cannot actually delete a thread object "
195 "if INCLUDE_vTaskDelete is not defined.");
196}
197
198#endif
199
200
201void Thread::TaskFunctionAdapter(void *pvParameters)
202{
203 Thread *thread = static_cast<Thread *>(pvParameters);
204
205 thread->Run();
206
207#if (INCLUDE_vTaskDelete == 1)
208
209 thread->Cleanup();
210
211 vTaskDelete(thread->handle);
212
213#else
214 configASSERT( ! "Cannot return from a thread.run function "
215 "if INCLUDE_vTaskDelete is not defined.");
216#endif
217}
218
219
220#if (INCLUDE_vTaskDelayUntil == 1)
221
222void Thread::DelayUntil(const TickType_t Period)
223{
226 delayUntilPreviousWakeTime = xTaskGetTickCount();
227 }
228
229 vTaskDelayUntil(&delayUntilPreviousWakeTime, Period);
230}
231
232
234{
235 delayUntilInitialized = false;
236}
237
238#endif
239
240
241
242#ifdef CPP_FREERTOS_CONDITION_VARIABLES
243
245 Mutex &CvLock,
246 TickType_t Timeout)
247{
248 Cv.AddToWaitList(this);
249
250 //
251 // Drop the associated external lock, as per cv semantics.
252 //
253 CvLock.Unlock();
254
255 //
256 // And block on the internal semaphore. The associated Cv
257 // will call Thread::Signal, which will release the semaphore.
258 //
259 bool timed_out = ThreadWaitSem.Take(Timeout);
260
261 //
262 // Grab the external lock again, as per cv semantics.
263 //
264 CvLock.Lock();
265
266 return timed_out;
267}
268
269
270#endif
271
272
virtual bool Unlock()=0
virtual bool Lock(TickType_t Timeout=portMAX_DELAY)=0
bool Take(TickType_t Timeout=portMAX_DELAY)
Definition: csemaphore.cpp:46
static volatile bool SchedulerActive
Definition: thread.hpp:417
const std::string Name
Definition: thread.hpp:423
const uint16_t StackDepth
Definition: thread.hpp:431
static MutexStandard StartGuardLock
Definition: thread.hpp:446
static void TaskFunctionAdapter(void *pvParameters)
Definition: cthread.cpp:201
BinarySemaphore ThreadWaitSem
Definition: thread.hpp:475
bool delayUntilInitialized
Definition: thread.hpp:460
UBaseType_t Priority
Definition: thread.hpp:436
TickType_t delayUntilPreviousWakeTime
Definition: thread.hpp:465
bool Wait(ConditionVariable &Cv, Mutex &CvLock, TickType_t Timeout=portMAX_DELAY)
Definition: cthread.cpp:244
virtual void Run()=0
virtual void Cleanup()
Definition: cthread.cpp:179
void DelayUntil(const TickType_t Period)
Definition: cthread.cpp:222
TaskHandle_t handle
Definition: thread.hpp:412
Thread(const std::string Name, uint16_t StackDepth, UBaseType_t Priority)
Definition: cthread.cpp:56