SylixOS 在进入中断退出,进入内核退出时会进行任务切换。分为两种情况讨论:

1.中断退出时任务切换

在SylixOS 中无论是同步异常还是异步异常都会首先将系统寄存器保存到系统异常栈中,然后获取当前任务的tcb控制块,最后将保存到异常堆栈中的系统上下文寄存器保存到任务控制tcb中。在SylixOS 中EXC_SAVE_VOLATILE是定义成了一个宏,所以不会进入函数,LR被改变的问题(SylixOS相关上下文保存和恢复的都定位为一个宏)

 ;/*; * 使用异常临时栈, 并在异常临时栈开辟临时上下文保存区, 将 volatile 寄存器保存到临时上下文保存区; * SP 指向异常临时栈; */EXC_SAVE_VOLATILEBL      API_InterEnter;/*; * 如果不是第一次进入中断, 跳转; */CMP     X0 , #1BNE     1f;/*; * 获得当前任务 TCB 的 ARCH_REG_CTX 地址; */BL      API_ThreadTcbInter                                          ;/*  get current tcb             */;/*; * 拷贝 volatile 寄存器到当前任务 TCB 的 ARCH_REG_CTX 里; */EXC_COPY_VOLATILE;/*; * 保存 non volatile 寄存器到当前任务 TCB 的 ARCH_REG_CTX 里; */EXC_SAVE_NON_VOLATILE

此时有个很重要地方就是当在系统中断处理函数中保存的系统寄存器中,LR寄存器也就是程序链接寄存器,保存函数的返回值。函数的返回值就是进入中断前的那一句代码,也就是系统当前运行的程序PC指针被中断打断的地方。在中断的处理函数最后调用下面函数

  ;/*; * API_InterExit(); * 如果没有发生中断嵌套, 则 API_InterExit 会调用 archIntCtxLoad 函数; */BL      API_InterExit

API_InetExit函数会进行一系列判断,如果查找到需要切换的任务,会获得任务的tcb控制块。然后使用archIntCtxLoad函数

