Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
鸿蒙内核源码分析
注释鸿蒙内核源码
提交
95734ecf
注释鸿蒙内核源码
项目概览
鸿蒙内核源码分析
/
注释鸿蒙内核源码
通知
270
Star
29
Fork
11
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
106
Wiki
分析
仓库
DevOps
项目成员
Pages
注释鸿蒙内核源码
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
106
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
95734ecf
编写于
3月 16, 2021
作者:
鸿蒙内核源码分析
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
注解汇编代码如何保存任务上下文
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
上级
361754bf
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
22 addition
and
22 deletion
+22
-22
arch/arm/arm/src/include/los_hw_pri.h
arch/arm/arm/src/include/los_hw_pri.h
+1
-1
arch/arm/arm/src/los_dispatch.S
arch/arm/arm/src/los_dispatch.S
+7
-7
arch/arm/arm/src/los_hw.c
arch/arm/arm/src/los_hw.c
+5
-5
kernel/base/core/los_task.c
kernel/base/core/los_task.c
+4
-4
kernel/base/include/los_task_pri.h
kernel/base/include/los_task_pri.h
+4
-4
zzz/git/push.sh
zzz/git/push.sh
+1
-1
未找到文件。
arch/arm/arm/src/include/los_hw_pri.h
浏览文件 @
95734ecf
...
...
@@ -51,7 +51,7 @@ extern "C" {
/* The size of this structure must be smaller than or equal to the size specified by OS_TSK_STACK_ALIGN (16 bytes). */
typedef
struct
{
//参考OsTaskSchedule来理解
#if !defined(LOSCFG_ARCH_FPU_DISABLE)
#if !defined(LOSCFG_ARCH_FPU_DISABLE)
//支持浮点运算
UINT64
D
[
FP_REGS_NUM
];
/* D0-D31 */
UINT32
regFPSCR
;
/* FPSCR */
UINT32
regFPEXC
;
/* FPEXC */
...
...
arch/arm/arm/src/los_dispatch.S
浏览文件 @
95734ecf
...
...
@@ -134,12 +134,12 @@ LDM/STR架构中{∧}为可选后缀,当指令为LDM且寄存器列表中包含R
/*
macros
to
save
and
restore
fpu
regs
*/
.
macro
PUSH_FPU_REGS
reg1
/*
保存
fpu
寄存器
*/
#if !defined(LOSCFG_ARCH_FPU_DISABLE) @FPU使能
VMRS
\
reg1
,
FPEXC
PUSH
{
\
reg1
}
VMRS
\
reg1
,
FPSCR
PUSH
{
\
reg1
}
VMRS
\
reg1
,
FPEXC
PUSH
{
\
reg1
}
@
对应
TaskContext
->
regFPEXC
VMRS
\
reg1
,
FPSCR
PUSH
{
\
reg1
}
@
对应
TaskContext
->
regFPSCR
#if defined(LOSCFG_ARCH_FPU_VFP_D32)
VPUSH
{
D16
-
D31
}
VPUSH
{
D16
-
D31
}
@
对应
TaskContext
->
D
#
endif
VPUSH
{
D0
-
D15
}
#
endif
...
...
@@ -200,14 +200,14 @@ OsTaskSchedule: /*任务调度,OsTaskSchedule的目的是将寄存器值按Tas
PUSH_FPU_REGS
R2
/*
保存
fpu
寄存器
*/
/
*
store
sp
on
running
task
*/
STR
SP
,
[
R1
]
@
在运行的任务栈中保存
SP
,
即
runTask
->
stackPointer
=
sp
STR
SP
,
[
R1
]
@
在运行的任务栈中保存
SP
,
即
*
runTask
->
stackPointer
=
sp
OsTaskContextLoad
:
@加载上下文
/
*
clear
the
flag
of
ldrex
*/
@
LDREX
可从内存加载数据
,
如果物理地址有共享
TLB
属性,则
LDREX
会将该物理地址标记为由当前处理器独占访问,并且会清除该处理器对其他任何物理地址的任何独占访问标记。
CLREX
@
清除
ldrex
指令的标记
/
*
switch
to
new
task
's sp */
LDR
SP
,
[
R0
]
@
即:
sp
=
new
task
->
stackPointer
LDR
SP
,
[
R0
]
@
即:
sp
=
*
task
->
stackPointer
/
*
restore
fpu
registers
*/
POP_FPU_REGS
R2
@
恢复
fpu
寄存器
,
这里用了汇编宏
R2
是宏的参数
...
...
arch/arm/arm/src/los_hw.c
浏览文件 @
95734ecf
...
...
@@ -74,7 +74,7 @@ VOID OsTaskEntrySetupLoopFrame(UINT32 arg0)
"
\t
pop {fp, pc}
\n
"
);
}
#endif
//
任务栈初始化,非常重要的函数
//
内核态运行栈初始化
LITE_OS_SEC_TEXT_INIT
VOID
*
OsTaskStackInit
(
UINT32
taskID
,
UINT32
stackSize
,
VOID
*
topStack
,
BOOL
initFlag
)
{
UINT32
index
=
1
;
...
...
@@ -83,7 +83,7 @@ LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOI
if
(
initFlag
==
TRUE
)
{
OsStackInit
(
topStack
,
stackSize
);
}
taskContext
=
(
TaskContext
*
)(((
UINTPTR
)
topStack
+
stackSize
)
-
sizeof
(
TaskContext
));
//
注意看上下文将
存放在栈的底部
taskContext
=
(
TaskContext
*
)(((
UINTPTR
)
topStack
+
stackSize
)
-
sizeof
(
TaskContext
));
//
上下文
存放在栈的底部
/* initialize the task context */
//初始化任务上下文
#ifdef LOSCFG_GDB
...
...
@@ -94,10 +94,10 @@ LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOI
taskContext
->
LR
=
(
UINTPTR
)
OsTaskExit
;
/* LR should be kept, to distinguish it's THUMB or ARM instruction */
taskContext
->
resved
=
0x0
;
taskContext
->
R
[
0
]
=
taskID
;
/* R0 */
taskContext
->
R
[
index
++
]
=
0x01010101
;
/* R1, 0x01010101 : reg initialed magic word */
taskContext
->
R
[
index
++
]
=
0x01010101
;
/* R1, 0x01010101 : reg initialed magic word */
//0x55
for
(;
index
<
GEN_REGS_NUM
;
index
++
)
{
//R2 - R12的初始化很有意思,为什么要这么做?
taskContext
->
R
[
index
]
=
taskContext
->
R
[
index
-
1
]
+
taskContext
->
R
[
1
];
/* R2 - R12 */
}
}
//R[2]=R[2]<<1=0xAA
#ifdef LOSCFG_INTERWORK_THUMB // 16位模式
taskContext
->
regPSR
=
PSR_MODE_SVC_THUMB
;
/* CPSR (Enable IRQ and FIQ interrupts, THUMNB-mode) */
...
...
@@ -127,7 +127,7 @@ LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *
(
VOID
)
memcpy_s
(
childTaskCB
->
stackPointer
,
sizeof
(
TaskContext
),
cloneStack
,
sizeof
(
TaskContext
));
//直接把任务上下文拷贝了一份
context
->
R
[
0
]
=
0
;
//R0寄存器为0
}
//用户
任务使用
栈初始化
//用户
态运行
栈初始化
LITE_OS_SEC_TEXT_INIT
VOID
OsUserTaskStackInit
(
TaskContext
*
context
,
TSK_ENTRY_FUNC
taskEntry
,
UINTPTR
stack
)
{
LOS_ASSERT
(
context
!=
NULL
);
...
...
kernel/base/core/los_task.c
浏览文件 @
95734ecf
...
...
@@ -762,12 +762,12 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB,
const
VOID
*
topStack
,
const
TSK_INIT_PARAM_S
*
initParam
)
{
taskCB
->
stackPointer
=
(
VOID
*
)
stackPtr
;
taskCB
->
stackPointer
=
(
VOID
*
)
stackPtr
;
//内核态SP位置
taskCB
->
args
[
0
]
=
initParam
->
auwArgs
[
0
];
/* 0~3: just for args array index */
taskCB
->
args
[
1
]
=
initParam
->
auwArgs
[
1
];
taskCB
->
args
[
2
]
=
initParam
->
auwArgs
[
2
];
taskCB
->
args
[
3
]
=
initParam
->
auwArgs
[
3
];
taskCB
->
topOfStack
=
(
UINTPTR
)
topStack
;
//内核态栈
顶
位置
taskCB
->
topOfStack
=
(
UINTPTR
)
topStack
;
//内核态栈
起始
位置
taskCB
->
stackSize
=
initParam
->
uwStackSize
;
//
taskCB
->
priority
=
initParam
->
usTaskPrio
;
taskCB
->
taskEntry
=
initParam
->
pfnTaskEntry
;
...
...
@@ -809,7 +809,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_IN
SCHEDULER_LOCK
(
intSave
);
processCB
=
OS_PCB_FROM_PID
(
initParam
->
processID
);
//通过ID获取PCB ,单核进程数最多64个
taskCB
->
processID
=
processCB
->
processID
;
//进程-线程的父子关系绑定
mode
=
processCB
->
processMode
;
//
调度
方式同步process
mode
=
processCB
->
processMode
;
//
模式
方式同步process
LOS_ListTailInsert
(
&
(
processCB
->
threadSiblingList
),
&
(
taskCB
->
threadList
));
//挂入进程的线程链表
if
(
mode
==
OS_USER_MODE
)
{
//用户模式
taskCB
->
userArea
=
initParam
->
userParam
.
userArea
;
...
...
@@ -887,7 +887,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S
goto
LOS_ERREND_REWIND_TCB
;
}
//OsTaskStackAlloc 只在LOS_TaskCreateOnly中被调用,此处是分配任务在内核态栈空间
OsTaskStackAlloc
(
&
topStack
,
initParam
->
uwStackSize
,
pool
);
//为任务
栈分配
空间
OsTaskStackAlloc
(
&
topStack
,
initParam
->
uwStackSize
,
pool
);
//为任务
分配内核态栈
空间
if
(
topStack
==
NULL
)
{
errRet
=
LOS_ERRNO_TSK_NO_MEMORY
;
goto
LOS_ERREND_REWIND_SYNC
;
...
...
kernel/base/include/los_task_pri.h
浏览文件 @
95734ecf
...
...
@@ -145,7 +145,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
*
* The time for waiting for an event to occur expires.
*/
#define OS_TASK_STATUS_TIMEOUT 0x0040U
#define OS_TASK_STATUS_TIMEOUT 0x0040U
//任务超时
/**
* @ingroup los_task
...
...
@@ -294,13 +294,13 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
#define OS_TCB_NAME_LEN 32
typedef
struct
{
VOID
*
stackPointer
;
/**< Task stack pointer */
//
用于保存任务上下文TaskContext *context
VOID
*
stackPointer
;
/**< Task stack pointer */
//
内核态栈指针,SP位置,切换任务时先保存上下文并指向TaskContext位置.
UINT16
taskStatus
;
/**< Task status */
//各种状态标签,可以拥有多种标签,按位标识
UINT16
priority
;
/**< Task priority */
//任务优先级[0:31],默认是31级
UINT16
policy
;
//任务的调度方式(三种 .. LOS_SCHED_RR )
UINT16
timeSlice
;
/**< Remaining time slice */
//剩余时间片
UINT32
stackSize
;
/**< Task stack size */
//
非用户模式下
栈大小
UINTPTR
topOfStack
;
/**< Task stack top */
//
非用户模式下的
栈顶 bottom = top + size
UINT32
stackSize
;
/**< Task stack size */
//
内核态
栈大小
UINTPTR
topOfStack
;
/**< Task stack top */
//
内核态
栈顶 bottom = top + size
UINT32
taskID
;
/**< Task ID */
//任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128
TSK_ENTRY_FUNC
taskEntry
;
/**< Task entrance function */
//任务执行入口函数
VOID
*
joinRetval
;
/**< pthread adaption */
//用来存储join线程的返回值
...
...
zzz/git/push.sh
浏览文件 @
95734ecf
git add
-A
git commit
-m
'注解汇编代码如何保
持
任务上下文
git commit
-m
'注解汇编代码如何保
存
任务上下文
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录