SatCat5
message_buffer.cc
1 // Copyright 2024-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
6 #include <hal_freertos/message_buffer.h>
7 #include <satcat5/utils.h>
8 
9 // User-adjustable constants
10 #ifndef SATCAT5_FREERTOS_MSG_BUF_SEMPHR_TIMEOUT_MS
11  #define SATCAT5_FREERTOS_MSG_BUF_SEMPHR_TIMEOUT_MS 1
12 #endif
13 
14 #ifndef SATCAT5_FREERTOS_MSG_BUFF_SEND_TIMEOUT_MS
15  #define SATCAT5_FREERTOS_MSG_BUFF_SEND_TIMEOUT_MS 1
16 #endif
17 
18 #ifndef SATCAT5_MESSAGEBUFFER_BUFFSIZE
19  #define SATCAT5_MESSAGEBUFFER_BUFFSIZE 1600
20 #endif
21 
26 
27 MessageCopy::MessageCopy(
29  MessageBufferHandle_t* msg_buff_handle,
30  SemaphoreHandle_t* msg_buff_mutex)
31  : m_src(src)
32  , m_handle(msg_buff_handle)
33  , m_mutex(msg_buff_mutex)
34 {
35  if (m_src) m_src->set_callback(this);
36 }
37 
38 #if SATCAT5_ALLOW_DELETION
39 MessageCopy::~MessageCopy() {
40  if (m_src) m_src->set_callback(nullptr);
41 }
42 #endif
43 
45  m_src = 0;
46 }
47 
49  // Check TX Ready Bytes & Transfer
50  u8 tmp[SATCAT5_MESSAGEBUFFER_BUFFSIZE];
51  while (unsigned rx_bytes = src->get_read_ready()) {
52  // Copy data from source to temporary buffer.
53  rx_bytes = min_unsigned(rx_bytes, SATCAT5_MESSAGEBUFFER_BUFFSIZE);
54  src->read_bytes(rx_bytes, tmp);
55  src->read_finalize();
56 
57  // Take Semaphore
58  BaseType_t status = xSemaphoreTake(
59  *m_mutex,
60  pdMS_TO_TICKS(SATCAT5_FREERTOS_MSG_BUF_SEMPHR_TIMEOUT_MS));
61  if (!status) break;
62 
63  // Send to Message Buffer
64  status = xMessageBufferSend(
65  *m_handle,
66  tmp,
67  rx_bytes,
68  pdMS_TO_TICKS(SATCAT5_FREERTOS_MSG_BUFF_SEND_TIMEOUT_MS));
69 
70  // Release Semaphore
71  xSemaphoreGive(*m_mutex);
72  if (!status) break;
73  }
74 }
75 
77  u8* txbuff, unsigned txbytes,
78  MessageBufferHandle_t* msg_buff_handle,
79  SemaphoreHandle_t* msg_buff_mutex)
80  : satcat5::io::WriteableRedirect(&m_tx)
81  , m_tx(txbuff, txbytes, 32)
82  , m_copy(&m_tx, msg_buff_handle, msg_buff_mutex)
83 {
84  // Nothing else to initialize.
85 }
86 
87 MessageBufferPort::MessageBufferPort(
89  MessageBufferHandle_t* msg_buff_handle,
90  SemaphoreHandle_t* msg_buff_mutex)
91  : SwitchPort(sw, this)
92  , m_copy(&m_egress, msg_buff_handle, msg_buff_mutex)
93 {
94  // Nothing else to initialize.
95 }
A shared-memory Ethernet switch based on the MultiBuffer class.
Definition: eth_switch.h:93
PacketBuffer to MessageBuffer adapter.
MessageBuffer(u8 *txbuff, unsigned txbytes, MessageBufferHandle_t *msg_buff_handle, SemaphoreHandle_t *msg_buff_semphr)
Constructor requires a working buffer, plus handles for the FreeRTOS MessageBuffer and Semaphore.
SwitchPort to FreeRTOS MessageBuffer adapter.
Copy data from a Readable source to a FreeRTOS MessageBuffer.
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
void data_unlink(satcat5::io::Readable *src) override
Unlink this EventListener from the designated source, because the designated Readable object is being...
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
virtual bool read_bytes(unsigned nbytes, void *dst)
Read 0 or more bytes into a buffer.
Definition: io_readable.cc:190
virtual void read_finalize()
Consume any remaining bytes in this frame, if applicable.
Definition: io_readable.cc:270
virtual void set_callback(satcat5::io::EventListener *callback)
Update registered callback for data_rcvd() events.
Definition: io_readable.cc:39
virtual unsigned get_read_ready() const =0
How many bytes can be read without blocking?
Miscellaneous mathematical utility functions.
constexpr unsigned min_unsigned(unsigned a, unsigned b)
Min and max functions.
Definition: utils.h:111