查看: 3157|回复: 6

[求助] 基于K21F的MPU的non-base thread无法实现问题

[复制链接]

该用户从未签到

5

主题

17

帖子

0

注册会员

Rank: 2

积分
67
最后登录
2015-4-8
发表于 2015-3-30 15:30:26 | 显示全部楼层 |阅读模式
根据《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禁止用户权限访问。
我知道答案 目前已有6人回答
QQ图片20150330144531.png
回复

使用道具 举报

该用户从未签到

5

主题

17

帖子

0

注册会员

Rank: 2

积分
67
最后登录
2015-4-8
 楼主| 发表于 2015-3-30 15:36:22 | 显示全部楼层
void timer_isr(void)     
{
                uint32_t tcot,fd;
                __asm__ volatile
                (                               
                                "        svc 250                                                        \n"
                                " mrs %0,control                        \n"
                                :"=r" (tcot)::
                );
                dprintf("control:%p\n\r",tcot);
                while(1);
}
dprintf为串口显示函数,ROM、RAM对于用户程序不能访问。
执行结果:control:1

__attribute__ (( naked ))void svc_isr(void)
{
                __asm__ volatile
                (
                        "        tst lr, #4                                                \n"
                        "        ite eq                                                                \n"
                        "        mrseq r0, msp                                        \n"
                        "        mrsne r0, psp                                        \n"
                        "        b %0                                                                        \n"
                        "        .align 2                                                        \n"
                        ::"i"        (prvSVCHandler):       
                );
}


static void prvSVCHandler(uint32_t *pulParam)
{
                uint8_t ucSVCNumber , i;
                ucSVCNumber = (( uint8_t * ) pulParam[6])[-2];                               

                switch( ucSVCNumber )
                {
                   
                    case 250:
                                __asm__ volatile
                                (                               
                                                "        mrs r0,psp                                        \n"
                                                " tst r0,#0x4                                        \n"
                                                " ite eq                                                        \n"
                                                " movseq r3,0x20                        \n"
                                                " movsne r3,0x24                        \n"
                                                " subs r0, r0, r3                        \n"
                                                " msr psp, r0                                        \n"
                                                " movs r1, #0x20                        \n"
                                                "        svc_0_copy_loop:                 \n"
                                                " subs r1,r1,#4                                \n"
                                                " ldr r2,[sp,r1]                        \n"
                                                " str r2,[r0,r1]                        \n"
                                                " cmp r1,#0                                                \n"
                                                "        bne svc_0_copy_loop \n"       
                                                " ldr r1,[r0,#0x1C]                \n"
                                                " movw r2,#0x3FF                        \n"
                                                " bic r1,r1,r2                                \n"
                                                "        str r1,[r0,#0x1C]                \n"
                                                " ldr r0,=0xE000ED14        \n"
                                                " ldr r1,[r0]                                        \n"
                                                " orr r1,#1                                                \n"
                                                "        str r1,[r0]                                        \n"
                                                "        mrs r0,control                        \n"
                                                "        orr r0,#1                                                \n"
                                                "        msr control,r0                        \n"
                                                "        orr lr,#0x1C                                \n"
                                );
                    return;

}

回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

17

帖子

0

注册会员

Rank: 2

积分
67
最后登录
2015-4-8
 楼主| 发表于 2015-3-31 07:58:20 | 显示全部楼层
顶上去顶上去顶上去
回复 支持 反对

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
发表于 2015-3-31 09:55:08 | 显示全部楼层
楼主,你好!
ROM、RAM通过MPU禁止用户权限访问
你现在是禁止MPU的ROM、RAM访问,但是实际上没有产生hardfault,并且能够正常访问没有异常?
还有,你串口显示,这个串口打印信息是否可靠,有没有去看看具体的寄存器是否真的禁止成功了。
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

17

帖子

0

注册会员

Rank: 2

积分
67
最后登录
2015-4-8
 楼主| 发表于 2015-3-31 10:28:19 | 显示全部楼层
本帖最后由 hdfghd 于 2015-3-31 10:34 编辑
FSL_TICS_ZJJ 发表于 2015-3-31 09:55
楼主,你好!
ROM、RAM通过MPU禁止用户权限访问
你现在是禁止MPU的ROM、RAM访问,但是实际上没有产生hardfa ...

1. 在APP主线程中(用户权限)调用dprintf,必定会跑飞。跑飞进入bus fault,报精确数据异常。K21F的MPU玩了1个月,应该不会有太大问题。
2. 用户模式下(control 为 1)程序会报bus fault,原因有2个
  a. dprintf的处理位于MPU的禁区。用户程序不得访问。(MPU配置不存在问题,见1)
  b. 即使不开mpu,串口寄存器位于scs区域(虽然不确定peripheral是否属于scs区域,但是app线程模式关MPU调用dprintf报bus fault)3. 判断内核进入用户模式依据有2个
  a. 内核手册有完整的non-base thread功能描述,处理部分完全移植内核手册,详见23.5。如果不成熟或者无法实现内核应该不单独提出这么一个章节。
  b. 基本排除non-base thread实现问题,代码是参考手册23.5。源码见顶楼。经测试中断服务control为0,加入non-base thread 处理后control为1。说明non-base thread实现方法正确(稍有不慎就会跑飞)。
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

17

帖子

0

注册会员

Rank: 2

积分
67
最后登录
2015-4-8
 楼主| 发表于 2015-4-1 09:00:00 | 显示全部楼层
内核的MPU寄存器的地址在0xE000ED90 ~ 0xE000EDB8
K21F的MPU 是0x4000D000~ 0x4000D82C
前者位于SCS区域,后者在Peripheral Bridge 0
芯片手册没找到对MPU变动的说明。怀疑是不是MPU和内核不同步造成的
回复 支持 反对

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
发表于 2015-4-1 15:33:49 | 显示全部楼层
hdfghd 发表于 2015-4-1 09:00
内核的MPU寄存器的地址在0xE000ED90 ~ 0xE000EDB8
K21F的MPU 是0x4000D000~ 0x4000D82C
前者位于SCS区域, ...

非常感谢你的技术问题。我们建议您将此Kinetis的技术问题提交到飞思卡尔的英文论坛。网址是http://community.freescale.com/welcome 谢谢。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-7-23 04:56 , Processed in 0.102355 second(s), 28 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表