RT-thread串口驱动框架的使用问题,无DMA不能使用IDLE中断

2019-11-26 14:26 [复制链接] 0 143

RT-thread串口驱动框架的使用问题,无DMA不能使用IDLE中断4 D" H8 g$ d! g+ |* g7 S
% M0 K, B+ y7 c4 a$ z
我先贴一下部分代码,这个是串口中断的,STM32的串口中断直接调用的函数,正常情况下我是使用接收中断去接受数据,但是存在断帧,一帧多次接收的现象! w& G4 \/ s" z6 v/ q( l

) x5 m! G9 {3 c  l
  1. rt_device_open(“serial_name”, RT_DEVICE_FLAG_INT_RX);
复制代码

* Q9 u% Q9 {& ^% g+ f
4 a' p3 g$ v$ K' A# X8 a4 e6 q# }9 G
  W& r# l. h. a% U# z打开了static void uart_isr(struct rt_serial_device *serial)函数发现
7 Q/ C) X) @2 m: b& s4 X& N它调用了
) k5 ^; @( j1 Q1 e4 Q  Ort_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);1 h# E; N- r0 Q
而在这个函数里面一直不停读数据,直到读不到数据并调用indicate回调函数完成接收,
8 ]5 W: z' ~( r+ N9 U我想说这样并不能很好的接收数据,倒不如用IDLE中断去提示完成接收数据,但是这个中断被DMA接收占用了,我所在串口并没有DMA,希望RTT能改进以下支持IDLE方式的中断接收' N; w3 `- k( ?- Z/ z
, p: j% m& j  h2 c

2 ^1 O6 u) A$ }6 \8 Q- r, m
. L4 w+ e. R& A& J, x( H
) Y' B7 n1 S% J( p" o& u5 F7 t
+ {8 k3 r9 O3 i7 r2 }
  1. static void uart_isr(struct rt_serial_device *serial)
    6 F% g8 b* L9 n
  2. {4 ]  A& C! q/ Q2 A0 S
  3.     struct stm32_uart *uart;, v" T" y& V1 E7 D5 A
  4. #ifdef RT_SERIAL_USING_DMA
    1 |) A- ]/ @0 i, L: r. N
  5.     rt_size_t recv_total_index, recv_len;7 ^4 D% G; ?5 r3 k) U6 j/ W+ s
  6.     rt_base_t level;
    ( D5 r: h6 U5 s* K* r0 Y
  7. #endif7 G7 V: N5 w$ D# C! ]2 e
  8. ) N4 Q, z2 m2 q
  9.     RT_ASSERT(serial != RT_NULL);
    ( {; e- `- I6 z7 s2 O* |
  10.     uart = rt_container_of(serial, struct stm32_uart, serial);* D$ A& O( M# ^" c

  11. / [% ~* ^# A1 k$ t  j7 X
  12.     /* UART in mode Receiver -------------------------------------------------*/
    ( {1 b; D. r. Q. K7 N
  13.     if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) &&
    # Z9 T0 G7 S# h3 a# J
  14.             (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET))9 I1 _. y  P) j* b, X7 _
  15.     {' H+ C% q! U  g3 l0 W
  16.         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);* ?# R) y  W5 Y. B& f( d
  17.     }
    , v5 G: m6 ^! ~+ R0 U: u" d3 |
  18. #ifdef RT_SERIAL_USING_DMA
    1 a# }2 y8 D0 n1 K7 H4 R9 }
  19.     else if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET)
    % Q6 J; y" @, O0 v
  20.              && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET))
    5 [0 K& H" f; `# }9 M
  21.     {( u  Q0 l: g1 V. Y
  22.         level = rt_hw_interrupt_disable();9 t! b0 [+ z, z2 j6 L; m0 L, O
  23.         recv_total_index = serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma_rx.handle));9 b/ L" N/ w# ]2 W* p6 m% _3 h0 S# p
  24.         recv_len = recv_total_index - uart->dma_rx.last_index;
      H; q9 b- A& Q0 k& P
  25.         uart->dma_rx.last_index = recv_total_index;
      C; }/ p2 ?% A0 L! K3 y
  26.         rt_hw_interrupt_enable(level);
    : B& o9 R* |/ g% c

  27. 8 N) p( O) P0 w4 S" ?4 U
  28.         if (recv_len)6 G# [$ W" O7 ^+ K9 ]
  29.         {
    & S# n: n1 d, [7 y, a1 {
  30.             rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
    * c  U6 T$ R, n) J4 V' u7 ]
  31.         }2 J" ]' u) c1 P# H1 E
  32.         __HAL_UART_CLEAR_IDLEFLAG(&uart->handle);
    3 f& _! Y4 \. b4 k
  33.     }
    5 _, Z- Y# e6 Q# n
  34.     else if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) != RESET)
    2 B" |! q. o+ a
  35.     {
    , y8 a) f6 R+ L& E' A
  36.         if ((serial->parent.open_flag & RT_DEVICE_FLAG_DMA_TX) != 0)
    $ y" ^; a5 F& \) x& Q) f
  37.         {
    8 o  v; _. z! F8 f4 J& R
  38.             HAL_UART_IRQHandler(&(uart->handle));
    # F% X: _* B! N5 u. q! l
  39.         }. _( b! G9 P2 n
  40.         else) ^: X) @+ m# P; s6 u
  41.         {3 o6 Z9 G" ~1 j' P5 p7 m
  42.             UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC);
    5 k8 Q/ G* H  o9 X# ?! A
  43.         }
    7 C# f" Y7 o, A* g1 B, d
  44.     }  V9 O! G" N8 p% d! S: h/ }
  45. #endif, t5 H# U- g0 ~9 ~( R: \
  46.     else
