当前位置: 首页 > news >正文

做任务的电脑网站大同优化推广

做任务的电脑网站,大同优化推广,百度下载安装免费,南宁制作网站的公司SylixOS 操作系统下,任务切换可以分为两种 中断退出时,执行的任务切换(_ScheduleInt)内核退出时,执行的任务切换(_Schedule) 下面分别讲讲这两种任务切换 1、中断退出时任务切换 关于 ARM 架…

SylixOS 操作系统下,任务切换可以分为两种

  • 中断退出时,执行的任务切换(_ScheduleInt)
  • 内核退出时,执行的任务切换(_Schedule)

下面分别讲讲这两种任务切换

1、中断退出时任务切换

关于 ARM 架构下,栈空间,推荐这篇文章:ARM 栈和函数调用

;/*********************************************************************************************************
;  中断入口
;*********************************************************************************************************/FUNC_DEF(archIntEntry);/* 在 IRQ 模式下,LR(R14_irq)存储的是 当前执行地址 + 4,所以需要 减 4 调整回正确的返回地址 */SUB     LR , LR, #4                                                 ;/*  调整用于中断返回的 PC 值    */;/* 保存 REG 到 IRQ 模式栈空间(中断上下文保存)*/STMFD   SP!, {LR}                                                   ;/*  保存返回地址                */STMFD   SP!, {R0-R12}                                               ;/*  保存寄存器                  */;/* 将当前 IRQ 模式的栈指针 SP_irq 存入 R1(用于后续保存 SYS 模式寄存器)*/MOV     R1 , SPMSR     CPSR_c, #(DIS_INT | SYS32_MODE)                             ;/*  回到 SYS 模式               */;/* 将 SYS 模式的栈指针 SP_sys 存入 R1 指向的内存(保存任务栈)*/STMFD   R1!, {SP}                                                   ;/*  保存 SP_sys                 */;/* 将 SYS 模式的链接寄存器 LR_sys 存入 R1 指向的内存(保存任务返回地址) */STMFD   R1 , {LR}                                                   ;/*  保存 LR_sys                 */MSR     CPSR_c, #(DIS_INT | IRQ32_MODE)                             ;/*  回到 IRQ 模式               */SUB     SP , SP , #(2 * 4)                                          ;/*  调整 SP_irq                 */;/* 读取 SPSR_irq(保存了被中断任务的 CPSR_sys) */MRS     R2 , SPSR;/* 将 SPSR_irq(即原 CPSR_sys)压入 IRQ 模式栈(保存任务状态) */STMFD   SP!, {R2}                                                   ;/*  保存 CPSR_sys               */;/*; * API_InterEnter(SP_irq), 如果是第一次中断, 会将 IRQ 模式栈空间的 ARCH_REG_CTX; * 拷贝到当前任务 TCB 的 ARCH_REG_CTX 里; */MOV     R0 , SPLDR     R1 , =API_InterEnterMOV     LR , PCBX      R1;/*; * 如果不是第一次进入中断, 那么上一次中断(工作在 SYS 模式)已经设置 SP_sys, 只需要回到 SYS 模式; */CMP     R0 , #1BNE     1f;/*; * 第一次进入中断: 因为已经将 IRQ 模式栈空间的 ARCH_REG_CTX 拷贝到当前任务 TCB 的 ARCH_REG_CTX 里; * 调整 SP_irq; */ADD     SP , SP , #(ARCH_REG_CTX_SIZE);/*; * 第一次进入中断: 获得当前 CPU 中断堆栈栈顶, 并回到 SYS 模式, 并设置 SP_sys; */LDR     R0 , =API_InterStackBaseGetMOV     LR , PCBX      R0MSR     CPSR_c, #(DIS_INT | SYS32_MODE)                             ;/*  回到 SYS 模式               */MOV     SP , R0                                                     ;/*  设置 SP_sys                 */1:MSR     CPSR_c, #(DIS_INT | SYS32_MODE)                             ;/*  回到 SYS 模式(不是多余的)   */;/*; * bspIntHandle(); */LDR     R1 , =bspIntHandleMOV     LR , PCBX      R1;/*; * API_InterExit(); * 如果没有发生中断嵌套, 则 API_InterExit 会调用 archIntCtxLoad 函数, SP_irq 在上面已经调整好; */LDR     R1 , =API_InterExitMOV     LR , PCBX      R1

  这里有一个很重要的点,API_InterStackBaseGet函数。因为 ARM 异常栈通常不会很大,而我们后面调用的 bspIntHandle 是一个 C 函数,需要用到堆栈。所以这里调用 API_InterStackBaseGet 函数设置了一个操作系统给每个 CPU 分配的中断堆栈。

