1+ #include " FreeRTOS.h"
2+ #include " timers.h"
3+ #include " FakeTimers.hpp"
4+
5+ namespace cms {
6+ namespace test {
7+
8+ static FakeTimers* s_fakeTimers = nullptr ;
9+
10+ void InitFakeTimers ()
11+ {
12+ configASSERT (s_fakeTimers == nullptr );
13+
14+ std::chrono::milliseconds sysTick { configTICK_RATE_HZ * 1 /1000 };
15+ s_fakeTimers = new FakeTimers (sysTick);
16+ }
17+
18+ void DestroyFakeTimers ()
19+ {
20+ configASSERT (s_fakeTimers != nullptr );
21+ delete s_fakeTimers;
22+ s_fakeTimers = nullptr ;
23+ }
24+
25+ void MoveTimeForward (std::chrono::nanoseconds duration)
26+ {
27+ configASSERT (s_fakeTimers != nullptr );
28+ s_fakeTimers->MoveTimeForward (duration);
29+ }
30+
31+ std::chrono::nanoseconds TicksToChrono (TickType_t ticks)
32+ {
33+ std::chrono::milliseconds rtn (pdTICKS_TO_MS (ticks));
34+ return rtn;
35+ }
36+
37+ static const uint8_t s_an_object = 1 ;
38+
39+ void * HandleToPointer (FakeTimers::Handle handle)
40+ {
41+ return (void *)((&s_an_object) + handle);
42+ }
43+
44+ FakeTimers::Handle PointerToHandle (void * ptr)
45+ {
46+ return ((uint8_t *)ptr - &s_an_object);
47+ }
48+
49+ } // namespace test
50+ } // namespace cms
51+
52+ using namespace cms ::test;
53+
54+ extern " C" TimerHandle_t xTimerCreate ( const char * const pcTimerName,
55+ const TickType_t xTimerPeriodInTicks,
56+ const BaseType_t xAutoReload,
57+ void * const pvTimerID,
58+ TimerCallbackFunction_t pxCallbackFunction )
59+ {
60+ configASSERT (s_fakeTimers != nullptr );
61+ auto behavior = FakeTimers::Behavior::SingleShot;
62+ if (xAutoReload == pdTRUE)
63+ {
64+ behavior = FakeTimers::Behavior::AutoReload;
65+ }
66+ auto handle = s_fakeTimers->TimerCreate (pcTimerName,
67+ TicksToChrono (xTimerPeriodInTicks),
68+ behavior, pvTimerID,
69+ [=](FakeTimers::Handle handle, FakeTimers::Context){
70+ pxCallbackFunction (
71+ (TimerHandle_t)cms::test::HandleToPointer (handle));
72+ });
73+
74+ return (TimerHandle_t)HandleToPointer (handle);
75+ }
76+
77+ extern " C" BaseType_t xTimerGenericCommandFromTask ( TimerHandle_t xTimer,
78+ const BaseType_t xCommandID,
79+ const TickType_t xOptionalValue,
80+ BaseType_t * const pxHigherPriorityTaskWoken,
81+ const TickType_t xTicksToWait )
82+ {
83+ configASSERT (s_fakeTimers != nullptr );
84+ configASSERT (xTimer != nullptr );
85+
86+ (void )pxHigherPriorityTaskWoken;
87+ (void )xTicksToWait;
88+
89+ switch (xCommandID) {
90+ case tmrCOMMAND_START: {
91+ bool ok = s_fakeTimers->TimerStart (PointerToHandle (xTimer));
92+ configASSERT (ok);
93+ break ;
94+ }
95+ case tmrCOMMAND_DELETE: {
96+ bool ok = s_fakeTimers->TimerDelete (PointerToHandle (xTimer));
97+ configASSERT (ok);
98+ break ;
99+ }
100+ case tmrCOMMAND_STOP: {
101+ bool ok = s_fakeTimers->TimerStop (PointerToHandle (xTimer));
102+ configASSERT (ok);
103+ break ;
104+ }
105+ case tmrCOMMAND_CHANGE_PERIOD: {
106+ bool ok = s_fakeTimers->TimerChangePeriod (
107+ PointerToHandle (xTimer),
108+ std::chrono::milliseconds (pdTICKS_TO_MS (xOptionalValue)));
109+ configASSERT (ok);
110+ break ;
111+ }
112+ case tmrCOMMAND_RESET: {
113+ bool ok = s_fakeTimers->TimerReset (PointerToHandle (xTimer));
114+ configASSERT (ok);
115+ break ;
116+ }
117+ default :
118+ configASSERT (true == false );
119+ break ;
120+ }
121+
122+ return pdPASS;
123+ }
124+
125+ extern " C" TickType_t xTaskGetTickCount (void )
126+ {
127+ configASSERT (s_fakeTimers != nullptr );
128+ auto current = s_fakeTimers->GetCurrentInternalTime ();
129+ auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(current);
130+
131+ return pdMS_TO_TICKS (milliseconds.count ());
132+ }
133+
134+ extern " C" BaseType_t xTimerIsTimerActive ( TimerHandle_t xTimer )
135+ {
136+ configASSERT (s_fakeTimers != nullptr );
137+ bool active = s_fakeTimers->TimerIsActive (PointerToHandle (xTimer));
138+ if (active)
139+ {
140+ return pdTRUE;
141+ }
142+ else
143+ {
144+ return pdFALSE;
145+ }
146+ }
147+
148+ extern " C" void * pvTimerGetTimerID ( const TimerHandle_t xTimer )
149+ {
150+ configASSERT (s_fakeTimers != nullptr );
151+ auto context = s_fakeTimers->TimerGetContext (PointerToHandle (xTimer));
152+ return context;
153+ }
154+
155+ extern " C" void vTimerSetTimerID ( TimerHandle_t xTimer, void * pvNewID )
156+ {
157+ configASSERT (s_fakeTimers != nullptr );
158+ s_fakeTimers->TimerSetContext (PointerToHandle (xTimer), pvNewID);
159+ }
160+
161+ extern " C" const char * pcTimerGetName ( TimerHandle_t xTimer )
162+ {
163+ configASSERT (s_fakeTimers != nullptr );
164+ return s_fakeTimers->TimerGetName (PointerToHandle (xTimer));
165+ }
166+
167+ extern " C" BaseType_t xTimerGetReloadMode (TimerHandle_t xTimer)
168+ {
169+ configASSERT (s_fakeTimers != nullptr );
170+ auto behavior = s_fakeTimers->TimerGetBehavior (PointerToHandle (xTimer));
171+ if (behavior == cms::test::FakeTimers::Behavior::AutoReload)
172+ {
173+ return pdTRUE;
174+ }
175+ else
176+ {
177+ return pdFALSE;
178+ }
179+ }
180+
181+ extern " C" void vTimerSetReloadMode (TimerHandle_t xTimer, const BaseType_t xAutoReload)
182+ {
183+ configASSERT (s_fakeTimers != nullptr );
184+
185+ if (xAutoReload == pdTRUE)
186+ {
187+ s_fakeTimers->TimerSetBehavior (PointerToHandle (xTimer), FakeTimers::Behavior::AutoReload);
188+ }
189+ else
190+ {
191+ s_fakeTimers->TimerSetBehavior (PointerToHandle (xTimer), FakeTimers::Behavior::SingleShot);
192+ }
193+ }
194+
195+ extern " C" TickType_t xTimerGetPeriod ( TimerHandle_t xTimer )
196+ {
197+ configASSERT (s_fakeTimers != nullptr );
198+ auto period = s_fakeTimers->TimerGetPeriod (PointerToHandle (xTimer));
199+ auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(period);
200+ return pdMS_TO_TICKS (milliseconds.count ());
201+ }
202+
203+ extern " C" TickType_t xTimerGetExpiryTime ( TimerHandle_t xTimer )
204+ {
205+ configASSERT (s_fakeTimers != nullptr );
206+ auto period = s_fakeTimers->TimerGetExpiryTime (PointerToHandle (xTimer));
207+ auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(period);
208+ return pdMS_TO_TICKS (milliseconds.count ());
209+ }
0 commit comments