Skip to content

Commit

Permalink
[components][serial_v2] 优化txflush逻辑、对tx的activated做中断保护
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan-CW-Code committed Sep 4, 2024
1 parent 915ce05 commit 37140fe
Showing 1 changed file with 28 additions and 27 deletions.
55 changes: 28 additions & 27 deletions components/drivers/serial/serial_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ static int serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req)
mask |= POLLIN;
rt_hw_interrupt_enable(level);
}
// mask|=POLLOUT;
/* mask|=POLLOUT; */
return mask;
}

Expand Down Expand Up @@ -500,6 +500,7 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
{
struct rt_serial_device *serial;
struct rt_serial_tx_fifo *tx_fifo;
rt_base_t level;
rt_ssize_t send_size;
rt_err_t ret;

Expand All @@ -518,12 +519,16 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,

/* When serial transmit in tx_blocking mode,
* if the activated mode is RT_TRUE, it will return directly */
level = rt_hw_interrupt_disable();
if (tx_fifo->activated == RT_TRUE)
{
rt_hw_interrupt_enable(level);
return 0;
}

tx_fifo->activated = RT_TRUE;
rt_hw_interrupt_enable(level);


/* clear tx_cpt flag */
rt_completion_wait(&tx_fifo->tx_cpt, 0);
Expand All @@ -542,7 +547,10 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
}

/* Inactive tx mode flag */
level = rt_hw_interrupt_disable();
tx_fifo->activated = RT_FALSE;
rt_hw_interrupt_enable(level);

return send_size;
}

Expand Down Expand Up @@ -579,8 +587,15 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
}
/* When serial transmit in tx_blocking mode,
* if the activated mode is RT_TRUE, it will return directly */
if (tx_fifo->activated == RT_TRUE) return 0;
level = rt_hw_interrupt_disable();
if (tx_fifo->activated == RT_TRUE)
{
rt_hw_interrupt_enable(level);
return 0;
}
tx_fifo->activated = RT_TRUE;
rt_hw_interrupt_enable(level);


rt_int32_t tx_timeout = tx_fifo->tx_timeout;
rt_tick_t now_tick = 0;
Expand Down Expand Up @@ -625,8 +640,11 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
}
}
}

/* Finally Inactivate the tx->fifo */
level = rt_hw_interrupt_disable();
tx_fifo->activated = RT_FALSE;
rt_hw_interrupt_enable(level);

return send_size;
}
Expand Down Expand Up @@ -809,6 +827,7 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
dev->write = _serial_fifo_tx_nonblocking;
#endif

rt_completion_init(&tx_fifo->tx_cpt);
dev->open_flag |= RT_SERIAL_TX_NON_BLOCKING;

/* Call the control() API to configure the serial device by RT_SERIAL_TX_NON_BLOCKING*/
Expand Down Expand Up @@ -1296,26 +1315,15 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
{
struct rt_serial_tx_fifo* tx_fifo;
rt_base_t level;

tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx;
if(serial->parent.open_flag & RT_SERIAL_TX_BLOCKING)
level = rt_hw_interrupt_disable();
if(tx_fifo->activated != RT_FALSE)
{
level = rt_hw_interrupt_disable();
if(tx_fifo->activated != RT_FALSE)
{
rt_hw_interrupt_enable(level);
rt_completion_wait(&tx_fifo->tx_cpt, RT_WAITING_FOREVER);
break;
}
rt_hw_interrupt_enable(level);
rt_completion_wait(&tx_fifo->tx_cpt, RT_WAITING_FOREVER);
break;
}
else
{
while(tx_fifo->activated == RT_TRUE)
{
// rt_thread_mdelay(1);
}
}
rt_hw_interrupt_enable(level);
}
break;

Expand Down Expand Up @@ -1746,11 +1754,7 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
* then the transmit completion callback is triggered*/
if (tx_length == 0)
{
/* Maybe some datas left in the buffer still need to be sent in block mode */
if (serial->parent.open_flag & RT_SERIAL_TX_BLOCKING)
{
rt_completion_done(&tx_fifo->tx_cpt);
}
rt_completion_done(&tx_fifo->tx_cpt);

/* Trigger the transmit completion callback */
if (serial->parent.tx_complete != RT_NULL)
Expand Down Expand Up @@ -1790,10 +1794,7 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)

if (tx_length == 0)
{
if (serial->parent.open_flag & RT_SERIAL_TX_BLOCKING)
{
rt_completion_done(&tx_fifo->tx_cpt);
}
rt_completion_done(&tx_fifo->tx_cpt);

/* Trigger the transmit completion callback */
if (serial->parent.tx_complete != RT_NULL)
Expand Down

0 comments on commit 37140fe

Please sign in to comment.