@@ -109,7 +109,7 @@ struct cdc_acm_uart_data {
109
109
*/
110
110
bool flow_ctrl ;
111
111
/* USBD CDC ACM TX fifo work */
112
- struct k_work tx_fifo_work ;
112
+ struct k_work_delayable tx_fifo_work ;
113
113
/* USBD CDC ACM RX fifo work */
114
114
struct k_work rx_fifo_work ;
115
115
atomic_t state ;
@@ -140,6 +140,12 @@ static ALWAYS_INLINE int cdc_acm_work_submit(struct k_work *work)
140
140
return k_work_submit_to_queue (& cdc_acm_work_q , work );
141
141
}
142
142
143
+ static ALWAYS_INLINE int cdc_acm_work_schedule (struct k_work_delayable * work ,
144
+ k_timeout_t delay )
145
+ {
146
+ return k_work_schedule_for_queue (& cdc_acm_work_q , work , delay );
147
+ }
148
+
143
149
static ALWAYS_INLINE bool check_wq_ctx (const struct device * dev )
144
150
{
145
151
return k_current_get () == k_work_queue_thread_get (& cdc_acm_work_q );
@@ -277,7 +283,7 @@ static void usbd_cdc_acm_enable(struct usbd_class_data *const c_data)
277
283
cdc_acm_work_submit (& data -> irq_cb_work );
278
284
} else {
279
285
/* Queue pending TX data on IN endpoint */
280
- cdc_acm_work_submit (& data -> tx_fifo_work );
286
+ cdc_acm_work_schedule (& data -> tx_fifo_work , K_NO_WAIT );
281
287
}
282
288
}
283
289
}
@@ -520,13 +526,14 @@ static int cdc_acm_send_notification(const struct device *dev,
520
526
*/
521
527
static void cdc_acm_tx_fifo_handler (struct k_work * work )
522
528
{
529
+ struct k_work_delayable * dwork = k_work_delayable_from_work (work );
523
530
struct cdc_acm_uart_data * data ;
524
531
struct usbd_class_data * c_data ;
525
532
struct net_buf * buf ;
526
533
size_t len ;
527
534
int ret ;
528
535
529
- data = CONTAINER_OF (work , struct cdc_acm_uart_data , tx_fifo_work );
536
+ data = CONTAINER_OF (dwork , struct cdc_acm_uart_data , tx_fifo_work );
530
537
c_data = data -> c_data ;
531
538
532
539
if (!atomic_test_bit (& data -> state , CDC_ACM_CLASS_ENABLED )) {
@@ -541,7 +548,7 @@ static void cdc_acm_tx_fifo_handler(struct k_work *work)
541
548
542
549
buf = cdc_acm_buf_alloc (cdc_acm_get_bulk_in (c_data ));
543
550
if (buf == NULL ) {
544
- cdc_acm_work_submit (& data -> tx_fifo_work );
551
+ cdc_acm_work_schedule (& data -> tx_fifo_work , K_MSEC ( 1 ) );
545
552
return ;
546
553
}
547
554
@@ -819,7 +826,7 @@ static void cdc_acm_irq_cb_handler(struct k_work *work)
819
826
820
827
if (data -> tx_fifo .altered ) {
821
828
LOG_DBG ("tx fifo altered, submit work" );
822
- cdc_acm_work_submit (& data -> tx_fifo_work );
829
+ cdc_acm_work_schedule (& data -> tx_fifo_work , K_NO_WAIT );
823
830
}
824
831
825
832
if (atomic_test_bit (& data -> state , CDC_ACM_IRQ_RX_ENABLED ) &&
@@ -887,7 +894,11 @@ static void cdc_acm_poll_out(const struct device *dev, const unsigned char c)
887
894
k_msleep (1 );
888
895
}
889
896
890
- cdc_acm_work_submit (& data -> tx_fifo_work );
897
+ /* Schedule with minimal timeout to make it possible to send more than
898
+ * one byte per USB transfer. The latency increase is negligible while
899
+ * the increased throughput and reduced CPU usage is easily observable.
900
+ */
901
+ cdc_acm_work_schedule (& data -> tx_fifo_work , K_MSEC (1 ));
891
902
}
892
903
893
904
#ifdef CONFIG_UART_LINE_CTRL
@@ -1006,7 +1017,7 @@ static int usbd_cdc_acm_preinit(const struct device *dev)
1006
1017
1007
1018
k_thread_name_set (& cdc_acm_work_q .thread , "cdc_acm_work_q" );
1008
1019
1009
- k_work_init (& data -> tx_fifo_work , cdc_acm_tx_fifo_handler );
1020
+ k_work_init_delayable (& data -> tx_fifo_work , cdc_acm_tx_fifo_handler );
1010
1021
k_work_init (& data -> rx_fifo_work , cdc_acm_rx_fifo_handler );
1011
1022
k_work_init (& data -> irq_cb_work , cdc_acm_irq_cb_handler );
1012
1023
0 commit comments