[问题] 关于 kernel driver interrupt ISR

楼主: gn00618777 (非常念旧)   2017-03-08 17:50:55
先进们好,现在状况是这样的。目前 MCU 端要传 data 给我 AP 开发板端,透过一根
gpio,注册为irq,我这边写了个 driver,当中用到的 API 为 request_threaded_irq。
这个 api 的第二个参数 handler(上半部)为 null,第三个参数为一个 function thread
这个 thread(下半部),会透过 spi_sync 来跟 MCU 要资料,至于什么时候 MCU
会透过 irq 来通知我的 driver? 也就是每 1ms(每秒1000笔) 来通知我,我
每次透过 spi_sync要到的 64 byte 资料,都还会做个 check crc 的错误判断,只要
有错,这64 byte 就作废。录了 7200 秒,crc error 98 笔,大概1%,想要降至0.x%
看了波型,发现错误的时机点几乎都是,MCU发了irq,而我的 driver 却没有马上
进入 thread 发 spi command 来要资料,都是延迟了才要,也就是延迟进入 thread。
我估狗了中断机制,和API查询,发现用 request_threaded_irq 创造的 thread,
会类似于 workqueue 这下半部机制,而且属于 process 上下文。既然属于process
它就会被 kernel 来排班,什么时候执行,是看 kernel 而定。
request_thread_irq 里面有个 irqflags 参数,我给他设定为 IRQF_ONE_SHOT,这个
参数代表表的是 当我这个 thread 执行完毕,才会再把 irq 打开,所以我猜想,
也许就是 kernel 还在处理 thread 的 task,irq 还没被打开,所以 MCU 就算发 irq
我可能会导致延迟去处理,或者甚至不理IRQ(有看过波型也有发生过)。请问有什么可
行的方向来解决我想要即刻去处理中断的问题?
1 我有想过把 thread 要做的内容写在第二个参数的上半部 funcion,既然是上半部
的中断的函式,driver 一定能立即去做处理。可是这又有一个问题,我在网络上
搜寻到,在中断的 context 下,规定他不能睡眠,也不能阻塞,我 spi_sync 似乎
是个阻塞的 function,我除了作 spi_sync 也有做 input_sync 的 function,这看
起来也是个阻塞同步 function。中断函式一定不能加上阻塞的吗? 即使它运作时间
非常短?
2 softirq (下半部机制方法)???
希望能有些资讯能从前辈们获得,万分感激。
作者: wens (文思)   2017-03-09 10:49:00
不能等 buffer 满了才送 interrupt 啊, 大概 1/2 ~ 3/4 满就该送了。interrupt handler没有保证马上执行的
楼主: gn00618777 (非常念旧)   2017-03-09 12:57:00
好感动,感谢w大回应。您说 buffer 满是说谁的 bufferinterrupt handler 没有保证马上执行,那如果我是在上半部,也就是request_thread_irq的第二个参数设一个ISR(硬中断),会不会这个handler 就会保证马上执行?因为查询结果,request_thread_irq的第三个参数,是在process context的,所以不保证迅速执行,而是被kerne排班,而 request_thread_irq的irqflags我有设IRQF_ONE_SHOT,这个代表 thread process要执行完才能再打开 interrupt,所以我的 driver 会不理 mcu 发的interrupt 甚至会延迟进入 thread handler
作者: askacis (ASKA)   2017-03-10 12:53:00
要是我会请MCU那边改写法,miss interrupt就掉资料,别人一天到晚在等MCU就饱了
楼主: gn00618777 (非常念旧)   2017-03-11 11:26:00
好,我再花点时间去了解MCU有没有更好的解决方案AP这端我还有两到三种方法可以尝试,之后再来这边报告谢谢。
作者: wens (文思)   2017-03-13 00:09:00
没设ONE_SHOT会更崩溃,而且SPI bus一次也只能一个存取啊我说的buffer指的是MCU上的buffer。举一些I/O装置为例,通常会内建个FIFO,可以存一点资料,然后可以设定要满到什么程度的时候发 interrupt或DRQ (DMA的状况)AP这端我觉得你没太多可以做的,因为你就是没办法在top half做IO去读资料出来,而且即便是top half也没保证马上轮到你,其他的ISR 也会挡你啊
作者: askacis (ASKA)   2017-03-13 09:19:00
另外一个暴力的方式是不要用kernel的SPI API,自己填register去控制SPI拿资料,
楼主: gn00618777 (非常念旧)   2017-03-14 19:17:00
为什么要用填 register的方式? 目前测时间 spi cs 拉下来到被拉上来,整个spi写入读取只花 0.1ms请问w大,您说我没办法在 top half 读资料,是因为API是阻塞的function吗? 然后a大才说用填暂存器方式?另外为何说没设 ONE_SHOT会更崩溃..?? 我就是不打算在 thread 做,所以 ONE_SHOT 没有应该不会影响吧??抱歉..因为板子还未到,我只能一直先这样询问了解恳请各位赐教 谢谢
作者: wens (文思)   2017-03-17 16:50:00
如果没有要在 thread 里面做,那似乎无所谓?然后top half不能读资料确实是 API 限制没错 (SPI可能sleep)

Links booklink

Contact Us: admin [ a t ] ucptt.com