首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
SAAS
ToB门户
了解全球最新的ToB事件
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
微博
Follow
记录
Doing
博客
Blog
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
排行榜
Ranklist
相册
Album
应用中心
qidao123.com ToB IT社区-企服评测·应用市场
»
论坛
›
数据库
›
SQL-Server
›
鸿蒙内核源码分析(任务切换篇) | 看汇编怎样切换任务 ...
返回列表
发新帖
鸿蒙内核源码分析(任务切换篇) | 看汇编怎样切换任务
[复制链接]
发表于 2026-2-4 15:51:50
|
显示全部楼层
|
阅读模式
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
×
在鸿蒙的内核线程就是任务,系列篇中说的任务和线程当一个东西去明确.
一样平常二种场景下须要切换任务上下文:
在线程环境下,从当火线程切换到目标线程,这种方式也称为软切换,能由软件控制的自主式切换.哪些环境下会出现软切换呢?
运行的线程申请某种资源(好比各种锁,读/写消息队列)失败时,须要自动开释CPU的控制权,将自己挂入等候队列,调理算法重新调理新任务运行.
每隔10ms就实行一次的OsTickHandler节奏处置惩罚函数,检测到任务的时间片用完了,就发起任务的重新调理,切换到新任务运行.
不管是内核态的任务照旧用户态的任务,于切换而言是同一处置惩罚,等量齐观的,由于切换是须要换栈运行,寄存器有限,须要频仍的复用,这就须要将当前寄存器值老师存到任务自己的栈中,以便别人用完了轮到自己再用时规复寄存器其时的值,确保老任务还能继续跑下去. 而生存寄存器次序的布局体叫:任务上下文(TaskContext).
在停止环境下,从当火线程切换到目标线程,这种方式也称为硬切换.不由软件控制的被动式切换.哪些环境下会出现硬切换呢?
由硬件产生的停止,好比 鼠标,键盘外部装备每次点击和敲打,屏幕的触摸,USB的插拔等等这些都是硬停止.同样的须要切换栈运行,须要复用寄存器,但与软切换不一样的是,硬切换会切换工作模式(停止模式).以是会更复杂点,但原理照旧一样要生存和规复切换现场寄存器的值, 而生存寄存器次序的布局体叫:任务停止上下文(TaskIrqContext).
本篇详细说清楚以下几个题目:
任务上下文(TaskContext)怎么生存的?
代码
的实现细节是怎样的?
怎样包管切换不会发生错误,指令不会丢失?
前置条件
一个任务要跑起来,须要两个必不可少的硬性条件:
1.从
代码
段哪个位置取指令? 也就是入口所在,main函数是应用步调的入口所在, 留意main函数也是一个线程,只是不须要你来new而已,加载步调阶段会默认创建好. run()是new一个线程实行的入口所在.高级语言是这么叫,但到了汇编层的叫法就是PC寄存器.给PC寄存器赋什么值,指令就从那边开始实行.
2.运行的园地(栈空间)在那边? ARM有7种工作模式,到了历程层面只须要思量内核模式和用户模式两种,对应到任务会有内核态栈空间和用户态栈空间.内核模式的任务只有内核态的栈空间,用户模式任务二者都有.栈空间是在初始化一个任务时就分配指定好的.以下是两种栈空间的初始化过程.为了简洁省去了部分
代码
,留下了核心部分.
//任务控制块中对两个栈空间的描述
typedef struct {
VOID *stackPointer; /**< Task stack pointer */ //内核态栈指针,SP位置,切换任务时先保存上下文并指向TaskContext位置.
UINT32 stackSize; /**< Task stack size */ //内核态栈大小
UINTPTR topOfStack; /**< Task stack top */ //内核态栈顶 bottom = top + size
// ....
UINTPTR userArea; //使用区域,由运行时划定,根据运行态不同而不同
UINTPTR userMapBase; //用户态下的栈底位置
UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
} LosTaskCB;
复制代码
<hr>
//内核态运行栈初始化
LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag)
{
UINT32 index = 1;
TaskContext *taskContext = NULL;
taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext));//上下文存放在栈的底部
/* initialize the task context */ //初始化任务上下文
taskContext->PC = (UINTPTR)OsTaskEntry;//程序计数器,CPU首次执行task时跑的第一条指令位置
taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */
复制代码
回复
使用道具
举报
返回列表
浏览过的版块
分布式数据库
Oracle
linux
SAAS
物联网
Java
IOS
云原生
DevOps与敏捷开发
惊雷无声
+ 我要发帖
登录后关闭弹窗
登录参与点评抽奖 加入IT实名职场社区
去登录
微信订阅号
微信服务号
微信客服(加群)
H5
小程序
快速回复
返回顶部
返回列表