sis地址获取器_TencentOS tiny深度源码分析(2)—— 调度器

温馨提示:本文不描述与浮点相关的寄存器的内容,如需了解自行查阅

调度器的基本概念

TencentOS tiny中提供的任务调度器是基于优先级的全抢占式调度,在系统运行过程中,当有比当前任务优先级更高的任务就绪时,当前任务将立刻被切出,高优先级任务抢占处理器运行。

TencentOS tiny内核中也允许创建相同优先级的任务。相同优先级的任务采用时间片轮转方式进行调度(也就是通常说的分时调度器),时间片轮转调度仅在当前系统中无更高优先级就绪任务的情况下才有效。

为了保证系统的实时性,系统尽最大可能地保证高优先级的任务得以运行。任务调度的原则是一旦任务状态发生了改变,并且当前运行的任务优先级小于优先级队列中任务最高优先级时,立刻进行任务切换(除非当前系统处于中断处理程序中或禁止任务切换的状态)。

调度器是操作系统的核心,其主要功能就是实现任务的切换,即从就绪列表里面找到优先级最高的任务,然后去执行该任务。

启动调度器

调度器的启动由cpu_sched_start函数来完成,它会被tos_knl_start函数调用,这个函数中主要做两件事,首先通过readyqueue_highest_ready_task_get函数获取当前系统中处于最高优先级的就绪任务,并且将它赋值给指向当前任务控制块的指针k_curr_task,然后设置一下系统的状态为运行态KNL_STATE_RUNNING

当然最重要的是调用汇编代码写的函数cpu_sched_start启动调度器,该函数在源码的arch\arm\arm-v7m目录下的port_s.S汇编文件下,TencentOS tiny支持多种内核的芯片,如M3/M4/M7等,不同的芯片该函数的实现方式不同,port_s.S也是TencentOS tiny作为软件与CPU硬件连接的桥梁。以M4的cpu_sched_start举个例子:

__API__ k_err_t tos_knl_start(void)
{
    if (tos_knl_is_running()) {
        return K_ERR_KNL_RUNNING;
    }

    k_next_task = readyqueue_highest_ready_task_get();
    k_curr_task = k_next_task;
    k_knl_state = KNL_STATE_RUNNING;
    cpu_sched_start();

    return K_ERR_NONE;
}
port_sched_start
    CPSID   I    

    ; set pendsv priority lowest
    ; otherwise trigger pendsv in port_irq_context_switch will cause a context swich in irq
    ; that would be a disaster
    MOV32   R0, NVIC_SYSPRI14
    MOV32   R1, NVIC_PENDSV_PRI
    STRB    R1, [R0]

    LDR     R0, =SCB_VTOR
    LDR     R0, [R0]
    LDR     R0, [R0]
    MSR     MSP, R0

    ; k_curr_task = k_next_task
    MOV32   R0, k_curr_task
    MOV32   R1, k_next_task
    LDR     R2, [R1]
    STR     R2, [R0]

    ; sp = k_next_task->sp
    LDR     R0, [R2]
    ; PSP = sp
    MSR     PSP, R0

    ; using PSP
    MRS     R0, CONTROL
    ORR     R0, R0, #2
    MSR     CONTROL, R0

    ISB

    ; restore r4-11 from new process stack
    LDMFD   SP!, {R4 - R11}

    IF {FPU} != "SoftVFP"
    ; ignore EXC_RETURN the first switch
    LDMFD   SP!, {R0}
    ENDIF

    ; restore r0, r3
    LDMFD    SP!, {R0 - R3}
    ; load R12 and LR
    LDMFD    SP!, {R12, LR}
    ; load PC and discard xPSR
    LDMFD    SP!, {R1, R2}

    CPSIE    I
    BX       R1

Cortex-M内核关中断指令

从上面的汇编代码,我又想介绍一下Cortex-M内核关中断指令,唉~感觉还是有点麻烦!
为了快速地开关中断, Cortex-M内核专门设置了一条 CPS 指令,用于操作PRIMASK寄存器跟FAULTMASK寄存器的,这两个寄存器是与屏蔽中断有关的,除此之外Cortex-M内核还存在BASEPRI寄存器也是与中断有关的,也顺带介绍一下吧。

CPSID I     ;PRIMASK=1     ;关中断
CPSIE I     ;PRIMASK=0     ;开中断
CPSID F     ;FAULTMASK=1   ;关异常
CPSIE F     ;FAULTMASK=0   ;开异常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值