FUNC_DEF(archIntCtxLoad)LDR     X18 , [X0]                                                  ;/*  获取当前 TCB 的 REG_CTX 地址*/LDR     X9  , [X18, #CTX_TYPE_OFFSET]                               ;/*  获得上下文类型              */CMP     X9  , #0B.NE    _RestoreSmallCtxRESTORE_BIG_REG_CTX                                                 ;/*  恢复大寄存器上下文          */FUNC_END()

在SylixOS中有个大小上下文的区别,有的体系结构不需要保存全部系统寄存器,使用的小上文。这里会判断类型,选择相应的恢复。下面以小上下文恢复为例。

;/*********************************************************************************************************
;  恢复小上下文寄存器(参数 X18: ARCH_REG_CTX 地址)
;*********************************************************************************************************/MACRO_DEF(RESTORE_SMALL_REG_CTX)LDR     X1 , [X18 , #XSP_OFFSET]                                    ;/*  恢复 SP 指针                */MOV     SP , X1RESTORE_PSTATE                                                      ;/*  恢复 PSTATE                 */LDR     X1 , [X18 , #XPC_OFFSET]                                    ;/*  恢复 PC 到 ELR_EL1          */MSR     ELR_EL1 , X1LDP     X0  , X1  , [X18 , #XGREG_OFFSET(0) ]LDP     X19 , X20 , [X18 , #XGREG_OFFSET(19)]LDP     X21 , X22 , [X18 , #XGREG_OFFSET(21)]LDP     X23 , X24 , [X18 , #XGREG_OFFSET(23)]LDP     X25 , X26 , [X18 , #XGREG_OFFSET(25)]LDP     X27 , X28 , [X18 , #XGREG_OFFSET(27)]LDP     X29 , LR  , [X18 , #XGREG_OFFSET(29)]ERETMACRO_END();

LDP指令也能猜出来是把对应偏移的值加载到系统寄存器中。有个比较特殊的地方是将PC寄存器放入到了ELR_EL1 寄存器中。由于操作系统是运行在EL1层。所以这里使用的是ELR_EL1寄存器。前面进入中断保存上下文的时候将LR寄存器保存到了PC寄存器对应的位置,ELR_EL1 寄存器保存的是异常返回地址,也就是进入中断后退出的地址,把它赋值为PC所对应的值(也就是刚进中断处理函数时LR的值)这样中断退出的时候又恢复到了进入中断前的PC地址。最后一句代码 ERET 就是返回到异常链接寄存器(ERET和RET 是有区别的)。这样就完成了一个任务的切换。

2.内核退出时任务切换

在内涵退出时最终会调用archTaskCtxSwitch函数进行任务切换。

;/*********************************************************************************************************
;  线程切换
;  参数为当前 CPU 控制块, 即 X0 为当前 CPU 控制块指针
;*********************************************************************************************************/FUNC_DEF(archTaskCtxSwitch)LDR     X18, [X0]                                                   ;/*  获取当前 TCB 的 REG_CTX 地址*/SAVE_SMALL_REG_CTX                                                  ;/*  保存小寄存器上下文          */MOV     X19 , X0                                                    ;/*  X19 暂存 X0                 */#if LW_CFG_SMP_EN > 0    BL      _SchedSafeStack                                             ;/*  _SchedSafeStack();          */MOV     SP , X0                                                     ;/*  设置 SP                     */MOV     X0 , X19                                                    ;/*  恢复 X0                     */
#endifBL      _SchedSwp                                                   ;/*  _SchedSwp();                */LDR     X18, [X19]                                                  ;/*  获取当前 TCB 的 REG_CTX 地址*/LDR     X9 , [X18, #CTX_TYPE_OFFSET]                                ;/*  获得上下文类型              */CMP     X9 , #0B.NE    _RestoreSmallCtxRESTORE_BIG_REG_CTX                                                 ;/*  恢复大寄存器上下文          */LINE_LABEL(_RestoreSmallCtx)RESTORE_SMALL_REG_CTX                                               ;/*  恢复小寄存器上下文          */FUNC_END()

首先是保存当前上下文,和进入中断时一样还是会调用SAVE_SMALL_REG_CTX(在SylixOS定义为一个宏),和前面一样除了正常的系统寄存器,sp等保存,还将LR寄存器保存到了PC。系统首先获得了一个调度程序使用的堆栈,然后调用_SchedSwp程序进行判断哪个程序需要调度,将返回需要调度程序的tcb控制块,然后进行上下文恢复。

;/*********************************************************************************************************
;  恢复小上下文寄存器(参数 X18: ARCH_REG_CTX 地址)
;*********************************************************************************************************/MACRO_DEF(RESTORE_SMALL_REG_CTX)LDR     X1 , [X18 , #XSP_OFFSET]                                    ;/*  恢复 SP 指针                */MOV     SP , X1RESTORE_PSTATE                                                      ;/*  恢复 PSTATE                 */LDR     X1 , [X18 , #XPC_OFFSET]                                    ;/*  恢复 PC 到 ELR_EL1          */MSR     ELR_EL1 , X1LDP     X0  , X1  , [X18 , #XGREG_OFFSET(0) ]LDP     X19 , X20 , [X18 , #XGREG_OFFSET(19)]LDP     X21 , X22 , [X18 , #XGREG_OFFSET(21)]LDP     X23 , X24 , [X18 , #XGREG_OFFSET(23)]LDP     X25 , X26 , [X18 , #XGREG_OFFSET(25)]LDP     X27 , X28 , [X18 , #XGREG_OFFSET(27)]LDP     X29 , LR  , [X18 , #XGREG_OFFSET(29)]ERETMACRO_END();

这里和中断退出时恢复寄存器一样,通过ELR_EL1 和ERET 配合完成任务切换。

备注:

在进入中断的时候状态寄存器会发生变化,关闭中断。此时SPSR_EL1存放的是关闭中断之前的状态寄存器,最后调用ERET命令时除了返回ELR_EL1中的地址,也会将SPSR_EL1重新加载到PSTATE。此时重新开启中断

SylixOS armv8 任务切换相关推荐

  1. SylixOS网络性能测试

    1.应用场景 在进行一些研究和开发时经常需要对网络性能进行测试,iperf是一款非常出色的网络性能测试工具,它拥有多个参数,可以测量TCP和UDP的带宽,延时抖动以及丢包率.SylixOS支持iper ...

  2. 【050】SylixOS全面支持C-SKY系列处理器

    SylixOS全面支持C-SKY系列处理器 发布于2018年11月09日 翼辉欢迎新朋友C-SKY 今天是C-SKYCPU架构加入SylixOS生态的日子,有了C-SKY的加入,SylixOS能够支持 ...

  3. ARMV8/ARMV9的执行状态的切换

    背景:为什么会有执行状态的切换 在一个大系统中,我们所说这它是64位的,还是32位的,往往说的是kernel内核.事实上,在这么的一个大系统中,有着多级镜像,并非全都是64位的,也并非全都是32位的. ...

  4. [architecture]-ARMV8的ELx等级切换

    在armv8中,有EL0.EL1.EL2.EL3四个权限级别. 低级别像高级别切换是通过触发异常来进行的.例如: 1.在EL0时调用svc指令,触发一个同步异常,cpu则会陷入EL1: 2.在EL0时 ...

  5. SylixOS更新记录

    内容来自 SylixOS内核文件<CHANGELOG>,从中我们可以看到SylixOS不断完善的细节. HISTORY (GIT HEAD) ++ New features: 2020-0 ...

  6. 基于ARMv8的固件系统体系结构

    基于ARMv8的固件系统体系结构 The architecture of ARMv8-based firmware systems 自2011年发布以来,ARMv8处理器架构在移动设备市场上已经相当普 ...

  7. SylixOS DSP upgrade命令解析

    SylixOS DSP upgrade命令解析 --SylixOS DSP6678平台下升级BSP 一.适用范围 本升级方案,针对TI官方评估板(TMDSEVM6678LE),主要介绍如何将Sylix ...

  8. [register]-ARMV8系统中通用寄存器和系统寄存器的介绍和总结

    ★★★ 个人博客导读首页-点击此处 ★★★ . 说明: 在默认情况下,本文讲述的都是ARMV8-aarch64架构,linux kernel 64位 . 自制ARMv8 aarch64 registe ...

  9. [trustzone]-ARM Core的扩展和ELx级别的切换过程

    目录 1.ARM Core的扩展 : 增加SCR.NS bit位 2.ELx级别的切换过程 ★★★ 友情链接 : 个人博客导读首页-点击此处 ★★★ 1.ARM Core的扩展 : 增加SCR.NS ...

  10. armv8/armv7中SCTLR的区别

    ★★★ 友情链接 : 个人博客导读首页-点击此处 ★★★ 以SCTLR寄存器来阐述在armv7.armv8-arch64.armv8-arch64的使用方式 (其实大多数的系统寄存器,都是这种处理方式 ...

最新文章

  1. (转)hibernate 注解的问题(异常)集合
  2. 如何分析SAPPSPRO-S_MAT_ENHANC_COMM问题
  3. 安卓camera总体框架
  4. Python中的多进程创建和传值(克隆)Queue方法
  5. window下Python2.7和3.5共存以及两个版本下使用pip
  6. 深层理解-栈平衡原理
  7. 精简win服务器系统,My Server之管理Win Server 2012精简版
  8. noj [1480] 懒惰的风纪委Elaine (多重背包)
  9. 什么是指纹浏览器,修改浏览器指纹工具
  10. TeamTalk的windows客户端流程
  11. Python:实现pollard rho大数分解算法(附完整源码)
  12. HC32F460 SPI DMA 驱动 TFT显示屏
  13. Github之First day on Github,带你学习并完成任务点,纯手敲超详细教程!(下)
  14. 琵琶行·并序--白居易
  15. php中获得上个月的同一时间,PHP判断两个给定日期是否在同一周的方法
  16. Inspect的学习笔记
  17. 想自学编程,先学什么好?给你三个建议,自己斟酌
  18. 苹果cms模板_9ccms与苹果cms介绍.推荐小白用9ccms程序
  19. leetcode每日一题信息抓取 早安语录 定时任务
  20. 油条、油饼,千滚百沸的油怎让人放心

热门文章

  1. JDK和CGLIB生成动态代理类的区别
  2. (原創) 如何Real Time產生灰階影像? (SOC) (DE2-70) (TRDB-D5M)
  3. java B2B2C Springboot电子商城系统-消息队列之 RabbitMQ
  4. 前端:用css打造炫酷3d特效- css3d立方体
  5. 你需要的不是大数据 而是正确的数据~
  6. pandas 修改 DataFrame 列名 1
  7. 自动更改IP地址反爬虫封锁,支持多线程(转)
  8. CentOS6.5 webserver---网络配置
  9. redis缓存和mysql数据库同步
  10. CIKERS Shane 20190603