Переход в привилегированный режим в cortex-m3

Я пытаюсь получить доступ к таймеру SysTick Cortex-M3, поэтому мне нужно переключиться в привилегированный режим. я делаю это как

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

Но это не работает, потому что я не могу записать регистр SYST_CSR. Для выполнения этой операции требуется любая запись об исключении, если ДА, то как?


person Sajjad Ahmed    schedule 14.03.2017    source источник
comment
вам не нужно переключать режимы для начинающих, чтобы получить доступ к таймеру, режимы просто дают вам два указателя стека или два из некоторого набора регистров, и это не то же самое, что разные режимы в полноразмерной руке. у вас действительно должна быть причина для переключения режимов. пока я не знаю ни одного.   -  person old_timer    schedule 15.03.2017
comment
Не путайте пользовательский и привилегированный режимы с двумя разными указателями стека, msp и psp. Хотя они могут использоваться вместе, это разные вещи. Прерывания всегда используют MSP. Другой код может использовать файлы msp или psp. Вы ДОЛЖНЫ находиться в привилегированном режиме для доступа к SYST_CSR, в котором вы находитесь при запуске.   -  person Realtime Rik    schedule 15.03.2017
comment
Большинство систем с «голым железом» (не RTOS), над которыми я работал, всегда находятся в привилегированном режиме и используют только файл msp. Переключение в пользовательский режим на «голом железе» может сделать код более безопасным, но увеличивает сложность. В RTOS RTOS и прерывания используют msp, а потоки используют psp. Честно говоря, если вы не используете MPU, вы не получите всех преимуществ пользовательского и привилегированного режима.   -  person Realtime Rik    schedule 15.03.2017


Ответы (2)


Вы не можете поднять режим до привилегированного непосредственно из пользовательского режима (вы можете перейти в пользовательский режим прямо из привилегированного режима). Вы должны сделать это через вызов SVC (вызов супервизора).

То, как вы инициируете вызов SVC, будет зависеть от вашего компилятора, если вы делаете это на C, однако на ассемблере вы можете использовать asm("svc, #1");

#1 может быть любым числом. Это делается доступным для обработчика SVC. Если вы хотите использовать обработчик SVC только для этой цели, вам не нужно декодировать число в обработчике, и вы можете просто использовать свою сборку выше, чтобы повысить привилегию. Однако, если вы хотите использовать SVC более чем для одной цели, вам необходимо расшифровать номер, чтобы № 1 для повышения привилегии, № 2 для выполнения чего-то еще и т. д. Здесь главное знать, что SVC номер будет находиться в стеке, который вы использовали, когда был сделан вызов (либо в MSP, либо в PSP). Если вы когда-либо использовали только один стек, тогда это проще. Вам нужно будет найти кадр стека в руководствах пользователя.

Итак, вам нужно реализовать обработчик SVC. Вы должны быть, чтобы найти несколько примеров в Интернете. Хороший пример есть в книге «Полное руководство по ARM Cortex-M3 и Cortex M4».

person Realtime Rik    schedule 15.03.2017
comment
Для синтаксиса GCC будет asm("SVC #11"); - person Sajjad Ahmed; 03.05.2017

У Джанатана Вальвано есть пример кода таймера SysTick и другие материалы по адресу 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
person InfinitelyManic    schedule 15.03.2017
comment
На С намного проще - person Realtime Rik; 15.03.2017