[已解决]pin驱动设置回调函数出现问题

2020-1-28 18:28 [复制链接] 5 90

本帖最后由 aozima 于 2020-1-29 15:31 编辑 - R( u& [) t6 T8 A& x. v$ I
  1. #define DW1000_IRQ                16/ n7 u  B' s: t. P

  2. ( G3 G- g/ C/ u3 b6 ]
  3. rt_pin_attach_irq(DW1000_IRQ, PIN_IRQ_MODE_RISING, func_dw1000_irq, RT_NULL);8 x  {. ^3 r! q  l( J9 O
  4. rt_pin_irq_enable(DW1000_IRQ, 1);
复制代码

& _# r5 U. u1 k0 e5 h$ b" U
0 I/ J' a9 e1 ^. [, g其中func_dw1000_irq是我的中断回调函数,这样就出现问题了,烧到板子上debug时,可以一步一步根下去,能正常进入中断函数func_dw1000_irq里,但烧板子上直接运行跑不起来,点rtthread的logo都打印不出来,说明起码没执行到rtthread_startup函数里的rt_show_version这个地方,很是费解。1 P& A8 |0 [' r0 e
5 a  a$ W6 x2 F) p4 `% V
同时加上上面的attach和enable函数后调试会有一个现象和以往正常调试不同:正常时不加任何断点的情况下点调试,程序首次断在main函数开头,但加上上面两句后是断在这里
2 d5 Y. {3 Y+ F. lLDR     R0, =SystemInit         而且要多次点击run按钮才会进入main函数,其后就可以正常单步运行了。
- t% e# C( U2 @5 a" |- f) H. E
0 F! L( J8 Y* w& u( Z4 v& C; i8 b由于代码量比较大,就不贴出来了,需要哪些代码我再贴。5 \6 u7 i) h( Q; Z

) T! F. g# w& x. p
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
发表于 2020-1-29 00:15:12 | 显示全部楼层
本帖最后由 aozima 于 2020-1-29 09:48 编辑
6 h5 e7 M% ^* {, k1 e) o+ `% @, p  V+ R5 Q
干了6个小时,还是自己解决了问题,这是官网论坛怎么就没人出来帮个忙说个话呢。$ e  o9 q: n* o, b5 o
本人代码水平有限没有根本解决问题,只是找到了不出问题的办法。! K% ~- p. K" r: X$ X, d
先是把rtthread裁剪到最简态,然后在main里使用attach IRQ函数,还是出现上述问题,基于rtthread本身的稳定性我猜测是驱动调用出来问题,虽然官网上和网上一些帖子都是这么使用的,于是我打算用rt_device_control系统调用来实现,cmd参数用来指示是添加中断功能的,args指向构建好的struct rt_pin_irq_hdr结构,到pin里再解开该结构,调用下层的gpio接口即rt_pin_attach_irq和rt_pin_irq_enable。如此就可以正常跑起来了。7 m* ^0 o1 i( V0 `% r
虽然没有查到根本问题所在(1M多的反汇编看起来真的头大),但起码问题不再了,只是改了下pin,下面贴出改动后的代码
2 c9 `# [: o0 i% D/ c4 t
  1. static rt_err_t  _pin_control(rt_device_t dev, int cmd, void *args)
    : o1 d% p4 Y, P! [( W
  2. {" C) S$ Q9 T' E# n  C. B
  3.     struct rt_device_pin_mode *mode;# {4 j$ c- D) m
  4.     struct rt_device_pin *pin = (struct rt_device_pin *)dev;) u. T5 |/ \0 x
  5. , ^: C0 c( ?& }6 G, c; Z9 ~% y
  6.     /* check parameters */1 j. Y0 l) h) J- q
  7.     RT_ASSERT(pin != RT_NULL);
    7 y2 K2 P9 p: N: p# v
  8. - |. T  b8 ?5 K  S# e) @5 Z
  9.     mode = (struct rt_device_pin_mode *) args;
    8 l& ?0 m" k% i. ]
  10.     if (mode == RT_NULL) return -RT_ERROR;0 u2 R9 @5 W+ V* Z  k, u/ g
  11. 2 }2 S6 i8 S- d) G9 M3 x
  12.                 if(cmd == PIN_IRQ_ENABLE)( p- O' x" A2 I* p5 ]9 \% A
  13.                 {
    % j( O' A" Y" j3 @( ?
  14.                         struct rt_pin_irq_hdr* irq = (struct rt_pin_irq_hdr*)args;
    ( Y& {* {1 u" t) z, y3 z
  15.                         pin->ops->pin_attach_irq(dev, irq->pin, irq->mode, irq->hdr, irq->args);9 m: v1 \/ n8 P& r' g
  16.                         pin->ops->pin_irq_enable(dev, irq->pin, PIN_IRQ_ENABLE);, v- u5 ^5 P. C7 U# d* U
  17.                 }( x$ B# M$ s+ c3 N; x
  18.                 else- \* V3 l. ?+ K: `: l+ }! u
  19.                 {
    / z. L) m# w- Z* R
  20.                         pin->ops->pin_mode(dev, (rt_base_t)mode->pin, (rt_base_t)mode->mode);
    $ _, V# x1 ]. Y+ h$ E! h* x
  21.                 }1 b* B; `% m  t' D  |+ ~

  22. 1 k  W/ `3 t9 b+ s3 O: M
  23.     return 0;' d! H; Y: v; l0 F9 }' n6 B% ]
  24. }
复制代码

7 r, o& h4 ~- v, b: [$ e7 m5 H! Q. V" C& k1 g1 o% M
使用道具 举报 回复
发表于 2020-1-29 00:29:49 | 显示全部楼层
本帖最后由 aozima 于 2020-1-29 09:48 编辑
  _$ |, w3 Y) H( L
# `  s: s$ k" r0 v- o6 q% \6 `& A0 B有哪位代码功底牛逼得大神找找原因贴上来呗,我把问题重现的方法也贴出来
6 m$ f5 n, T/ \) c( Urtthread裁剪最简后在main里添加
) o! D' u& A7 ?+ F1 v
  1. struct rt_pin_irq_hdr irq_s;! g# q& H" [. y
  2. irq_s.hdr = func_dw1000_irq;
复制代码

  Y/ x+ C5 \9 ~1 z# x6 s& o. B, ?2 {0 m, I$ S0 Z5 _% f6 _4 J
其实任何地方添加这两句都会有问题,0 u- C- A) \1 v; M+ T+ `; U
) W& s: K# l  b- Q
  1. void func_dw1000_irq(void *args)
    $ W9 B; _) s5 g" U# g" A6 g9 u) X
  2. {( |+ r; q) \$ |7 h
  3.         printf("i'm in interrupt\n");
      T8 p7 u7 {+ Z
  4. }
复制代码
( ]" X, @+ q0 G2 C) V
' P2 ^1 `1 B) u6 Q" e5 f4 x
回调函数里只有一个打印,这样问题就重现了。
; g& a! F3 E4 @4 Y有请各位大神
使用道具 举报 回复
发表于 2020-1-29 00:32:13 | 显示全部楼层
额,又进一步定位了问题,是回调函数里,习惯性的用了printf函数,正确的应该使用rt_kprintf函数打印,把printf换掉就没问题,但我功底差,想问一句为什么
使用道具 举报 回复
发表于 2020-1-29 09:49:27 | 显示全部楼层
本帖最后由 aozima 于 2020-1-29 10:03 编辑 9 Q* F6 \8 q! U

9 F3 r6 a& R: v+ _% @所以,最终问题在哪?; [& M; e! u& z  M9 k
能直接发个补丁吗?没看懂。& Z1 R$ D  N/ g/ M# I$ C; ~* V
" K6 R; p" @' V* E# K. f1 G
因为最开始就使用了 printf 吗?改掉就好了?8 t+ \+ L+ I" q4 L; _
. d8 ]$ Q$ U/ J3 c: i7 D0 j
printf 只能在线程中使用,不能在中断里面使用。1 g' O1 t( o" K# i$ _
rt_kprintf 可以在中断里面调用,直接打印。0 C, X; M! B+ U0 Q; R
所以中断里面打印请使用 rt_kprintf( A, `' \/ y  n

# O9 ^( c; |( ?9 E3 B前面的那堆改动其实没有实际作用吧?只是换了个位置,换了个方式。% [0 M8 S& e0 Z7 m( B( y1 Y6 r! T
把 printf 修改为 rt_kprintf 后,上面的修改再恢复回去也可以的吧?! u& J( r+ I( S

2 [+ N7 [! H4 H+ F+ `
使用道具 举报 回复
发表于 2020-1-29 15:25:11 | 显示全部楼层
aozima 发表于 2020-1-29 09:49
: e; H# f: k8 D1 r( [所以,最终问题在哪?8 T# X; a; B$ N3 W( ?& j
能直接发个补丁吗?没看懂。
0 H+ o1 S" u* l1 n. q5 n
对的,前面对_pin_control的修改只是换个了位置,换了个实现方式,不用直接操作驱动框架层的东西,根本原因是在中断中习惯性的用了printf,把printf换成rt_kprintf就OK了。; b" n# I' I- b/ m
刚知道printf只能在线程中使用,再去官网看看资料去...
使用道具 举报 回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

Powered by RT-Thread

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