复制代码
3 K& r4 m* h/ o4 ?6 G7 x: D

5 R( U  u' k/ r6 o  w& r$ F' Z+ i2 ?$ C4 _

' u; V, u& p2 d* t3 f3 Z1 ?7 g
! K3 t$ q8 M* H$ A2 d

  1. , x! P" g  {0 `, L7 i- G3 M
  2. /* ISR for serial interrupt */% D4 Y' m7 Z4 _. a$ W
  3. void rt_hw_serial_isr(struct rt_serial_device *serial, int event): K% n+ }( m, W8 `* j
  4. {
    8 P2 z, j; f. k, `4 Y
  5.     switch (event & 0xff)
    4 u! Y% ~; U) C. _
  6.     {$ n$ B/ G, Z& ]' {1 w% x) n
  7.         case RT_SERIAL_EVENT_RX_IND:
    4 [) E' v6 n) y9 X% T2 ^9 w4 q% h
  8.         {3 k2 T0 \; X2 G; q: q: ?# n, k
  9.             int ch = -1;6 F( j+ f: }; m- c+ m( ?
  10.             rt_base_t level;6 F, e: a0 a: o; S+ J
  11.             struct rt_serial_rx_fifo* rx_fifo;8 K$ t, z: b1 H: R1 u; b& n7 J, R9 N" ~
  12. # U# n! L! ~- [' Y+ F
  13.             /* interrupt mode receive */
      l0 e7 P" _" w) h+ u
  14.             rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;' U4 I3 h$ O% C: V  C4 x/ N2 E0 t
  15.             RT_ASSERT(rx_fifo != RT_NULL);
    & R' K! y: D4 C  z: u8 D2 p+ s
  16. ! B2 o8 w8 L! c( S  X
  17.             while (1)
    " x0 E9 P0 S% u3 _. j# r
  18.             {
    : p# n6 E+ \+ o% i
  19.                 ch = serial->ops->getc(serial);: g5 m2 ?3 n; K( Q8 P( h
  20.                 if (ch == -1) break;( ]2 J4 v8 o! n* \
  21. & A% `$ t7 _* n) B" ~

  22. 4 G; [; m/ L( M
  23.                 /* disable interrupt */% Y" j+ O4 d$ y' G
  24.                 level = rt_hw_interrupt_disable();
    . X) d& w+ t9 W8 w5 \5 G0 h3 S. |' X
  25. : g' n. Z  o' b2 v1 a+ K  z
  26.                 rx_fifo->buffer[rx_fifo->put_index] = ch;
    ) }8 w: X* O  \- x
  27.                 rx_fifo->put_index += 1;
    : d, V- v) ~. F  i, e# t4 ^
  28.                 if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0;3 ]: D6 R. j) W0 [+ |- P6 N3 x' x% j

  29. . c" F5 J) {& j: ]$ b) K! z
  30.                 /* if the next position is read index, discard this 'read char' */# }. g& ~4 f/ _
  31.                 if (rx_fifo->put_index == rx_fifo->get_index)7 a2 [: P/ Q8 b9 O- [
  32.                 {
    8 v3 `5 }# p" |) V% F& Y
  33.                     rx_fifo->get_index += 1;  Y' a& C/ m% \' _2 P9 A
  34.                     rx_fifo->is_full = RT_TRUE;
    & ?- ~9 h$ J# E! h
  35.                     if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;4 F* a/ f) u* k& v

  36. 2 ]3 r6 \6 @: ~
  37.                     _serial_check_buffer_size();: v. ?( g0 D& o! k
  38.                 }1 q2 J4 |: o1 m* K( {9 G" f/ y

  39. - j1 A  F$ I: g" \
  40.                 /* enable interrupt */' R9 q$ R( v6 d! g- k
  41.                 rt_hw_interrupt_enable(level);6 j1 Q- N0 g9 k. S) I* \( y
  42.             }. C1 u+ w& v7 M% O: v

  43. ( T$ t  B! h7 C$ t; @
  44.             /* invoke callback */7 S- i( k7 q: ?" M. a; k7 F
  45.             if (serial->parent.rx_indicate != RT_NULL); w! Y% i4 Z9 y/ C, ?% W; `
  46.             {
    ; a9 n' ~- O8 E- v* ^
  47.                 rt_size_t rx_length;0 R* D# V: ]1 ?6 ]
  48. - T5 D( E: ~- l. B9 j4 g2 f
  49.                 /* get rx length */
    ( T- e3 z# `5 K! v) h7 E: n
  50.                 level = rt_hw_interrupt_disable();8 l7 j& H0 w  w! O6 G' _, b
  51.                 rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index):# Y+ l) D& l6 `% b( s
  52.                     (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index));
    : E1 J7 [1 L, A" J" n* c1 y
  53.                 rt_hw_interrupt_enable(level);
    9 v8 \1 k' a& U& s6 c
  54. , J) w: m8 B& G  j8 y) u
  55.                 if (rx_length)
    5 y) C! i8 _1 t! O3 j
  56.                 {5 O9 @" C  y3 @$ D; n2 S
  57.                     serial->parent.rx_indicate(&serial->parent, rx_length);
    4 P  y3 K3 G- [
  58.                 }
    + r# q( Z/ ?" J# l- ]2 s
  59.             }
    2 o2 ~9 z# S$ X) a2 b
  60.             break;5 ]. d, n/ U6 l+ C5 {
  61.         }
复制代码
  c) o: V* {0 {; y* r0 B& Q
" n$ @7 w- P6 Q; Y) f8 v

+ u+ C: }3 q  D4 p" V" e9 a0 N1 r9 [: Y+ H1 y

7 f( h& C9 ~2 p) Z  k
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|RT-Thread开发者社区 ( 沪ICP备13014002号-1

有害信息举报电话:021-31165890 手机:18930558079

© 2006-2019 上海睿赛德电子科技有限公司

Powered by RT-Thread

快速回复 返回顶部 返回列表