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

发布于 2020-01-28 18:28:20
    本帖最后由 aozima 于 2020-1-29 15:31 编辑


#define DW1000_IRQ                16

rt_pin_attach_irq(DW1000_IRQ, PIN_IRQ_MODE_RISING, func_dw1000_irq, RT_NULL);
rt_pin_irq_enable(DW1000_IRQ, 1);


其中func_dw1000_irq是我的中断回调函数,这样就出现问题了,烧到板子上debug时,可以一步一步根下去,能正常进入中断函数func_dw1000_irq里,但烧板子上直接运行跑不起来,点rtthread的logo都打印不出来,说明起码没执行到rtthread_startup函数里的rt_show_version这个地方,很是费解。

同时加上上面的attach和enable函数后调试会有一个现象和以往正常调试不同:正常时不加任何断点的情况下点调试,程序首次断在main函数开头,但加上上面两句后是断在这里
LDR R0, =SystemInit 而且要多次点击run按钮才会进入main函数,其后就可以正常单步运行了。

由于代码量比较大,就不贴出来了,需要哪些代码我再贴。

查看更多

关注者
0
被浏览
258
5 个回答
pedro
pedro 2020-01-29
    本帖最后由 aozima 于 2020-1-29 09:48 编辑


干了6个小时,还是自己解决了问题,这是官网论坛怎么就没人出来帮个忙说个话呢。
本人代码水平有限没有根本解决问题,只是找到了不出问题的办法。
先是把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。如此就可以正常跑起来了。
虽然没有查到根本问题所在(1M多的反汇编看起来真的头大),但起码问题不再了,只是改了下pin,下面贴出改动后的代码
static rt_err_t  _pin_control(rt_device_t dev, int cmd, void *args)
{
struct rt_device_pin_mode *mode;
struct rt_device_pin *pin = (struct rt_device_pin *)dev;

/* check parameters */
RT_ASSERT(pin != RT_NULL);

mode = (struct rt_device_pin_mode *) args;
if (mode == RT_NULL) return -RT_ERROR;

if(cmd == PIN_IRQ_ENABLE)
{
struct rt_pin_irq_hdr* irq = (struct rt_pin_irq_hdr*)args;
pin->ops->pin_attach_irq(dev, irq->pin, irq->mode, irq->hdr, irq->args);
pin->ops->pin_irq_enable(dev, irq->pin, PIN_IRQ_ENABLE);
}
else
{
pin->ops->pin_mode(dev, (rt_base_t)mode->pin, (rt_base_t)mode->mode);
}

return 0;
}


pedro
pedro 2020-01-29
    本帖最后由 aozima 于 2020-1-29 09:48 编辑


有哪位代码功底牛逼得大神找找原因贴上来呗,我把问题重现的方法也贴出来
rtthread裁剪最简后在main里添加
struct rt_pin_irq_hdr irq_s;
irq_s.hdr = func_dw1000_irq;


其实任何地方添加这两句都会有问题,

void func_dw1000_irq(void *args)
{
printf("i'm in interrupt\n");
}


回调函数里只有一个打印,这样问题就重现了。
有请各位大神
pedro
pedro 2020-01-29
额,又进一步定位了问题,是回调函数里,习惯性的用了printf函数,正确的应该使用rt_kprintf函数打印,把printf换掉就没问题,但我功底差,想问一句为什么
aozima
aozima 2020-01-29
拒绝白嫖,拒绝键盘侠!
    本帖最后由 aozima 于 2020-1-29 10:03 编辑


所以,最终问题在哪?
能直接发个补丁吗?没看懂。

因为最开始就使用了 printf 吗?改掉就好了?

printf 只能在线程中使用,不能在中断里面使用。
rt_kprintf 可以在中断里面调用,直接打印。
所以中断里面打印请使用 rt_kprintf

前面的那堆改动其实没有实际作用吧?只是换了个位置,换了个方式。
把 printf 修改为 rt_kprintf 后,上面的修改再恢复回去也可以的吧?

pedro
pedro 2020-01-29
aozima 发表于 2020-1-29 09:49
所以,最终问题在哪?
能直接发个补丁吗?没看懂。



对的,前面对_pin_control的修改只是换个了位置,换了个实现方式,不用直接操作驱动框架层的东西,根本原因是在中断中习惯性的用了printf,把printf换成rt_kprintf就OK了。
刚知道printf只能在线程中使用,再去官网看看资料去...

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友