os_port_windows.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  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-2023 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.2.4
  27. **/
  28. //Switch to the appropriate trace level
  29. #define TRACE_LEVEL TRACE_LEVEL_OFF
  30. //Memory leaks detection
  31. #if (defined(_WIN32) && defined(_DEBUG))
  32. #define _CRTDBG_MAP_ALLOC
  33. #include <stdlib.h>
  34. #include <crtdbg.h>
  35. #endif
  36. //Dependencies
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <windows.h>
  40. #include "os_port.h"
  41. #include "os_port_windows.h"
  42. #include "debug.h"
  43. /**
  44. * @brief Kernel initialization
  45. **/
  46. void osInitKernel(void)
  47. {
  48. //Not implemented
  49. }
  50. /**
  51. * @brief Start kernel
  52. **/
  53. void osStartKernel(void)
  54. {
  55. //Not implemented
  56. }
  57. /**
  58. * @brief Create a task
  59. * @param[in] name A name identifying the task
  60. * @param[in] taskCode Pointer to the task entry function
  61. * @param[in] param A pointer to a variable to be passed to the task
  62. * @param[in] stackSize The initial size of the stack, in words
  63. * @param[in] priority The priority at which the task should run
  64. * @return Task identifier referencing the newly created task
  65. **/
  66. OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode,
  67. void *param, size_t stackSize, int_t priority)
  68. {
  69. void *handle;
  70. //Create a new thread
  71. handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) taskCode,
  72. param, 0, NULL);
  73. //Return a pointer to the newly created thread
  74. return (OsTaskId) handle;
  75. }
  76. /**
  77. * @brief Delete a task
  78. * @param[in] taskId Task identifier referencing the task to be deleted
  79. **/
  80. void osDeleteTask(OsTaskId taskId)
  81. {
  82. //Delete the calling thread?
  83. if(taskId == OS_SELF_TASK_ID)
  84. {
  85. //Kill ourselves
  86. ExitThread(0);
  87. }
  88. else
  89. {
  90. //Delete the specified thread
  91. TerminateThread((HANDLE) taskId, 0);
  92. }
  93. }
  94. /**
  95. * @brief Delay routine
  96. * @param[in] delay Amount of time for which the calling task should block
  97. **/
  98. void osDelayTask(systime_t delay)
  99. {
  100. //Delay the task for the specified duration
  101. Sleep(delay);
  102. }
  103. /**
  104. * @brief Yield control to the next task
  105. **/
  106. void osSwitchTask(void)
  107. {
  108. //Not implemented
  109. }
  110. /**
  111. * @brief Suspend scheduler activity
  112. **/
  113. void osSuspendAllTasks(void)
  114. {
  115. //Not implemented
  116. }
  117. /**
  118. * @brief Resume scheduler activity
  119. **/
  120. void osResumeAllTasks(void)
  121. {
  122. //Not implemented
  123. }
  124. /**
  125. * @brief Create an event object
  126. * @param[in] event Pointer to the event object
  127. * @return The function returns TRUE if the event object was successfully
  128. * created. Otherwise, FALSE is returned
  129. **/
  130. bool_t osCreateEvent(OsEvent *event)
  131. {
  132. //Create an event object
  133. event->handle = CreateEvent(NULL, FALSE, FALSE, NULL);
  134. //Check whether the returned handle is valid
  135. if(event->handle != NULL)
  136. {
  137. return TRUE;
  138. }
  139. else
  140. {
  141. return FALSE;
  142. }
  143. }
  144. /**
  145. * @brief Delete an event object
  146. * @param[in] event Pointer to the event object
  147. **/
  148. void osDeleteEvent(OsEvent *event)
  149. {
  150. //Make sure the handle is valid
  151. if(event->handle != NULL)
  152. {
  153. //Properly dispose the event object
  154. CloseHandle(event->handle);
  155. }
  156. }
  157. /**
  158. * @brief Set the specified event object to the signaled state
  159. * @param[in] event Pointer to the event object
  160. **/
  161. void osSetEvent(OsEvent *event)
  162. {
  163. //Set the specified event to the signaled state
  164. SetEvent(event->handle);
  165. }
  166. /**
  167. * @brief Set the specified event object to the nonsignaled state
  168. * @param[in] event Pointer to the event object
  169. **/
  170. void osResetEvent(OsEvent *event)
  171. {
  172. //Force the specified event to the nonsignaled state
  173. ResetEvent(event->handle);
  174. }
  175. /**
  176. * @brief Wait until the specified event is in the signaled state
  177. * @param[in] event Pointer to the event object
  178. * @param[in] timeout Timeout interval
  179. * @return The function returns TRUE if the state of the specified object is
  180. * signaled. FALSE is returned if the timeout interval elapsed
  181. **/
  182. bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
  183. {
  184. //Wait until the specified event is in the signaled state or the timeout
  185. //interval elapses
  186. if(WaitForSingleObject(event->handle, timeout) == WAIT_OBJECT_0)
  187. {
  188. return TRUE;
  189. }
  190. else
  191. {
  192. return FALSE;
  193. }
  194. }
  195. /**
  196. * @brief Set an event object to the signaled state from an interrupt service routine
  197. * @param[in] event Pointer to the event object
  198. * @return TRUE if setting the event to signaled state caused a task to unblock
  199. * and the unblocked task has a priority higher than the currently running task
  200. **/
  201. bool_t osSetEventFromIsr(OsEvent *event)
  202. {
  203. //Not implemented
  204. return FALSE;
  205. }
  206. /**
  207. * @brief Create a semaphore object
  208. * @param[in] semaphore Pointer to the semaphore object
  209. * @param[in] count The maximum count for the semaphore object. This value
  210. * must be greater than zero
  211. * @return The function returns TRUE if the semaphore was successfully
  212. * created. Otherwise, FALSE is returned
  213. **/
  214. bool_t osCreateSemaphore(OsSemaphore *semaphore, uint_t count)
  215. {
  216. //Create a semaphore object
  217. semaphore->handle = CreateSemaphore(NULL, count, count, NULL);
  218. //Check whether the returned handle is valid
  219. if(semaphore->handle != NULL)
  220. {
  221. return TRUE;
  222. }
  223. else
  224. {
  225. return FALSE;
  226. }
  227. }
  228. /**
  229. * @brief Delete a semaphore object
  230. * @param[in] semaphore Pointer to the semaphore object
  231. **/
  232. void osDeleteSemaphore(OsSemaphore *semaphore)
  233. {
  234. //Make sure the handle is valid
  235. if(semaphore->handle != NULL)
  236. {
  237. //Properly dispose the semaphore object
  238. CloseHandle(semaphore->handle);
  239. }
  240. }
  241. /**
  242. * @brief Wait for the specified semaphore to be available
  243. * @param[in] semaphore Pointer to the semaphore object
  244. * @param[in] timeout Timeout interval
  245. * @return The function returns TRUE if the semaphore is available. FALSE is
  246. * returned if the timeout interval elapsed
  247. **/
  248. bool_t osWaitForSemaphore(OsSemaphore *semaphore, systime_t timeout)
  249. {
  250. //Wait until the specified semaphore becomes available
  251. if(WaitForSingleObject(semaphore->handle, timeout) == WAIT_OBJECT_0)
  252. {
  253. return TRUE;
  254. }
  255. else
  256. {
  257. return FALSE;
  258. }
  259. }
  260. /**
  261. * @brief Release the specified semaphore object
  262. * @param[in] semaphore Pointer to the semaphore object
  263. **/
  264. void osReleaseSemaphore(OsSemaphore *semaphore)
  265. {
  266. //Release the semaphore
  267. ReleaseSemaphore(semaphore->handle, 1, NULL);
  268. }
  269. /**
  270. * @brief Create a mutex object
  271. * @param[in] mutex Pointer to the mutex object
  272. * @return The function returns TRUE if the mutex was successfully
  273. * created. Otherwise, FALSE is returned
  274. **/
  275. bool_t osCreateMutex(OsMutex *mutex)
  276. {
  277. //Create a mutex object
  278. mutex->handle = CreateMutex(NULL, FALSE, NULL);
  279. //Check whether the returned handle is valid
  280. if(mutex->handle != NULL)
  281. {
  282. return TRUE;
  283. }
  284. else
  285. {
  286. return FALSE;
  287. }
  288. }
  289. /**
  290. * @brief Delete a mutex object
  291. * @param[in] mutex Pointer to the mutex object
  292. **/
  293. void osDeleteMutex(OsMutex *mutex)
  294. {
  295. //Make sure the handle is valid
  296. if(mutex->handle != NULL)
  297. {
  298. //Properly dispose the mutex object
  299. CloseHandle(mutex->handle);
  300. }
  301. }
  302. /**
  303. * @brief Acquire ownership of the specified mutex object
  304. * @param[in] mutex Pointer to the mutex object
  305. **/
  306. void osAcquireMutex(OsMutex *mutex)
  307. {
  308. //Obtain ownership of the mutex object
  309. WaitForSingleObject(mutex->handle, INFINITE);
  310. }
  311. /**
  312. * @brief Release ownership of the specified mutex object
  313. * @param[in] mutex Pointer to the mutex object
  314. **/
  315. void osReleaseMutex(OsMutex *mutex)
  316. {
  317. //Release ownership of the mutex object
  318. ReleaseMutex(mutex->handle);
  319. }
  320. /**
  321. * @brief Retrieve system time
  322. * @return Number of milliseconds elapsed since the system was last started
  323. **/
  324. systime_t osGetSystemTime(void)
  325. {
  326. //Get current tick count
  327. return GetTickCount();
  328. }
  329. /**
  330. * @brief Allocate a memory block
  331. * @param[in] size Bytes to allocate
  332. * @return A pointer to the allocated memory block or NULL if
  333. * there is insufficient memory available
  334. **/
  335. __weak_func void *osAllocMem(size_t size)
  336. {
  337. //Allocate a memory block
  338. return malloc(size);
  339. }
  340. /**
  341. * @brief Release a previously allocated memory block
  342. * @param[in] p Previously allocated memory block to be freed
  343. **/
  344. __weak_func void osFreeMem(void *p)
  345. {
  346. //Free memory block
  347. free(p);
  348. }