Skip to content

Commit 89bccfa

Browse files
authored
Differentiate sync/async ByteStreamDriver and update ComStub to work with both (#3987)
* Update ByteStream interface, interface implementations (and UTs) and ComStub * Update ComStub UTs * Fix RHEL8 static cast failure * spelling * Update Async driver to async port * Make code more readable... part 1 * Refactor code for human readability * Update docs * Remove unused helper
1 parent 96f445f commit 89bccfa

24 files changed

+371
-174
lines changed

Drv/ByteStreamDriverModel/ByteStreamDriverModel.fpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ module Drv {
1010

1111
@ Port to exchange buffer and status with the ByteStreamDriver model
1212
@ This port is used for receiving data from the driver as well as on
13-
@ callback of a send call
13+
@ callback of an asynchronous send call
1414
port ByteStreamData(
1515
ref buffer: Fw.Buffer,
1616
status: ByteStreamStatus
1717
)
1818

19+
@ Synchronous only - Send data out through the byte stream
20+
port ByteStreamSend(
21+
ref sendBuffer: Fw.Buffer @< Data to send
22+
) -> ByteStreamStatus
23+
1924
@ Signal indicating the driver is ready to send and received data
2025
port ByteStreamReady()
2126

Drv/ByteStreamDriverModel/docs/sdd.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ The outgoing stream is represented by the input `send` port; other components ca
55

66
## Design
77

8+
There are two versions for the ByteStreamDriver, a synchronous version (`Drv.ByteStreamDriver`) and an asynchronous version (`Drv.AsyncByteStreamDriver`). In the synchronous version, the (guarded) `send` port blocks and returns status. In the asynchronous version, the (async) `send` port calls back on the `sendReturnOut` port to return status and buffer ownership.
9+
810
### Send
911

10-
The manager component (for example a radio manager) initiates the transfer of send data by calling the "send" port.
11-
The caller will provide a `Fw::Buffer` containing the data to send. The driver component **must** perform a callback on its `sendReturnOut` port to return the status of that send as well as returning ownership of the `Fw::Buffer` to the caller.
12+
The manager component (for example a radio manager) initiates the transfer of send data by calling the "send" port. The caller will provide a `Fw::Buffer` containing the data to send.
13+
14+
1. Async case: The driver component **must** perform a callback on its `sendReturnOut` port to return the status of that send as well as returning ownership of the `Fw::Buffer` to the caller.
15+
2. Sync case: The driver component **must** return a status of the send operation and ownership of the `Fw::Buffer` to the caller.
16+
1217
These responses are an enumeration whose values are described in the following table:
1318

1419
| Value | Description | Buffer Ownership |
@@ -19,8 +24,7 @@ These responses are an enumeration whose values are described in the following t
1924

2025
### Receive
2126

22-
In the callback formation, the byte stream driver component initiates the transfer of received data by calling the
23-
"recv" output port. This port transfers any read data in a `Fw::Buffer` along with a status for the receive.
27+
The byte stream driver component initiates the transfer of received data by calling the "recv" output port. This port transfers any read data in a `Fw::Buffer` along with a status for the receive.
2428
This status is an enumeration whose values are described in the following table:
2529

2630
| Value | Description |
@@ -29,7 +33,7 @@ This status is an enumeration whose values are described in the following table:
2933
| ByteStreamStatus::RECV_NO_DATA | Receive worked, but there was no data |
3034
| ByteStreamStatus::OTHER_ERROR | Receive produced an error and buffer contains no valid data. |
3135

32-
The following components implement the byte stream model using a callback formation:
36+
The following components implement the byte stream model using the synchronous interface:
3337
- [`Drv::TcpClient`](../../TcpClient/docs/sdd.md): a F´ component wrapper of the tcp client
3438
- [`Drv::TcpServer`](../../TcpServer/docs/sdd.md): a F´ component wrapper of the tcp server
3539
- [`Drv::Udp`](../../Udp/docs/sdd.md): a F´ component wrapper of the udp
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module Drv {
2+
# In the asynchronous ByteStreamDriver interface, the send operation is non-blocking,
3+
# and returns status through the sendReturnOut callback
4+
5+
@ Asynchronous ByteStreamDriver interface
6+
interface AsyncByteStreamDriver {
7+
@ Port invoked when the driver is ready to send/receive data
8+
output port ready: Drv.ByteStreamReady
9+
10+
@ Port invoked by the driver when it receives data
11+
output port $recv: Drv.ByteStreamData
12+
13+
@ Invoke this port to send data out the driver (asynchronous)
14+
@ Status and ownership of the buffer are returned through the sendReturnOut callback
15+
async input port $send: Fw.BufferSend
16+
17+
@ Port returning ownership of data received on $send port
18+
output port sendReturnOut: Drv.ByteStreamData
19+
20+
@ Port receiving back ownership of data sent out on $recv port
21+
guarded input port recvReturnIn: Fw.BufferSend
22+
}
23+
}

Drv/Interfaces/ByteStreamDriver.fpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
module Drv {
2+
# In the synchronous ByteStreamDriver interface, the send operation is blocking
3+
# and returns a send status
4+
5+
@ Synchronous ByteStreamDriver interface
26
interface ByteStreamDriver {
37
@ Port invoked when the driver is ready to send/receive data
48
output port ready: Drv.ByteStreamReady
59

610
@ Port invoked by the driver when it receives data
711
output port $recv: Drv.ByteStreamData
812

9-
@ Invoke this port to send data out the driver
10-
guarded input port $send: Fw.BufferSend
11-
12-
@ Port returning ownership of data received on $send port
13-
output port sendReturnOut: Drv.ByteStreamData
13+
@ Invoke this port to send data out the driver (synchronous)
14+
@ Status is returned, and ownership of the buffer is retained by the caller
15+
guarded input port $send: Drv.ByteStreamSend
1416

1517
@ Port receiving back ownership of data sent out on $recv port
1618
guarded input port recvReturnIn: Fw.BufferSend

Drv/Interfaces/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
register_fprime_module(
99
Drv_Interfaces
1010
AUTOCODER_INPUTS
11+
"${CMAKE_CURRENT_LIST_DIR}/AsyncByteStreamDriver.fpp"
1112
"${CMAKE_CURRENT_LIST_DIR}/ByteStreamDriver.fpp"
1213
"${CMAKE_CURRENT_LIST_DIR}/Gpio.fpp"
1314
"${CMAKE_CURRENT_LIST_DIR}/I2c.fpp"

Drv/LinuxUartDriver/LinuxUartDriver.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ void LinuxUartDriver ::run_handler(FwIndexType portNum, U32 context) {
300300
this->tlmWrite_BytesRecv(this->m_bytesReceived);
301301
}
302302

303-
void LinuxUartDriver ::send_handler(const FwIndexType portNum, Fw::Buffer& serBuffer) {
303+
Drv::ByteStreamStatus LinuxUartDriver ::send_handler(const FwIndexType portNum, Fw::Buffer& serBuffer) {
304304
Drv::ByteStreamStatus status = Drv::ByteStreamStatus::OP_OK;
305305
if (this->m_fd == -1 || serBuffer.getData() == nullptr || serBuffer.getSize() == 0) {
306306
status = Drv::ByteStreamStatus::OTHER_ERROR;
@@ -319,8 +319,7 @@ void LinuxUartDriver ::send_handler(const FwIndexType portNum, Fw::Buffer& serBu
319319
this->m_bytesSent += static_cast<FwSizeType>(stat);
320320
}
321321
}
322-
// Return the buffer back to the caller
323-
sendReturnOut_out(0, serBuffer, status);
322+
return status;
324323
}
325324

326325
void LinuxUartDriver::recvReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {

Drv/LinuxUartDriver/LinuxUartDriver.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ class LinuxUartDriver final : public LinuxUartDriverComponentBase {
105105

106106
//! Handler implementation for serialSend
107107
//!
108-
void send_handler(FwIndexType portNum, /*!< The port number*/
109-
Fw::Buffer& serBuffer) override;
108+
Drv::ByteStreamStatus send_handler(FwIndexType portNum, /*!< The port number*/
109+
Fw::Buffer& serBuffer) override;
110110

111111
//! Handler implementation for recvReturnIn
112112
//!

Drv/TcpClient/TcpClientComponentImpl.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void TcpClientComponentImpl::connected() {
7070
// Handler implementations for user-defined typed input ports
7171
// ----------------------------------------------------------------------
7272

73-
void TcpClientComponentImpl::send_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) {
73+
Drv::ByteStreamStatus TcpClientComponentImpl::send_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) {
7474
FW_ASSERT_NO_OVERFLOW(fwBuffer.getSize(), U32);
7575
Drv::SocketIpStatus status = send(fwBuffer.getData(), static_cast<U32>(fwBuffer.getSize()));
7676
Drv::ByteStreamStatus returnStatus;
@@ -85,8 +85,7 @@ void TcpClientComponentImpl::send_handler(const FwIndexType portNum, Fw::Buffer&
8585
returnStatus = ByteStreamStatus::OTHER_ERROR;
8686
break;
8787
}
88-
// Return the buffer and status to the caller
89-
this->sendReturnOut_out(0, fwBuffer, returnStatus);
88+
return returnStatus;
9089
}
9190

9291
void TcpClientComponentImpl::recvReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {

Drv/TcpClient/TcpClientComponentImpl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class TcpClientComponentImpl final : public TcpClientComponentBase, public Socke
124124
* \param portNum: fprime port number of the incoming port call
125125
* \param fwBuffer: buffer containing data to be sent
126126
*/
127-
void send_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) override;
127+
Drv::ByteStreamStatus send_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) override;
128128

129129
//! Handler implementation for recvReturnIn
130130
//!

Drv/TcpClient/test/ut/TcpClientTester.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ void TcpClientTester ::test_with_loop(U32 iterations, bool recv_thread) {
8080
Drv::Test::force_recv_timeout(server_fd.serverFd, server);
8181
m_data_buffer.setSize(sizeof(m_data_storage));
8282
size = Drv::Test::fill_random_buffer(m_data_buffer);
83-
invoke_to_send(0, m_data_buffer);
84-
ASSERT_from_sendReturnOut_SIZE(i + 1);
85-
Drv::ByteStreamStatus status = this->fromPortHistory_sendReturnOut->at(i).status;
83+
Drv::ByteStreamStatus status = invoke_to_send(0, m_data_buffer);
8684
EXPECT_EQ(status, ByteStreamStatus::OP_OK);
8785
Drv::Test::receive_all(server, server_fd, buffer, size);
8886
Drv::Test::validate_random_buffer(m_data_buffer, buffer);

0 commit comments

Comments
 (0)