LW_API
ULONG    API_InterEnter (ARCH_REG_T  reg0,ARCH_REG_T  reg1,ARCH_REG_T  reg2,ARCH_REG_T  reg3)
{PLW_CLASS_CPU  pcpu;pcpu = LW_CPU_GET_CUR();pcpu->CPU_ulInterNesting++;#if !defined(__SYLIXOS_ARM_ARCH_M__) || (LW_CFG_CORTEX_M_SVC_SWITCH > 0)archIntCtxSaveReg(pcpu, reg0, reg1, reg2, reg3);
#endif	......
}

这里要注意,中断上下文的保存,不仅仅需要保存到 ARM 架构的异常栈中,同时也需要保存一份,到当前任务 TCB 中。因为中断退出时(API_InterExit),会进行调度(_ScheduleInt)。所以无法保证中断结束后,一定运行的是之前被中断的任务,也有可能是其它高优先级任务。之前被中断的任务的上下文现场,必须要保存一份到它自己的 TCB 中!用于后面恢复!

  API_InterExit 函数中的 __KERNEL_SCHED_INT 会进行一系列判断,查找到需要切换的任务(不一定是之前被打断的任务),获得任务的 TCB 控制块。然后使用 archIntCtxLoad 函数进行任务上下文切换。

LW_API
VOID    API_InterExit (VOID)
{......__KERNEL_SCHED_INT(pcpu);											/*  中断中的调度                */......
#if !defined(__SYLIXOS_ARM_ARCH_M__) || (LW_CFG_CORTEX_M_SVC_SWITCH > 0)archIntCtxLoad(pcpu);                                               /*  中断返回 (当前任务 CTX 加载)*/
#endif......
}
FUNC_DEF(archTaskCtxStart)LDR     R0 , [R0]                                                   ;/*  获取当前 TCB 的 REG_CTX 地址*/LINE_LABEL(archTaskCtxLoad)LDMIA   R0!, {R2-R4}                                                ;/*  读取 CPSR LR SP             */MSR     CPSR_c , #(DIS_INT | SYS32_MODE)                            ;/*  进入 SYS 模式, 关中断       */MOV     SP , R4                                                     ;/*  恢复 SP_sys                 */MOV     LR , R3                                                     ;/*  恢复 LR_sys                 */MSR     CPSR_c, #(DIS_INT | SVC32_MODE)                             ;/*  进入 SVC 模式, 关中断       */MSR     SPSR_cxsf , R2                                              ;/*  CPSR_sys -> SPSR_svc        */LDMIA   R0 , {R0-R12, PC}^                                          ;/*  恢复包括 PC 的所有寄存器,   */;/*  同时更新 CPSR               */FUNC_END()FUNC_DEF(archIntCtxLoad)B       archTaskCtxStartFUNC_END()

2、内核退出时任务切换

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

INT  _Schedule (VOID)
{....../* 前面的调度已经找到了一个最适合在当前核上运行的任务,下面就是将该任务加载到当前 CPU 核的寄存器中 */archTaskCtxSwitch(pcpuCur);  ......
}
/*********************************************************************************************************
** 函数名称: __kernelExit
** 功能描述: 退出内核状态
** 输 入  : NONE
** 输 出  : 调度器返回值
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
INT  __kernelExit (VOID)
{......iRetVal = _Schedule();                                      /*  尝试调度                    */......
}

  首先是保存当前上下文,和进入中断时一样,保存当前 TCB 上下文。这里有一个很重要的点,_SchedSafeStack函数。因为是任务调度,所以使用的栈还是当前 TCB 的栈。因为我们下面需要调用 _SchedSwp C 函数,会用到栈,可能会破坏之前 TCB 的栈空间。所以我们需要调用 _SchedSafeStack函数来获取一个额外的堆栈空间。

  然后调用 _SchedSwp 程序进行切换当前 CPU 控制块的当前 TCB,然后进行上下文恢复。

