使用串口通讯遇到Function[rt_sem_take] shall not be used in ISR

发表在 Kernel2019-12-6 11:28 [复制链接] 4 97

本帖最后由 JonasWen 于 2019-12-6 11:32 编辑 9 N$ K- p  x5 W  F$ \

7 ]  E; U1 P- n7 R! J8 F( n定位到rt_debug.h(100)——rt_interrupt_get_nest() = 0xFE
5 G  {' M$ d4 brt_interrupt_nest是在函数rt_interrupt_leave()中由0减到0xFE的
) p$ Y1 p7 s, v$ g5 n所有的rt_interrupt_leave()和rt_interrupt_enter()都是成对使用的
1 U  E+ y* {+ y, {  ?6 G
  1. static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size)
    # d# }, {: F9 k+ ]! J' y+ i" p
  2. {! l; ^# e0 I: m( E( \6 L8 p6 l* E
  3.     /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */& A" k2 d1 P0 C4 m
  4.     rt_sem_release(&rx_sem);
    * p+ U3 X1 l0 g. N% ]7 K
  5. 3 y4 L$ g5 P" [# V
  6.     return RT_EOK;  J4 o( t3 K$ j5 u4 K$ b
  7. }
    + C$ t6 f+ \" |8 {2 E8 n9 f
复制代码
  1. static uint8_t uart_get_char(void)
    4 N+ ]3 n* h0 g- W: W0 E
  2. {
      r0 n1 e6 s" a' q
  3.     uint8_t ch;
    6 d9 h# N: Q) [
  4. ' f& S; @4 G) [
  5.     while (rt_device_read(dwin_serial, -1, &ch, 1) != 1)* K& U8 M0 L) F8 a7 v( u: `
  6.     {' p2 }' N; Y" T9 V9 z( H! E' r
  7.         rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
    - Y  {, H& J9 _8 o; i6 h
  8.    }
    * g7 S+ l2 A" q
  9. }
复制代码
  1. void dwin_serial_thread_entry(void *parameter)" Y/ Y' ~/ y; E, E. _
  2. {. s7 t! @+ c* z) |1 S
  3.    uint8_t ch;" g7 R- z4 t  e" |
  4.    char data[ONE_DATA_MAXLEN];
    8 _% V, w4 v5 E4 ?: c
  5.    while(1)
    3 [2 q& B8 {2 e# e/ h$ u6 a# q
  6.    {
    / k' n  ~6 f3 `$ G
  7.        ch = uart_get_char();
    - \2 G4 \9 D/ p8 V) C: R
  8.     }& G% O4 e0 g; Z- O6 q' B
  9. }
复制代码
) g, U  I" {: D& x2 m  `0 i4 o
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
发表于 2019-12-6 11:52:23 | 显示全部楼层
Function[rt_sem_take] shall not be used in ISR
3 R7 y5 ?3 x4 \8 C4 j* @
8 B8 h% j4 Z8 F4 U( g6 ^- h4 C是你在中断中使用 获取信号量的操作造成的
使用道具 举报 回复
发表于 2019-12-6 12:03:37 | 显示全部楼层
本帖最后由 JonasWen 于 2019-12-6 12:05 编辑
% Z* O$ ^2 E# K7 D: s& q) |! l
yangjie 发表于 2019-12-6 11:52
1 N+ U' r" V, _Function[rt_sem_take] shall not be used in ISR: M+ i2 i; r& F

% {5 O# h: }$ N& L5 e) W是你在中断中使用 获取信号量的操作造成的 ...

( `, l# l; z/ Y7 B4 P' y0 D没有在中断中使用,我只在线程中做了操作,现在会停顿在断言处,但并不是一直出现,系统运行一段时间后才会发生这种现象,没有规律可循
  1. void USART3_IRQHandler(void)
    0 L  e" \$ O  d+ `
  2. {
    ! w* U* U! l1 K2 J" ]9 S
  3.     /* enter interrupt */  h# q  ?$ K8 K% t1 G- h
  4.     rt_interrupt_enter();
    & s# _3 ~1 T2 A
  5.     " y7 N( i' N' O* j& ?: O9 S
  6.     extern volatile rt_uint8_t rt_interrupt_nest;# L$ _, Y) P' a" ~8 x# T
  7.     if(rt_interrupt_nest == RT_NULL)
    : `! P. ~2 r/ a8 X( K: t/ ?6 S
  8.     {5 d5 `$ t4 Z) \0 G
  9.         RT_ASSERT(rt_interrupt_nest);3 i& Y1 w; P* j4 [( \
  10.     }
    - l2 Q0 ?% R1 h) m. T7 b: Y+ C* L
  11.    
    / O0 C4 q5 V' v+ K, |
  12.     uart_isr(&(uart_obj[UART3_INDEX].serial));
    8 s# E) ]* n; \! l) C5 ~( \
  13.    
    * M8 _! l6 a, s$ Y5 J' H% g( T7 A
  14.     /* leave interrupt */5 |% V: P4 P& r
  15.     rt_interrupt_leave();
      C8 Y$ U' I, O6 F3 g: n
  16. }
复制代码

; E  l* r0 k% f2 }
- g5 D; p- W& T# d# Q3 [
使用道具 举报 回复
发表于 2019-12-6 13:36:08 | 显示全部楼层
JonasWen 发表于 2019-12-6 12:03
+ {+ ^2 O' |* B4 H0 {  h" z, T没有在中断中使用,我只在线程中做了操作,现在会停顿在断言处,但并不是一直出现,系统运行一段时间后才 ...

# o5 g* Z/ A# p# W2 D7 u看提示确实是这样呀,楼主可以在检查下代码
使用道具 举报 回复
发表于 2019-12-6 14:27:06 | 显示全部楼层
本帖最后由 JonasWen 于 2019-12-6 14:29 编辑 5 |; q( Q! ]/ x6 c' D+ A
yangjie 发表于 2019-12-6 13:36, ~2 w7 m  i; j
看提示确实是这样呀,楼主可以在检查下代码
& |+ g" `) L! T$ T- s$ j5 J
已经检查问题查了两天了,也没有其他什么复杂的代码,就是串口来回通讯,如果是因为中断中获取信号量导致的也就不特地发帖求助了现在从仿真和断言的结果来看是rt_interrupt_nest意外的变化导致的,但是中断对rt_interrupt_nest操作都是成对出现的,进入中断加计数,退出中断减计数
- `7 ~& t7 s0 e3 [- O  |
使用道具 举报 回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

Powered by RT-Thread

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