__asm void xPortPendSVHandler( void )
{
extern uxCriticalNesting;
extern pxCurrentTCB;
extern vTaskSwitchContext; PRESERVE8        //栈的8字节对齐 mrs r0, psp          //读取当前psp进程指针,存入r0
isb
/* 获取当前任务控制块 */
ldr r3, =pxCurrentTCB  //把当前任务控制块的指针给r3
ldr r2, [r3]        //把r3地址中的值给r2,r2中就存储当前的任务控制块 /* 是否使用了FPU,使用的话要手动保存s16~s31 */
tst r14, #0x10
it eq
vstmdbeq r0!, {s16-s31} /* Save the core registers. */
stmdb r0!, {r4-r11, r14} //含义::依次压栈r0 = r0 - 4,先压r14,r0 = r14(即将r14中的内容放入r0所指的内存地址)
// r0 = r0 - 4,再压r11,r0 = r11。
// r0 = r0 - 4,再压r10,r0 = r10......r0 = r0 - 4,最后压r4,r0 = r4。
// 则r0中就保存最新的栈顶指针值 /* 保存最新的栈顶指针到当前任务控制块的第一字段*/
str r0, [r2]       //把r0的值存入r2的地址,相当于*r2 = r0,[r2]中已经保存了最新的任务的控制块,经过上面的两个ldr指令,r2中已经保存最新的任务控制块的地址 stmdb sp!, {r3}      //将寄存器R3的值临时压栈,寄存器r3中仍然保存着当前任务的任务控制块,
      //而接下来要调用函数vTaskSwitchContext,防止r3的值被改写,故临时压栈 mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0 //关中断,进入临界区 dsb
isb
bl vTaskSwitchContext  //调用函数vTaskSwitchContext,此函数用来获取下一个要运行的任务,并将pxCurrentTCB更新为要运行的这个任务 mov r0, #
msr basepri, r0      //开中断,退出临界区 ldmia sp!, {r3} //刚刚保存的寄存器R3的值出栈,恢复寄存器R3的值。注意,经过调用函数vTaskSwitchContext,此时
//pxCurrentTCB的值已经改变了,所以读取R3所保存的地址处的数据就会发现其值改变了,成
//为了下一个要运行的任务的任务控制块。 ldr r1, [r3]
ldr r0, [r1] //获取新的运行任务的栈顶,并存到r0中去 /* 弹出内核寄存器 */
ldmia r0!, {r4-r11, r14} //含义::依次出栈 r0 = r0 + 4,先弹出r14,r0 = r14(即将r14中的内容放入r0所指的内存地址)
// r0 = r0 + 4,再弹r11,r0 = r11。
// r0 = r0 + 4,再弹r10,r0 = r10......r0 = r0 - 4,最后出r4,r0 = r4。 /*是够使用了FPU,使用了徐要手动保存s16~s31*/
tst r14, #0x10
it eq
vldmiaeq r0!, {s16-s31} msr psp, r0 //更新进程栈指针PSP的值
isb
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata *///这块暂时不用管
#if WORKAROUND_PMU_CM001 == 1
push { r14 }
pop { pc }
nop
#endif
#endif bx r14 //执行此行代码以后硬件自动恢复寄存器R0~R3、R12、LR、PC和xPSR的值,确定异常返回以后应该进入处理器模式还是进程模式,使用主栈指针(MSP)还是进程栈指针(PSP)。
        很明显这里会进入进程模式,并且使用进程栈指针(PSP), 寄存器PC值会被恢复为即将运行的任务的任务函数,新的任务开始运行!至此,任务切换成功。
}

最新文章

  1. ios app内嵌入http服务器
  2. MySQL 远程连接(federated存储引擎)
  3. office2003?2007共存?版本各自打开的解决方案
  4. 【leetcode】Regular Expression Matching
  5. UCenter整合登陆时出现’Authorization has expired’错误(2014-03-13记)
  6. 详解MemCached原理
  7. webBroser获取cookie
  8. HDU5875:Function
  9. ntpd和ntpdate
  10. MySQL中用户授权/删除授权的方法
  11. uva 1597 Searching the Web
  12. [译]Java 设计模式之单例
  13. 浅析如何在Nancy中使用Swagger生成API文档
  14. Genymotion的安装与使用(附百度云盘下载地址,全套都有,无需注册Genymotion即可使用)
  15. JSP之Cookie的实现
  16. eclipse 没有web项目和server
  17. Leetcode 树(102, 637)
  18. [转]Angular2 使用管道Pipe以及自定义管道格式数据
  19. B轮公司技术问题列表(转)
  20. VB改写C#

热门文章

  1. android之Framework问题总结:
  2. Flutter dio伪造请求头获取数据
  3. Jmeter 逻辑控制器 之 Runtime Controller
  4. 设计模式七大原则(C++描述)
  5. [Tensorflow] 使用 model.save_weights() 保存 / 加载 Keras Subclassed Model
  6. 《精通并发与Netty》学习笔记(11 - 详解NIO (二) 分散/聚集 Scatter/Gather、Selector)
  7. kubernetes资源调度
  8. ffmpeg学习笔记-音频播放
  9. Python报错:TypeError: data type not understood
  10. [Cometoj#3 D]可爱的菜菜子_线段树_差分_线性基