PendSV_Handler

参考野火的程序:

; OSTCBCurPtr = OSTCBHighRdyPtr;

LDR     R0, = OSTCBCurPtr                 ; 加载 OSTCBCurPtr 指针的地址到R0,这里LDR属于伪指令

分析:运行后R0=0x20000018=&OSTCBCurPtr

LDR     R1, = OSTCBHighRdyPtr             ; 加载 OSTCBHighRdyPtr 指针的地址到R1,这里LDR属于伪指令

分析:R1=0x2000001C=&OSTCBHighRdyPtr

LDR     R2, [R1]                          ; 加载 OSTCBHighRdyPtr 指针到R2,这里LDR属于ARM指令

分析:R2=0x20000008=&Task1TCB=OSTCBHighRdyPtr

STR     R2, [R0]                          ; 存储 OSTCBHighRdyPtr 到 OSTCBCurPtr

分析:OSTCBCurPtr=R2=0x20000008==OSTCBHighRdyPtr

LDR     R0, [R2]                          ; 加载 OSTCBHighRdyPtr 到 R0

分析:R0 = 0x20000038 = OSTCBCurPtr->StkPtr = &Task1Stk[4] (初始化后剩余的栈顶地址)

LDMIA   R0!, {R4-R11}                     ; 加载需要手动保存的信息到CPU寄存器R4-R11

分析:R0 = 0x20000058 = &Task1Stk[12] (加载R4-R11共8个寄存器,R0自动增加4*8=32;0x38+0x20=0x58)

MSR     PSP, R0                           ; 更新PSP的值,这个时候PSP指向下一个要执行的任务的堆栈的栈底(这个栈底已经加上刚刚手动加载到CPU寄存器R4-R11的偏移)

分析:PSP = 0x20000058

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
不超过100行的FReeRTOS,只有核心代码。只适合转牛角尖者,研究FReeRTOS原理者。 #include "task.h" #include "usart.h" TCB *TCBCur; u32 Prio_t = 0; TCB TCBL[64]; void task_create(void (* task)(void ),u32 *STK,u32 prio) { TCBCur = &TCBL;[prio]; *(--STK) = 1<<24; *(--STK) = ( u32 ) task; TCBL[prio].stkPtr = STK-14; } void CtxSw( void ) { TCBCur = &TCBL;[ Prio_t ]; } u8 STK_SizeChk(u32 *STK) { u32 i=0; while(!*STK++)i++; return i; } __asm void OSstart( void ) { extern TCBCur; PRESERVE8 ldr r3, =TCBCur /* Obtain location of TCBCur. */ ldr r1, [r3] ldr r0, [r1] /* The first item in TCBCur is the task top of stack. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ movs r0, #2 /* Switch to the psp stack. */ msr CONTROL, r0 pop {r0-r5} /* Pop the registers that are saved automatically. */ mov lr, r5 /* lr is now in r5. */ cpsie i /* The first task has its context and interrupts can be enabled. */ pop {pc} /* Finally, pop the PC to jump to the user defined task code. */ ALIGN } __asm void PendSV_Handler( void ) { extern CtxSw extern TCBCur PRESERVE8 mrs r0, psp ldr r3, =TCBCur /* Get the location of the current TCB. */ ldr r2, [r3] subs r0, #32 /* Make space for the remaining low registers. */ str r0, [r2] /* Save the new top of stack. */ stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */ mov r4, r8 /* Store the high registers. */ mov r5, r9 mov r6, r10 mov r7, r11 stmia r0!, {r4-r7} push {r3, r14} cpsid i bl CtxSw cpsie i pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */ ldr r1, [r2] ldr r0, [r1] /* The first item in TCBCur is the task top of stack. */ adds r0, #16 /* Move to the high registers. */ ldmia r0!, {r4-r7} /* Pop the high registers. */ mov r8, r4 mov r9, r5 mov r10, r6 mov r11, r7 msr psp, r0 /* Remember the new top of stack for the task. */ subs r0, #32 /* Go back for the low registers that are not automatically restored. */ ldmia r0!, {r4-r7} /* Pop low registers. */ bx r3 ALIGN }
查看文章 STM32 keil mdk启动代码发分析_转2010年01月29日 星期五 13:50 ;// Stack Configuration ;// Stack Size (in Bytes) ;// Stack_Size EQU 0x00000200 ;//定义堆栈大小 AREA STACK, NOINIT, READWRITE, ALIGN=3 ;//定义一个数据段 按8字节对齐 ;AREA 伪指令用于定义一个代码段或数据段 NOINIT:指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个内存单元值初始化为0 Stack_Mem SPACE Stack_Size ;//保留Stack_Size大小的堆栈空间 分 配连续 Stack_Size 字节的存储单元并初始化为 0 __initial_sp ;//标号,代表堆栈顶部地址,后面有用 ;// Heap Configuration ;// Heap Size (in Bytes) ;// Heap_Size EQU 0x00000020 ;//定义堆空间大小 AREA HEAP, NOINIT, READWRITE, ALIGN=3 ;//定义一个数据段,8字节对齐 __heap_base Heap_Mem SPACE Heap_Size ;//保留Heap_Size的堆空间 __heap_limit ;//标号,代表堆末尾地址,后面有用 PRESERVE8 ;//指示编译器8字节对齐 THUMB ;//指示编译器为THUMB指令 ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY ;//定义只读数据段,其实放在CODE区,位于0地址 EXTERN NMIException EXTERN HardFaultException EXTERN MemManageException EXTERN BusFaultException EXTERN UsageFaultException EXTERN SVCHandler EXTERN DebugMonitor EXTERN PendSVC EXTERN SysTickHandler ;//声明这些符号在外部定义,同C ;//在××it.c中实现这些函数 ,中断就能自动调用了 EXPORT __Vectors EXPORT __initial_sp ;EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用;I

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值