在线时间11 小时
UID3090169
注册时间2015-1-7
NXP金币0
该用户从未签到
注册会员

- 积分
- 67
- 最后登录
- 2015-4-8
|
根据《The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors, 3rd Edition.pdf》第23.5 Non-base Thread enable
由于CortexM内核中规定,在不使用Non-base Thread时,中断服务一定是特权级别。
由于内核需要为应用程序提供定时回调功能,即应用程序可以通过申请定时器,定时执行APP的特定程序段。由于转入的动作在定时器中断服务中,这将导致被执行的APP程序段具有特权。因此,需要使用Non-base Thread功能。
《The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors, 3rd Edition.pdf》第23.5 Non-base Thread enable提供了 Non-base Thread实现的源码:
__asm void SysTick_Handler(void)
{ // Redirect handler - no Floating point instruction
PUSH {R4, LR} ; Push 2 words for double word stack alignment
SVC 0 ; A SVC function to change from privileged to
; unprivileged mode
BL __cpp(User_SysTick_Handler)
SVC 1 ; A SVC function to change back from user to
; privileged mode
POP {R4, PC} ; Return
}
__asm void SVC_Handler(void)
{
; Extract SVC number
TST LR, #0x4 ; Test EXC_RETURN bit 2
ITE EQ ; if zero then
MRSEQ R0, MSP ; Get correct stack pointer to R0
MRSNE R0, PSP
LDR R1, [R0, #24] ; Get stacked PC
LDRB.W R0, [R1, #-2] ; Get SVC parameter at stacked PC minus 2
CBZ R0, svc_service_0 ; if zero, branch to SVC service 0
CMP R0, #1
BEQ svc_service_1 ; if one, branch to SVC service 1
B.W Unknown_SVC_Request
748 CHAPTER 23 Advanced Topics
; -----------------------------------------------------------
svc_service_0 ; Service to switch handler from
; privileged mode to unprivileged mode
; and use Process Stack. For this service,
; stack framce must be in Main Stack because it is
; called from an exception handler.
MRS R0, PSP ; Adjust PSP to create space for new stack frame
; and make a back up of PSP due to the
TST R0, #0x4 ; Check PSP to see if it is double word aligned
ITE EQ
MOVSEQ R3, #0x20 ; No Padding
MOVWNE R3, #0x24 ; Padding needed.
LDR R1, =__cpp(&svc_PSP_adjust)
STRB R3, [R1] ; Record PSP adjustment for use in SVC #1
SUBS R0, R0, R3 ; PSP = PSP - 0x20 or 0x24
; Make sure Process Stack is double word aligned
MSR PSP, R0 ; Copy back to PSP
MOVS R1, #0x20 ; Copy stack frame from main stack to
; process stack. This stack frame is 8 words
; because SysTick_Handler has not execute
; any FP instruction yet.
svc_service_0_copy_loop
SUBS R1, R1, #4
LDR R2, [SP, R1] ; Read data
STR R2, [R0, R1] ;
CMP R1, #0
BNE svc_service_0_copy_loop
LDR R1,[R0, #0x1C] ; Changed stacked xPSR so that IPSR=0
MOVW R2, #0x3FF ; Clear IPSR, stack alignment bit
BIC R1, R1, R2
STR R1,[R0, #0x1C] ; Clear stacked IPSR of user stack to 0
LDR R0, =0xE000ED14 ; Set Non-base thread enable in CCR
LDR r1,[r0]
ORR r1, #1
STR r1,[r0]
MRS R0, CONTROL ; Set CONTROL[0] so Thread run in unprivileged
; state
ORRS R0, R0, #1
MSR CONTROL, R0
ORR LR, #0x1C ; Change LR to return to thread,using PSP,
; 8 words stack frame
BX LR
; -----------------------------------------------------------
23.5 Non-base Thread enable 749
svc_service_1 ; Service to switch handler back from
; unprivileged mode to
; privileged mode
MRS R0, PSP ; Update stacked PC in original privileged
; stack so that it
LDR R1,[R0, #0x18] ; return to the instruction after 2nd
; SVC in the redirect handler
STR R1,[SP, #0x18] ;
MRS R0, PSP ; Adjust PSP back to what it was
; before 1st SVC
LDR R1, =__cpp(&svc_PSP_adjust)
LDRB R1, [R1]
ADDS R0, R0, R1
MSR PSP, R0
LDR R0, =0xE000ED14 ; Clear Non-base thread enable in CCR
LDR r1,[r0]
BIC r1, #1
STR r1,[r0]
MRS R0, CONTROL ; Clear CONTROL[0]
BICS R0, R0, #1
MSR CONTROL, R0
ORR LR, #0x10 ; Return using 8 word stack frame
BIC LR, #0xC ; Return to handler mode, using main stack
BX LR
Unknown_SVC_Request ; Output error message
BL __cpp(Unknown_SVC_Request_Msg)
B .
ALIGN
}
对于以上代码在Freescale MK21FN1M0xxx12 (allow security)上做了测试。
1: 程序SVC处理部分与手册代码完全一致
2: 执行SVC 0后,立即死循环,通过串口显示control为1。说明已进入用户级,SVC处理代码与手册完全一致,可认为无误。
问题:
1. MPU已经初始化并开启,串口显示函数ROM、RAM通过MPU禁止用户权限访问。访问MPU禁区不产生bus fault。(control为1说明内核已经进入用户模式)
2. SVC 0处理结束后,重启MPU,然后检测contorl,并用串口显示。control为1,程序不跑飞。串口显示函数ROM、RAM通过MPU禁止用户权限访问。
|
-
|