嵌入式編程需注意的Cache機制及其原理
為了證實以上說法,循環(huán)執(zhí)行如下測試程序:
如果沒有Cache的影響,結(jié)果應(yīng)該是55 aa aa。可見,Cache關(guān)閉再打開的確可造成Cache數(shù)據(jù)過時。
3 其他CPU解決方案
Atmel公司的AT91RM9200和Samsung公司的S3C44B0,用這兩種CPU先后移植過操作系統(tǒng),且在對外設(shè)訪問的整個過程中Cache都是使能的。它們的解決方案是什么呢?
AT91RM9200是ARM9系列帶有MMU的CPU。MMU對內(nèi)存有分頁管理功能,可以實現(xiàn)多個進程的內(nèi)存空間保護。Cache是通過MMU管理的,這也是Cache和MMU經(jīng)常同時存在的原因。
S3C44B0和S3C4510B同樣都是Samsung公司產(chǎn)品,并且都不帶MMU。與S3CA510不同的是,S3C4480自帶的SFR可以配置非緩存范圍,即使Cache使能,所設(shè)置范圍的地址空間訪問也不通過Cache實現(xiàn)。這樣,可以很方便地實現(xiàn)內(nèi)存是緩存區(qū),其他外設(shè)是非緩存區(qū)。
這兩種方案對于S3C4510B都無法實現(xiàn)。網(wǎng)絡(luò)上有人用volatile關(guān)鍵字解決外設(shè)訪問問題。volatile關(guān)鍵字是在源代碼中給編譯器看的,它可能影響編譯器的編譯結(jié)果,但是最終CPU執(zhí)行都體現(xiàn)到匯編語句,如果匯編語句都不能解決Cache問題,volatile語句也是不可能解決的。
對于易變數(shù)據(jù)的外設(shè)使用volatile關(guān)鍵字是應(yīng)該的,可避免編譯器的優(yōu)化,比如以下語句:
在兩次讀取portAdd地址的數(shù)據(jù)相同時等待,可以用到等待信號跳變的程序。如果將volatile關(guān)鍵字去除,有可能經(jīng)編譯器優(yōu)化,Value2不會從實際的portAdd地址讀取數(shù)據(jù),而是利用Valuel讀取語句的中間寄存器直接獲得。
4 本文解決方案
由S3C4510B手冊上第5節(jié)的第4頁可知,可以通過兩種方式保證Cache數(shù)據(jù)的正確:
?、賹ache映射表的Tag RAM數(shù)據(jù)清零。Cache映射表數(shù)據(jù)一般是通過上電復(fù)位清零的,如果Cache或內(nèi)存段的設(shè)置被修改,則會造成Cache映射表數(shù)據(jù)廢棄,這時就需要通過程序?qū)ache映射表數(shù)據(jù)清0。
?、赟3C4510B提供非Cache方式訪問控制位,控制位ADDR[26](地址線26位)為“1”時,按非Cache方式訪問。因此,Cache使能的情況下,地址0x000 0000~0x3FFFFFF按Cache方式訪問,而0x400 0000~0x7FF FFFF按非Cache方式訪問。實際上,0x000 0000+offset與0x400 0000+offset(offset在0x000 0000~0X3FF FFFF之間)是同一地址,不同的是Cache是否起作用。
可以得到兩種解決方案:
(1)Cache映射表手動更新 既然在開關(guān)Cache之后內(nèi)容過時,并且CPU不會自動刷新,可以通過手動更新的辦法來拋棄廢舊信息。也就是說,將Tag RAM區(qū)(前面所說的Cache映射表)清除,這樣所有Cache數(shù)據(jù)區(qū)的內(nèi)容都不使能,再次讀取數(shù)據(jù)時同時更新Cache映射表和Cache數(shù)據(jù)區(qū)內(nèi)容,之后才能使用。清除操作將Tag RAM的1 KB內(nèi)容清零,需要消耗一定時間;并且這樣操作后Cache是0命中率的,只有一定訪問次數(shù)后Cache信息重新填滿,才能恢復(fù)正常的命中率。因此,頻繁地開關(guān)Cache時采用這種方案是不可取的。
(2)bit26位控制Cache使能
S3C4510B的地址線為26位(bit0~bit25),實際上CPU可訪問空間為32位(bit0~bit31)。一般我們都不使用bit26~bit31,不過S3C4510B的這些位有著特殊的控制功能。通過bit26的高電平可以禁止該地址的Cache功能,因此將外設(shè)的地址由原來的ADDR_PORT改為(ADDR PORT∣(126)),就可以實現(xiàn)外設(shè)訪問時Cache不使能。這樣就不用改為SYSCFG的Cache使能控制位。比較來看,SYSCFG的Cache使能位是控制整個CPU訪問的Cache使能與否,而bit26只控制當(dāng)前訪問的一個具體地址的Cache使能與否。采用這種解決方案理論上有依據(jù),并且可以最大程度發(fā)揮CPU的功能。
5 修改程序后的試驗結(jié)果
修改Cache解決方案后,可以解決內(nèi)存訪問錯誤的問題。經(jīng)過測試,采用“bit26位控制Cache使能”的方案可以順利訪問外設(shè),代碼執(zhí)行始終是在Cache使能的情況下,并且不影響內(nèi)存數(shù)據(jù)。若完全關(guān)閉Cache的程序,執(zhí)行同樣代碼需要花費5~8倍的時間。
評論