Ch6. uC/OS-II分析 宋健建 南京大学软件学院.

Slides:



Advertisements
Similar presentations
作者 : 陳鍾誠 單位 : 金門技術學院資管系 URL : 日期 : 2016/7/21 行程的同步 註:本章學術性較重,但考試常考。
Advertisements

阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
Linux 系统. 操作系统发展需求 1 没有操作系统 2 简单批处理操作系统 3 多道程序设计的批处理 4 多道程序设计的分时操作系统 5 多处理机并行系统 6 网络操作系统 7 分布式操作系统.
讓你的程式具有多工(Multitasking) 及多重處理(Multiprocessing)的能力
Memory Pool ACM Yanqing Peng.
单片机应用技术 项目一 循环彩灯装置 第7讲 Keil软件的使用 《单片机应用技术》精品课程组 湖北职业技术学院机电工程系.
实用操作系统概念 张惠娟 副教授 1.
Chapter 6 時序.
Oracle数据库 Oracle 子程序.
Nucleus嵌入式操作系统.
第五章 C/OS-II在ARM系统中的应用与开发
嵌入式系统概论 —基于32位微处理器与实时操作系统 第五讲实时操作系统C/OS-Ⅱ分析 北京航空航天大学 机器人研究所 魏洪兴.
陈香兰 助教:陈博、李春华 Spring 2009 嵌入式操作系统 陈香兰 助教:陈博、李春华 Spring 2009.
Operating System Concepts 作業系統原理 Chapter 3 行程觀念 (Process Concept)
Kvm异步缺页中断 浙江大学计算机体系结构实验室 徐浩.
Chap 3 堆疊與佇列 Stack and Queue.
VxWorks软硬件设计及实例分析
嵌入式系统课程简介 宋健建 南京大学软件学院 2004/02/10.
嵌入式系统及应用.
Chapter 3 行程觀念 (Process Concept)
第十五章 Linked List, Stack and Queue
嵌入式操作系统ucOS-II分析.
嵌入式系统 —RTEOS μC/OS-II 的移植
第7章 移植μC/OS-II到ARM7.
UcOS-II(RTOS)的基本概念.
UcOS-II任务管理.
嵌入式系统及应用.
《手把手教你学STM32-UCOS》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
UCOS -II的使用 撰写:李湧 2006-06-29.
《手把手教你学STM32-UCOS》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
《手把手教你学STM32-UCOS》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
临界区软件互斥软件实现算法.
移植μC/OS-Ⅱ.
嵌入式系统 —嵌入式实时操作系统C/OS-Ⅱ分析 2006年5月.
第48组:姜立群(SC ) 谭兆路(SC ) 闫 佼(SC )
第五讲 C/OS-Ⅱ移植分析和系统初始化
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
逆向工程-汇编语言
临界区软件互斥软件实现算法 主讲教师:夏莹杰
ΜC/OSⅡ中的任务调度 Group01小组 柴永锋 李逢春 苗 冬.
UcOS-II时间管理.
嵌入式系统设计与实例开发 ——ARM与C/OS-Ⅱ 北京航空航天大学 智能嵌入式技术工作室 王田苗 魏洪兴.
CPU结构和功能.
第五章 C/C++及汇编语言的混合编程 5.1 ARM C/C++编译器 5.2 在C/C++程序中内嵌汇编指令
第3章 認識處理元.
Unit 11.Operating System 11.1 What’s OS 11.2 Related Courses
3. µC/OS-II内核 2019/4/11.
内容摘要 ■ 课程概述 ■ 教学安排 ■ 什么是操作系统? ■ 为什么学习操作系统? ■ 如何学习操作系统? ■ 操作系统实例
C语言程序设计 主讲教师:陆幼利.
程式結構&語法.
5. µC/OS-II应用实例.
5-6 串列埠模式0輸出埠擴充實習.
UcOS-II任务之间的通讯与同步.
实验四、TinyOS执行机制实验 一、实验目的 1、了解tinyos执行机制,实现程序异步处理的方法。
进程概念.
6. 面向任务程序设计(TOP).
Chap2 Stack & Queue.
信号量(Semaphore).
College of Computer Science & Technology
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
ARM简介及BootLoader介绍 黄大荣
Ch7 uC/OS-II分析(2) 宋健建 南京大学软件学院 2006/11.
临界区问题的硬件指令解决方案 (Synchronization Hardware)
本节内容 Windows线程切换_时钟中断切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
Go 语言编程 —— 平台研发部 吴植民.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
《手把手教你学STM32-UCOS》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
本节内容 进程 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
FVX1100介绍 法视特(上海)图像科技有限公司 施 俊.
本节内容 SEMAPHORE 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
Presentation transcript:

Ch6. uC/OS-II分析 宋健建 南京大学软件学院

内容 uC/OS-II概述 一些基本概念 内核情景分析 完整的程序 源代码文件结构 任务、任务控制块、任务间通信、共享与互斥、中断 从boot到操作系统,操作系统初始化,任务创建,启动多任务,任务调度,任务切换,任务定时等待… 完整的程序

uC/OS-II概述 源代码开放 微内核 内核与应用软件没有明确区分 易移植 共享同一个地址空间,一个映像,一个main()入口函数 与通用操作系统,或其他比较大比较通用的嵌入式操作系统如Linux,Windows CE的比较; 方便由test case改造;

Application Software CPU Timer uC/OS-II Port uC/OS-II (Processor Independent Code) OS_MBOX.C OS_CORE.C OS_MEM.C uCOS_II.C OS_Q.C uCOS_II.H OS_SEM.C OS_TASK.C OS_FLAG.C OS_TIME.C OS_MUTEX.C uC/OS-II Configuration (Application Specific) OS_CFG.H INCLUDE.H uC/OS-II Port (Processor Specific Code) OS_CPU.H OS_CPU_A.A OS_CPU_C.C CPU Timer

uC/OS-II源代码组成 核心部分(OS_Core.c) 任务处理部分(OS_Task.c) 时钟部分(OS_Time.c) 操作系统的处理核心。包括操作系统初始化、操作系统运行、中断进出的前导、时钟节拍、任务调度、事件处理等多部分。能够维持系统基本工作的部分都在这里。 任务处理部分(OS_Task.c) 与任务的操作密切相关,包括任务的建立、删除、挂起、恢复等等。 时钟部分(OS_Time.c) uC/OS-II中的最小时钟单位是timetick(时钟节拍)。任务延时等操作在这里完成的。

uC/OS-II源代码组成(续) 任务同步和通信部分 与CPU的接口部分 事件处理部分,包括信号量、邮箱、邮箱队列、事件标志等部分;主要用于任务间的互相联系和对临界资源的访问。 与CPU的接口部分 uC/OS-II针对所使用的CPU的移植部分。主要包括中断级任务切换的底层实现、任务级任务切换的底层实现、时钟节拍的产生和处理、中断的相关处理部分等内容。由于涉及SP等系统指针,通常用汇编语言编写。

应用范例 一个PC机上的基于uC/OS-II的应用范例 13个任务 空闲任务和统计任务(OSInit产生) TaskStart任务 10个任务在屏幕随机的位置显示0-9的数字,每个任务只显示同一个数字

内容 uC/OS-II概述 一些基本概念 内核情景分析 完整的程序 源代码文件结构 任务、任务控制块、任务间通信、共享与互斥、中断 从boot到操作系统,操作系统初始化,任务创建,启动多任务,任务调度,任务切换,任务定时等待… 完整的程序

任务 实时应用程序的设计过程包括如何把问题分割成多个任务 每个任务 任务与进程/线程 是整个应用的一部分 被赋予一定的优先级 有自己的一套CPU寄存器和栈空间 任务与进程/线程

任务的创建 Interface Example INT8U OSTaskCreate ( void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio); Example OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 0); OSTaskCreate(Task, (void *)&TaskData[i], &TaskStk[i][TASK_STK_SIZE – 1], i+1);

SetTickIn5MS() IRQ_Handler() OSTaskStkInit() OSStartHighRdy() IntTaskSwitch()

任务控制块 OS_TCB (in uCOS_II.h) typedef struct os_tcb { OS_STK *OSTCBStkPtr; /* Pointer to current top of stack */ #if OS_TASK_CREATE_EXT_EN > 0 … #endif struct os_tcb *OSTCBNext; /* Pointer to next TCB in the TCB list */ struct os_tcb *OSTCBPrev; /* Pointer to previous TCB in the TCB list */ #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0) OS_EVENT *OSTCBEventPtr; /* Pointer to event control block */

任务控制块(续) OS_TCB (in uCOS_II.h) #if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) void *OSTCBMsg; /* Message received from OSMboxPost() or OSQPost() */ #endif #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) #if OS_TASK_DEL_EN > 0 OS_FLAG_NODE *OSTCBFlagNode; /* Pointer to event flag node */ OS_FLAGS OSTCBFlagsRdy; /*Event flags that made task ready to run*/

任务控制块(续2) OS_TCB (in uCOS_II.h) INT16U OSTCBDly; /* Nbr ticks to delay task or, timeout waiting for event */ INT8U OSTCBStat; /* Task status */ INT8U OSTCBPrio; /* Task priority (0: highest, 63: lowest) */ INT8U OSTCBX; INT8U OSTCBY; INT8U OSTCBBitX; INT8U OSTCBBitY; #if OS_TASK_DEL_EN > 0 BOOLEAN OSTCBDelReq; /* Indicates whether a task needs to delete itself */ #endif } OS_TCB;

任务间通信 途径 uC/OS-II提供的机制 全局变量 消息传递 Event, Mail box, Message queue, Semaphore,Mutex

共享与互斥 共享 互斥的方法? 实现任务间通信最简单的办法就是使用共享数据结构。特别是当所有任务都在一个单一地址空间时,这种方法尤其方便 关中断 使用“Test-And-Set”(TAS)操作 某些微处理器(如Motorola 68k系列)具有硬件TAS指令 禁止任务切换 利用信号量

临界区(Critical Region) 禁中断临界区 禁调度临界区 禁共享临界区 OS_ENTER_CRITICAL() OS_EXIT_CRITICAL() (in os_cpu.h) 禁调度临界区 OSSchedLock() OSSchedUnlock() (in os_core.c) 禁共享临界区 Semaphore, etc.

中断 中断:一种硬件机制 中断处理完成后: 异步事件的发生 中断一旦被识别,CPU保存部分或全部现场(context),即部分或全部寄存器的值,跳转到中断服务子程序(ISR)。 中断处理完成后: 对前后台系统,程序回到后台程序 对不可剥夺型内核,程序回到被中断的任务 读可剥夺型内核,重新调度选择任务执行 ->OSIntExit()函数

中断的几个概念 中断延迟 中断响应时间 中断恢复时间 中断延迟 = 关中断的最长时间 + 开始执行中断服务子程序第一条指令的时间 从中断发生到开始执行用户的中断服务程序来处理中断的时间 中断响应时间 = 中断延迟 + 保存CPU内部寄存器的时间 + … 中断恢复时间 微处理器返回到被中断了的程序代码所需要的时间,或返回到更高优先级任务的时间

中断的几个概念(续)

内容 uC/OS-II概述 一些基本概念 内核情景分析 完整的程序 源代码文件结构 任务、任务控制块、任务间通信、共享与互斥、中断 从boot到操作系统,操作系统初始化,任务创建,启动多任务,任务调度,任务切换,任务定时等待… 完整的程序

从boot到操作系统 入口方式 ldr pc,=dummyOs bl CEntry

操作系统初始化 OSInit() (os_core.c) 初始化uC/OS-II所有的变量和数据结构; 创建空闲任务OS_TaskIdle(),该任务优先级最低(OS_LOWEST_PRIO),总处于就绪状态 (可选的)创建统计任务OS_TaskStat(),该任务优先级次低(OS_LOWEST_PRIO - 1)

任务创建 OSTaskCreate() (os_task.c) 附: 数组OSTCBPrioTbl[] (ucos_II.h)

OSTaskCreate() OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing */ OS_EXIT_CRITICAL(); psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* Initialize the task's stack */ err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); if (err == OS_NO_ERR) { OSTaskCtr++; /* Increment the #tasks counter */ if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */ OS_Sched(); } } else { OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */ return (err); return (OS_PRIO_EXIST);

启动多任务 OSStart(): (os_core.c) 真正启动操作系统,启动进程和进程调度 OSStartHighRdy() (os_cpu_a.s)

OSStart() void OSStart (void) { INT8U y; INT8U x; if (OSRunning == FALSE) { y = OSUnMapTbl[OSRdyGrp]; /* Find highest priority's task priority number */ x = OSUnMapTbl[OSRdyTbl[y]]; OSPrioHighRdy = (INT8U)((y << 3) + x); OSPrioCur = OSPrioHighRdy; OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */ OSTCBCur = OSTCBHighRdy; OSStartHighRdy(); /* Execute target specific code to start task */ }

任务调度 数据结构: 编组就绪位图OSRdyGrp, 组内就绪位图OSRdyTbl[] (ucos_II.h) OSMapTbl[] (os_core.c) Priority Resolution Table: OSUnMapTbl[] (os_core.c)

调度时机 OSStart(): (os_core.c) 任务级调度和中断级调度 OSStartHighRdy() (os_cpu_a.s) OS_Sched(): (os_core.c) OSIntExit(): (os_core.c)

OS_Sched() #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif INT8U y; OS_ENTER_CRITICAL(); if ((OSIntNesting == 0) && (OSLockNesting == 0)) { y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */ OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; /* Increment context switch counter */ OS_TASK_SW(); /* Perform a context switch */ } OS_EXIT_CRITICAL();

OSIntExit() if (OSRunning == TRUE) { OS_ENTER_CRITICAL(); if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */ OSIntNesting--; } if ((OSIntNesting == 0) && (OSLockNesting == 0)) { OSIntExitY = OSUnMapTbl[OSRdyGrp]; OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]); if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; /* Keep track of the number of ctx switches */ OSIntCtxSw(); /* Perform interrupt level ctx switch */ OS_EXIT_CRITICAL();

任务切换 OSStartHighRdy() (os_cpu_a.s) OS_TASK_SW() (os_cpu_a.s) OSIntCtxSw()

Main()>OSStart()>OSStartHighRdy() EXPORT OSStartHighRdy OSStartHighRdy ; Store the address of OSTCBHighRdy in r0 … LDR sp, [r0] ; switch to the new stack LDMFD sp!, {r0} ; get saved SPSR; popup LDMFD sp!, {r0} ; get CPSR from top of the stack MSR CPSR_cxsf, r0 ; CPSR should be SVC32Mode LDMFD sp!, {r0-r12,pc} ; start the new task END

OS_TASK_SW() EXPORT OS_TASK_SW OS_TASK_SW ; store old STMFD sp!, {r0-r12, lr} ; save register file and ret address MRS r0, CPSR STMFD sp!, {r0} ; save current PSR STMFD sp!, {r0} ; save SPSR ; store old sp in PCB BL GetOSTCBCur; STR sp, [r0] ;the Same as OSStartHighRdy …

进程定时等待 时间管理 SetTickIn5MS() OSTickISR(): OSTimeDly(): (os_time.c) OSTimeTick() OSTimeDly(): (os_time.c)

OSTickISR() IRQ_Hander()完成的任务如下: 保存被中断任务的上下文; 调用函数OSIntEnter(); 调用函数OSTimeTick(); 清中断源; 调用函数OSIntExit(); 如果进行任务切换,则调用IntTaskSwitch(),否则恢复被中断任务的上下文,并返回该任务。

一个完整的程序 完整程序 实验

Highest Priority OS_LOWEST_PRO Wait for ISR… OSStart()