trace_recorder_parser/streaming/event/
mod.rs

1use crate::time::Timestamp;
2use crate::types::UserEventArgRecordCount;
3use derive_more::{Binary, Deref, Display, From, Into, LowerHex, Octal, UpperHex};
4use enum_iterator::Sequence;
5
6pub use base::BaseEvent;
7pub use object_name::ObjectNameEvent;
8pub use parser::EventParser;
9
10pub use trace_start::TraceStartEvent;
11pub use ts_config::TsConfigEvent;
12pub use unused_stack::UnusedStackEvent;
13pub use user::UserEvent;
14
15pub use event_group::*;
16pub use isr::*;
17pub use memory::*;
18pub use message_buffer::*;
19pub use mutex::*;
20pub use queue::*;
21pub use semaphore::*;
22pub use state_machine::*;
23pub use task::*;
24pub use task_notify::*;
25
26pub mod base;
27pub mod event_group;
28pub mod isr;
29pub mod memory;
30pub mod message_buffer;
31pub mod mutex;
32pub mod object_name;
33pub mod parser;
34pub mod queue;
35pub mod semaphore;
36pub mod state_machine;
37pub mod task;
38pub mod task_notify;
39pub mod trace_start;
40pub mod ts_config;
41pub mod unused_stack;
42pub mod user;
43
44pub(crate) const FIXED_USER_EVENT_ID: u16 = 0x98;
45
46#[derive(
47    Copy,
48    Clone,
49    Eq,
50    PartialEq,
51    Ord,
52    PartialOrd,
53    Hash,
54    Debug,
55    Into,
56    Display,
57    Binary,
58    Octal,
59    LowerHex,
60    UpperHex,
61    Deref,
62)]
63#[display(fmt = "{_0}")]
64pub struct EventCount(pub(crate) u16);
65
66#[derive(
67    Copy,
68    Clone,
69    Eq,
70    PartialEq,
71    Ord,
72    PartialOrd,
73    Hash,
74    Debug,
75    Into,
76    Display,
77    Binary,
78    Octal,
79    LowerHex,
80    UpperHex,
81    Deref,
82)]
83#[display(fmt = "{_0}")]
84pub struct EventParameterCount(pub(crate) u8);
85
86impl EventParameterCount {
87    pub const MAX: usize = 15;
88}
89
90impl From<EventParameterCount> for usize {
91    fn from(c: EventParameterCount) -> Self {
92        c.0.into()
93    }
94}
95
96/// Event codes for streaming mode
97/// Note that the upper 4 bits are the parameter count
98#[derive(
99    Copy,
100    Clone,
101    Eq,
102    PartialEq,
103    Ord,
104    PartialOrd,
105    Hash,
106    Debug,
107    Into,
108    Display,
109    Binary,
110    Octal,
111    LowerHex,
112    UpperHex,
113)]
114#[display(fmt = "{_0:X}")]
115pub struct EventCode(u16);
116
117impl EventCode {
118    pub fn event_id(&self) -> EventId {
119        EventId(self.0 & 0x0F_FF)
120    }
121
122    pub fn event_type(&self) -> EventType {
123        EventType::from(self.event_id())
124    }
125
126    /// Return the number of 32-bit parameters for the event
127    pub fn parameter_count(&self) -> EventParameterCount {
128        EventParameterCount(((self.0 >> 12) & 0x0F) as u8)
129    }
130}
131
132/// Event IDs for streaming mode, derived from the lower 12 bits of the EventId
133#[derive(
134    Copy,
135    Clone,
136    Eq,
137    PartialEq,
138    Ord,
139    PartialOrd,
140    Hash,
141    Debug,
142    From,
143    Into,
144    Display,
145    Binary,
146    Octal,
147    LowerHex,
148    UpperHex,
149    Sequence,
150)]
151#[display(fmt = "{_0:X}")]
152pub struct EventId(pub u16);
153
154/// Event types for streaming mode
155#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display, Sequence)]
156pub enum EventType {
157    #[display(fmt = "NULL")]
158    Null,
159
160    #[display(fmt = "TRACE_START")]
161    TraceStart,
162    #[display(fmt = "TIMESTAMP_CONFIG")]
163    TsConfig,
164    #[display(fmt = "OBJECT_NAME")]
165    ObjectName,
166    #[display(fmt = "TASK_PRIORITY")]
167    TaskPriority,
168    #[display(fmt = "TASK_PRIORITY_INHERIT")]
169    TaskPriorityInherit,
170    #[display(fmt = "TASK_PRIORITY_DISINHERIT")]
171    TaskPriorityDisinherit,
172    #[display(fmt = "DEFINE_ISR")]
173    DefineIsr,
174
175    #[display(fmt = "TASK_CREATE")]
176    TaskCreate,
177    #[display(fmt = "TASK_CREATE_FAILED")]
178    TaskCreateFailed,
179    #[display(fmt = "TASK_READY")]
180    TaskReady,
181    #[display(fmt = "TASK_SWITCH_ISR_BEGIN")]
182    TaskSwitchIsrBegin,
183    #[display(fmt = "TASK_SWITCH_ISR_RESUME")]
184    TaskSwitchIsrResume,
185    #[display(fmt = "TASK_SWITCH_TASK_BEGIN")]
186    TaskSwitchTaskBegin,
187    #[display(fmt = "TASK_SWITCH_TASK_RESUME")]
188    TaskSwitchTaskResume,
189    #[display(fmt = "TASK_ACTIVATE")]
190    TaskActivate,
191    #[display(fmt = "TASK_DELAY_UNTIL")]
192    TaskDelayUntil,
193    #[display(fmt = "TASK_DELAY")]
194    TaskDelay,
195    #[display(fmt = "TASK_SUSPEND")]
196    TaskSuspend,
197    #[display(fmt = "TASK_RESUME")]
198    TaskResume,
199    #[display(fmt = "TASK_RESUME_FROM_ISR")]
200    TaskResumeFromIsr,
201    #[display(fmt = "TASK_NOTIFY")]
202    TaskNotify,
203    #[display(fmt = "TASK_NOTIFY_WAIT")]
204    TaskNotifyWait,
205    #[display(fmt = "TASK_NOTIFY_WAIT_FAILED")]
206    TaskNotifyWaitFailed,
207    #[display(fmt = "TASK_NOTIFY_WAIT_BLOCK")]
208    TaskNotifyWaitBlock,
209    #[display(fmt = "TASK_NOTIFY_FROM_ISR")]
210    TaskNotifyFromIsr,
211
212    #[display(fmt = "MEMORY_ALLOC")]
213    MemoryAlloc,
214    #[display(fmt = "MEMORY_FREE")]
215    MemoryFree,
216
217    #[display(fmt = "QUEUE_CREATE")]
218    QueueCreate,
219    #[display(fmt = "QUEUE_CREATE_FAILED")]
220    QueueCreateFailed,
221    #[display(fmt = "QUEUE_SEND")]
222    QueueSend,
223    #[display(fmt = "QUEUE_SEND_FAILED")]
224    QueueSendFailed,
225    #[display(fmt = "QUEUE_SEND_BLOCK")]
226    QueueSendBlock,
227    #[display(fmt = "QUEUE_SEND_FROM_ISR")]
228    QueueSendFromIsr,
229    #[display(fmt = "QUEUE_SEND_FROM_ISR_FAILED")]
230    QueueSendFromIsrFailed,
231    #[display(fmt = "QUEUE_RECEIVE")]
232    QueueReceive,
233    #[display(fmt = "QUEUE_RECEIVE_FAILED")]
234    QueueReceiveFailed,
235    #[display(fmt = "QUEUE_RECEIVE_BLOCK")]
236    QueueReceiveBlock,
237    #[display(fmt = "QUEUE_RECEIVE_FROM_ISR")]
238    QueueReceiveFromIsr,
239    #[display(fmt = "QUEUE_RECEIVE_FROM_ISR_FAILED")]
240    QueueReceiveFromIsrFailed,
241    #[display(fmt = "QUEUE_PEEK")]
242    QueuePeek,
243    #[display(fmt = "QUEUE_PEEK_FAILED")]
244    QueuePeekFailed,
245    #[display(fmt = "QUEUE_PEEK_BLOCK")]
246    QueuePeekBlock,
247    #[display(fmt = "QUEUE_SEND_FRONT")]
248    QueueSendFront,
249    #[display(fmt = "QUEUE_SEND_FRONT_BLOCK")]
250    QueueSendFrontBlock,
251    #[display(fmt = "QUEUE_SEND_FRONT_FROM_ISR")]
252    QueueSendFrontFromIsr,
253
254    #[display(fmt = "MUTEX_CREATE")]
255    MutexCreate,
256    #[display(fmt = "MUTEX_CREATE_FAILED")]
257    MutexCreateFailed,
258    #[display(fmt = "MUTEX_GIVE")]
259    MutexGive,
260    #[display(fmt = "MUTEX_GIVE_FAILED")]
261    MutexGiveFailed,
262    #[display(fmt = "MUTEX_GIVE_BLOCK")]
263    MutexGiveBlock,
264    #[display(fmt = "MUTEX_GIVE_RECURSIVE")]
265    MutexGiveRecursive,
266    #[display(fmt = "MUTEX_TAKE")]
267    MutexTake,
268    #[display(fmt = "MUTEX_TAKE_FAILED")]
269    MutexTakeFailed,
270    #[display(fmt = "MUTEX_TAKE_BLOCK")]
271    MutexTakeBlock,
272    #[display(fmt = "MUTEX_TAKE_RECURSIVE")]
273    MutexTakeRecursive,
274    #[display(fmt = "MUTEX_TAKE_RECURSIVE_BLOCK")]
275    MutexTakeRecursiveBlock,
276
277    #[display(fmt = "SEMAPHORE_BINARY_CREATE")]
278    SemaphoreBinaryCreate,
279    #[display(fmt = "SEMAPHORE_BINARY_CREATE_FAILED")]
280    SemaphoreBinaryCreateFailed,
281    #[display(fmt = "SEMAPHORE_COUNTING_CREATE")]
282    SemaphoreCountingCreate,
283    #[display(fmt = "SEMAPHORE_COUNTING_CREATE_FAILED")]
284    SemaphoreCountingCreateFailed,
285    #[display(fmt = "SEMAPHORE_GIVE")]
286    SemaphoreGive,
287    #[display(fmt = "SEMAPHORE_GIVE_FAILED")]
288    SemaphoreGiveFailed,
289    #[display(fmt = "SEMAPHORE_GIVE_BLOCK")]
290    SemaphoreGiveBlock,
291    #[display(fmt = "SEMAPHORE_GIVE_FROM_ISR")]
292    SemaphoreGiveFromIsr,
293    #[display(fmt = "SEMAPHORE_GIVE_FROM_ISR_FAILED")]
294    SemaphoreGiveFromIsrFailed,
295    #[display(fmt = "SEMAPHORE_TAKE")]
296    SemaphoreTake,
297    #[display(fmt = "SEMAPHORE_TAKE_FAILED")]
298    SemaphoreTakeFailed,
299    #[display(fmt = "SEMAPHORE_TAKE_BLOCK")]
300    SemaphoreTakeBlock,
301    #[display(fmt = "SEMAPHORE_TAKE_FROM_ISR")]
302    SemaphoreTakeFromIsr,
303    #[display(fmt = "SEMAPHORE_TAKE_FROM_ISR_FAILED")]
304    SemaphoreTakeFromIsrFailed,
305    #[display(fmt = "SEMAPHORE_PEEK")]
306    SemaphorePeek,
307    #[display(fmt = "SEMAPHORE_PEEK_FAILED")]
308    SemaphorePeekFailed,
309    #[display(fmt = "SEMAPHORE_PEEK_BLOCK")]
310    SemaphorePeekBlock,
311
312    #[display(fmt = "TIMER_CREATE")]
313    TimerCreate,
314    #[display(fmt = "TIMER_START")]
315    TimerStart,
316    #[display(fmt = "TIMER_RESET")]
317    TimerReset,
318    #[display(fmt = "TIMER_STOP")]
319    TimerStop,
320    #[display(fmt = "TIMER_EXPIRED")]
321    TimerExpired,
322
323    #[display(fmt = "EVENTGROUP_CREATE")]
324    EventGroupCreate,
325    #[display(fmt = "EVENTGROUP_CREATE_FAILED")]
326    EventGroupCreateFailed,
327    #[display(fmt = "EVENTGROUP_SYNC")]
328    EventGroupSync,
329    #[display(fmt = "EVENTGROUP_WAITBITS")]
330    EventGroupWaitBits,
331    #[display(fmt = "EVENTGROUP_CLEARBITS")]
332    EventGroupClearBits,
333    #[display(fmt = "EVENTGROUP_CLEARBITS_FROM_ISR")]
334    EventGroupClearBitsFromIsr,
335    #[display(fmt = "EVENTGROUP_SETBITS")]
336    EventGroupSetBits,
337    #[display(fmt = "EVENTGROUP_SETBITS_FROM_ISR")]
338    EventGroupSetBitsFromIsr,
339    #[display(fmt = "EVENTGROUP_SYNC_BLOCK")]
340    EventGroupSyncBlock,
341    #[display(fmt = "EVENTGROUP_WAITBITS_BLOCK")]
342    EventGroupWaitBitsBlock,
343    #[display(fmt = "EVENTGROUP_SYNC_FAILED")]
344    EventGroupSyncFailed,
345    #[display(fmt = "EVENTGROUP_WAITBITS_FAILED")]
346    EventGroupWaitBitsFailed,
347
348    #[display(fmt = "MESSAGEBUFFER_CREATE")]
349    MessageBufferCreate,
350    #[display(fmt = "MESSAGEBUFFER_CREATE_FAILED")]
351    MessageBufferCreateFailed,
352    #[display(fmt = "MESSAGEBUFFER_SEND")]
353    MessageBufferSend,
354    #[display(fmt = "MESSAGEBUFFER_SEND_BLOCK")]
355    MessageBufferSendBlock,
356    #[display(fmt = "MESSAGEBUFFER_FAILED")]
357    MessageBufferSendFailed,
358    #[display(fmt = "MESSAGEBUFFER_RECEIVE")]
359    MessageBufferReceive,
360    #[display(fmt = "MESSAGEBUFFER_RECEIVE_BLOCK")]
361    MessageBufferReceiveBlock,
362    #[display(fmt = "MESSAGEBUFFER_RECEIVE_FAILED")]
363    MessageBufferReceiveFailed,
364    #[display(fmt = "MESSAGEBUFFER_SEND_FROM_ISR")]
365    MessageBufferSendFromIsr,
366    #[display(fmt = "MESSAGEBUFFER_SEND_FROM_ISR_FAILED")]
367    MessageBufferSendFromIsrFailed,
368    #[display(fmt = "MESSAGEBUFFER_RECEIVE_FROM_ISR")]
369    MessageBufferReceiveFromIsr,
370    #[display(fmt = "MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED")]
371    MessageBufferReceiveFromIsrFailed,
372    #[display(fmt = "MESSAGEBUFFER_RESET")]
373    MessageBufferReset,
374
375    #[display(fmt = "STATEMACHINE_STATE_CREATE")]
376    StateMachineStateCreate,
377    #[display(fmt = "STATEMACHINE_CREATE")]
378    StateMachineCreate,
379    #[display(fmt = "STATEMACHINE_STATE_CHANGE")]
380    StateMachineStateChange,
381
382    // User events
383    // Note that user event code range is 0x90..=0x9F
384    // Allow for 0-15 arguments (the arg count == word count, always 32 bits) is added to event code
385    // num_args = EventCode - 0x90
386    //
387    // This also supports fixed user events (PSF_EVENT_USER_EVENT_FIXED, 0x98..=0x9F)
388    #[display(fmt = "USER_EVENT")]
389    UserEvent(UserEventArgRecordCount),
390
391    #[display(fmt = "UNUSED_STACK")]
392    UnusedStack,
393
394    // Variant to handle unknown/unsupported event ID
395    #[display(fmt = "UNKNOWN({_0})")]
396    Unknown(EventId),
397}
398
399impl From<EventId> for EventType {
400    fn from(id: EventId) -> Self {
401        use EventType::*;
402        match u16::from(id) {
403            0x00 => Null,
404
405            0x01 => TraceStart,
406            0x02 => TsConfig,
407            0x03 => ObjectName,
408            0x04 => TaskPriority,
409            0x05 => TaskPriorityInherit,
410            0x06 => TaskPriorityDisinherit,
411            0x07 => DefineIsr,
412
413            0x10 => TaskCreate,
414            0x40 => TaskCreateFailed,
415            0x30 => TaskReady,
416            0x33 => TaskSwitchIsrBegin,
417            0x34 => TaskSwitchIsrResume,
418            0x35 => TaskSwitchTaskBegin,
419            0x36 => TaskSwitchTaskResume,
420            0x37 => TaskActivate,
421            0x79 => TaskDelayUntil,
422            0x7A => TaskDelay,
423            0x7B => TaskSuspend,
424            0x7C => TaskResume,
425            0x7D => TaskResumeFromIsr,
426            0xC9 => TaskNotify,
427            0xCA => TaskNotifyWait,
428            0xCB => TaskNotifyWaitBlock,
429            0xCC => TaskNotifyWaitFailed,
430            0xCD => TaskNotifyFromIsr,
431
432            0x38 => MemoryAlloc,
433            0x39 => MemoryFree,
434
435            0x11 => QueueCreate,
436            0x41 => QueueCreateFailed,
437            0x50 => QueueSend,
438            0x53 => QueueSendFailed,
439            0x56 => QueueSendBlock,
440            0x59 => QueueSendFromIsr,
441            0x5C => QueueSendFromIsrFailed,
442            0x60 => QueueReceive,
443            0x63 => QueueReceiveFailed,
444            0x66 => QueueReceiveBlock,
445            0x69 => QueueReceiveFromIsr,
446            0x6C => QueueReceiveFromIsrFailed,
447            0x70 => QueuePeek,
448            0x73 => QueuePeekFailed,
449            0x76 => QueuePeekBlock,
450            0xC0 => QueueSendFront,
451            0xC2 => QueueSendFrontBlock,
452            0xC3 => QueueSendFrontFromIsr,
453
454            0x13 => MutexCreate,
455            0x43 => MutexCreateFailed,
456            0x52 => MutexGive,
457            0x55 => MutexGiveFailed,
458            0x58 => MutexGiveBlock,
459            0xC5 => MutexGiveRecursive,
460            0x62 => MutexTake,
461            0x65 => MutexTakeFailed,
462            0x68 => MutexTakeBlock,
463            0xC7 => MutexTakeRecursive,
464            0xF6 => MutexTakeRecursiveBlock,
465
466            0x12 => SemaphoreBinaryCreate,
467            0x42 => SemaphoreBinaryCreateFailed,
468            0x16 => SemaphoreCountingCreate,
469            0x46 => SemaphoreCountingCreateFailed,
470            0x51 => SemaphoreGive,
471            0x54 => SemaphoreGiveFailed,
472            0x57 => SemaphoreGiveBlock,
473            0x5A => SemaphoreGiveFromIsr,
474            0x5D => SemaphoreGiveFromIsrFailed,
475            0x61 => SemaphoreTake,
476            0x64 => SemaphoreTakeFailed,
477            0x67 => SemaphoreTakeBlock,
478            0x6A => SemaphoreTakeFromIsr,
479            0x6D => SemaphoreTakeFromIsrFailed,
480            0x71 => SemaphorePeek,
481            0x74 => SemaphorePeekFailed,
482            0x77 => SemaphorePeekBlock,
483
484            0x14 => TimerCreate,
485            0xA0 => TimerStart,
486            0xA1 => TimerReset,
487            0xA2 => TimerStop,
488            0xD2 => TimerExpired,
489
490            0x15 => EventGroupCreate,
491            0x45 => EventGroupCreateFailed,
492            0xB0 => EventGroupSync,
493            0xB1 => EventGroupWaitBits,
494            0xB2 => EventGroupClearBits,
495            0xB3 => EventGroupClearBitsFromIsr,
496            0xB4 => EventGroupSetBits,
497            0xB5 => EventGroupSetBitsFromIsr,
498            0xB6 => EventGroupSyncBlock,
499            0xB7 => EventGroupWaitBitsBlock,
500            0xB8 => EventGroupSyncFailed,
501            0xB9 => EventGroupWaitBitsFailed,
502
503            0x19 => MessageBufferCreate,
504            0x4A => MessageBufferCreateFailed,
505            0xDE => MessageBufferSend,
506            0xDF => MessageBufferSendBlock,
507            0xE0 => MessageBufferSendFailed,
508            0xE1 => MessageBufferReceive,
509            0xE2 => MessageBufferReceiveBlock,
510            0xE3 => MessageBufferReceiveFailed,
511            0xE4 => MessageBufferSendFromIsr,
512            0xE5 => MessageBufferSendFromIsrFailed,
513            0xE6 => MessageBufferReceiveFromIsr,
514            0xE7 => MessageBufferReceiveFromIsrFailed,
515            0xE8 => MessageBufferReset,
516
517            0xEC => StateMachineStateCreate,
518            0xED => StateMachineCreate,
519            0xEE => StateMachineStateChange,
520
521            raw @ 0x90..=0x9F => UserEvent(UserEventArgRecordCount(raw as u8 - 0x90)),
522
523            0xEB => UnusedStack,
524
525            _ => Unknown(id),
526        }
527    }
528}
529
530impl From<EventType> for EventId {
531    fn from(et: EventType) -> Self {
532        use EventType::*;
533        let id = match et {
534            Null => 0x00,
535
536            TraceStart => 0x01,
537            TsConfig => 0x02,
538            ObjectName => 0x03,
539            TaskPriority => 0x04,
540            TaskPriorityInherit => 0x05,
541            TaskPriorityDisinherit => 0x06,
542            DefineIsr => 0x07,
543
544            TaskCreate => 0x10,
545            TaskCreateFailed => 0x40,
546            TaskReady => 0x30,
547            TaskSwitchIsrBegin => 0x33,
548            TaskSwitchIsrResume => 0x34,
549            TaskSwitchTaskBegin => 0x35,
550            TaskSwitchTaskResume => 0x36,
551            TaskActivate => 0x37,
552            TaskDelayUntil => 0x79,
553            TaskDelay => 0x7A,
554            TaskSuspend => 0x7B,
555            TaskResume => 0x7C,
556            TaskResumeFromIsr => 0x7D,
557            TaskNotify => 0xC9,
558            TaskNotifyWait => 0xCA,
559            TaskNotifyWaitBlock => 0xCB,
560            TaskNotifyWaitFailed => 0xCC,
561            TaskNotifyFromIsr => 0xCD,
562
563            MemoryAlloc => 0x38,
564            MemoryFree => 0x39,
565
566            QueueCreate => 0x11,
567            QueueCreateFailed => 0x41,
568            QueueSend => 0x50,
569            QueueSendFailed => 0x53,
570            QueueSendBlock => 0x56,
571            QueueSendFromIsr => 0x59,
572            QueueSendFromIsrFailed => 0x5C,
573            QueueReceive => 0x60,
574            QueueReceiveFailed => 0x63,
575            QueueReceiveBlock => 0x66,
576            QueueReceiveFromIsr => 0x69,
577            QueueReceiveFromIsrFailed => 0x6C,
578            QueuePeek => 0x70,
579            QueuePeekFailed => 0x73,
580            QueuePeekBlock => 0x76,
581            QueueSendFront => 0xC0,
582            QueueSendFrontBlock => 0xC2,
583            QueueSendFrontFromIsr => 0xC3,
584
585            MutexCreate => 0x13,
586            MutexCreateFailed => 0x43,
587            MutexGive => 0x52,
588            MutexGiveFailed => 0x55,
589            MutexGiveBlock => 0x58,
590            MutexGiveRecursive => 0xC5,
591            MutexTake => 0x62,
592            MutexTakeFailed => 0x65,
593            MutexTakeBlock => 0x68,
594            MutexTakeRecursive => 0xC7,
595            MutexTakeRecursiveBlock => 0xF6,
596
597            SemaphoreBinaryCreate => 0x12,
598            SemaphoreBinaryCreateFailed => 0x42,
599            SemaphoreCountingCreate => 0x16,
600            SemaphoreCountingCreateFailed => 0x46,
601            SemaphoreGive => 0x51,
602            SemaphoreGiveFailed => 0x54,
603            SemaphoreGiveBlock => 0x57,
604            SemaphoreGiveFromIsr => 0x5A,
605            SemaphoreGiveFromIsrFailed => 0x5D,
606            SemaphoreTake => 0x61,
607            SemaphoreTakeFailed => 0x64,
608            SemaphoreTakeBlock => 0x67,
609            SemaphoreTakeFromIsr => 0x6A,
610            SemaphoreTakeFromIsrFailed => 0x6D,
611            SemaphorePeek => 0x71,
612            SemaphorePeekFailed => 0x74,
613            SemaphorePeekBlock => 0x77,
614
615            TimerCreate => 0x14,
616            TimerStart => 0xA0,
617            TimerReset => 0xA1,
618            TimerStop => 0xA2,
619            TimerExpired => 0xD2,
620
621            EventGroupCreate => 0x15,
622            EventGroupCreateFailed => 0x45,
623            EventGroupSync => 0xB0,
624            EventGroupWaitBits => 0xB1,
625            EventGroupClearBits => 0xB2,
626            EventGroupClearBitsFromIsr => 0xB3,
627            EventGroupSetBits => 0xB4,
628            EventGroupSetBitsFromIsr => 0xB5,
629            EventGroupSyncBlock => 0xB6,
630            EventGroupWaitBitsBlock => 0xB7,
631            EventGroupSyncFailed => 0xB8,
632            EventGroupWaitBitsFailed => 0xB9,
633
634            MessageBufferCreate => 0x19,
635            MessageBufferCreateFailed => 0x4A,
636            MessageBufferSend => 0xDE,
637            MessageBufferSendBlock => 0xDF,
638            MessageBufferSendFailed => 0xE0,
639            MessageBufferReceive => 0xE1,
640            MessageBufferReceiveBlock => 0xE2,
641            MessageBufferReceiveFailed => 0xE3,
642            MessageBufferSendFromIsr => 0xE4,
643            MessageBufferSendFromIsrFailed => 0xE5,
644            MessageBufferReceiveFromIsr => 0xE6,
645            MessageBufferReceiveFromIsrFailed => 0xE7,
646            MessageBufferReset => 0xE8,
647
648            StateMachineStateCreate => 0xEC,
649            StateMachineCreate => 0xED,
650            StateMachineStateChange => 0xEE,
651
652            UserEvent(ac) => (0x90 + ac.0).into(),
653
654            UnusedStack => 0xEB,
655
656            Unknown(raw) => raw.0,
657        };
658        EventId(id)
659    }
660}
661
662impl EventType {
663    /// Return the number of expected parameters for the event type, otherwise
664    /// return None for event types with variable parameters.
665    pub(crate) fn expected_parameter_count(&self) -> Option<usize> {
666        use EventType::*;
667        Some(match self {
668            Null => 0,
669            TraceStart => 1,
670
671            TaskPriority | TaskPriorityInherit | TaskPriorityDisinherit => 2,
672
673            TsConfig | ObjectName | DefineIsr | TaskActivate | UserEvent(_) | Unknown(_) => {
674                return None
675            }
676
677            TaskCreate
678            | QueueCreate
679            | MutexCreate
680            | SemaphoreCountingCreate
681            | SemaphoreBinaryCreate => 2,
682
683            TaskReady | TaskSwitchIsrBegin | TaskSwitchIsrResume | TaskSwitchTaskBegin
684            | TaskSwitchTaskResume => 1,
685
686            TaskNotify | TaskNotifyFromIsr => 1,
687            TaskNotifyWait | TaskNotifyWaitBlock => 2,
688
689            MemoryAlloc | MemoryFree => 2,
690
691            QueueSend
692            | QueueSendBlock
693            | QueueSendFromIsr
694            | QueueReceiveFromIsr
695            | QueueSendFront
696            | QueueSendFrontBlock
697            | QueueSendFrontFromIsr => 2,
698
699            QueueReceive | QueueReceiveBlock | QueuePeek | QueuePeekBlock => 3,
700
701            MutexGive | MutexGiveBlock | MutexGiveRecursive => 1,
702            MutexTake | MutexTakeBlock | MutexTakeRecursive | MutexTakeRecursiveBlock => 2,
703
704            SemaphoreGive | SemaphoreGiveBlock | SemaphoreGiveFromIsr | SemaphoreTakeFromIsr => 2,
705
706            SemaphoreTake | SemaphoreTakeBlock | SemaphorePeek | SemaphorePeekBlock => 3,
707
708            UnusedStack => 2,
709
710            EventGroupCreate |
711            EventGroupSync |
712            EventGroupWaitBits |
713            EventGroupClearBits|
714            EventGroupClearBitsFromIsr |
715            EventGroupSetBits |
716            EventGroupSetBitsFromIsr |
717            EventGroupSyncBlock |
718            EventGroupWaitBitsBlock => 2,
719
720            MessageBufferCreate |
721            MessageBufferSend |
722            MessageBufferReceive |
723            MessageBufferSendFromIsr |
724            MessageBufferReceiveFromIsr |
725            MessageBufferReset => 2,
726
727            MessageBufferSendBlock |
728            MessageBufferReceiveBlock => 1,
729
730            StateMachineCreate | StateMachineStateCreate | StateMachineStateChange => 2,
731
732            _ /* Event types not handled */ => return None,
733        })
734    }
735}
736
737#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display)]
738pub enum Event {
739    #[display(fmt = "TraceStart({_0})")]
740    TraceStart(TraceStartEvent),
741    #[display(fmt = "TsConfig({_0})")]
742    TsConfig(TsConfigEvent),
743    #[display(fmt = "ObjectName({_0})")]
744    ObjectName(ObjectNameEvent),
745    #[display(fmt = "TaskPriority({_0})")]
746    TaskPriority(TaskPriorityEvent),
747    #[display(fmt = "TaskPriorityInherit({_0})")]
748    TaskPriorityInherit(TaskPriorityInheritEvent),
749    #[display(fmt = "TaskPriorityDisinherit({_0})")]
750    TaskPriorityDisinherit(TaskPriorityDisinheritEvent),
751    #[display(fmt = "IsrDefine({_0})")]
752    IsrDefine(IsrDefineEvent),
753
754    #[display(fmt = "TaskCreate({_0})")]
755    TaskCreate(TaskCreateEvent),
756    #[display(fmt = "QueueCreate({_0})")]
757    QueueCreate(QueueCreateEvent),
758    #[display(fmt = "MutexCreate({_0})")]
759    MutexCreate(MutexCreateEvent),
760    #[display(fmt = "SemaphoreBinaryCreate({_0})")]
761    SemaphoreBinaryCreate(SemaphoreCreateEvent),
762    #[display(fmt = "SemaphoreCountingCreate({_0})")]
763    SemaphoreCountingCreate(SemaphoreCreateEvent),
764
765    #[display(fmt = "TaskReady({_0})")]
766    TaskReady(TaskReadyEvent),
767    #[display(fmt = "IsrBegin({_0})")]
768    IsrBegin(IsrBeginEvent),
769    #[display(fmt = "IsrResume({_0})")]
770    IsrResume(IsrResumeEvent),
771    #[display(fmt = "TaskBegin({_0})")]
772    TaskBegin(TaskBeginEvent),
773    #[display(fmt = "TaskResume({_0})")]
774    TaskResume(TaskResumeEvent),
775    #[display(fmt = "TaskActivate({_0})")]
776    TaskActivate(TaskActivateEvent),
777
778    #[display(fmt = "TaskNotify({_0})")]
779    TaskNotify(TaskNotifyEvent),
780    #[display(fmt = "TaskNotifyFromIsr({_0})")]
781    TaskNotifyFromIsr(TaskNotifyFromIsrEvent),
782    #[display(fmt = "TaskNotifyWait({_0})")]
783    TaskNotifyWait(TaskNotifyWaitEvent),
784    #[display(fmt = "TaskNotifyWaitBlock({_0})")]
785    TaskNotifyWaitBlock(TaskNotifyWaitBlockEvent),
786
787    #[display(fmt = "MemoryAlloc({_0})")]
788    MemoryAlloc(MemoryAllocEvent),
789    #[display(fmt = "MemoryFree({_0})")]
790    MemoryFree(MemoryFreeEvent),
791
792    #[display(fmt = "QueueSend({_0})")]
793    QueueSend(QueueSendEvent),
794    #[display(fmt = "QueueSendBlock({_0})")]
795    QueueSendBlock(QueueSendBlockEvent),
796    #[display(fmt = "QueueSendFromIsr({_0})")]
797    QueueSendFromIsr(QueueSendFromIsrEvent),
798    #[display(fmt = "QueueReceive({_0})")]
799    QueueReceive(QueueReceiveEvent),
800    #[display(fmt = "QueueReceiveBlock({_0})")]
801    QueueReceiveBlock(QueueReceiveBlockEvent),
802    #[display(fmt = "QueueReceiveFromIsr({_0})")]
803    QueueReceiveFromIsr(QueueReceiveFromIsrEvent),
804    #[display(fmt = "QueuePeek({_0})")]
805    QueuePeek(QueuePeekEvent),
806    #[display(fmt = "QueuePeekBlock({_0})")]
807    QueuePeekBlock(QueuePeekBlockEvent),
808    #[display(fmt = "QueueSendFront({_0})")]
809    QueueSendFront(QueueSendFrontEvent),
810    #[display(fmt = "QueueSendFrontBlock({_0})")]
811    QueueSendFrontBlock(QueueSendFrontBlockEvent),
812    #[display(fmt = "QueueSendFrontFromIsr({_0})")]
813    QueueSendFrontFromIsr(QueueSendFrontFromIsrEvent),
814
815    #[display(fmt = "MutexGive({_0})")]
816    MutexGive(MutexGiveEvent),
817    #[display(fmt = "MutexGiveBlock({_0})")]
818    MutexGiveBlock(MutexGiveBlockEvent),
819    #[display(fmt = "MutexGiveRecursive({_0})")]
820    MutexGiveRecursive(MutexGiveRecursiveEvent),
821    #[display(fmt = "MutexTake({_0})")]
822    MutexTake(MutexTakeEvent),
823    #[display(fmt = "MutexTakeBlock({_0})")]
824    MutexTakeBlock(MutexTakeBlockEvent),
825    #[display(fmt = "MutexTakeRecursive({_0})")]
826    MutexTakeRecursive(MutexTakeRecursiveEvent),
827    #[display(fmt = "MutexTakeRecursiveBlock({_0})")]
828    MutexTakeRecursiveBlock(MutexTakeRecursiveBlockEvent),
829
830    #[display(fmt = "SemaphoreGive({_0})")]
831    SemaphoreGive(SemaphoreGiveEvent),
832    #[display(fmt = "SemaphoreGiveBlock({_0})")]
833    SemaphoreGiveBlock(SemaphoreGiveBlockEvent),
834    #[display(fmt = "SemaphoreGiveFromIsr({_0})")]
835    SemaphoreGiveFromIsr(SemaphoreGiveFromIsrEvent),
836    #[display(fmt = "SemaphoreTake({_0})")]
837    SemaphoreTake(SemaphoreTakeEvent),
838    #[display(fmt = "SemaphoreTakeBlock({_0})")]
839    SemaphoreTakeBlock(SemaphoreTakeBlockEvent),
840    #[display(fmt = "SemaphoreTakeFromIsr({_0})")]
841    SemaphoreTakeFromIsr(SemaphoreTakeFromIsrEvent),
842    #[display(fmt = "SemaphorePeek({_0})")]
843    SemaphorePeek(SemaphorePeekEvent),
844    #[display(fmt = "SemaphorePeekBlock({_0})")]
845    SemaphorePeekBlock(SemaphorePeekBlockEvent),
846
847    #[display(fmt = "EventGroupCreate({_0})")]
848    EventGroupCreate(EventGroupCreateEvent),
849    #[display(fmt = "EventGroupSync({_0})")]
850    EventGroupSync(EventGroupSyncEvent),
851    #[display(fmt = "EventGroupWaitBits({_0})")]
852    EventGroupWaitBits(EventGroupWaitBitsEvent),
853    #[display(fmt = "EventGroupClearBits({_0})")]
854    EventGroupClearBits(EventGroupClearBitsEvent),
855    #[display(fmt = "EventGroupClearBitsFromIsr({_0})")]
856    EventGroupClearBitsFromIsr(EventGroupClearBitsFromIsrEvent),
857    #[display(fmt = "EventGroupSetBits({_0})")]
858    EventGroupSetBits(EventGroupSetBitsEvent),
859    #[display(fmt = "EventGroupSetBitsFromIsr({_0})")]
860    EventGroupSetBitsFromIsr(EventGroupSetBitsFromIsrEvent),
861    #[display(fmt = "EventGroupSyncBlock({_0})")]
862    EventGroupSyncBlock(EventGroupSyncBlockEvent),
863    #[display(fmt = "EventGroupWaitBitsBlock({_0})")]
864    EventGroupWaitBitsBlock(EventGroupWaitBitsBlockEvent),
865
866    #[display(fmt = "MessageBufferCreate({_0})")]
867    MessageBufferCreate(MessageBufferCreateEvent),
868    #[display(fmt = "MessageBufferSend({_0})")]
869    MessageBufferSend(MessageBufferSendEvent),
870    #[display(fmt = "MessageBufferReceive({_0})")]
871    MessageBufferReceive(MessageBufferReceiveEvent),
872    #[display(fmt = "MessageBufferSendFromIsr({_0})")]
873    MessageBufferSendFromIsr(MessageBufferSendFromIsrEvent),
874    #[display(fmt = "MessageBufferReceiveFromIsr({_0})")]
875    MessageBufferReceiveFromIsr(MessageBufferReceiveFromIsrEvent),
876    #[display(fmt = "MessageBufferReset({_0})")]
877    MessageBufferReset(MessageBufferResetEvent),
878    #[display(fmt = "MessageBufferSendBlock({_0})")]
879    MessageBufferSendBlock(MessageBufferSendBlockEvent),
880    #[display(fmt = "MessageBufferReceiveBlock({_0})")]
881    MessageBufferReceiveBlock(MessageBufferReceiveBlockEvent),
882
883    #[display(fmt = "StateMachineCreate({_0})")]
884    StateMachineCreate(StateMachineCreateEvent),
885    #[display(fmt = "StateMachineStateCreate({_0})")]
886    StateMachineStateCreate(StateMachineStateCreateEvent),
887    #[display(fmt = "StateMachineStateChange({_0})")]
888    StateMachineStateChange(StateMachineStateChangeEvent),
889
890    #[display(fmt = "User({_0})")]
891    User(UserEvent),
892
893    #[display(fmt = "UnusedStack({_0})")]
894    UnusedStack(UnusedStackEvent),
895
896    #[display(fmt = "BaseEvent({_0})")]
897    Unknown(BaseEvent),
898}
899
900impl Event {
901    /// Get the event count (sequence number).
902    /// NOTE:
903    /// * V10: TraceStart reports 1 (doesn't track the internal header/timestamp-info/etc)
904    /// * V12: TraceStart reports 6 (does track the internal header/timestamp-info/etc)
905    pub fn event_count(&self) -> EventCount {
906        use Event::*;
907        match self {
908            TraceStart(e) => e.event_count,
909            TsConfig(e) => e.event_count,
910            ObjectName(e) => e.event_count,
911            TaskPriority(e) => e.event_count,
912            TaskPriorityInherit(e) => e.event_count,
913            TaskPriorityDisinherit(e) => e.event_count,
914            IsrDefine(e) => e.event_count,
915            TaskCreate(e) => e.event_count,
916            QueueCreate(e) => e.event_count,
917            MutexCreate(e) => e.event_count,
918            SemaphoreBinaryCreate(e) => e.event_count,
919            SemaphoreCountingCreate(e) => e.event_count,
920            TaskReady(e) => e.event_count,
921            IsrBegin(e) => e.event_count,
922            IsrResume(e) => e.event_count,
923            TaskBegin(e) => e.event_count,
924            TaskResume(e) => e.event_count,
925            TaskActivate(e) => e.event_count,
926            TaskNotify(e) => e.event_count,
927            TaskNotifyFromIsr(e) => e.event_count,
928            TaskNotifyWait(e) => e.event_count,
929            TaskNotifyWaitBlock(e) => e.event_count,
930            MemoryAlloc(e) => e.event_count,
931            MemoryFree(e) => e.event_count,
932            QueueSend(e) => e.event_count,
933            QueueSendBlock(e) => e.event_count,
934            QueueSendFromIsr(e) => e.event_count,
935            QueueReceive(e) => e.event_count,
936            QueueReceiveBlock(e) => e.event_count,
937            QueueReceiveFromIsr(e) => e.event_count,
938            QueuePeek(e) => e.event_count,
939            QueuePeekBlock(e) => e.event_count,
940            QueueSendFront(e) => e.event_count,
941            QueueSendFrontBlock(e) => e.event_count,
942            QueueSendFrontFromIsr(e) => e.event_count,
943            MutexGive(e) => e.event_count,
944            MutexGiveBlock(e) => e.event_count,
945            MutexGiveRecursive(e) => e.event_count,
946            MutexTake(e) => e.event_count,
947            MutexTakeBlock(e) => e.event_count,
948            MutexTakeRecursive(e) => e.event_count,
949            MutexTakeRecursiveBlock(e) => e.event_count,
950            SemaphoreGive(e) => e.event_count,
951            SemaphoreGiveBlock(e) => e.event_count,
952            SemaphoreGiveFromIsr(e) => e.event_count,
953            SemaphoreTake(e) => e.event_count,
954            SemaphoreTakeBlock(e) => e.event_count,
955            SemaphoreTakeFromIsr(e) => e.event_count,
956            SemaphorePeek(e) => e.event_count,
957            SemaphorePeekBlock(e) => e.event_count,
958            EventGroupCreate(e) => e.event_count,
959            EventGroupSync(e) => e.event_count,
960            EventGroupWaitBits(e) => e.event_count,
961            EventGroupClearBits(e) => e.event_count,
962            EventGroupClearBitsFromIsr(e) => e.event_count,
963            EventGroupSetBits(e) => e.event_count,
964            EventGroupSetBitsFromIsr(e) => e.event_count,
965            EventGroupSyncBlock(e) => e.event_count,
966            EventGroupWaitBitsBlock(e) => e.event_count,
967            MessageBufferCreate(e) => e.event_count,
968            MessageBufferSend(e) => e.event_count,
969            MessageBufferReceive(e) => e.event_count,
970            MessageBufferSendFromIsr(e) => e.event_count,
971            MessageBufferReceiveFromIsr(e) => e.event_count,
972            MessageBufferReset(e) => e.event_count,
973            MessageBufferSendBlock(e) => e.event_count,
974            MessageBufferReceiveBlock(e) => e.event_count,
975            StateMachineCreate(e) => e.event_count,
976            StateMachineStateCreate(e) => e.event_count,
977            StateMachineStateChange(e) => e.event_count,
978            User(e) => e.event_count,
979            UnusedStack(e) => e.event_count,
980            Unknown(e) => e.event_count,
981        }
982    }
983
984    pub fn timestamp(&self) -> Timestamp {
985        use Event::*;
986        match self {
987            TraceStart(e) => e.timestamp,
988            TsConfig(e) => e.timestamp,
989            ObjectName(e) => e.timestamp,
990            TaskPriority(e) => e.timestamp,
991            TaskPriorityInherit(e) => e.timestamp,
992            TaskPriorityDisinherit(e) => e.timestamp,
993            IsrDefine(e) => e.timestamp,
994            TaskCreate(e) => e.timestamp,
995            QueueCreate(e) => e.timestamp,
996            MutexCreate(e) => e.timestamp,
997            SemaphoreBinaryCreate(e) => e.timestamp,
998            SemaphoreCountingCreate(e) => e.timestamp,
999            TaskReady(e) => e.timestamp,
1000            IsrBegin(e) => e.timestamp,
1001            IsrResume(e) => e.timestamp,
1002            TaskBegin(e) => e.timestamp,
1003            TaskResume(e) => e.timestamp,
1004            TaskActivate(e) => e.timestamp,
1005            TaskNotify(e) => e.timestamp,
1006            TaskNotifyFromIsr(e) => e.timestamp,
1007            TaskNotifyWait(e) => e.timestamp,
1008            TaskNotifyWaitBlock(e) => e.timestamp,
1009            MemoryAlloc(e) => e.timestamp,
1010            MemoryFree(e) => e.timestamp,
1011            QueueSend(e) => e.timestamp,
1012            QueueSendBlock(e) => e.timestamp,
1013            QueueSendFromIsr(e) => e.timestamp,
1014            QueueReceive(e) => e.timestamp,
1015            QueueReceiveBlock(e) => e.timestamp,
1016            QueueReceiveFromIsr(e) => e.timestamp,
1017            QueuePeek(e) => e.timestamp,
1018            QueuePeekBlock(e) => e.timestamp,
1019            QueueSendFront(e) => e.timestamp,
1020            QueueSendFrontBlock(e) => e.timestamp,
1021            QueueSendFrontFromIsr(e) => e.timestamp,
1022            MutexGive(e) => e.timestamp,
1023            MutexGiveBlock(e) => e.timestamp,
1024            MutexGiveRecursive(e) => e.timestamp,
1025            MutexTake(e) => e.timestamp,
1026            MutexTakeBlock(e) => e.timestamp,
1027            MutexTakeRecursive(e) => e.timestamp,
1028            MutexTakeRecursiveBlock(e) => e.timestamp,
1029            SemaphoreGive(e) => e.timestamp,
1030            SemaphoreGiveBlock(e) => e.timestamp,
1031            SemaphoreGiveFromIsr(e) => e.timestamp,
1032            SemaphoreTake(e) => e.timestamp,
1033            SemaphoreTakeBlock(e) => e.timestamp,
1034            SemaphoreTakeFromIsr(e) => e.timestamp,
1035            SemaphorePeek(e) => e.timestamp,
1036            SemaphorePeekBlock(e) => e.timestamp,
1037            EventGroupCreate(e) => e.timestamp,
1038            EventGroupSync(e) => e.timestamp,
1039            EventGroupWaitBits(e) => e.timestamp,
1040            EventGroupClearBits(e) => e.timestamp,
1041            EventGroupClearBitsFromIsr(e) => e.timestamp,
1042            EventGroupSetBits(e) => e.timestamp,
1043            EventGroupSetBitsFromIsr(e) => e.timestamp,
1044            EventGroupSyncBlock(e) => e.timestamp,
1045            EventGroupWaitBitsBlock(e) => e.timestamp,
1046            MessageBufferCreate(e) => e.timestamp,
1047            MessageBufferSend(e) => e.timestamp,
1048            MessageBufferReceive(e) => e.timestamp,
1049            MessageBufferSendFromIsr(e) => e.timestamp,
1050            MessageBufferReceiveFromIsr(e) => e.timestamp,
1051            MessageBufferReset(e) => e.timestamp,
1052            MessageBufferSendBlock(e) => e.timestamp,
1053            MessageBufferReceiveBlock(e) => e.timestamp,
1054            StateMachineCreate(e) => e.timestamp,
1055            StateMachineStateCreate(e) => e.timestamp,
1056            StateMachineStateChange(e) => e.timestamp,
1057            User(e) => e.timestamp,
1058            UnusedStack(e) => e.timestamp,
1059            Unknown(e) => e.timestamp,
1060        }
1061    }
1062}
1063
1064pub type DroppedEventCount = u64;
1065
1066/// Event counter that tracks rollovers and discontinuities.
1067#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display)]
1068#[display(fmt = "{}", "self.count()")]
1069pub struct TrackingEventCounter {
1070    count: u16,
1071    rollovers: u32,
1072}
1073
1074impl TrackingEventCounter {
1075    /// Creates a new counter with an initial value of zero
1076    pub const fn zero() -> Self {
1077        Self {
1078            count: 0,
1079            rollovers: 0,
1080        }
1081    }
1082
1083    /// Sets the initial counter value and reset the rollover tracking.
1084    pub fn set_initial_count(&mut self, count: EventCount) {
1085        self.count = count.0;
1086        self.rollovers = 0;
1087    }
1088
1089    /// Updates the event count handling rollovers.
1090    /// Returns the number of dropped events, if any.
1091    /// NOTE: must be called at least once per event count type (u16) rollover interval
1092    pub fn update(&mut self, event_count: EventCount) -> Option<DroppedEventCount> {
1093        let prev_count = self.count();
1094
1095        // Handle rollover
1096        if event_count.0 <= self.count {
1097            self.rollovers += 1;
1098        }
1099        self.count = event_count.0;
1100
1101        let diff = self.count() - prev_count;
1102        if diff != 1 {
1103            // SAFETY: diff will always be >=1 due to the rollover handling above
1104            Some(diff - 1)
1105        } else {
1106            None
1107        }
1108    }
1109
1110    pub fn count(&self) -> u64 {
1111        u64::from(self.rollovers) << u16::BITS | u64::from(self.count)
1112    }
1113}
1114
1115#[cfg(test)]
1116mod test {
1117    use super::*;
1118
1119    #[test]
1120    fn event_type_roundtrip() {
1121        for raw in 0..=0xFF {
1122            let eid = EventId(raw);
1123            let et = EventType::from(eid);
1124            assert_eq!(eid, EventId::from(et));
1125        }
1126    }
1127
1128    #[test]
1129    fn event_counter_tracking() {
1130        let mut ec = TrackingEventCounter::zero();
1131        assert_eq!(ec.count(), 0);
1132
1133        // Reset initial count works
1134        ec.set_initial_count(EventCount(u16::MAX));
1135        assert_eq!(ec.count(), u16::MAX.into());
1136
1137        // Non-rollover discontinuities
1138        ec.set_initial_count(EventCount(0));
1139        assert_eq!(ec.count(), 0);
1140        assert_eq!(ec.update(EventCount(10)), Some(9)); // Missed events 1..=9
1141        assert_eq!(ec.count(), 10);
1142        assert_eq!(ec.update(EventCount(12)), Some(1)); // Missed event 11
1143        assert_eq!(ec.count(), 12);
1144        assert_eq!(ec.update(EventCount(13)), None);
1145        assert_eq!(ec.count(), 13);
1146
1147        // Rollover discontinuities
1148        ec.set_initial_count(EventCount(10));
1149        assert_eq!(ec.count(), 10);
1150        assert_eq!(
1151            ec.update(EventCount(10_u16.wrapping_add(u16::MAX))), // 9
1152            Some(u64::from(u16::MAX - 1)) // Missed events 11..<wrap-around>..=8
1153        );
1154        assert_eq!(ec.count(), u64::from(u16::MAX) + 10);
1155        assert_eq!(ec.update(EventCount(10)), None);
1156        assert_eq!(ec.count(), u64::from(u16::MAX) + 11);
1157        assert_eq!(ec.update(EventCount(12)), Some(1));
1158        assert_eq!(ec.count(), u64::from(u16::MAX) + 13);
1159
1160        // Similar, but show that updating with same event count means a rollover
1161        ec.set_initial_count(EventCount(10));
1162        assert_eq!(ec.count(), 10);
1163        assert_eq!(
1164            ec.update(EventCount(10)),
1165            Some(u64::from(u16::MAX)) // Missed events 11..<wrap-around>..=9
1166        );
1167        assert_eq!(ec.count(), u64::from(u16::MAX) + 11);
1168    }
1169}