使用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的移植的更多相关文章

  1. 操作系统学习笔记----进程/线程模型----Coursera课程笔记

    操作系统学习笔记----进程/线程模型----Coursera课程笔记 进程/线程模型 0. 概述 0.1 进程模型 多道程序设计 进程的概念.进程控制块 进程状态及转换.进程队列 进程控制----进 ...

  2. 深挖计算机基础:趣谈Linux操作系统学习笔记

    参考极客时间专栏<趣谈Linux操作系统>学习笔记 核心原理篇:内存管理 趣谈Linux操作系统学习笔记:第二十讲 趣谈Linux操作系统学习笔记:第二十一讲 趣谈Linux操作系统学习笔 ...

  3. 操作系统学习笔记5 | 用户级线程 && 内核级线程

    在上一部分中,我们了解到操作系统实现多进程图像需要组织.切换.考虑进程之间的影响,组织就是用PCB的队列实现,用到了一些简单的数据结构知识.而本部分重点就是进程之间的切换. 参考资料: 课程:哈工大操 ...

  4. ucos实时操作系统学习笔记——任务间通信(消息)

    ucos另一种任务间通信的机制是消息(mbox),个人感觉是它是queue中只有一个信息的特殊情况,从代码中可以很清楚的看到,因为之前有关于queue的学习笔记,所以一并讲一下mbox.为什么有了qu ...

  5. ucos实时操作系统学习笔记——任务间通信(信号量)

    ucos实时操作系统的任务间通信有好多种,本人主要学习了sem, mutex, queue, messagebox这四种.系统内核代码中,这几种任务间通信机制的实现机制相似,接下来记录一下本人对核心代 ...

  6. ucos实时操作系统学习笔记——内核结构和任务创建

    对于ucos实时操作系统,邵贝贝的那本书已经写得很详细了,我因为之前不深的研究过ucos,所以在这里做一个笔记,写一些个人对该操作系统的理解,仅仅是个人理解,如果有人看到这边随笔有不对的地方,望给我指 ...

  7. 操作系统学习笔记(五)--CPU调度

    由于第四章线程的介绍没有上传视频,故之后看书来补. 最近开始学习操作系统原理这门课程,特将学习笔记整理成技术博客的形式发表,希望能给大家的操作系统学习带来帮助.同时盼望大家能对文章评论,大家一起多多交 ...

  8. ucore操作系统学习笔记(二) ucore lab2物理内存管理分析

    一.lab2物理内存管理介绍 操作系统的一个主要职责是管理硬件资源,并向应用程序提供具有良好抽象的接口来使用这些资源. 而内存作为重要的计算机硬件资源,也必然需要被操作系统统一的管理.最初没有操作系统 ...

  9. 操作系统学习笔记4 | CPU管理 && 多进程图像

    操作系统的核心功能就是管理计算机硬件,而CPU就是计算机中最核心的硬件.而通过学习笔记3的简史回顾,操作系统通过多进程图像实现对CPU的管理.所以多进程图像是操作系统的核心图像. 参考资料: 课程:哈 ...

随机推荐

  1. 彻底理解AC多模式匹配算法

    (本文尤其适合遍览网上的讲解而仍百思不得姐的同学) 一.原理 AC自动机首先将模式组记录为Trie字典树的形式,以节点表示不同状态,边上标以字母表中的字符,表示状态的转移.根节点状态记为0状态,表示起 ...

  2. Jquery 搭配 css 使用,简单有效

    前几篇博客中讲了Jquery的基础和点击实际,下面来说一下和css搭配着来怎么做 还是和往常一样,举个例子 好几个方块,然后设置颜色 <!DOCTYPE html PUBLIC "-/ ...

  3. 【翻译】MongoDB指南/CRUD操作(一)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...

  4. Jquery的事件操作和文档操作

    对于熟悉前端开发的小伙伴,相信对于Jquery一定不陌生,相对于JavaScript的繁琐,Jquery更加的简洁,当然简洁不意味着简单,我们可以使用Jquery完成我们想要实现全部功能,这里为小白们 ...

  5. .NET平台开源项目速览(16)C#写PDF文件类库PDF File Writer介绍

    1年前,我在文章:这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)中(第9个项目),给大家推荐了一个开源免费的PDF读写组件 PDFSharp,PDFSharp我2年前就看过 ...

  6. IIC驱动移植在linux3.14.78上的实现和在linux2.6.29上实现对比(deep dive)

    首先说明下为什么写这篇文章,网上有许多博客也是介绍I2C驱动在linux上移植的实现,但是笔者认为他们相当一部分没有分清所写的驱动时的驱动模型,是基于device tree, 还是基于传统的Platf ...

  7. gRPC源码分析1-SSL/TLS

    引子 前几天看到微信后台团队分享了TLS相关文章,正好gRPC里TLS数据加密是很重要的一块,于是整理出了这篇文章. 在gRPC里,如果仅仅是用来做后端微服务,可以考虑不加密.本文太长,先给个大纲. ...

  8. js闭包for循环总是只执行最后一个值得解决方法

    <style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...

  9. iOS 数据存储之SQLite3的使用

    SQLite3是iOS内嵌的数据库,SQLite3在存储和检索大量数据方面非常有效,它使得不必将每个对象都加到内存中.还能够对数据进行负责的聚合,与使用对象执行这些操作相比,获得结果的速度更快. SQ ...

  10. Android中使用ExpandableListView实现微信通讯录界面(完善仿微信APP)

    之前的博文<Android中使用ExpandableListView实现好友分组>我简单介绍了使用ExpandableListView实现简单的好友分组功能,今天我们针对之前的所做的仿微信 ...