;/*********************************************************************************************************
;  线程切换 
;  参数为当前 CPU 控制块, 即 R0 为当前 CPU 控制块指针
;*********************************************************************************************************/FUNC_DEF(archTaskCtxSwitch)LDR     R1 , [R0]                                                   ;/*  获取当前 TCB                */ADD     R1 , R1 , #(ARCH_REG_CTX_SIZE)                              ;/*  当前 TCB 的 REG_CTX 顶端地址*//* 保存当前 TCB 的上下文,保存到当前 TCB 中 */STMFD   R1!, {LR}                                                   ;/*  保存返回地址                */STMFD   R1 , {R0-R12}                                               ;/*  保存寄存器                  */SUB     R1 , R1 , #(13 * 4)                                         ;/*  调整 R1                     */STMFD   R1!, {SP}                                                   ;/*  保存 SP                     */STMFD   R1!, {LR}                                                   ;/*  保存 LR                     */MRS     R2 , CPSR                                                   ;/*  保存 CPSR                   */STMFD   R1!, {R2}MOV     R9 , R0                                                     ;/*  备份 R0                     */
#if LW_CFG_SMP_EN > 0LDR     R1 , =_SchedSafeStack                                       ;/*  _SchedSafeStack();          */MOV     LR , PCBX      R1MOV     SP , R0                                                     ;/*  设置 SP                     */MOV     R0 , R9                                                     ;/*  恢复 R0                     */
#endif;/* 这里会去切换当前 CPU 控制块的当前 TCB */LDR     R1 , =_SchedSwp                                             ;/*  _SchedSwp();                */MOV     LR , PCBX      R1MOV     R0 , R9                                                     ;/*  恢复 R0                     */;/* 因为刚刚已经切换过,这里直接恢复切换后的 TCB 上下文 */B       archTaskCtxStartFUNC_END()

archTaskCtxStart 这里和中断退出时恢复寄存器一样。

http://www.sczhlp.com/news/76343/

相关文章:

  • 做网站南京在线免费logo设计网站
  • 个人能否做网站惠州惠城网站建设
  • 淘宝客网站一定要备案吗阿里巴巴跟建设网站的区别
  • 网站建设 技术架构成免费crm软件下载
  • 一般做网站价格百度账号购买1元40个
  • 福建住房和城乡建设局网站浙江省建设工程质量安全管理协会网站
  • 织梦框架做网站简单宁波网站制作工作室
  • 嘉兴建设企业网站百度竞价排名算法
  • 建网站松滋哪家强?wordpress 好用的插件
  • 重庆官方网站有哪些阿里云学生服务器购买
  • 查网站开发者丽江网页制作
  • 涂料网站设计公司广州互帮物流哪家公司做的网站
  • 无备案网站加速怎么做游戏和网站漏洞
  • 网站后台怎么做下载链接seo优化心得
  • Linux系统构成与shell核心知识
  • wordpress怎样搭建网站用手机域名做网站有多少
  • 学校网站网页模板网站怎么做百度的关键字
  • 海淀做网站学网站建设要多少钱
  • 项目案例 化妆品网站网站有利于seo的细节
  • 手机网站建设的影响票务网站模板
  • 免费制作单页的网站怎么做宣传
  • 太原网站建设 网站制作网站建设自助建站
  • 网站模板可以自己做吗王一博网页制作模板
  • 最全DIY嵌入式智能手表 | STM32可编程多功能手表 [开源分享]
  • 加速板子
  • 镇江网站建设教程怎让做淘宝网站
  • 百度有没有做游戏下载网站吗wordpress seo代码
  • 知道网站是wp程序做的如何仿站网站关键词库如何做
  • 上海做网站公wordpress必须先登录
  • 麻栗坡网站建设网站没后台怎么修改类容