17static constexpr size_t SPMC_CHUNK_NUM_FRAMES = 512;
18static constexpr size_t SPMC_CHUNK_CAPACITY = 12;
19static constexpr size_t SPMC_FRAME_CAPACITY = SPMC_CHUNK_NUM_FRAMES * SPMC_CHUNK_CAPACITY;
21 SPMC_FRAME_CAPACITY % SPMC_CHUNK_NUM_FRAMES == 0,
22 "the SPMC capacity must be a multiple of SPMC_CHUNK_NUM_FRAMES "
23 "to prevent DMA wraparound issues and fragmentation"
25static constexpr size_t SPMC_BYTES_PER_CHUNK = SPMC_CHUNK_NUM_FRAMES *
sizeof(
timestamped_frame_t);
27static constexpr size_t SPMC_MINI_NUM_FRAMES = 16;
29 SPMC_CHUNK_NUM_FRAMES % SPMC_MINI_NUM_FRAMES == 0,
30 "SPMC_CHUNK_NUM_FRAMES must be divisible by SPMC_MINI_NUM_FRAMES "
31 "to allow mini chunk peeks for the ETH follower"
37 volatile size_t master_tail;
38 volatile size_t follower_tail;
41 volatile uint32_t overflows;
42 volatile uint32_t follower_drops;
43 volatile bool is_full;
50 "32-bit loads and stores are atomic, this is required for the lock-free design to work"
bool SPMC_enqueue_from_ISR(SPMC_t *spmc, timestamped_frame_t *incoming_frame)
Enqueues a received CAN message into the SPMC buffer from an ISR context. ! the two producer ISRs mus...
Definition spmc.c:65
bool SPMC_master_peek_chunk(SPMC_t *spmc, timestamped_frame_t **first_item)
Peeks at the next chunk for the master (SD logging) without committing the tail.
Definition spmc.c:100
void SPMC_master_advance_tail(SPMC_t *spmc)
Advances the master tail pointer by one chunk.
Definition spmc.c:131
void SPMC_init(SPMC_t *spmc)
Initializes the SPMC instance and configures CAN RX interrupts.
Definition spmc.c:41
size_t SPMC_follower_peek_minis(SPMC_t *spmc, timestamped_frame_t **first_item)
Peeks at the number of contiguous mini chunks available for the follower without lapping the master's...
Definition spmc.c:155
void SPMC_follower_advance_tail(SPMC_t *spmc, size_t minis_consumed)
Advances the follower tail pointer by a given number of mini chunks.
Definition spmc.c:202
Definition timestamped_frame.h:13
Definition for timestamped CAN frames.