抱歉,小弟的標題下的不好(真的不曉得該怎麼下)。最近小弟在拜讀David E.Simon的An
Embedded Software Primer一書,目前讀到第四章"中斷"。
本章前面舉幾個例題,說明當中斷發生在CPU正在把hardware register的value搬近data
memory的途中,會導致程式有bug。其中有一個方法是當在處理資料的之前,先關掉中斷,
等處理完資料後,在開啟中斷。
然後作者說這種方式的優點可以解決shared-data problem,但缺點是會增加interrupt
latency。接著作者在繼續介紹如何不用disable -> 處理資料 -> enable的方式達到解決
shared-data problem的問題。
圖1:https://imgur.com/a/PMYE1
這個例題利用了一個變數fTaskCodeUsingTempsB解決這個問題。
當中斷發生時,會先去判斷fTaskCodeUsingTempsB的值,如果TURE,則改變A矩陣的值(此
時主函式main在處理的是B矩陣的值);如果FALSE,則改變B矩陣的值(此時主函式處理A矩
陣)。藉此可以解決shared-data problem(因為沒有一種情況是當主程式在處理A矩陣的值
,中斷的副程式又改變A矩陣的值)。但這個程式有個小小的缺點是:如果中斷發生在While
迴圈的起點(此時fTaskCodeUsingTempsB為1)且硬體丟進A[0]跟A[1]的值不一樣,在中斷完
成並跳回主程式的時候,alarm並不會發作(因為此時在判斷矩陣B),必須要等到主程式跑
到fTaskCodeUsingTempB = !fTaskCodeUsingTempB;才能在下一個while判斷到矩陣A。
作者則提供了修正這個bug後的例題。
圖2:https://imgur.com/a/GjJzz
圖3:https://imgur.com/a/oFsqm
我的問題在於,我看不懂第二個例題在做什麼。
中斷副函式把一組溫度寫進iTemperatureQueue的矩陣。Because the iHead pointer and
the iTail pointer ensure that the interrupt routine will be writing to
different locations in the queue(array) than the ones(locations) from which the
task code(the code in the main) is reading, the shared-data problem is
eliminated.
這是作者的意思(英文有解讀錯誤請指正)
我曉得在中斷副函式中,一組溫度的值會先放在iTemperatureQueue[0]跟[1],接著放進
[2]跟[3](iHead = iHead + 2),且當iHead超過上限100時,下一組溫度會覆蓋[0]跟[1]的
值,以此類推。
在主函式中,一開始iTail跟iHead都為0,表示第一輪迴圈並不會進入if,接著中斷發生,
if條件成立,array[0]跟array[1]被放進去值,iHead變2,跳出中斷。
第二輪迴圈,if條件成立(0 != 2),a[0]跟a[1]的值放進iTemperature1跟iTemperature2
以此類推...但我不懂為什麼這種方式就可以解決例題1的問題。
第二個是,我看不懂在中斷副函式裡面的if成立的條件,我覺得很複雜。
我想把!拿掉,拿掉後應該是會變成這樣子:
if( (iHead+2 != iTail) && (iHead != QUEUE_SIZE-2 || iTail != 0) )
但我還沒想出來為什麼這行判斷式是陣列還沒滿的條件。
謝謝大家耐心看完這冗長的文章。小弟感激不盡~