os_port_windows.c
Go to the documentation of this file.
1 /**
2  * @file os_port_windows.c
3  * @brief RTOS abstraction layer (Windows)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 2.4.4
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL TRACE_LEVEL_OFF
31 
32 //Memory leaks detection
33 #if (defined(_WIN32) && defined(_DEBUG))
34  #define _CRTDBG_MAP_ALLOC
35  #include <stdlib.h>
36  #include <crtdbg.h>
37 #endif
38 
39 //Dependencies
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <windows.h>
43 #include "os_port.h"
44 #include "os_port_windows.h"
45 #include "debug.h"
46 
47 //Default task parameters
49 {
50  0, //Size of the stack
51  0 //Task priority
52 };
53 
54 
55 /**
56  * @brief Kernel initialization
57  **/
58 
59 void osInitKernel(void)
60 {
61  //Not implemented
62 }
63 
64 
65 /**
66  * @brief Start kernel
67  **/
68 
69 void osStartKernel(void)
70 {
71  //Not implemented
72 }
73 
74 
75 /**
76  * @brief Create a task
77  * @param[in] name NULL-terminated string identifying the task
78  * @param[in] taskCode Pointer to the task entry function
79  * @param[in] arg Argument passed to the task function
80  * @param[in] params Task parameters
81  * @return Task identifier referencing the newly created task
82  **/
83 
84 OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg,
85  const OsTaskParameters *params)
86 {
87  void *handle;
88 
89  //Create a new thread
90  handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) taskCode,
91  arg, 0, NULL);
92 
93  //Return a pointer to the newly created thread
94  return (OsTaskId) handle;
95 }
96 
97 
98 /**
99  * @brief Delete a task
100  * @param[in] taskId Task identifier referencing the task to be deleted
101  **/
102 
103 void osDeleteTask(OsTaskId taskId)
104 {
105  //Delete the calling thread?
106  if(taskId == OS_SELF_TASK_ID)
107  {
108  //Kill ourselves
109  ExitThread(0);
110  }
111  else
112  {
113  //Delete the specified thread
114  TerminateThread((HANDLE) taskId, 0);
115  }
116 }
117 
118 
119 /**
120  * @brief Delay routine
121  * @param[in] delay Amount of time for which the calling task should block
122  **/
123 
125 {
126  //Delay the task for the specified duration
127  Sleep(delay);
128 }
129 
130 
131 /**
132  * @brief Yield control to the next task
133  **/
134 
135 void osSwitchTask(void)
136 {
137  //Not implemented
138 }
139 
140 
141 /**
142  * @brief Suspend scheduler activity
143  **/
144 
146 {
147  //Not implemented
148 }
149 
150 
151 /**
152  * @brief Resume scheduler activity
153  **/
154 
156 {
157  //Not implemented
158 }
159 
160 
161 /**
162  * @brief Create an event object
163  * @param[in] event Pointer to the event object
164  * @return The function returns TRUE if the event object was successfully
165  * created. Otherwise, FALSE is returned
166  **/
167 
169 {
170  //Create an event object
171  event->handle = CreateEvent(NULL, FALSE, FALSE, NULL);
172 
173  //Check whether the returned handle is valid
174  if(event->handle != NULL)
175  {
176  return TRUE;
177  }
178  else
179  {
180  return FALSE;
181  }
182 }
183 
184 
185 /**
186  * @brief Delete an event object
187  * @param[in] event Pointer to the event object
188  **/
189 
190 void osDeleteEvent(OsEvent *event)
191 {
192  //Make sure the handle is valid
193  if(event->handle != NULL)
194  {
195  //Properly dispose the event object
196  CloseHandle(event->handle);
197  }
198 }
199 
200 
201 /**
202  * @brief Set the specified event object to the signaled state
203  * @param[in] event Pointer to the event object
204  **/
205 
206 void osSetEvent(OsEvent *event)
207 {
208  //Set the specified event to the signaled state
209  SetEvent(event->handle);
210 }
211 
212 
213 /**
214  * @brief Set the specified event object to the nonsignaled state
215  * @param[in] event Pointer to the event object
216  **/
217 
218 void osResetEvent(OsEvent *event)
219 {
220  //Force the specified event to the nonsignaled state
221  ResetEvent(event->handle);
222 }
223 
224 
225 /**
226  * @brief Wait until the specified event is in the signaled state
227  * @param[in] event Pointer to the event object
228  * @param[in] timeout Timeout interval
229  * @return The function returns TRUE if the state of the specified object is
230  * signaled. FALSE is returned if the timeout interval elapsed
231  **/
232 
234 {
235  //Wait until the specified event is in the signaled state or the timeout
236  //interval elapses
237  if(WaitForSingleObject(event->handle, timeout) == WAIT_OBJECT_0)
238  {
239  return TRUE;
240  }
241  else
242  {
243  return FALSE;
244  }
245 }
246 
247 
248 /**
249  * @brief Set an event object to the signaled state from an interrupt service routine
250  * @param[in] event Pointer to the event object
251  * @return TRUE if setting the event to signaled state caused a task to unblock
252  * and the unblocked task has a priority higher than the currently running task
253  **/
254 
256 {
257  //Not implemented
258  return FALSE;
259 }
260 
261 
262 /**
263  * @brief Create a semaphore object
264  * @param[in] semaphore Pointer to the semaphore object
265  * @param[in] count The maximum count for the semaphore object. This value
266  * must be greater than zero
267  * @return The function returns TRUE if the semaphore was successfully
268  * created. Otherwise, FALSE is returned
269  **/
270 
272 {
273  //Create a semaphore object
274  semaphore->handle = CreateSemaphore(NULL, count, count, NULL);
275 
276  //Check whether the returned handle is valid
277  if(semaphore->handle != NULL)
278  {
279  return TRUE;
280  }
281  else
282  {
283  return FALSE;
284  }
285 }
286 
287 
288 /**
289  * @brief Delete a semaphore object
290  * @param[in] semaphore Pointer to the semaphore object
291  **/
292 
294 {
295  //Make sure the handle is valid
296  if(semaphore->handle != NULL)
297  {
298  //Properly dispose the semaphore object
299  CloseHandle(semaphore->handle);
300  }
301 }
302 
303 
304 /**
305  * @brief Wait for the specified semaphore to be available
306  * @param[in] semaphore Pointer to the semaphore object
307  * @param[in] timeout Timeout interval
308  * @return The function returns TRUE if the semaphore is available. FALSE is
309  * returned if the timeout interval elapsed
310  **/
311 
313 {
314  //Wait until the specified semaphore becomes available
315  if(WaitForSingleObject(semaphore->handle, timeout) == WAIT_OBJECT_0)
316  {
317  return TRUE;
318  }
319  else
320  {
321  return FALSE;
322  }
323 }
324 
325 
326 /**
327  * @brief Release the specified semaphore object
328  * @param[in] semaphore Pointer to the semaphore object
329  **/
330 
332 {
333  //Release the semaphore
334  ReleaseSemaphore(semaphore->handle, 1, NULL);
335 }
336 
337 
338 /**
339  * @brief Create a mutex object
340  * @param[in] mutex Pointer to the mutex object
341  * @return The function returns TRUE if the mutex was successfully
342  * created. Otherwise, FALSE is returned
343  **/
344 
346 {
347  //Create a mutex object
348  mutex->handle = CreateMutex(NULL, FALSE, NULL);
349 
350  //Check whether the returned handle is valid
351  if(mutex->handle != NULL)
352  {
353  return TRUE;
354  }
355  else
356  {
357  return FALSE;
358  }
359 }
360 
361 
362 /**
363  * @brief Delete a mutex object
364  * @param[in] mutex Pointer to the mutex object
365  **/
366 
367 void osDeleteMutex(OsMutex *mutex)
368 {
369  //Make sure the handle is valid
370  if(mutex->handle != NULL)
371  {
372  //Properly dispose the mutex object
373  CloseHandle(mutex->handle);
374  }
375 }
376 
377 
378 /**
379  * @brief Acquire ownership of the specified mutex object
380  * @param[in] mutex Pointer to the mutex object
381  **/
382 
384 {
385  //Obtain ownership of the mutex object
386  WaitForSingleObject(mutex->handle, INFINITE);
387 }
388 
389 
390 /**
391  * @brief Release ownership of the specified mutex object
392  * @param[in] mutex Pointer to the mutex object
393  **/
394 
396 {
397  //Release ownership of the mutex object
398  ReleaseMutex(mutex->handle);
399 }
400 
401 
402 /**
403  * @brief Retrieve system time
404  * @return Number of milliseconds elapsed since the system was last started
405  **/
406 
408 {
409  //Get current tick count
410  return GetTickCount();
411 }
412 
413 
414 /**
415  * @brief Allocate a memory block
416  * @param[in] size Bytes to allocate
417  * @return A pointer to the allocated memory block or NULL if
418  * there is insufficient memory available
419  **/
420 
421 __weak_func void *osAllocMem(size_t size)
422 {
423  //Allocate a memory block
424  return malloc(size);
425 }
426 
427 
428 /**
429  * @brief Release a previously allocated memory block
430  * @param[in] p Previously allocated memory block to be freed
431  **/
432 
433 __weak_func void osFreeMem(void *p)
434 {
435  //Free memory block
436  free(p);
437 }
bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout)
Wait for the specified semaphore to be available.
int bool_t
Definition: compiler_port.h:53
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void osSwitchTask(void)
Yield control to the next task.
const OsTaskParameters OS_TASK_DEFAULT_PARAMS
void osStartKernel(void)
Start kernel.
SemaphoreHandle_t handle
uint8_t p
Definition: ndp.h:300
#define TRUE
Definition: os_port.h:50
Event object.
void osDelayTask(systime_t delay)
Delay routine.
__weak_func void * osAllocMem(size_t size)
Allocate a memory block.
char_t name[]
#define OS_SELF_TASK_ID
Semaphore object.
#define FALSE
Definition: os_port.h:46
void osReleaseSemaphore(OsSemaphore *semaphore)
Release the specified semaphore object.
bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count)
Create a semaphore object.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
void(* OsTaskCode)(void *arg)
Task routine.
bool_t osCreateEvent(OsEvent *event)
Create an event object.
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg, const OsTaskParameters *params)
Create a task.
Task parameters.
void osSuspendAllTasks(void)
Suspend scheduler activity.
void osDeleteSemaphore(OsSemaphore *semaphore)
Delete a semaphore object.
void osInitKernel(void)
Kernel initialization.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
Mutex object.
uint32_t systime_t
System time.
char char_t
Definition: compiler_port.h:48
RTOS abstraction layer (Windows)
void osResumeAllTasks(void)
Resume scheduler activity.
bool_t osCreateMutex(OsMutex *mutex)
Create a mutex object.
SemaphoreHandle_t handle
systime_t osGetSystemTime(void)
Retrieve system time.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
__weak_func void osFreeMem(void *p)
Release a previously allocated memory block.
void osResetEvent(OsEvent *event)
Set the specified event object to the nonsignaled state.
void osDeleteTask(OsTaskId taskId)
Delete a task.
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
void osDeleteEvent(OsEvent *event)
Delete an event object.
thread_t * OsTaskId
Task identifier.
unsigned int uint_t
Definition: compiler_port.h:50
RTOS abstraction layer.
Debugging facilities.
void osDeleteMutex(OsMutex *mutex)
Delete a mutex object.
SemaphoreHandle_t handle