启动之OS_CPU_C
在uC/OS-II中,任务是一个无限循环,任务之间也不会互相调用,但是uC/OS-II总是执行优先级最高的任务,假定当前有一个更高优先级的任务进入就绪状态,为了保证原来低优先级任务的完整性,uC/OS-II为每个任务建立了任务堆栈,就相当于函数调用时保存返回地址和参数一样,用来保存当前任务的状态,保证任务切换能和函数调用一样正确.只不过函数调用时函数堆栈的操作过程是编译器自动完成的,而任务切换时需要模拟一个和编译器类似的任务堆栈的操作过程.
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
INT16U *stk;
opt = opt; /* 'opt' is not used, prevent warning */
//堆栈栈顶指针
stk = (INT16U *)ptos; /* Load stack pointer */
//堆栈有高地址往低地址增长,故使用*stk--
//pada参数
//假定pdata会被编译器保存到堆栈中,OSTaskStkInit()就会模仿编译器的这种行为,将pdata保存到堆栈中.
*stk-- = (INT16U)FP_SEG(pdata); /* Simulate call to function with argument */
*stk-- = (INT16U)FP_OFF(pdata);
//任务起始地址.理论上,此处应该为任务的返回地址,但在uC/OS-II中,任务函数必须为无限循环结构,不能有返回点
*stk-- = (INT16U)FP_SEG(task);
*stk-- = (INT16U)FP_OFF(task);
/*
PC:是你退出的当时执行程序时program counter,相当于你放下手中的事A去进行另一庄事情B,你得记住之前A事情已经做到什么阶段了,也许B事情你得花上1年2年
PSW:是program status word.同样道理,你开始做B事情的时候必须记住A事情的大致情况status.
堆栈:stack memory就像是一本旧的笔记本,记下A事情的各种问题,以便以后再做A事情,如果又有一个C事情,那B事情也得记到stack memory中
psw指程序状态字(program status word的缩写),是用来控制指令执行顺序并且保留和指示与程序相关的系统状态.
一般说来,程序状态字包含程序基本状态、中断码、中断屏蔽位三部分内容.
基本状态包括:指令地址,条件码,目态管态,等待计算
中断码:保存程序执行时当前发生的中断事件,以便操作系统进行分析处理
中断屏蔽位:用来指出不要响应出现的中断事件,若设置了中断屏蔽位,则即使出现了中断事件也不中止程序的执行,就像没有发生中断事件一样
*/
//中断使能-PSW状态字-0000 0010 0000 0010即
//堆栈中的SW初始化为0x0202,这将使任务启动后允许中断发生;如果设为0x0002,则任务启动后将禁止中断
*stk-- = (INT16U)0x0202; /* SW = Interrupts enabled */
//堆栈顶端放置指向任务代码的指针
*stk-- = (INT16U)FP_SEG(task); /* Put pointer to task on top of stack */
*stk-- = (INT16U)FP_OFF(task);
//注意寄存器在堆栈中的位置要和运行指令PUSHA,PUSH ES,和PUSH DS和压入堆栈的次序相同
//AX,BX,CX,DX,SP,BP,SI,和DI的次序是和指令PUSHA的压栈次序相同的.如果使用没有PUSHA指令的8086处理器,就要使用多个PUSH指令压入上述寄存器,且顺序要与PUSHA相同
//AX……的值在任务运行前无所谓的,因为在任务运行后在这些寄存器会有新的需要的值,写0xAAAA……是为了堆栈的这个位置是AX……,其实用其他的值也行
*stk-- = (INT16U)0xAAAA; /* AX = 0xAAAA */
*stk-- = (INT16U)0xCCCC; /* CX = 0xCCCC */
*stk-- = (INT16U)0xDDDD; /* DX = 0xDDDD */
*stk-- = (INT16U)0xBBBB; /* BX = 0xBBBB */
*stk-- = (INT16U)0x0000; /* SP = 0x0000 */
*stk-- = (INT16U)0x1111; /* BP = 0x1111 */
*stk-- = (INT16U)0x2222; /* SI = 0x2222 */
*stk-- = (INT16U)0x3333; /* DI = 0x3333 */
*stk-- = (INT16U)0x4444; /* ES = 0x4444 */
*stk = _DS; /* DS = Current value of DS */
return ((OS_STK *)stk);
}
//浮点仿真任务栈初始化函数 OSTaskStkInit_FPE_x86(),其中将分段寻址的地址转换为线性地址
void OSTaskStkInit_FPE_x86 (OS_STK **pptos, OS_STK **ppbos, INT32U *psize)
{
INT32U lin_tos; /* 'Linear' version of top-of-stack address */
INT32U lin_bos; /* 'Linear' version of bottom-of-stack address */
INT16U seg;
INT16U off;
INT32U bytes;
seg = FP_SEG(*pptos); /* Decompose top-of-stack pointer into seg:off */
off = FP_OFF(*pptos);
lin_tos = ((INT32U)seg << 4) + (INT32U)off; /* Convert seg:off to linear address */
bytes = *psize * sizeof(OS_STK); /* Determine how many bytes for the stack */
lin_bos = (lin_tos - bytes + 15) & 0xFFFFFFF0L; /* Ensure paragraph alignment for BOS */
seg = (INT16U)(lin_bos >> 4); /* Get new 'normalized' segment */
*ppbos = (OS_STK *)MK_FP(seg, 0x0000); /* Create 'normalized' BOS pointer */
memcpy(*ppbos, MK_FP(_SS, 0), 384); /* Copy FP emulation memory to task's stack */
bytes = bytes - 16; /* Loose 16 bytes because of alignment */
*pptos = (OS_STK *)MK_FP(seg, (INT16U)bytes); /* Determine new top-of-stack */
*ppbos = (OS_STK *)MK_FP(seg, 384); /* Determine new bottom-of-stack */
bytes = bytes - 384;
*psize = bytes / sizeof(OS_STK); /* Determine new stack size */
}
启动之OS_CPU_C相关推荐
- os_cpu_c.c
定位到源码的uCOS-II/Ports/ARM-Cortex-M3/Generic/IAR/os_cpu_c.c: os_cpu_c.c定义了9个钩子(Hook)函数和一个堆栈初始化函数. ...
- 启动ucosii之四OSTaskCreate()
函数原型来自OS_TASK.C /*********************************************************************************** ...
- linux环境下nacos的安装+启动,阿里云服务器安装nacos
nacos安装+启动(linux环境): 基础:安装java环境 官网下载压缩包:如 nacos-server-1.2.1.tar.gz 放在自定义目录下 # 解压 tar -xvf nacos-se ...
- 两步完成项目定时启动,java项目定时启动
两步完成项目定时设置: 在需要定时启动或运行的方法上面加上注解@Scheduled //当天只跑一次 @Scheduled(cron = "0 40 21 * * ?") 在启动类 ...
- Solr部署如何启动
Solr部署如何启动 Posted on 一月 10, 2013 in: Solr入门|评论关闭 我刚接触solr,我要怎么启动,这是群里的朋友问得比较多的问题, solr最新版本下载地址: http ...
- Python 多进程笔记 — 启动进程的方式、守护进程、进程间通信、进程池、进程池之间通信、多进程生产消费模型
1 面向过程启动多进程 Python 操作进程的类都定义在 multiprocessing 模块,该模块提供了一个 Process 类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另 ...
- RabbitMQ 入门系列(4)— RabbitMQ 启动、停止节点和应用程序、用户管理、权限配置
1. 服务器管理 我们使用 "节点" 来指代 RabbitMQ 实例,当我们谈到 RabbitMQ 节点时指的是 RabbitMQ 应用程序和其所在的 Erlang 节点. 1.1 ...
- Redis 笔记(01)— 安装、启动配置、开启远程连接、设置密码、远程连接
1. Redis 简介 1月份将 <Redis入门指南>过了一遍,现将 Redis 五大类型的常用命令做一总结,留着后续备用. Redis 是 RemoteDictionary Serve ...
- Docker 入门系列(3)- Docker 容器(创建、启动、终止、进入、删除、导入、导出容器、容器和镜像转化)
Docker 容器 简单来说,容器是镜像的一个运行实例.所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层. 如果认为虚拟机是模拟运行的一整套操作系统(包括内核.应用运行态环境和其他系 ...
最新文章
- java成绩管理系统论文总结,JAVA论文成绩管理系统课程设计
- TensorFlow搭建简易Wide and Deep 模型
- Spring Transaction 使用入门 (转)
- Ubuntu8.10安装小记
- UVALive2245 POJ1131 HDU1376 ZOJ1086 Octal Fractions【进制】
- js焦点图片层叠轮播切换滚动
- epoll LT/ET 深度剖析
- js 获取浏览器高度、浏览器宽度
- CentOS7.9 查询内网ip
- 局域网聊天软件源代码(包括语音聊天)
- UNLIMITED TABLESPACE权限
- 照片太大了怎么改小kb?图片压缩在线处理方法
- html button 点击无效,HTML button点击不了
- 嵌入式Linux--Lichee Pi Zero原理图分析
- 邻接矩阵无向图的介绍
- Win10系统安装tensorflow-cpu和gpu版本(按照步骤一次成功)
- 面试”作弊“,不看绝对会后悔!
- 顶级技术公司的CEO是如何看待AI的?
- 发光二极管pcb封装图画法_LM2596电源模块原理图及PCB分享
- 小学妹问我【CodeBlocks提示no such file or directory】怎么解决【巧妙篇】
热门文章
- 【题解】 [HEOI2016]排序题解 (二分答案,线段树)
- DAL,IDAL,BLL,Factory作用
- Photoshop脚本指南——Hello World
- 关于HTML5中的video和audio元素
- [网络安全提高篇] 一〇八.Powershell和PowerSploit脚本渗透详解 (1)
- C# 系统应用之通过注册表获取USB使用记录(一)
- 【数据结构与算法】之深入解析“分割数组的最大值”的求解思路与算法示例
- iOS之深入解析CFRunloop的多线程隐患
- Swift之深入解析“属性”的底层原理
- iOS之深入解析数组遍历的底层原理和性能分析