__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值会被恢复为即将运行的任务的任务函数,新的任务开始运行!至此,任务切换成功。
}

freeertos中关于PendSV中断服务函数的解析的更多相关文章

  1. 探究为什么FreeRTOS 有些API不能在中断服务函数中调用,转而需要调用带ISR的版本

    用了好久的FreeRTOS以前只是知道,如果在中断服务程序中调用某一些FreeRTOS的API函数时需要注意,如果有ISR版本的一定要调用末尾带ISR的函数,并且中断服务程序要调用freeRTOS的A ...

  2. 在中断服务函数中使用FreeRTOS系统延时函数vTaskDelay导致看门狗复位的情况

    @2019-04-09 [问题] 控制程序工作一段时间异常重启 [分析] 经定位分析重启原因为看门狗复位导致 [解决] 经排查发现在中断服务函数中使用了FreeRTOS的系统时延函数vTaskDela ...

  3. request_irq() | 注册中断服务函数【转】

    本文转载自:http://blog.csdn.net/wealoong/article/details/7566546#t0 参考  : ARM Linux 中断机制分析.pdf linux-2.6. ...

  4. STM32是如何进入中断服务函数xxx_IRQHandler的

    今天在看stm32的中断,一时间不理解stm32主函数是如何进入中断函数的,按C编程的理解,会有个特定的入口之类的,但是看demo过程中没有发现入口. 以串口中断服务函数void USART1_IRQ ...

  5. (C/C++学习)5.C++中的虚继承-虚函数-多态解析

    说明:在C++学习的过程中,虚继承-虚函数经常是初学者容易产生误解的两个概念,它们与C++中多态形成的关系,也是很多初学者经常产生困惑的地方,这篇文章将依次分别对三者进行解析,并讲述其之间的联系与不同 ...

  6. stm32中断服务函数

    你打开stm32的启动文件,例如startup_stm32f10x_hd.s 里面有很多中断跳转的入口.用白话说就是固件库帮你写好了发生什么中断时跳转到哪里,这些名字是一个函数名,你要把这些函数写出来 ...

  7. request_irq() | 注册中断服务

    一.中断注册方法 在linux内核中用于申请中断的函数是request_irq(),函数原型在Kernel/irq/manage.c中定义: int request_irq(unsigned int ...

  8. 函数可重入问题reentrant functions(函数执行过程中可以被中断,允许多个副本)

    最近经常听到这个名词,以前也听到过,不过接触更多的是“线程安全问题”,而且本人也一直理解的是两个名字的含义是一样的.今天仔细总结一下这个名词相关的概念. 引用博文:可重入函数和不可重入函数 (http ...

  9. AngularJS 中的Promise --- $q服务详解

    先说说什么是Promise,什么是$q吧.Promise是一种异步处理模式,有很多的实现方式,比如著名的Kris Kwal's Q还有JQuery的Deffered. 什么是Promise 以前了解过 ...

随机推荐

  1. Spring Aop(六)——@DeclareParents介绍

    转发:https://www.iteye.com/blog/elim-2395410 6 @DeclareParents介绍 @DeclareParents注解也是Aspectj提供的,在使用基于As ...

  2. iOS-保存图片到相册

    //保存      UIButton *saveBtn = [[UIButton alloc] init];    //    saveBtn.frame = CGRectMake((screenWi ...

  3. List的add方法与addAll方法的区别、StringBuffer的delete方法与deleteCharAt的区别

    List的add方法与addAll方法 区别 add add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素 addAll addAll是传 ...

  4. 单元测试ppt

      单元测试ppt思路详解 目前的状况:1,现在很多单元测试只是利用@Test注解把代码或者整个请求接口内的business做测试2,单测的过程就很多查数据库的方法,但是没必要每次都测sql,因为sq ...

  5. PHP新特性

    1.太空船操作符<=> 2.变量类型限定 3.$a = $b??$c 4.常量数组,define($arr,['a','b']) 5.namespace批量导入 等等

  6. 洛谷 题解 P1336 【最佳课题选择】

    详细解析解题过程 设计状态 dp[i][j]表示前i节课题写j篇论文花费的最少时间 初始数组 for(int i=0;i<=20;i++) for(int j=0;j<=200;j++)d ...

  7. 关于SQLSERVER登录不了的情况

    是这样的,本人为了复制一个数据库文件把默认数据库设置成了脱机状态.在此点击联机的时候SSMS显示重启,重启后在用windows登录显示无法打开默认数据库.用其他不适该默认数据库的账号可以登录.想问一下 ...

  8. LUA的table实现

    数据结构 下面的结构体是lua中所定义的table typedef struct Table { CommonHeader; lu_byte flags; /* 1<<p means ta ...

  9. C++目录

    C++ lambda表达式 C++中如何设计一个类只能在堆或者栈上创建对象,面试题 C++之STL总结精华笔记 指针强制类型转换的理解 关于指针类型和指针类型转换的理解 C++继承种类 C++ 单例模 ...

  10. Oracle笔记2

    24.复杂查询的三道题 # 案例一:列出与SCOTT从事相同工作的所有员工及部门名称.人数.平均工资 GROUP BY使用限制: 查询语句中没有GROUP BY,则SELECT子句中只能出现统计函数; ...