STM32,MDK升級(jí)5.0后,編譯出現(xiàn)問題,本人用的是win8.1,開始因?yàn)橐恢毙枰?lián)機(jī)而不得不停止工作,后來用管理員身份運(yùn)行MDK,問題的到解決,但后續(xù)編譯又出現(xiàn)如下問題error:L6002U: Could not open file ..outputcore_cm3.o: No such file ordirectory", 沒有產(chǎn)生core_cm3.o。一時(shí)間在網(wǎng)上也沒有找到好的解決方案,后來就索性把core_cm3.c從工程中移除,編譯通過了,但是不知道會(huì)不會(huì)出現(xiàn)其他未知問題。最后發(fā)現(xiàn)是CMSIS1.x和CMSIS2.x不兼容的問題,解決方案是從ARM官網(wǎng)下載最新的CMSIS文件,取而代之。 STM32從3.0庫開始引入了CMSIS,CMSIS是Cortex微控制器軟件接口標(biāo)準(zhǔn)(Cortex MicroControllerSoftware InterfaceStandard)的縮寫,這個(gè)是ARM定制的一個(gè)用于Cortex-M系列的一個(gè)標(biāo)準(zhǔn),主要是為了提供通用api接口來訪問內(nèi)核和一些片上外設(shè),提高代碼的可移植性。 CMSIS有三個(gè)層:核內(nèi)外設(shè)訪問層Core Peripheral AccessLayer(CPAL),中間件訪問層Middleware Access Layer(MWAL),設(shè)備訪問層(DevicePeripheral Access Layer)。 CPAL用于訪問內(nèi)核的寄存器和組件,如NVIC,調(diào)試系統(tǒng)等。該層是由ARM實(shí)現(xiàn)的。 MWAL用于對(duì)中間件的訪問,現(xiàn)在該層還未實(shí)現(xiàn)。(也不知道所謂的中間件是什么東西)。 DPAL用于定義一些硬件寄存器的地址和一些外設(shè)訪問函數(shù),由芯片制造商實(shí)現(xiàn)。 CPAL層的實(shí)現(xiàn)就是Core_cm3.c文件,DPAL層的實(shí)現(xiàn)就是system_stm32f10x.c文件(似乎還應(yīng)該加上外設(shè)的函數(shù)庫)。 接下來就來了解一下Core_cm3.c里面有什么東東: 首先是匯編關(guān)鍵字__ASM和__INLINE的宏定義,支持不同的編譯器。由于使用的是Keil,所以就只看第一種,__CC_ARM。 這里面的函數(shù)調(diào)用都只符合ARM過程調(diào)用標(biāo)準(zhǔn)的,如R0到R3用作參數(shù)和返回值傳遞,這也是這里面唯一用到的。 此外,在Keil中使用了__asm關(guān)鍵字后,編譯器不會(huì)為函數(shù)增加返回指令,所以需要自己編寫返回命令,也就是每個(gè)函數(shù)后面的 bx lr。 1. __ASM uint32_t __get_PSP(void):獲取進(jìn)程堆棧指針PSP。 2. __ASM void __set_PSP(uint32_t topOfProcStack):設(shè)置PSP。 3. __ASM uint32_t __get_MSP(void):獲取主堆棧指針MSP。 4. __ASM void __set_MSP(uint32_t mainStackPointer):設(shè)置MSP。 5. __ASM uint32_t __REV16(uint16_tvalue):反轉(zhuǎn)半字中字節(jié)順序,如0xABCD反轉(zhuǎn)后得到0xCDAB。 6. __ASM int32_t __REVSH(int16_tvalue):反轉(zhuǎn)字節(jié)順序,并做符號(hào)拓展。就是在__REV16函數(shù)得到的結(jié)果上再進(jìn)行一次符號(hào)拓展。這兩個(gè)函數(shù)主要是方便進(jìn)行大小端的切換。 7. __ASM void__CLREX(void):清除由LDREX指令造成的互斥鎖。LDREX和STREX是Cortex用來實(shí)現(xiàn)互斥訪問,保護(hù)臨界資源的指令,LDREX執(zhí)行后,只有離它最近的一條存儲(chǔ)指令(STR,STREX)才能執(zhí)行,其他的存儲(chǔ)指令都會(huì)被駁回,而CLREX就是用于清除互斥訪問狀態(tài)的標(biāo)記。 8. __ASM uint32_t __get_BASEPRI(void):獲取BASEPRI寄存器的值,優(yōu)先級(jí)號(hào)高于該寄存器的中斷都會(huì)被屏蔽(優(yōu)先級(jí)號(hào)越大,優(yōu)先級(jí)越低),為零時(shí)不屏蔽任何中斷。 9. __ASM void __set_BASEPRI(uint32_t basePri):設(shè)置BASEPRI的值。 10. __ASM uint32_t__get_PRIMASK(void):PRIMASK是一個(gè)只有一位的寄存器,置位時(shí)屏蔽絕大部分的異常中斷,只剩下NMI和HardFault可以響應(yīng)。 11. __ASM void__set_PRIMASK(uint32_t priMask):設(shè)置PRIMASK的值。 12. __ASMuint32_t __get_FAULTMASK(void):FAULTMASK也是一個(gè)只有一位的寄存器,為1時(shí)只有NMI才能響應(yīng),其他異常與中斷全部被屏蔽。 13. __ASM void__set_FAULTMASK(uint32_t faultMask):設(shè)置FAULTMASK的值。 14. __ASM uint32_t__get_CONTROL(void):獲取CONTROL的值。寄存器CONTROL只有兩位。CONTROL[0]選擇特權(quán)級(jí)別,0為特權(quán)級(jí),1為敵用戶級(jí)。CONTROL[1]用于選擇堆棧指針,0為MSP,1為PSP。 15. __ASM void__set_CONTROL(uint32_t control):設(shè)置CONTROL寄存器的值。 BASEPRI,PRIMASK,F(xiàn)AULTMASK,CONTROL都只能在特權(quán)模式下被修改。
|