新人求教信号量创建问题

发表在 Kernel2019-11-18 10:27 [复制链接] 6 102

最近刚接触RT-Thread,在学习信号量。发现创建静态信号量的时候,程序代码死机,串口debug出如下数据。  i, j9 [) Y/ }# z$ R7 v+ Y/ s3 X
: q: V, y9 U4 P
psr: 0x21000000
" l. |4 d/ @- U- v! X2 U; [r00: 0x00000000
' G" l9 W9 Z- Z3 or01: 0x08000f18
) c, ]% n& x# X6 ^5 Sr02: 0x00000010
/ _6 x. {/ T6 b- Z0 gr03: 0x000000002 S3 ~1 H  @) E$ W
r04: 0x00000000
5 j. I8 z+ [7 X+ T# `" mr05: 0x00000001) c6 e4 L" x: U3 y4 f
r06: 0x08000f18' R& k4 R: a% |2 r. S
r07: 0x20000068
+ I# B( {9 N" m- ^" y3 N- }r08: 0xdeadbeef
+ Q$ b" t$ T! M+ _0 @% |- Cr09: 0xdeadbeef
& a# w+ Q2 P4 Y5 U/ j2 ]r10: 0xdeadbeef* G8 ?  W! W2 e& b- a. B' R
r11: 0xdeadbeef
4 y: s; T  d8 G* W: `r12: 0x00000000+ {0 G( y* N4 b8 o/ Q7 ]- ^) w
lr: 0x08001fff
# j; d6 L' K1 y- g+ P' T# l' J7 Q# g" v pc: 0x08002322/ w0 z# \* b. a( |3 S
hard fault on thread: pc
- D/ H% E3 _& a" f) B! l  a
7 ^- k) v3 A0 E! \; r0 |, [
5 Z  N. u' \* T: f! H我试了动态创建没有问题。求解?我猜想是不是堆栈设置不对?" c9 q! t0 I! u! T

) x- c1 f$ U: z) p& u, b' `程序大概如下:; ^! p/ P/ |: d& |; a) T
, P+ T8 o. L* h/ L" M- I
rt_sem_t sem2_pcrx = RT_NULL;//通知thread_pc串口接收一帧数据
  I% w# ^) K9 k( q' k& v
9 c3 R) A0 t) _; G$ V: t( S& U  A# X; d& _
/*7 y3 h8 i: q( e# M; C  x
*BriefC串口中断处理函数
. ?- Y9 O8 v3 @; L* C! g: `*/
: }- G$ b1 n# @void PC_UART_IRQHandler(void), A1 k" k$ G) ]  y/ L- I0 p
{
7 n% S% y4 m2 ?$ B rt_interrupt_enter();
( y; p) c' `8 k  V0 c2 @1 A  V5 ]) A9 T5 @5 ^
   
7 c: d8 ^. p! L& u! t    if(USART_GetITStatus(PC_UART, USART_IT_RXNE) != RESET) {
4 z$ V, J. m" L( b: u  7 ~' J; y  O3 k* h$ T) N+ N; e
  MyCirQueue_En(&Queue_PcRx,USART_ReceiveData(PC_UART));
" _$ Y, ?1 y; H3 X. i2 W        USART_ClearITPendingBit(PC_UART, USART_IT_RXNE);
# [& w  R6 h; Z7 E% A" ]& M( s  
. F% ~7 k4 \$ T7 m    }else if(USART_GetFlagStatus(PC_UART, USART_FLAG_IDLE) != RESET) {
6 c  U1 p! U5 d( y5 ]  rt_sem_release(sem2_pcrx);$ ~! e7 u$ ^6 `( q  D
        ! u2 A5 U" `: `, Z2 g* `
  PC_UART ->SR;4 B) C9 k& R3 W  Q% S8 u8 k! t: N* E
  PC_UART ->DR;
% {% @' M0 y  Y2 T. y }
9 e! F+ {1 h+ I; d" o/ K - P! {) H% N: i0 z, v3 r
rt_interrupt_leave();
# k+ r# _/ w6 @& Q6 L. q. E4 x; `% R
}
9 J- i+ Z3 o. z8 A2 o0 Z/ \3 U, |, b) y' c9 C4 ]
3 @! q; i) A6 Y7 z4 T3 H1 F+ L
/**
; ?! {( K( E+ D& x* S5 `6 n! T  * @Brief PC处理' v' T( ~8 |/ f0 [+ j
  * @Input None9 B1 d9 j" t% F, c$ o) U+ e6 `
  * @Output None
* P9 }) q. v! j# ~1 k1 T  * @Retval None3 P, M$ B  n6 G' _5 C& ]
  */+ u' a6 N. J, H+ ]2 ^; C
