diff options
Diffstat (limited to 'components/drivers/serial/dev_serial.c')
| -rw-r--r-- | components/drivers/serial/dev_serial.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/components/drivers/serial/dev_serial.c b/components/drivers/serial/dev_serial.c index 19043e2ad2..3a78ca5195 100644 --- a/components/drivers/serial/dev_serial.c +++ b/components/drivers/serial/dev_serial.c @@ -27,6 +27,7 @@ * 2020-12-14 Meco Man implement function of setting window's size(TIOCSWINSZ) * 2021-08-22 Meco Man implement function of getting window's size(TIOCGWINSZ) * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable + * 2024-11-25 zhujiale add bypass mode */ #include <rthw.h> @@ -303,6 +304,23 @@ rt_inline int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data, rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx; RT_ASSERT(rx_fifo != RT_NULL); +#ifdef RT_USING_SERIAL_BYPASS + if (serial->bypass) + { + rt_bypass_work_straight(serial); + while (length) + { + rt_uint8_t ch; + if (!rt_bypass_getchar(serial, &ch)) + break; + + *data = ch & 0xff; + data++; length--; + } + + return size - length; + } +#endif /* read from software FIFO */ while (length) { @@ -1410,13 +1428,33 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event) while (1) { + rt_bool_t skip = RT_FALSE; ch = serial->ops->getc(serial); if (ch == -1) break; - /* disable interrupt */ - level = rt_spin_lock_irqsave(&(serial->spinlock)); +#ifdef RT_USING_SERIAL_BYPASS + if (serial->bypass && serial->bypass->upper_h && (serial->bypass->upper_h->head.next != &serial->bypass->upper_h->head)) + { + char buf = (char)ch; + int ret; + rt_list_t* node = serial->bypass->upper_h->head.next; + do { + struct rt_serial_bypass_func* bypass_run = rt_container_of(node, struct rt_serial_bypass_func, node); + ret = bypass_run->bypass(serial, buf, bypass_run->data); + if (!ret) + { + skip = RT_TRUE; + break; + } + node = node->next; + } while (node != &serial->bypass->upper_h->head); + } + if (skip) + continue; +#endif + level = rt_spin_lock_irqsave(&(serial->spinlock)); rx_fifo->buffer[rx_fifo->put_index] = ch; rx_fifo->put_index += 1; if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0; @@ -1435,6 +1473,11 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event) rt_spin_unlock_irqrestore(&(serial->spinlock), level); } +#ifdef RT_USING_SERIAL_BYPASS + if (serial->bypass && serial->bypass->lower_h) + rt_workqueue_dowork(serial->bypass->lower_workq, &serial->bypass->work); +#endif + /** * Invoke callback. * First try notify if any, and if notify is existed, rx_indicate() |
