[問題] 關於 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