void Thread_Pc_Entry(void *parameter)
9 h& _& U2 x; h% Q{
+ V" v* [" d0 ~/ Y( Y
3 |1 a' W+ _6 ^2 C, h    rt_err_t result = RT_NULL;% G8 r# K5 L4 v: T( y' U
    result = rt_sem_init(sem2_pcrx,(const char*)"sem2pcrx",1,RT_IPC_FLAG_FIFO);
3 e- b* R2 o( X- D' k; I if(result != RT_EOK){
& m- B! @) e: P  v+ e  rt_kprintf("\r\nsem2pcrx init error!\r\n");
7 T' w: t+ |5 C5 f$ _. J5 J6 C }- o. Y9 e5 V5 f

9 x9 c/ a3 p1 @# {2 r; j5 F* D    while(1)8 ~; m3 ?* G( Z, }, ^: U- ^
    {
% |6 ~, `* K; Q+ a4 P2 i* ^        result = rt_sem_take(sem2_pcrx,RT_WAITING_FOREVER);9 R  ^& @7 U$ [; `9 B
        if(result == RT_EOK) {
4 |3 q9 R0 [  g% ^( z) Y; d3 K& Q: Y' A ' I  H( U  p6 }7 ^
        }" H8 ~( W7 t: I3 B6 c: _
    }/ f+ `5 c6 B$ |/ A  r& D
}
' \- N) c8 `$ V1 A6 Z2 ^* w+ J, o& d5 M# [1 s5 K' X8 W" u

* e# h7 S& a6 H' N# B
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
发表于 2019-11-18 13:37:48 | 显示全部楼层
本帖最后由 flyboy 于 2019-11-18 13:39 编辑 7 H0 i- O! o% K) f- y

" [5 n* I4 a% M+ q+ d6 @; X代码没看出来问题,官网的信号量的示例程序能跑起来吗?6 x5 t& q* \. W, H
https://www.rt-thread.org/document/site/programming-manual/ipc1/ipc1/#_11
6 j5 D6 V* Z7 U2 o
使用道具 举报 回复
发表于 2019-11-18 16:51:58 | 显示全部楼层
本帖最后由 iamyhw 于 2019-11-18 16:58 编辑 - N$ \  ^3 ?, ^9 K: x$ Q
; o' Z0 p6 l( \4 K% a2 y
中断中释放信号量,信号量的获取与是否需要成对出现,也有顺序讲究,您的代码看不出哪个先到来,中断先来的概率高& a/ q+ s$ I1 l" Z% L/ r; k3 B
使用道具 举报 回复
发表于 2019-11-18 16:53:47 | 显示全部楼层
你应该用  create7 J, i( x! v9 }- {: y
或改为静态的,用init
使用道具 举报 回复
发表于 2019-11-18 17:01:02 | 显示全部楼层
最大的可能是release了为init的信号量,在Thread_Pc_Entry之前中断了
使用道具 举报 回复
发表于 2019-11-18 17:52:08 | 显示全部楼层
使用 rt_sem_init 初始化信号量时,你传入的变量为:sem2_pcrx。这个变量你定义为:rt_sem_t sem2_pcrx = RT_NULL;  p( x: r! `. T

) Z/ h4 s' P: [你不能进将一个指针传入到 init 中。你需要传递一片有效内存的地址到 init 中。. M5 j2 `( e- n$ z
0 K5 x" a( K. d
所以你需要:
) z" a7 }- |) Q$ Bstruct rt_semaphore sem2_pcrx。
. V3 z& P8 c  E1 j- y/ }rt_sem_init(&sem2_pcrx,(const char*)"sem2pcrx",1,RT_IPC_FLAG_FIFO);: S  L4 ^1 Y4 [
( N0 k$ i% V3 R( g
使用道具 举报 回复
发表于 2019-11-28 11:21:42 | 显示全部楼层
还没想好 发表于 2019-11-18 17:52; }# w; i  ^# V9 y
使用 rt_sem_init 初始化信号量时,你传入的变量为:sem2_pcrx。这个变量你定义为:rt_sem_t sem2_pcrx = R ...
2 ~( ]3 b' Y* ?$ s/ t3 Y8 \
感谢,你说的是对的。
使用道具 举报 回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

Powered by RT-Thread

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