2017-03-14 45 views
0

我試圖訪問Cortex-M3的SysTick計時器,所以我必須切換到特權模式。我這樣做在cortex-m3切換到特權模式

/* Active previlige mode */ 
asm ("mov r0, #0x0"); 
asm ("msr control, r0"); 
asm ("ISB"); 

但它不工作,因爲我無法寫入SYST_CSR寄存器。如果是,則需要執行此操作的任何異常條目,如何?

+0

你不需要切換模式對於初學者來說,訪問定時器,系統定時器代碼示例和其他的東西,模式只是給你,我覺得兩個堆棧指針或兩者的某種一組寄存器,與全尺寸手臂中不同模式的體驗不一樣。你真的需要有一個切換模式的理由。到目前爲止我不知道其中之一。 –

+1

不要將用戶和特權模式與兩個不同的棧指針msp和psp混淆。雖然他們可以一起使用,但他們是不同的東西。中斷總是使用msp。其他代碼可能使用msp或psp。您必須處於特權模式才能訪問SYST_CSR,這是您啓動時所處的模式。 –

+0

我工作過的大多數裸機(非RTOS)系統總是處於特權模式,只能使用msp。在裸機系統上切換到用戶模式可能會使代碼更安全,但確實增加了複雜性。在RTOS上,RTOS和中斷使用msp,並且線程使用psp。說實話,除非你使用的是MPU,否則你並沒有真正獲得用戶和特權模式的全部好處。 –

回答

2

您無法將模式直接從用戶模式提升爲直接授予模式(您可以直接從特權模式切換到用戶模式)。您必須通過SVC呼叫(主管呼叫)來完成。

你如何提高一個SVC呼叫將取決於你的編譯器,如果你用C做,但在彙編你可以使用asm("svc, #1");

#1可以是任何數字。這可用於SVC處理程序。如果您只想使用SVC處理程序來實現此目的,那麼您不需要解碼處理程序中的數字,只需使用上述程序集來提高權限即可。然而,如果你想要將SVC用於多種目的,那麼你需要對數字進行解碼,因此#1用於提高特權,#2用於做其他事情等。這裏要知道的主要內容是SVC號碼將在您撥打電話時使用的堆棧上(msp或psp)。如果你只使用一個堆棧,那麼它更容易。您將不得不在用戶指南中查找堆棧幀。

所以你需要實現一個SVC處理程序。你應該在網上找到一些例子。在「ARM Cortex-M3和Cortex M4權威指南」一書中有一個很好的例子。

+0

對於GCC語法將是'asm(「SVC#11」);' –

0

Janathan Valvano具有http://users.ece.utexas.edu/~valvano/arm/#Timer

; SysTickInts.s 
; Runs on LM4F120/TM4C123 
; Use the SysTick timer to request interrupts at a particular period. 
; Daniel Valvano 
; September 11, 2013 

; This example accompanies the book 
; "Embedded Systems: Introduction to ARM Cortex M Microcontrollers" 
; ISBN: 978-1469998749, Jonathan Valvano, copyright (c) 2013 
; Volume 1, Program 9.7 

; "Embedded Systems: Real Time Interfacing to ARM Cortex M Microcontrollers", 
; ISBN: 978-1463590154, Jonathan Valvano, copyright (c) 2013 
; Volume 2, Program 5.12, section 5.7 
; 
;Copyright 2013 by Jonathan W. Valvano, [email protected] 
; You may use, edit, run or distribute this file 
; as long as the above copyright notice remains 
;THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 
;OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 
;MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 
;VALVANO SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, 
;OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 
;For more information about my classes, my research, and my books, see 
;http://users.ece.utexas.edu/~valvano/ 

NVIC_ST_CTRL_R  EQU 0xE000E010 
NVIC_ST_RELOAD_R  EQU 0xE000E014 
NVIC_ST_CURRENT_R  EQU 0xE000E018 
NVIC_ST_CTRL_COUNT EQU 0x00010000 ; Count flag 
NVIC_ST_CTRL_CLK_SRC EQU 0x00000004 ; Clock Source 
NVIC_ST_CTRL_INTEN EQU 0x00000002 ; Interrupt enable 
NVIC_ST_CTRL_ENABLE EQU 0x00000001 ; Counter mode 
NVIC_ST_RELOAD_M  EQU 0x00FFFFFF ; Counter load value 
NVIC_SYS_PRI3_R  EQU 0xE000ED20 ; Sys. Handlers 12 to 15 Priority 

     AREA |.text|, CODE, READONLY, ALIGN=2 
     THUMB 
     EXPORT SysTick_Init 

; **************SysTick_Init********************* 
; Initialize SysTick periodic interrupts, priority 2 
; Input: R0 interrupt period 
;  Units of period are 1/clockfreq 
;  Maximum is 2^24-1 
;  Minimum is determined by length of ISR 
; Output: none 
; Modifies: R0, R1, R2, R3 
SysTick_Init 
    ; start critical section 
    MRS R3, PRIMASK    ; save old status 
    CPSID I      ; mask all (except faults) 
    ; disable SysTick during setup 
    LDR R1, =NVIC_ST_CTRL_R   ; R1 = &NVIC_ST_CTRL_R (pointer) 
    MOV R2, #0 
    STR R2, [R1]     ; disable SysTick 
    ; maximum reload value 
    LDR R1, =NVIC_ST_RELOAD_R  ; R1 = &NVIC_ST_RELOAD_R (pointer) 
    SUB R0, R0, #1     ; counts down from RELOAD to 0 
    STR R0, [R1]     ; establish interrupt period 
    ; any write to current clears it 
    LDR R1, =NVIC_ST_CURRENT_R  ; R1 = &NVIC_ST_CURRENT_R (pointer) 
    STR R2, [R1]     ; writing to counter clears it 
    ; set NVIC system interrupt 15 to priority 2 
    LDR R1, =NVIC_SYS_PRI3_R  ; R1 = &NVIC_SYS_PRI3_R (pointer) 
    LDR R2, [R1]     ; friendly access 
    AND R2, R2, #0x00FFFFFF   ; R2 = R2&0x00FFFFFF (clear interrupt 15 priority) 
    ORR R2, R2, #0x40000000   ; R2 = R2|0x40000000 (interrupt 15 priority is in bits 31-29) 
    STR R2, [R1]     ; set SysTick to priority 2 
    ; enable SysTick with core clock 
    LDR R1, =NVIC_ST_CTRL_R   ; R1 = &NVIC_ST_CTRL_R 
; ENABLE SysTick (bit 0), INTEN enable interrupts (bit 1), and CLK_SRC (bit 2) is internal 
    MOV R2, #(NVIC_ST_CTRL_ENABLE+NVIC_ST_CTRL_INTEN+NVIC_ST_CTRL_CLK_SRC) 
    STR R2, [R1]     ; store a 7 to NVIC_ST_CTRL_R 
    ; end critical section 
    MSR PRIMASK, R3    ; restore old status 
    BX LR       ; return 

    ALIGN       ; make sure the end of this section is aligned 
    END        ; end of file 
+1

在C中更容易 –