当前位置:   article > 正文

5.2.鸿蒙LiteOS-M los_dispatch

5.2.鸿蒙LiteOS-M los_dispatch

请添加图片描述

一、cortex-m4 los_dispatch.S代码分析

.syntax unified     #.syntax [unified | divided], 指定arm 汇编语法规则
.arch armv7e-m      #指定平台, 与命令行参数-march同样的作用
.fpu fpv4-sp-d16    #指定浮点运算单元,与命令行参数-mfpu同样的作用
.thumb              # .thumb伪操作等同于.code 16, 表明使用Thumb指令

# .equ 定义静态符号,把常量值设置为可以在文本段中使用的符号
.equ    OS_FPU_CPACR,                0xE000ED88
.equ    OS_FPU_CPACR_ENABLE,         0x00F00000
.equ    OS_NVIC_INT_CTRL,            0xE000ED04
.equ    OS_NVIC_SYSPRI2,             0xE000ED20
.equ    OS_NVIC_PENDSV_PRI,          0xF0F00000
.equ    OS_NVIC_PENDSVSET,           0x10000000
.equ    OS_TASK_STATUS_RUNNING,      0x0010
.equ    OS_CONTROL_FPCA_ENABLE,      0x4
.equ    OS_CONTROL_KERNEL_MODE,      0x2
#if (LOSCFG_SECURE == 1)
.equ    OS_CONTROL_USER_MODE,        0x3
.equ    OS_TASK_FLAG_USER_TASK,      0x0200
#endif

    .section .text      # 后面那些指令都属于.text段
    .thumb
    

# .macro/.endm 定义一个宏,可以把需要重复执行的一段代码,或者是一组指令缩写成一个宏,
# 在程序调用的时候就可以直接去调用这个宏而使代码更加简洁清晰
.macro SIGNAL_CONTEXT_RESTORE
    push    {r12, lr}
    blx     OsSignalTaskContextRestore
    pop     {r12, lr}
    cmp     r0, #0
    mov     r1, r0
    bne     SignalContextRestore
.endm

    .type HalStartToRun, %function  # HalStartToRun 类型为函数
    .global HalStartToRun           # 声明全局符号。全局符号是指在本程序外可访问的符号
