ucos实时操作系统学习笔记——操作系统在STM32的移植
使用ucos实时操作系统是在上学的时候,导师科研项目中。那时候就是网上找到操作系统移植教程以及应用教程依葫芦画瓢,功能实现也就罢了,没有很深入的去研究过这个东西。后来工作了,闲来无聊就研究了一下这个只有几千行代码的操作系统,也没所有的代码都看,只是看了其中部分内容。自己还自不量力的尝试着去写过简单的操作系统,最后写着写着就被带到了ucos的设计思路上了,后来干脆就“copy”代码了,虽说对操作系统内核的理解有很大的帮助,但是很是惭愧啊,智力不够,对操作系统内核的设计者更加仰慕,O(∩_∩)O哈哈~
之前项目开发用的STM32,接下来就从ucos在STM32的移植开始讲一下学习过程吧。当时系统移植也是根据开发板例程来的,像OS_STK,OS_CPU_SR以及堆栈的增长方式等设置都已经根据ARM-CoreM3的硬件特性设置好了,所以移植过程相对简单一点。以下所讲内容纯属个人理解,如果不对的地方,请批评指正。
首先,讲一下个人对ucos操作系统整体架构的理解,网上有很多对ucos每个文件是干什么的做介绍的文章,在这里不做详细介绍,可以网上搜一下。ucos主要包括TIMER管理(os_tmr.c),任务(os_task.c),任务间通信(os_sem.c,os_mutex.c等),内存管理(os_mem.c),和处理器相关底层实现。除了处理器相关底层实现外,其他的算是操作系统内核的东西,处理器相关实现却因处理器的不同而具体实现不同。操作系统移植主要的操作就是做这部分内容。
其次,讲一下个人对ucos操作系统工作原理的理解,主要分为四点:
1. 操作系统给每个任务分配一个优先级,当有任务切换时,cpu的使用权会分配给优先级最高的任务;
2. 在操作系统内核中,当有比较重要的数据操作时,会通过开关中断来保证数据的可靠性和正确性;
3. 通过手动设置异步中断寄存器的值触发中断处理函数,实现任务的切换(此操作主要是任务间的通信操作实现的);
4. 中断会自动保存寄存器的值,完成中断处理之后,会检查有没有比当前任务优先级更高的任务,从而决定是否进行任务切换操作(此中断中比较重要的是“心跳”定时器中断保证了没有外部中断的情况下,实现任务切换);
ucos在STM32上的移植主要是针对上面提到的工作原理中的后面三点实现的,其中讲到的第一点是操作系统内核中做得事情。移植中的函数声明是在操作系统内核中,对于STM32的移植,函数的具体实现是在os_cpu_a.asm中。接下来分析一下移植过程中使用到的各个函数的。
1. 和工作原理第2条相关的进出临界区函数(其实是开关中断函数)。
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();};
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}.
2. 和工作原理第3条相关的任务切换函数
#define OS_TASK_SW() OSCtxSw()
3. 和工作原理第4条相关的中断退出任务切换函数
OSIntCtxSw(), 该函数是当中断处理函数完成操作之后由OSIntExit函数调用,实现原理和OSCtxSw相同,但是意义不同。
以上这三个函数是这样组织的:
对应1,对于进入临界区的函数,主要是通过修改中断寄存器中的值实现的。OS_CPU_SR_Save()通过将中断寄存器中的值取出并存入到cpu_sr中,修改中断寄存器的值,屏蔽中断(NMI和硬件fault是不能被屏蔽的)。OS_CPU_SR_Restore()是将之前存到cpu_sr中的值写入到中断寄存器,从而恢复到没有屏蔽中断之前的状态。
对应2和3,对于进行任务切换的函数,其主要是通过触发中断,在中断处理函数中通过将高优先级任务的堆栈中的数据填入到cpu寄存器中,从而实现任务的切换。这两步需要注意的是在STM32启动的过程中(即startup_stm32f10x_hd.s),需要设置中断向量对应的中断处理函数OS_CPU_PendSVHandler(),将原来的Pend_SVHandler()替换掉。
对于在STM32上的移植,比较重要的是设置操作系统的“心跳”函数SysTick_Handler,函数代码如下:
void SysTick_Handler(void)
{
OS_CPU_SR cpu_sr; OS_ENTER_CRITICAL(); /* Tell uC/OS-II that we are starting an ISR */
OSIntNesting++;
OS_EXIT_CRITICAL(); OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */ OSIntExit();
}
该函数首先是对操作系统嵌套计数自加操作,当退出中断处理程序时,会对该计数变量减操作。其他对方对OSIntNesting的引用都会判断如果该值大于0,则是出于中断中,如果该值等于0,则说明已经从中断中退出,加操作(OSIntNesting++)必须对应于退出中断的减操作(OSIntNesting--),否则会其他地方对OSIntNesting的操作会认为始终出于中断处理程序中。
OSTimeTick是对所有出于等待状态的task等待delay时间片减操作,如果有任务的等待时间已经变成0,则需要将该任务加入到readytable中,为任务切换到该任务做准备。
OSIntExit函数首先会判断嵌套等级变量OSIntNesting是否大于0,如果是会做减操作,然后判断是否所有的中断都已经处理完成,如果是,则会任务调度,会切换到高优先级的任务;如果不是,则说明只是退出当前中断处理函数,还有其他中断处理没有结束。
操作系统的移植,一个比较重要的设计操作系统切换的任务堆栈,ucos在创建任务的时候会有一个OSTaskStkInit操作,该操作的目的是为当前创建的task构建一个stack,该栈中存储的内容是像该任务刚被中断一样,模拟保存一些寄存器的值,当任务切换到当前task时,由任务调度函数操作从栈中弹出保存的内容,从而实现任务的切换。虽然说在中断等发生时cpu会自动保存一部分寄存器,但是我们是通过模拟的方式实现的类中断操作,所以cpu自动保存的内容,我们在创建task的时候也要给模拟实现。因为中断操作会pop出cpu自动保存的寄存器的值,在任务切换过程中,也会pop我们模拟存储的自动保存的寄存器的值,比如在STM32中的xPSR, PC, LR, R12, R3-R0等。
以上这些操作是ucos操作系统移植在STM32上的一些关键步骤和原理,在此作为学习笔记记录下来,为以后使用。网上有很多关于该操作系统移植的详细介绍,可供参考,其中百度文库中有一篇《ucosii在STM32上的移植详解》讲解的很不错,可供大家学习。
ucos实时操作系统学习笔记——操作系统在STM32的移植的更多相关文章
- 操作系统学习笔记----进程/线程模型----Coursera课程笔记
操作系统学习笔记----进程/线程模型----Coursera课程笔记 进程/线程模型 0. 概述 0.1 进程模型 多道程序设计 进程的概念.进程控制块 进程状态及转换.进程队列 进程控制----进 ...
- 深挖计算机基础:趣谈Linux操作系统学习笔记
参考极客时间专栏<趣谈Linux操作系统>学习笔记 核心原理篇:内存管理 趣谈Linux操作系统学习笔记:第二十讲 趣谈Linux操作系统学习笔记:第二十一讲 趣谈Linux操作系统学习笔 ...
- 操作系统学习笔记5 | 用户级线程 && 内核级线程
在上一部分中,我们了解到操作系统实现多进程图像需要组织.切换.考虑进程之间的影响,组织就是用PCB的队列实现,用到了一些简单的数据结构知识.而本部分重点就是进程之间的切换. 参考资料: 课程:哈工大操 ...
- ucos实时操作系统学习笔记——任务间通信(消息)
ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...
- ucos实时操作系统学习笔记——任务间通信(信号量)
ucos实时操作系统的任务间通信有好多种,本人主要学习了sem, mutex, queue, messagebox这四种.系统内核代码中,这几种任务间通信机制的实现机制相似,接下来记录一下本人对核心代 ...
- ucos实时操作系统学习笔记——内核结构和任务创建
对于ucos实时操作系统,邵贝贝的那本书已经写得很详细了,我因为之前不深的研究过ucos,所以在这里做一个笔记,写一些个人对该操作系统的理解,仅仅是个人理解,如果有人看到这边随笔有不对的地方,望给我指 ...
- 操作系统学习笔记(五)--CPU调度
由于第四章线程的介绍没有上传视频,故之后看书来补. 最近开始学习操作系统原理这门课程,特将学习笔记整理成技术博客的形式发表,希望能给大家的操作系统学习带来帮助.同时盼望大家能对文章评论,大家一起多多交 ...
- ucore操作系统学习笔记(二) ucore lab2物理内存管理分析
一.lab2物理内存管理介绍 操作系统的一个主要职责是管理硬件资源,并向应用程序提供具有良好抽象的接口来使用这些资源. 而内存作为重要的计算机硬件资源,也必然需要被操作系统统一的管理.最初没有操作系统 ...
- 操作系统学习笔记4 | CPU管理 && 多进程图像
操作系统的核心功能就是管理计算机硬件,而CPU就是计算机中最核心的硬件.而通过学习笔记3的简史回顾,操作系统通过多进程图像实现对CPU的管理.所以多进程图像是操作系统的核心图像. 参考资料: 课程:哈 ...
随机推荐
- 使用Monit监控本地进程
目前用它监控某些服务,失败自动重启,同时监控特定的日志文件,如果有变化,就发邮件报警 安装不细写了,网上好多 我先用cat /proc/version看了下我的系统是el6的,于是wget http: ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- 查看w3wp进程占用的内存及.NET内存泄露,死锁分析
一 基础知识 在分析之前,先上一张图: 从上面可以看到,这个w3wp进程占用了376M内存,启动了54个线程. 在使用windbg查看之前,看到的进程含有 *32 字样,意思是在64位机器上已32位方 ...
- Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境
首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...
- django server之间通过remote user 相互调用
首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...
- 史上最详细git教程
题外话 虽然这个标题很惊悚,不过还是把你骗进来了,哈哈-各位看官不要着急,耐心往下看 Git是什么 Git是目前世界上最先进的分布式版本控制系统. SVN与Git的最主要的区别 SVN是集中式版本控制 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- bash字符串操作
参考 http://www.cnblogs.com/chengmo/archive/2010/10/02/1841355.html 问题:bash怎么提取字符串的最后一位?例如python中strin ...
- DDD领域驱动设计 - 设计文档模板
设计文档模板: 系统背景和定位 业务需求描述 系统用例图 关键业务流程图 领域语言整理,主要是整理领域中的各种术语的定义,名词解释 领域划分(分析出子域.核心域.支撑域) 每个子域的领域模型设计(实体 ...
- H3 BPM产品安装手册(.Net版本)
1 安装说明 1.1 服务器安装必备软件 在使用该工作流软件之前,有以下一些软件是必须安装: l IIS7.0以上版本(必须): l .Net Framework 4.5(必 ...