|
ELEC-C7222
Libraries for ELEC C7222 Course Work
|
freertos_wrappers provides a consistent C++ API for RTOS synchronization, communication, and tasking primitives across two targets:
rpi_pico: wrappers call native FreeRTOS APIs.grader: wrappers call grader-facing extern "C" hooks (and in some cases hosted fallback behavior), so tests can store/inspect state and drive events.The goal is to keep application code mostly platform-agnostic while preserving core FreeRTOS semantics (ticks, ISR variants, explicit start/stop/take/give), including critical section enter/exit behavior.
Initialize() or convenience constructors.The FreeRTOS configuration in libs/elec_c7222/config/FreeRTOSConfig.h and the associated hooks are intended to:
std::thread) in course examples.RAII is useful for deterministic cleanup:
Lock/Unlock, Take/Give, Enter/Exit); wrappers are not scoped guard types that auto-acquire in constructors.RAII does not replace runtime lifecycle planning:
FreeRtosTask, deletion in destructor is convenient but you still must ensure the task body and any referenced data are safe to stop at that point.Use for one-shot/periodic deferred callbacks.
Common pattern:
Initialize(...) or constructor.Start(...) (or StartFromISR(...)).Notes:
rpi_pico) or grader equivalent.Use to create/manage an execution context.
Common pattern:
Initialize(...).Suspend/Resume, priority setters, Delete.Notes:
std::function<void(void*)>.FreeRtosTask also provides static utilities for operations tied to the current execution context and scheduler:
Delay(ticks): block the current task for a number of ticks.Yield(): yield the CPU from the current task.GetTickCount(): read the current scheduler tick counter.MsToTicks(ms): convert milliseconds to scheduler ticks.IdlePriority(): return the platform idle-priority baseline.StartScheduler(): start the scheduler (typically from main).These helpers let examples avoid direct FreeRTOS.h macro/API calls in application code while preserving FreeRTOS semantics.
Typical usage:
Use for event signaling (single token available/unavailable).
Common pattern:
Take(...) in waiter task.Give() or GiveFromISR() in producer/ISR.Use for bounded resource/token counting.
Common pattern:
(max_count, initial_count).Take(...) to consume token, Give()/GiveFromISR() to return token.GetCount() for observability.Use for mutual exclusion of shared state.
Common pattern:
Lock(...) before critical section.Unlock() after critical section.Notes:
Use for short non-blocking regions that require interrupt/scheduler exclusion.
Common pattern:
Enter() immediately before the protected instructions.Exit() immediately after the protected instructions.IsEntered() reports whether this wrapper object currently owns the critical section.Notes:
Exit() is missed.Use for bitmask-based synchronization across tasks.
Common pattern:
SetBits(...) / SetBitsFromISR(...).WaitBits(...) with clear/wait-all options.Use for fixed-size item passing with backpressure.
Common pattern:
Send(...)/Receive(...) for task context.Notes:
Overwrite(...) is intended for mailbox-style queues (length 1).Use for direct task-to-task signaling/value update.
Common pattern:
Notify*.Wait* or Take*.Notes:
Use for byte-stream transfer where message boundaries are not required.
Common pattern:
Send*.Receive*.Use for variable-size discrete message transfer.
Common pattern:
Send*.Receive*.freertos_wrappers/include/freertos_wrappers/platform/rpi_pico/freertos_wrappers/platform/grader/freertos_wrappers/freertos_wrappers.cmake