PER Firmware
Loading...
Searching...
No Matches
spmc.h
Go to the documentation of this file.
1#ifndef SPMC_H
2#define SPMC_H
3
12#include <stddef.h>
13#include <stdint.h>
14#include <string.h>
15
16#define SPMC_BUS_ID_Pos (31U)
17#define SPMC_IS_EXTID_Pos (30U)
18
19typedef struct {
20 uint32_t ticks_ms; // ms timestamp of reception
21 uint32_t identity; // [1 bit bus ID] [1 bit isExtID] [1 bit reserved] [29 bits CAN ID]
22 uint64_t payload; // message data
24
25typedef enum : int {
26 SPMC_OK = 0,
27 SPMC_FULL = -1,
28 SPMC_EMPTY = -2,
29} SPMC_status_t;
30
31static_assert(
32 sizeof(timestamped_frame_t) == 16,
33 "timestamped_frame_t must be 16 bytes for optimal access patterns"
34);
35
36// todo tune values based on testing
37static constexpr size_t SPMC_CAPACITY = 512;
38static constexpr size_t SD_WRITE_THRESHOLD = 32;
39static_assert(
40 SPMC_CAPACITY % SD_WRITE_THRESHOLD == 0,
41 "the SPMC capacity must be a multiple of SD_WRITE_THRESHOLD "
42 "to prevent DMA wraparound issues"
43);
44// ! allocate one extra frame to distinguish full vs empty conditions
45static constexpr size_t SPMC_ALLOCATED_CAPACITY = SPMC_CAPACITY + 1;
46
47typedef struct {
48 timestamped_frame_t data[SPMC_ALLOCATED_CAPACITY];
49 volatile size_t head;
50 volatile size_t master_tail; // SD tail
51 volatile size_t follower_tail; // best-effort ETH tail
52 volatile uint32_t overflows;
53} SPMC_t;
54
55void SPMC_init(SPMC_t *spmc);
56SPMC_status_t SPMC_enqueue_from_ISR(SPMC_t *spmc, timestamped_frame_t *incoming_frame);
57size_t SPMC_master_peek_all(SPMC_t *spmc, timestamped_frame_t **first_item, size_t *total_unread);
58void SPMC_master_commit_tail(SPMC_t *spmc, size_t num_consumed);
59SPMC_status_t SPMC_follower_pop(SPMC_t *spmc, timestamped_frame_t **out, uint32_t *consecutive_items);
60
61#endif // SPMC_H
void SPMC_master_commit_tail(SPMC_t *spmc, size_t num_consumed)
Commits the specified number of consumed frames by advancing the master tail pointer.
Definition spmc.c:107
size_t SPMC_master_peek_all(SPMC_t *spmc, timestamped_frame_t **first_item, size_t *total_unread)
Peeks at the next batch of frames available for processing by the master (SD logging) without committ...
Definition spmc.c:82
SPMC_status_t SPMC_follower_pop(SPMC_t *spmc, timestamped_frame_t **out, uint32_t *consecutive_items)
Pops a single frame for the follower (Ethernet transmission) and advances the follower tail pointer....
Definition spmc.c:130
SPMC_status_t 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:49
void SPMC_init(SPMC_t *spmc)
Initializes the SPMC instance and configures CAN RX interrupts.
Definition spmc.c:26
Definition spmc.h:47
Definition spmc.h:19