1#![allow(non_upper_case_globals)]
21#![allow(non_snake_case)]
22
23use core::ffi::{c_char, c_uint, c_void};
24use core::ptr;
25
26use super::types::{BaseType, StackType, UBaseType, TickType, EventBits};
27
28pub type ThreadHandle = *const c_void;
29pub type QueueHandle = *const c_void;
30pub type SemaphoreHandle = *const c_void;
31pub type EventGroupHandle = *const c_void;
32pub type TimerHandle = *const c_void;
33pub type MutexHandle = *const c_void;
34pub type TimerCallback = unsafe extern "C" fn(timer: TimerHandle);
35pub type TaskState = c_uint;
36
37pub const RUNNING: TaskState = 0;
38pub const READY: TaskState = 1;
39pub const BLOCKED: TaskState = 2;
40pub const SUSPENDED: TaskState = 3;
41pub const DELETED: TaskState = 4;
42pub const INVALID: TaskState = 5;
43
44
45pub const pdFALSE: BaseType = 0;
46
47pub const pdTRUE: BaseType = 1;
48
49pub const pdPASS: BaseType = pdTRUE;
50
51pub const pdFAIL: BaseType = pdFALSE;
52
53pub const tskDEFAULT_INDEX_TO_NOTIFY: UBaseType = 0;
54
55pub const semBINARY_SEMAPHORE_QUEUE_LENGTH: u8 = 1;
56
57pub const semSEMAPHORE_QUEUE_ITEM_LENGTH: u8 = 0;
58
59pub const semGIVE_BLOCK_TIME: TickType = 0;
60
61pub const queueSEND_TO_BACK: BaseType = 0;
62
63pub const queueSEND_TO_FRONT: BaseType = 1;
64
65pub const queueOVERWRITE: BaseType = 2;
66
67pub const queueQUEUE_TYPE_BASE: u8 = 0;
68
69pub const queueQUEUE_TYPE_MUTEX: u8 = 1;
70
71pub const queueQUEUE_TYPE_COUNTING_SEMAPHORE: u8 = 2;
72
73pub const queueQUEUE_TYPE_BINARY_SEMAPHORE: u8 = 3;
74
75pub const queueQUEUE_TYPE_RECURSIVE_MUTEX: u8 = 4;
76
77pub const queueQUEUE_TYPE_SET: u8 = 5;
78
79
80
81#[repr(C)]
82#[derive(Debug, Copy, Clone)]
83pub struct TaskStatus {
84 pub xHandle: ThreadHandle,
85 pub pcTaskName: *const c_char,
86 pub xTaskNumber: UBaseType,
87 pub eCurrentState: TaskState,
88 pub uxCurrentPriority: UBaseType,
89 pub uxBasePriority: UBaseType,
90 pub ulRunTimeCounter: u32,
91 pub pxStackBase: *mut StackType,
92 pub usStackHighWaterMark: StackType
93}
94
95impl Default for TaskStatus {
96 fn default() -> Self {
97 TaskStatus {
98 xHandle: ptr::null(),
99 pcTaskName: ptr::null(),
100 xTaskNumber: 0,
101 eCurrentState: INVALID,
102 uxCurrentPriority: 0,
103 uxBasePriority: 0,
104 ulRunTimeCounter: 0,
105 pxStackBase: ptr::null_mut(),
106 usStackHighWaterMark: 0,
107 }
108 }
109}
110
111pub type TaskFunction = Option<unsafe extern "C" fn(arg: *mut c_void)>;
112
113unsafe extern "C" {
114
115
116 pub fn pvPortMalloc(size: usize) -> *mut c_void;
124
125 pub fn vPortFree(pv: *mut c_void);
130
131 pub fn vTaskDelay(xTicksToDelay: TickType);
132
133 pub fn xTaskDelayUntil(
134 pxPreviousWakeTime: *mut TickType,
135 xTimeIncrement: TickType,
136 ) -> BaseType;
137
138
139 pub fn xTaskGetTickCount() -> TickType;
140
141 pub fn vTaskStartScheduler();
142
143 pub fn vTaskEndScheduler();
144
145 pub fn vTaskSuspendAll();
146
147 pub fn xTaskResumeAll() -> BaseType;
148
149 pub fn xTaskGetCurrentTaskHandle() -> ThreadHandle;
150
151 pub fn eTaskGetState(xTask: ThreadHandle) -> TaskState;
152
153 pub fn uxTaskGetNumberOfTasks() -> UBaseType;
154
155 pub fn uxTaskGetSystemState(
156 pxTaskStatusArray: *mut TaskStatus,
157 uxArraySize: UBaseType,
158 pulTotalRunTime: *mut u32,
159 ) -> UBaseType;
160
161 pub fn xTaskCreate(
162 pxTaskCode: TaskFunction,
163 pcName: *const c_char,
164 uxStackDepth: StackType,
165 pvParameters: *mut c_void,
166 uxPriority: UBaseType,
167 pxCreatedTask: *mut ThreadHandle,
168 ) -> BaseType;
169
170 pub fn vTaskDelete(xTaskToDelete: ThreadHandle);
171
172 pub fn vTaskSuspend(xTaskToSuspend: ThreadHandle);
173
174 pub fn vTaskResume(xTaskToResume: ThreadHandle);
175
176 pub fn vTaskGetInfo(
177 xTask: ThreadHandle,
178 pxTaskStatus: *mut TaskStatus,
179 xGetFreeStackSpace: BaseType,
180 eState: TaskState,
181 );
182
183 pub fn ulTaskGenericNotifyTake(uxIndexToWaitOn: UBaseType, xClearCountOnExit: BaseType, xTicksToWait: TickType) -> u32;
184
185
186 pub fn xTaskGenericNotifyWait(
187 uxIndexToWaitOn: UBaseType,
188 ulBitsToClearOnEntry: u32,
189 ulBitsToClearOnExit: u32,
190 pulNotificationValue: *mut u32,
191 xTicksToWait: TickType,
192 ) -> BaseType;
193
194
195 pub fn xTaskGenericNotify(
196 xTaskToNotify: ThreadHandle,
197 uxIndexToNotify: UBaseType,
198 ulValue: u32,
199 eAction: u32,
200 pulPreviousNotificationValue: *mut u32,
201 ) -> BaseType;
202
203
204 pub fn xTaskGenericNotifyFromISR(
205 xTaskToNotify: ThreadHandle,
206 uxIndexToNotify: UBaseType,
207 ulValue: u32,
208 eAction: u32,
209 pulPreviousNotificationValue: *mut u32,
210 pxHigherPriorityTaskWoken: *mut BaseType,
211 ) -> BaseType;
212
213 pub fn xEventGroupWaitBits(
214 xEventGroup: EventGroupHandle,
215 uxBitsToWaitFor: EventBits,
216 xClearOnExit: BaseType,
217 xWaitForAllBits: BaseType,
218 xTicksToWait: TickType,
219 ) -> EventBits;
220
221 pub fn xEventGroupClearBits(
222 xEventGroup: EventGroupHandle,
223 uxBitsToClear: EventBits,
224 ) -> EventBits;
225
226 pub fn xEventGroupClearBitsFromISR(
227 xEventGroup: EventGroupHandle,
228 uxBitsToClear: EventBits,
229 ) -> BaseType;
230
231 pub fn xEventGroupSetBits(
232 xEventGroup: EventGroupHandle,
233 uxBitsToSet: EventBits,
234 ) -> EventBits;
235
236
237 pub fn xEventGroupSetBitsFromISR(
238 xEventGroup: EventGroupHandle,
239 uxBitsToSet: EventBits,
240 pxHigherPriorityTaskWoken: *mut BaseType,
241 ) -> BaseType;
242
243 pub fn xEventGroupGetBitsFromISR(xEventGroup: EventGroupHandle) -> EventBits;
244
245 pub fn vEventGroupDelete(xEventGroup: EventGroupHandle);
246
247 pub fn xEventGroupCreate() -> EventGroupHandle;
248
249 pub fn osal_rs_critical_section_enter();
250
251 pub fn osal_rs_critical_section_exit();
252
253 pub fn osal_rs_port_yield_from_isr(pxHigherPriorityTaskWoken: BaseType);
254
255 pub fn osal_rs_port_end_switching_isr( xSwitchRequired: BaseType );
256
257 pub fn xQueueCreateMutex(ucQueueType: u8) -> QueueHandle;
258
259 pub fn xQueueCreateCountingSemaphore(
260 uxMaxCount: UBaseType,
261 uxInitialCount: UBaseType,
262 ) -> QueueHandle;
263
264 pub fn xQueueSemaphoreTake(xQueue: QueueHandle, xTicksToWait: TickType) -> BaseType;
265
266 pub fn xQueueReceiveFromISR(
267 xQueue: QueueHandle,
268 pvBuffer: *mut c_void,
269 pxHigherPriorityTaskWoken: *mut BaseType,
270 ) -> BaseType;
271
272 pub fn xQueueGenericSend(
273 xQueue: QueueHandle,
274 pvItemToQueue: *const c_void,
275 xTicksToWait: TickType,
276 xCopyPosition: BaseType,
277 ) -> BaseType;
278
279 pub fn xQueueGiveFromISR(
280 xQueue: QueueHandle,
281 pxHigherPriorityTaskWoken: *mut BaseType,
282 ) -> BaseType;
283
284 pub fn vQueueDelete(xQueue: QueueHandle);
285
286 pub fn xQueueGenericCreate(
287 uxQueueLength: UBaseType,
288 uxItemSize: UBaseType,
289 ucQueueType: u8,
290 ) -> QueueHandle;
291
292 pub fn xQueueReceive(
293 xQueue: QueueHandle,
294 pvBuffer: *mut c_void,
295 xTicksToWait: TickType,
296 ) -> BaseType;
297
298 pub fn xQueueGenericSendFromISR(
299 xQueue: QueueHandle,
300 pvItemToQueue: *const c_void,
301 pxHigherPriorityTaskWoken: *mut BaseType,
302 xCopyPosition: BaseType,
303 ) -> BaseType;
304
305 pub fn xQueueTakeMutexRecursive(xMutex: QueueHandle, xTicksToWait: TickType) -> BaseType;
306
307 pub fn xQueueGiveMutexRecursive(xMutex: QueueHandle) -> BaseType;
308
309 pub fn xPortGetFreeHeapSize() -> usize;
310
311 pub fn xTimerCreateTimerTask() -> BaseType;
312
313 pub fn xTimerCreate(
314 pcTimerName: *const c_char,
315 xTimerPeriodInTicks: TickType,
316 xAutoReload: BaseType,
317 pvTimerID: *mut c_void,
318 pxCallbackFunction: Option<TimerCallback>,
319 ) -> TimerHandle;
320
321 pub fn osal_rs_timer_start(xTimer: TimerHandle, xTicksToWait: TickType) -> BaseType;
322
323 pub fn osal_rs_timer_stop(xTimer: TimerHandle, xTicksToWait: TickType) -> BaseType;
324
325 pub fn osal_rs_timer_reset(xTimer: TimerHandle, xTicksToWait: TickType) -> BaseType;
326
327 pub fn osal_rs_timer_change_period(
328 xTimer: TimerHandle,
329 xNewPeriodInTicks: TickType,
330 xTicksToWait: TickType,
331 ) -> BaseType;
332
333 pub fn osal_rs_timer_delete(xTimer: TimerHandle, xTicksToWait: TickType) -> BaseType;
334
335 pub fn pvTimerGetTimerID(xTimer: TimerHandle) -> *mut c_void;
336
337 pub fn printf(fmt: *const u8, ...) -> i32;
338}
339
340#[macro_export]
341macro_rules! ulTaskNotifyTake {
342 ($xClearCountOnExit:expr, $xTicksToWait:expr) => {
343 unsafe {
344 $crate::freertos::ffi::ulTaskGenericNotifyTake(
345 $crate::freertos::ffi::tskDEFAULT_INDEX_TO_NOTIFY,
346 $xClearCountOnExit,
347 $xTicksToWait
348 )
349 }
350 };
351}
352
353#[macro_export]
354macro_rules! xTaskNotifyWait {
355 ($ulBitsToClearOnEntry:expr, $ulBitsToClearOnExit:expr, $pulNotificationValue:expr, $xTicksToWait:expr) => {
356 unsafe {
357 $crate::freertos::ffi::xTaskGenericNotifyWait(
358 $crate::freertos::ffi::tskDEFAULT_INDEX_TO_NOTIFY,
359 $ulBitsToClearOnEntry,
360 $ulBitsToClearOnExit,
361 $pulNotificationValue,
362 $xTicksToWait
363 )
364 }
365 };
366}
367
368#[macro_export]
369macro_rules! xTaskNotify {
370 ($xTaskToNotify:expr, $ulValue:expr, $eAction:expr) => {
371 unsafe {
372 $crate::freertos::ffi::xTaskGenericNotify(
373 $xTaskToNotify,
374 $crate::freertos::ffi::tskDEFAULT_INDEX_TO_NOTIFY,
375 $ulValue,
376 $eAction,
377 core::ptr::null_mut()
378 )
379 }
380 };
381}
382
383#[macro_export]
384macro_rules! xTaskNotifyFromISR {
385 ($xTaskToNotify:expr, $ulValue:expr, $eAction:expr, $pxHigherPriorityTaskWoken:expr) => {
386 unsafe {
387 $crate::freertos::ffi::xTaskGenericNotifyFromISR(
388 $xTaskToNotify,
389 $crate::freertos::ffi::tskDEFAULT_INDEX_TO_NOTIFY,
390 $ulValue,
391 $eAction,
392 core::ptr::null_mut(),
393 $pxHigherPriorityTaskWoken
394 )
395 }
396 };
397}
398
399#[macro_export]
400macro_rules! xTaskNotifyAndQuery {
401 ($xTaskToNotify:expr, $ulValue:expr, $eAction:expr, $pulPreviousNotificationValue:expr) => {
402 unsafe {
403 $crate::freertos::ffi::xTaskGenericNotify(
404 $xTaskToNotify,
405 $crate::freertos::ffi::tskDEFAULT_INDEX_TO_NOTIFY,
406 $ulValue,
407 $eAction,
408 $pulPreviousNotificationValue
409 )
410 }
411 };
412}
413
414#[macro_export]
415macro_rules! vTaskDelayUntil {
416 ($pxPreviousWakeTime:expr, $xTimeIncrement:expr) => {
417 unsafe {
418 $crate::freertos::ffi::xTaskDelayUntil(
419 $pxPreviousWakeTime,
420 $xTimeIncrement
421 );
422 }
423 };
424}
425
426#[macro_export]
427macro_rules! xEventGroupGetBits {
428 ($xEventGroup:expr) => {
429 unsafe {
430 $crate::freertos::ffi::xEventGroupClearBits($xEventGroup, 0)
431 }
432 };
433}
434
435#[macro_export]
436macro_rules! xSemaphoreCreateCounting {
437 ($uxMaxCount:expr, $uxInitialCount:expr) => {
438 unsafe {
439 $crate::freertos::ffi::xQueueCreateCountingSemaphore(
440 $uxMaxCount,
441 $uxInitialCount
442 )
443 }
444 };
445}
446
447#[macro_export]
448macro_rules! xSemaphoreTake {
449 ($xSemaphore:expr, $xBlockTime:expr) => {
450 unsafe {
451 $crate::freertos::ffi::xQueueSemaphoreTake(
452 $xSemaphore,
453 $xBlockTime
454 )
455 }
456 };
457}
458
459#[macro_export]
460macro_rules! xSemaphoreTakeFromISR {
461 ($xSemaphore:expr, $pxHigherPriorityTaskWoken:expr) => {
462 unsafe {
463 $crate::freertos::ffi::xQueueReceiveFromISR(
464 $xSemaphore,
465 core::ptr::null_mut(),
466 $pxHigherPriorityTaskWoken
467 )
468 }
469 };
470}
471
472#[macro_export]
473macro_rules! xSemaphoreGive {
474 ($xSemaphore:expr) => {
475 unsafe {
476 $crate::freertos::ffi::xQueueGenericSend(
477 $xSemaphore,
478 core::ptr::null(),
479 $crate::freertos::ffi::semGIVE_BLOCK_TIME,
480 $crate::freertos::ffi::queueSEND_TO_BACK
481 )
482 }
483 };
484}
485
486#[macro_export]
487macro_rules! xSemaphoreGiveFromISR {
488 ($xSemaphore:expr, $pxHigherPriorityTaskWoken:expr) => {
489 unsafe {
490 $crate::freertos::ffi::xQueueGiveFromISR(
491 $xSemaphore,
492 $pxHigherPriorityTaskWoken
493 )
494 }
495 };
496}
497
498#[macro_export]
499macro_rules! vSemaphoreDelete {
500 ($xSemaphore:expr) => {
501 unsafe {
502 $crate::freertos::ffi::vQueueDelete($xSemaphore)
503 }
504 };
505}
506
507#[macro_export]
508macro_rules! xQueueCreate {
509 ($uxQueueLength:expr, $uxItemSize:expr) => {
510 unsafe {
511 $crate::freertos::ffi::xQueueGenericCreate(
512 $uxQueueLength,
513 $uxItemSize,
514 $crate::freertos::ffi::queueQUEUE_TYPE_BASE
515 )
516 }
517 };
518}
519
520#[macro_export]
521macro_rules! xQueueSendToBackFromISR {
522 ($xQueue:expr, $pvItemToQueue:expr, $pxHigherPriorityTaskWoken:expr) => {
523 unsafe {
524 $crate::freertos::ffi::xQueueGenericSendFromISR(
525 $xQueue,
526 $pvItemToQueue,
527 $pxHigherPriorityTaskWoken,
528 $crate::freertos::ffi::queueSEND_TO_BACK
529 )
530 }
531 };
532}
533
534#[macro_export]
535macro_rules! xQueueSendToBack {
536 ($xQueue:expr, $pvItemToQueue:expr, $xTicksToWait:expr) => {
537 unsafe {
538 $crate::freertos::ffi::xQueueGenericSend(
539 $xQueue,
540 $pvItemToQueue,
541 $xTicksToWait,
542 $crate::freertos::ffi::queueSEND_TO_BACK
543 )
544 }
545 };
546}
547
548#[macro_export]
549macro_rules! xSemaphoreCreateRecursiveMutex {
550 () => {
551 unsafe {
552 $crate::freertos::ffi::xQueueCreateMutex(
553 $crate::freertos::ffi::queueQUEUE_TYPE_RECURSIVE_MUTEX
554 )
555 }
556 };
557}
558
559#[macro_export]
560macro_rules! xSemaphoreTakeRecursive {
561 ($xMutex:expr, $xBlockTime:expr) => {
562 unsafe {
563 $crate::freertos::ffi::xQueueTakeMutexRecursive(
564 $xMutex,
565 $xBlockTime
566 )
567 }
568 };
569}
570
571#[macro_export]
572macro_rules! xSemaphoreGiveRecursive {
573 ($xMutex:expr) => {
574 unsafe {
575 $crate::freertos::ffi::xQueueGiveMutexRecursive($xMutex)
576 }
577 };
578}