modem: pipe: Add TRANSMIT_IDLE event
Add transmit idle event to modem_pipe_event enum. This will allow modules to await transmit idle before trying to transmit more data, instead of blindly calling modem_pipe_transmit in a loop until all data has been accepted. This will reduce the time spent trying to transmit data while the backend is blocked. Similarly to the RECEIVE_READY event, backends will call modem_pipe_notify_transmit_idle() to indicate that transmit is idle, and the TRANSMIT_IDLE event will be reinvoked when the modem pipe is attached to synchronize the state of the pipe with the user of it. Additionally, the TRANSMIT_IDLE event is also invoked when the modem is opened to further help synchronization with the user of the pipe. Signed-off-by: Bjarki Arge Andreasen <bjarki@arge-andreasen.me>
This commit is contained in:
parent
0f95b6fbb0
commit
516af3cb84
|
@ -25,6 +25,7 @@ extern "C" {
|
|||
enum modem_pipe_event {
|
||||
MODEM_PIPE_EVENT_OPENED = 0,
|
||||
MODEM_PIPE_EVENT_RECEIVE_READY,
|
||||
MODEM_PIPE_EVENT_TRANSMIT_IDLE,
|
||||
MODEM_PIPE_EVENT_CLOSED,
|
||||
};
|
||||
|
||||
|
@ -73,7 +74,8 @@ struct modem_pipe {
|
|||
enum modem_pipe_state state;
|
||||
struct k_mutex lock;
|
||||
struct k_condvar condvar;
|
||||
bool receive_ready_pending;
|
||||
uint8_t receive_ready_pending : 1;
|
||||
uint8_t transmit_idle_pending : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -213,6 +215,15 @@ void modem_pipe_notify_closed(struct modem_pipe *pipe);
|
|||
*/
|
||||
void modem_pipe_notify_receive_ready(struct modem_pipe *pipe);
|
||||
|
||||
/**
|
||||
* @brief Notify user of pipe that pipe has no more data to transmit
|
||||
*
|
||||
* @param pipe Pipe instance
|
||||
*
|
||||
* @note Invoked from instance which initialized the pipe instance
|
||||
*/
|
||||
void modem_pipe_notify_transmit_idle(struct modem_pipe *pipe);
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
|
|
@ -21,6 +21,7 @@ void modem_pipe_init(struct modem_pipe *pipe, void *data, struct modem_pipe_api
|
|||
pipe->user_data = NULL;
|
||||
pipe->state = MODEM_PIPE_STATE_CLOSED;
|
||||
pipe->receive_ready_pending = false;
|
||||
pipe->transmit_idle_pending = true;
|
||||
|
||||
k_mutex_init(&pipe->lock);
|
||||
k_condvar_init(&pipe->condvar);
|
||||
|
@ -82,6 +83,10 @@ void modem_pipe_attach(struct modem_pipe *pipe, modem_pipe_api_callback callback
|
|||
pipe->callback(pipe, MODEM_PIPE_EVENT_RECEIVE_READY, pipe->user_data);
|
||||
}
|
||||
|
||||
if (pipe->transmit_idle_pending && (pipe->callback != NULL)) {
|
||||
pipe->callback(pipe, MODEM_PIPE_EVENT_TRANSMIT_IDLE, pipe->user_data);
|
||||
}
|
||||
|
||||
k_mutex_unlock(&pipe->lock);
|
||||
}
|
||||
|
||||
|
@ -97,6 +102,7 @@ int modem_pipe_transmit(struct modem_pipe *pipe, const uint8_t *buf, size_t size
|
|||
}
|
||||
|
||||
ret = pipe->api->transmit(pipe->data, buf, size);
|
||||
pipe->transmit_idle_pending = false;
|
||||
k_mutex_unlock(&pipe->lock);
|
||||
return ret;
|
||||
}
|
||||
|
@ -179,6 +185,7 @@ void modem_pipe_notify_opened(struct modem_pipe *pipe)
|
|||
|
||||
if (pipe->callback != NULL) {
|
||||
pipe->callback(pipe, MODEM_PIPE_EVENT_OPENED, pipe->user_data);
|
||||
pipe->callback(pipe, MODEM_PIPE_EVENT_TRANSMIT_IDLE, pipe->user_data);
|
||||
}
|
||||
|
||||
k_condvar_signal(&pipe->condvar);
|
||||
|
@ -190,6 +197,7 @@ void modem_pipe_notify_closed(struct modem_pipe *pipe)
|
|||
k_mutex_lock(&pipe->lock, K_FOREVER);
|
||||
pipe->state = MODEM_PIPE_STATE_CLOSED;
|
||||
pipe->receive_ready_pending = false;
|
||||
pipe->transmit_idle_pending = true;
|
||||
|
||||
if (pipe->callback != NULL) {
|
||||
pipe->callback(pipe, MODEM_PIPE_EVENT_CLOSED, pipe->user_data);
|
||||
|
@ -211,3 +219,16 @@ void modem_pipe_notify_receive_ready(struct modem_pipe *pipe)
|
|||
|
||||
k_mutex_unlock(&pipe->lock);
|
||||
}
|
||||
|
||||
void modem_pipe_notify_transmit_idle(struct modem_pipe *pipe)
|
||||
{
|
||||
k_mutex_lock(&pipe->lock, K_FOREVER);
|
||||
|
||||
pipe->transmit_idle_pending = true;
|
||||
|
||||
if (pipe->callback != NULL) {
|
||||
pipe->callback(pipe, MODEM_PIPE_EVENT_TRANSMIT_IDLE, pipe->user_data);
|
||||
}
|
||||
|
||||
k_mutex_unlock(&pipe->lock);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue