使用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. 如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念

    一.前言     DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...

  2. C语言 · Torry的困惑(基本型)

    问题描述 Torry从小喜爱数学.一天,老师告诉他,像2.3.5.7--这样的数叫做质数.Torry突然想到一个问题,前10.100.1000.10000--个质数的乘积是多少呢?他把这个问题告诉老师 ...

  3. [版本控制之道] Git 常用的命令总结(欢迎收藏备用)

    坚持每天学习,坚持每天复习,技术永远学不完,自己永远要前进 总结日常开发生产中常用的Git版本控制命令 ------------------------------main-------------- ...

  4. 开源一个跨平台运行的服务插件 - TaskCore.MainForm

    本次将要很大家分享的是一个跨平台运行的服务插件 - TaskCore.MainForm,此框架是使用.netcore来写的,现在netcore已经支持很多系统平台运行了,所以将以前的Task.Main ...

  5. js:给定两个数组,如何判断他们的相对应下标的元素类型是一样的

    题目: 给Array对象原型上添加一个sameStructureAs方法,该方法接收一个任意类型的参数,要求返回当前数组与传入参数数组(假定是)相对应下标的元素类型是否一致. 假设已经写好了Array ...

  6. P2V之后的磁盘扩容新思路

    背景: 原先的物理机环境多是若干块物理磁盘经过RAID卡进行了RAID5之后的虚拟磁盘组,这样我们在操作系统内看到的也就是一块完整的磁盘.我们会在上面进行分区,然后格式化后以便使用. Figure 1 ...

  7. JavaScript基础知识总结(三)

    JavaScript语法 七.循环语句 1.while 语法: while (exp) { //statements; } 说明:while (变量<=结束值) { 需执行的代码 } 例子: / ...

  8. springmvc+bootstrap+jquerymobile完整搭建案例(提供下载地址)

    用一张简单的截图说明下,然后提供一个下载地址. bootstrap的大部分样式官方都是写好的,所以只需要class="官方样式即可",具体可以看官方的案例,下面来个地址 http: ...

  9. CentOS:设置系统级代理(转)

    原文地址:http://www.cnblogs.com/cocowool/archive/2012/07/05/2578487.html YUM代理设置 编辑/etc/yum.conf,在最后加入 # ...

  10. linux-图形化远程管理协议

    远程管理控制方式: RDP(remote desktop protocol)协议: telnet: SSH(Secure Shell): RFB(Remote FrameBuffer)协议(图形化远程 ...