HalStartToRun:                      # 
    .fnstart                        # 函数开始
    .cantunwind                     # 可以被栈回溯

    # ldr Rt, label     从label加载一个字到寄存器Rt中
    # str Rt, label     从地址Rt读取一个字到label中
    # [Rt]表示读取地址Rt处数据
    ldr     r4, =OS_NVIC_SYSPRI2        # 加载OS_NVIC_SYSPRI2 符号到寄存器r4中
    ldr     r5, =OS_NVIC_PENDSV_PRI     # 加载OS_NVIC_PENDSV_PRI 符号到寄存器r4中
    str     r5, [r4]                    # 读取地址r5处一个字数据,到r4地址中
    # 以上3条指令等效于:*((volatile u32 *)0xE000ED20) = 0xF0F00000
    # 设置PENDSV优先级为最低

    # 给寄存器传递一个立即数,此时需要用“#”来修饰立即数,并且立即数为8位的,其值不能超过255.
    # 特殊寄存器必须用MRS(),MSR 指令访问
    # MRS <gp_reg>, <special_reg> ;读特殊功能寄存器的值到通用寄存器
    # MSR <special_reg>, <gp_reg> ;写通用寄存器的值到特殊功能寄存器
    mov     r0, #OS_CONTROL_KERNEL_MODE 
    msr     CONTROL, r0     # 将r0数据写入CONTROL特殊寄存器中
    # 以上2条指令完成,sp使用进程堆栈指针


    ldr     r1, =g_losTask      # 将g_losTask结构体变量地址加载到r1中
    ldr     r0, [r1, #4]        # 将g_losTask.newTask地址加载到r1中,r1此时为newTask的TaskCB的内存地址
    ldr     r12, [r0]           # g_losTask->newTask->stackPointer加载到寄存器r12
    # g以上3条指令完成,任务上下文加载

    ldr.w   r1, =OS_FPU_CPACR
    ldr     r1, [r1]
    and     r1, r1, #OS_FPU_CPACR_ENABLE
    cmp     r1, #OS_FPU_CPACR_ENABLE
    bne     __DisabledFPU           # if(r1 != 0) 执行__DisabledFPU符号位指令
    add     r12, r12, #100

    ldmfd   r12!, {R0-R7}
    add     r12, r12, #72
    msr     psp, r12
    vpush   {s0}
    vpop    {s0}
    mov     lr, r5
    cpsie   i
    bx      r6

__DisabledFPU:
    add     r12, r12, #36       # 加载数据变为context->uwR0 = taskID;

    ldmfd   r12!, {r0-r7}       # 加载context->uwR0~context->uwxPSR 到 r0-r7中
    msr     psp, r12            # 加载r12地址中一个字到psp中
    mov     lr, r5              # 加载r5 context->uwLR到lr寄存器中
    cpsie   I                   # 开中断
    bx      r6                  # pc跳转到context->uwPC

    .fnend                  # HalStartToRun end

    .type ArchIntLock, %function
    .global ArchIntLock
ArchIntLock:                    # 关闭中断
    .fnstart
    .cantunwind

    MRS R0, PRIMASK             # 读取寄存器PRIMASK到R0中
    CPSID I                     # 关中断
    BX LR                       # 返回
    .fnend

    .type ArchIntUnLock, %function
    .global ArchIntUnLock
ArchIntUnLock:                  # 开中断
    .fnstart
    .cantunwind

    MRS R0, PRIMASK             # 读取寄存器PRIMASK到R0中
    CPSIE I                     # 开中断
    BX LR                       # 返回
    .fnend

    .type ArchIntRestore, %function
    .global ArchIntRestore
ArchIntRestore:
    .fnstart
    .cantunwind

    MSR PRIMASK, R0             # 读取R0数据到PRIMAK
    BX LR                       # 返回
    .fnend

    .type ArchTaskSchedule, %function
    .global ArchTaskSchedule
ArchTaskSchedule:
    .fnstart
    .cantunwind

    ldr     r0, =OS_NVIC_INT_CTRL
    ldr     r1, =OS_NVIC_PENDSVSET
    str     r1, [r0]            # 悬起pendSV
    bx      lr                  # 返回
    dsb                         # 数据同步屏障,确保在下一条指令开始执行前,所有的存储器访问已经完成。
    isb                         # 指令同步屏障,清除流水线并且确保在新指令执行时,之前的指令都已经执行完毕。
    .fnend

    .type HalPendSV, %function
    .global HalPendSV
HalPendSV:                      # pendSV实现函数
    .fnstart
    .cantunwind

    mrs     r12, PRIMASK        # 加载PRIMASK寄存器到r12
    cpsid   I                   # 关中断

HalTaskSwitch:
    SIGNAL_CONTEXT_RESTORE

    push    {r12, lr}
    blx     OsSchedTaskSwitch   # 跳转执行任务切换
    pop     {r12, lr}
    cmp     r0, #0
    mov     r0, lr
    bne     TaskContextSwitch   # 如果cmp r0, #0 执行不等于0时,跳转执行任务上下文切换
    msr     PRIMASK, r12        # 开中断
    bx      lr                  # 若不切换任务上下文,则直接返回

TaskContextSwitch:
    mov     lr, r0
    mrs     r0, psp             # 任务栈指针保存到r0

    stmfd   r0!, {r4-r12}       # r4-r12数据存入任务栈
    ldr.w   r3, =OS_FPU_CPACR
    ldr     r3, [r3]
    and     r3, r3, #OS_FPU_CPACR_ENABLE
    cmp     r3, #OS_FPU_CPACR_ENABLE
    bne     __DisabledFPU1
    vstmdb  r0!, {d8-d15}       # 如果支持浮点寄存器时,把d8-d15压入栈中。

__DisabledFPU1:
    ldr     r5, =g_losTask      # 把g_losTask地址加载到r5
    ldr     r6, [r5]            # 获取当前运行任务栈指针,然后更新当前运行的任务栈指针。
    str     r0, [r6]

    ldr     r0, [r5, #4]        # 获取新任务newTask的地址,
    str     r0, [r5]            # 把newTask地址赋值到runTask
    ldr     r1, [r0]            # newTask地址赋值到r1

SignalContextRestore:
    ldr.w   r3, =OS_FPU_CPACR
    ldr     r3, [r3]
    and     r3, r3, #OS_FPU_CPACR_ENABLE
    cmp     r3, #OS_FPU_CPACR_ENABLE
    bne     __DisabledFPU2
    vldmia  r1!, {d8-d15}

__DisabledFPU2:
#if (LOSCFG_SECURE == 1)
    ldrh    r7, [r0, #4]
    tst     r7, #OS_TASK_FLAG_USER_TASK
    ite     eq
    moveq   r3, #OS_CONTROL_KERNEL_MODE
    movne   r3, #OS_CONTROL_USER_MODE
    msr     CONTROL, r3
#endif
    ldmfd   r1!, {r4-r12}       # 加载newTask任务栈数据到r4-r12中
    msr     psp,  r1            # 更新任务栈指针为newTask任务栈地址

    msr     PRIMASK, r12        # 开中断

    bx      lr                  # 返回
    .fnend


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205

坚持就有收获

请添加图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/171630
推荐阅读
相关标签
  

闽ICP备14008679号