MCPcopy Create free account
hub / github.com/RT-Thread/rt-thread / _serial_fifo_rx

Function _serial_fifo_rx

components/drivers/serial/dev_serial_v2.c:474–554  ·  view source on GitHub ↗

* @brief Serial receive data routines, This function will receive * data by using fifo * * @note In blocking mode, the function will wait until the specified amount of data is received or until a timeout occurs. * In non-blocking mode, the function will immediately attempt to retrieve as much data as possible from the ring buffer and return. * * @param dev The pointer of d

Source from the content-addressed store, hash-verified

472 * @return Returns the actual length of data received.
473 */
474static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
475 rt_off_t pos,
476 void *buffer,
477 rt_size_t size)
478{
479 struct rt_serial_device *serial;
480 struct rt_serial_rx_fifo *rx_fifo;
481 rt_base_t level;
482 rt_size_t recv_size = 0;
483
484 if (size == 0) return 0;
485 RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
486
487 serial = (struct rt_serial_device *)dev;
488 rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
489
490 if (dev->open_flag & RT_SERIAL_RX_BLOCKING)
491 {
492 rt_size_t data_len;
493 rt_tick_t delta_tick;
494 rt_size_t rx_bufsz_third = serial->config.rx_bufsz / 2;
495 rt_int32_t base_rx_timeout = rt_atomic_load(&rx_fifo->rx_timeout);
496 rt_int32_t rx_timeout_left = base_rx_timeout;
497 rt_tick_t begin_tick = rt_tick_get();
498
499 while (1)
500 {
501 if (rx_timeout_left != RT_WAITING_NO)
502 {
503 level = rt_spin_lock_irqsave(&serial->spinlock);
504 data_len = rt_ringbuffer_data_len(&rx_fifo->rb);
505 if (data_len < size - recv_size)
506 {
507 if (size - (recv_size + data_len) >= rx_bufsz_third)
508 {
509 rx_fifo->rx_cpt_index = rx_bufsz_third;
510 }
511 else
512 {
513 rx_fifo->rx_cpt_index = size - (recv_size + data_len);
514 }
515 rt_completion_wait(&rx_fifo->rx_cpt, 0);
516 }
517 rt_spin_unlock_irqrestore(&serial->spinlock, level);
518 }
519
520 level = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
521 recv_size += rt_ringbuffer_get(&rx_fifo->rb, (rt_uint8_t *)buffer + recv_size, size - recv_size);
522 RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
523 if (recv_size == size || rx_timeout_left == RT_WAITING_NO)
524 {
525 break;
526 }
527
528 rt_completion_wait(&rx_fifo->rx_cpt, rx_timeout_left);
529 if (rx_timeout_left != RT_WAITING_FOREVER)
530 {
531 delta_tick = rt_tick_get_delta(begin_tick);

Callers 1

rt_serial_readFunction · 0.85

Calls 7

rt_tick_getFunction · 0.85
rt_ringbuffer_data_lenFunction · 0.85
rt_completion_waitFunction · 0.85
rt_ringbuffer_getFunction · 0.85
rt_tick_get_deltaFunction · 0.85
rt_spin_lock_irqsaveFunction · 0.50

Tested by

no test coverage detected