[問題] disable中斷的替代方案(邏輯求救)

看板C_and_CPP作者 (brotherD)時間6年前 (2017/09/05 18:24), 6年前編輯推噓0(009)
留言9則, 3人參與, 最新討論串1/1
抱歉,小弟的標題下的不好(真的不曉得該怎麼下)。最近小弟在拜讀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) ) 但我還沒想出來為什麼這行判斷式是陣列還沒滿的條件。 謝謝大家耐心看完這冗長的文章。小弟感激不盡~ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 60.248.26.157 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1504607057.A.42C.html ※ 編輯: zzss2003 (60.248.26.157), 09/05/2017 18:25:51

09/05 18:45, , 1F
可以先問一下你有沒有學過queue?
09/05 18:45, 1F

09/05 21:04, , 2F
09/05 21:04, 2F
今早起床頭腦比較清醒,還是看不懂程式碼。 這個程式有一個前提,就是要先發生中斷(iHead指到的陣列有值),資料被餵到主程式的陣 列(由iTail控管)才有意義。 可以想像成有一個一百公尺長的操場,每一公尺為間隔,總共有一百格。有一個主人跟一 隻寵物,規則是主人會在每一個間隔上放入食物,寵物只要吃到食物就算得分。 有可能主人放食物的速度(中斷的速度)比寵物跑得快(主函式進入if的速度);也有可能寵 物跑的速度比主人放食物的速度還快(只要iTail != iHead便進入if),這時候寵物就必須 繞完一圈後才能吃到牠在上一圈還沒吃到的食物。 當寵物跟主人不在同一格上(iTail != iHead),則條件成立。這時可能是主人放的速度比 寵物跑得還快(則iTemperature1與2有意義);也有可能是寵物跑得比主人放的還快(反之無 意義)。 但寵物有可能跑得比主人放的速度還快嗎?換句話說,有可能iTail會大於iHead嗎? 當中斷發生且符合if條件時,主人才有資格在前面兩格放食物(iHead += 2)。 1. 主人往前走兩格,寵物會剛好在兩格後(代表寵物跑得比主人快) 這個時候表示if條件不成立,代表queue is full。 2. 主人食物已經放到98公尺了且寵物在起點上(代表已經跑到終點了,queue is full) 所以,條件是"寵物不能在主人的後兩格"且"食物還沒放滿整個跑道 || 寵物不在起點上" ,才能進入迴圈。進入迴圈後,主人才會在下兩格放入食物,寵物吃到才會有意義。 所以結果是,寵物是可以跑得比主人快的,只是這時候寵物就沒食物吃了(陣列拿到的值無 意義) 問題1:看不懂else中的//throw away next value,這個會是需要考慮的點嗎? 問題2:如果把中斷中的if條件裡的驚嘆號移除,if條件裡會變成什麼樣子? 問題3:中斷中的if,我還是看不懂它的滿足條件,我覺得我理解的有瑕疵 問題4:我還是不懂這個程式碼為什麼可以解決上一個例題中的問題啊! ※ 編輯: zzss2003 (60.248.26.157), 09/06/2017 11:04:03 ※ 編輯: zzss2003 (60.248.26.157), 09/06/2017 11:04:55

09/06 12:19, , 3F
1中斷裡會進到else,代表中斷的太頻繁,queue放不下了,
09/06 12:19, 3F

09/06 12:19, , 4F
只好把這次拿到值捨去
09/06 12:19, 4F

09/06 12:21, , 5F
2你自己不是有寫?就笛摩根出來的東西
09/06 12:21, 5F

09/06 12:22, , 6F
3circle queued看一看
09/06 12:22, 6F

09/06 12:51, , 7F
123(代表你不懂queue)4(該書該章已經解釋很清楚,你還
09/06 12:51, 7F

09/06 12:52, , 8F
不懂就是不理解書在表達什麼,重看吧)
09/06 12:52, 8F

09/06 15:19, , 9F
看了Circle queue後會了QQ
09/06 15:19, 9F
文章代碼(AID): #1PhdjHGi (C_and_CPP)