移植嵌入式操作系统心得Word文档下载推荐.docx

上传人:b****5 文档编号:16446644 上传时间:2022-11-23 格式:DOCX 页数:15 大小:23.39KB
下载 相关 举报
移植嵌入式操作系统心得Word文档下载推荐.docx_第1页
第1页 / 共15页
移植嵌入式操作系统心得Word文档下载推荐.docx_第2页
第2页 / 共15页
移植嵌入式操作系统心得Word文档下载推荐.docx_第3页
第3页 / 共15页
移植嵌入式操作系统心得Word文档下载推荐.docx_第4页
第4页 / 共15页
移植嵌入式操作系统心得Word文档下载推荐.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

移植嵌入式操作系统心得Word文档下载推荐.docx

《移植嵌入式操作系统心得Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《移植嵌入式操作系统心得Word文档下载推荐.docx(15页珍藏版)》请在冰豆网上搜索。

移植嵌入式操作系统心得Word文档下载推荐.docx

(3)任务级任务调度

指在非中断返回时进行任务调度,一般发生在当前任务因时间延迟或等待某事件而阻塞或被挂起,或有更高优先级的任务处于就绪状态。

任务的基本信息:

CPU的PC寄存器:

任务当前执行的位置;

CPU的通用寄存器:

任务当前执行涉及的临时数据;

CPU的状态寄存器:

存储当前CPU的状态。

任务级任务切换:

从一个任务直接切换至另一个任务,不涉及CPU状态的切换,OS_TASK_SW()既保存当前任务上下文,又恢复新任务上下文。

过程:

OS_Sched()->

OS_SchedNew()->

OS_TASK_SW()

(4)中断级任务调度

中断级任务切换:

在中断处理完成后,通过OSIntExit()判断是否有更高优先级就绪任务。

如果有,调用OSIntCtxSW()恢复新任务上下文。

注意:

在中断处理中,已经保存了被中断任务的上下文,所以这里仅仅恢复。

OSIntExt()–>

OSIntEnter()->

ISR–>

OSIntExit()->

OSIntCtxSW()

(5)调度器上锁与解锁

uC/OS-II提供调度器锁定功能,在锁定期间不能进行任务调度。

uC/OS-II使用全局变量OSLockNesting标识是否锁定了任务调度器。

OS_EXTINT8UOSLockNesting;

voidOSSchedLock(void);

voidOSSchedUnlock(void);

(6)中断管理函数

在中断处理中,不允许进行任务管理、事件管理及任务调度等操作。

uC/OS-II通过全局变量OSIntNesting标识当前是否处于中断状态。

在所有任务及事件管理的程序中,都有对OSIntNesting进行判断的语句。

voidOSIntEnter(void);

voidOSIntExit(void);

(7)中断相关问题

OS_ENTER_CRITICAL()

OS_EXIT_CRITICAL()

关中断使得uC/OS-II能够同时避免有其他任务或中断服务进入临界代码段。

调用uC/OS-II功能函数时,中断总应当是开着的。

uC/OS-II如何禁止调度?

在中断中允许调度吗?

为什么?

uC/OS-II如何屏蔽中断?

2.uC/OS-II系统启动

uC/OS-II首先调用OSInit()进行初始化,然后创建任务(此时还未启动系统,仅仅为其分配资源),然后调用OSStart()启动系统,将CPU控制权交给uC/OS-II,OS根据任务优先级选择由哪个任务开始执行,或创建新的任务。

(1)初始化函数OSInit()

OSInit()主要完成初始化操作,包括初始化全局变量(在OS_InitMisc()中)、任务就绪表、TCB、ECB、FCB、内存单元、消息队列,并创建空闲任务。

如果有必要,创建统计任务。

OS_InitMisc();

//初始化部分全局变量

OS_InitRdyList();

//初始化任务就绪表

OS_InitTCBList();

//初始化空闲TCB链表

OS_InitEventList();

//初始化ECB链表

OS_FlagInit();

//初始化事件组标志结构

OS_MemInit();

//初始化内存管理

OS_QInit();

//初始化消息队列

OS_InitTaskIdle();

//创建空闲任务

OS_InitTaskStat();

//创建统计任务

uC/OS-II初始化了5个空的数据结构缓冲区,每个缓冲区都是单向链表,允许uC/OS-II从缓冲区中迅速取得或释放一个缓冲区中的元素。

uC/OS-II调用OSInit()后的变量与数据结构如下图所示:

(2)启动函数OSStart()

OSStart()在一切准备就绪且需要首先创建的任务都被创建后,启动uC/OS-II。

它从就绪表中查找最高优先级就绪任务,并恢复其上下文开始执行。

OSStart()->

OSStartHighRdy()

问题:

任务第一次被调用时,哪来的上下文供其恢复呢?

创建任务时,调用了OSTaskStkInit()初始化任务堆栈,可此函数中没有涉及任务的上下文呀?

uC/OS-II调用OSStart()后的变量和数据结构如下图所示:

(3)统计任务OSTaskStat

OSTaskStat用于计算CPU利用率。

设置OS_CFG.H中的OS_TASK_STAT_EN为1,创建统计任务,在系统启动后一直处于就绪状

态。

刚开始时,空闲任务运行1S,为计算CPU利用率提供一个基准值,并保存在统计任务的堆栈中,这个值不会改变除非重新启动CPU。

此后空闲任每次被其

它任务抢去CPU时,它里面的计数器就会直接记录下CPU空闲的时间。

3.uC/OS-II系统时钟

任何实时系统的时钟硬件设备每隔一段时间(一个系统tick)产生一个硬件中断,OS接收到该中断后,更新时间计数器,更新所有对时钟依赖的程序代码,从而维持系统有序稳定的运行。

主要包含在C源文件OS_TIME.C中。

#defineOS_TICKS_PER_SEC100//系统时钟中断间隔

OS_EXTvolatileINT32UOSTime;

//系统运行的时间值

voidOSTimeTick(void);

//时钟中断服务程序

voidOSTimeDly(INT16Uticks);

//延迟指定时钟节拍

INT8UOSTimeDlyHMSM(…);

//延迟指定时间长度

INT8UOSTimeDlyResume(prio);

//恢复等待(时延/阻塞)任务

INT32UOSTimeGet(void);

//读取当前时间

voidOSTimeSet(INT32Uticks);

//设置当前时间

4.uC/OS-II事件管理

(1)事件控制块

INT8UOSEventType;

//事件类型

void*OSEventPtr;

//指向MBox或Queue

INT16UOSEventCnt;

//信号量计数器(注:

Mutex)

INT8UOSEventGrp;

//事件等待组标志

INT8UOSEventTbl[];

//时间任务等待表

INT8UOSEventName[];

//时间名称

(2)ECB管理机制

OS_EXTOS_EVENT*OSEventFreeList;

//空闲ECB链表指针

OS_EXTOS_EVENTOSEventTbl[];

//ECB结构体数组

(3)ECB管理函数

OS_InitEventList():

初始化ECB;

OS_EventWaitListInit():

在创建事件时调用,初始化ECB任务等待表;

OS_EventTaskRdy():

在事件发生时调用,修改此事件中最高优先级任务的TCB成员变量,在任务就绪表中添加此任务,将相应信息传递给该任务TCB,并将此任务从事件的任务等代表中删除;

OS_EventTaskWait():

在申请资源失败而暂停当前任务时被调用,将任务从任务就绪表中删除,并添加到事件的任务等代表中;

OS_EventTO():

在事件等待超时时调用,将此任务从事件的任务等代表中删除,并修改该任务的TCB成员变量;

【专题】uC/OS-II内核架构解析(4)---uC/OS-II任务管理

1.C可执行代码结构

(1)代码段.text:

存放CPU执行的机器指令,通常.text是可共享且只读的。

(2)数据段.data:

.rodata(常量数据)、.rwdata(已初始化全局变量、静态变量)。

(3)未初始化数据段.bss:

未初始化的全局变量、静态变量。

(4)栈.stack:

存放函数参数、局部变量及任务切换时的上下文。

(5)堆.heap:

用于动态内存分配。

2.任务结构

在uC/OS-II中,任务是事件运行和管理的基本单元。

一个uC/OS-II任务至少包含程序代码、栈和TCB,还可选择性使用相当于堆的动态内存空间。

程序运行时,uC/OS-II中的任务相当于可执行代码(可单独运行的单元)。

uC/OS-II任务的各部分如何管理?

?

3.任务栈

任务栈数据类型:

typedefunsignedshortOS_STK

任务栈增长方向:

#defineOS_STK_GROWTH0/1

任务栈基本功能:

4.任务控制块

(1)TCB描述

主要用来存储任务的当前属性。

(问:

任务第一次被调度时,该如何运行?

(2)TCB主要成员

任务栈空间位置:

OSTCBStkPtr、OSTCBStkBottom、OSTCBStkSize;

任务通信与同步:

OSTCBEventPtr、OSTCBMsg;

任务事件组标志:

OSTCBFlagNode、OSTCBFlagsRdy;

任务等待/阻塞:

OSTCBDly、OSTCBPendTO;

任务当前状态:

OSTCBStat;

任务优先级:

OSTCBPrio;

(3)TCB全局变量

OS_EXTOS_TCBOSTCBTbl[OS_MAX_TASKS+OS_N_SYS_TASKS];

OS_EXTOS_TCBOSTCBPrioTbl[OS_LOWEST_PRIO+1];

OS_EXTOS_TCB*OSTCBFreeList;

OS_EXTOS_TCB*OSTCBList;

OS_EXTOS_TCB*OSTCBHighRdy;

OS_EXTOS_TCB*OSTCBCur;

5.任务状态切换

6.任务管理函数

OS_TASK.C:

11个函数

OSTaskCreate();

OSTaskCreateExt();

OSTaskDel();

OSTaskDelReq();

OSTaskChangePrio();

OSTaskSuspend();

OSTaskResume();

OSTaskNameGet();

OSTaskNameSet();

OSTaskStkChk();

OS_TaskStkClr();

OSTaskQuery();

【专题】uC/OS-II内核架构解析(5)---uC/OS-II通信与同步

1.消息邮箱Mbox

Mbox用于多任务间单一消息的传递,uC/OS-II使用ECB管理Mbox的基本信息,OSEventPtr指向创建Mbox时指定的内存空间。

事件的创建由具体的事件管理程序实现。

主要包含在C源文件OS_MBOX.C中。

OS_EVENT*OSMboxCreate(void*msg);

void*OSMboxPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err);

void*OSMboxAccept(OS_EVENT*pevent);

INT8UOSMboxPost(OS_EVENT*pevent,void*msg);

INT8UOSMboxPostOpt(OS_EVENT*pevent,void*msg,INT8Uopt);

OS_EVENT*OSMboxDel(OS_EVENT*pevent,INT8Uopt,INT8U*err);

INT8UOSMboxQuery(OS_EVENT*pevent,OS_MBOX_DATA*);

2.消息队列msgQ

(1)msgQ基本内容

msgQ是uC/OS-II任务间通信的机制,可实现多条消息传递,即可以同时存储多条消息。

uC/OS-II使用循环队列管理机制。

主要包含在C源文件OS_Q.C中。

msgQ管理:

使用指针数组存储所有消息的位置;

使用QCB标识指针数组中消息的基本信息;

使用ECB管理整个msgQ。

QCB在编译时分配空间,即当前系统中可用的msgQ个数是预先设置的,系统运行时不能修改。

(2)msgQ全局变量

OS_EXTOS_Q*OSQTbl[OS_MAX_QS];

  //QCB结构体数组

OS_EXTOS_Q*OSQFreeList;

//空闲QCB头指针

typedefstructos_q{//消息队列控制块

      structos_q*OSQPtr;

//用于构建空闲QCB链表

      void**OSQStart;

//指向msgQ指针数组的起始位置

      void**OSQEnd;

//指向msgQ指针数组的结束位置

      void**OSQIn;

//指向msgQ指针数组下一个可以插入消息的位置

      void**OSQOut;

//指向msgQ指针数组下一个可以读出消息的位置

      INT16UOSQSize;

//msgQ指针数组的大小

      INT16UOSQEntries;

//msgQ指针数组当前可以读取的消息个数

}OS_Q;

(3)msgQ管理函数

OS_EVENT*OSQCreate(void**start,INT16Usize);

INT8UOSQPost(OS_EVENT*pevent,void*msg);

//发送消息到队尾

INT8UOSQPostFront(OS_EVENT*pevent,void*msg);

//msg至队首

INT8UOSQPostOpt(OS_EVENT*pevent,void*msg,INT8Uopt);

void*OSQPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err);

void*OSQAccept(OS_EVENT*pevent,INT8U*err);

OS_EVENT*OSQDel(OS_EVENT*pevent,INT8Uopt,INT8U*err);

INT8UOSQQuery(OS_EVENT*pevent,OS_Q_DATA*);

INT8UOSQFlush(OS_EVENT*pevent);

(4)msgQ几个问题

uC/OS-II中,什么是事件?

事件是uC/OS-II管理任务间同步与通信的机制。

事件是处理事件的对象感兴趣的,能够感知或捕获到一种事件状态的改变。

3.信号量Sem

Sem主要用来实现任务间同步及标识某类资源的可用个数,即某个特定资源可供多少任务同时使用。

主要包含在C源文件OS_SEM.C中。

OS_EVENT*OSSemCreate(INT16Ucnt);

voidOSSemPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err);

INT16UOSSemAccept(OS_EVENT*pevent);

INT8UOSSemPost(OS_EVENT*pevent);

OS_EVENT*OSSemDel(OS_EVENT*pevent,INT8Uopt,INT8U*err);

INT8UOSSemQuery(OS_EVENT*pevent,OS_SEM_DATA*);

voidOSSemSet(OS_EVENT*pevent,INT16Ucnt,INT8U*err);

4.互斥锁Mutex

(1)Mutex基本原理

Mutex用来实现对资源的排他性访问,可能引起优先级反转。

任何任务在占有某个互斥锁事件时,都不能阻塞等待其它任何事件,否则会造成死锁。

主要包含在C源文件OS_MUTEX.C中。

优先级反转是指,低优先级任务占有高优先级任务运行所需的资源,而使高优先级不得不等低优先级任务把资源释放才能执行。

uC/OS-II使用ECB管理Mutex,其成员变量OSEventCnt:

高8位存储Mutex被使用时提供给任务的prio;

低8位在没有任务占有Mutex时为0xFF,否则为占有任务的prio。

优先级反转及优先级反转避免分别如下图所示:

(2)提升/恢复优先级

a)提升Mutex拥有者任务的优先级的相关操作:

如果该任务原来处于就绪状态,则从就绪表中将其删除;

如果该任务正在等待某个事件,则从该事件的任务等待表中将其删除;

修改拥有Mutex的TCB,将其OSTCBPrio修改为欲提升的优先级;

如果该任务处于就绪状态,则将提升的优先级加载到任务就绪表中;

如果该任务未就绪且正在等待某个事件,则将提升的优先级添加到该事件的任务等待表中,并修改TCB中OSTCBEventPtr;

修改TCB中与优先级相关的成员变量。

b)恢复Mutex拥有任务的优先级的相关操作:

从任务就绪表中删除提升过的优先级值,修改当前TCB中与优先级相关的所有成员变量;

再次保留提升的优先级值控制块入口,避免将其分配给其它任务。

(3)Mutex管理函数

#defineOS_MUTEX_KEEP_LOWER_80x00FF

#defineOS_MUTEX_KEEP_UPPER_80xFF00

#defineOS_MUTEX_AVAILABLE0x00FF

OS_EVENT*OSMutexCreate(INT8Uprio,INT8U*err);

voidOSMutexPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err);

INT8UOSMutexAccept(OS_EVENT*pevent,INT8U*err);

INT8UOSMutexPost(OS_EVENT*pevent);

OS_EVENT*OSMutexDel(OS_EVENT*,INT8Uopt,INT8U*err);

INT8UOSMutexQuery(OS_EVENT*,OS_MUTEX_DATA*);

5.事件组标志Flag

(1)Flag基本原理

uC/OS-II提供事件组标志实现多事件管理。

Flag只是使用0/1来表示某个事件是否发生过,而不能直接被用来传递数据和消息。

可以选择性地设置一个Flag最多可以管理的任务同步状态。

主要包含在C源文件OS_FLAG.C中。

(2)Flag数据结构

#defineOS_FLAGS_NBITS8/16/32//定义OS_FLAGS的位数

FCB结构体:

   typedefstructos_flag_grp{

    INT8UOSFlagType;

 //事件类型

    void*OSFlagWaitList;

//指向等待的任务链表

    OS_FLAGSOSFlagFlags;

  //信号列表

    INT8UOSFlagName[OS_FLAG_NAME_SIZE];

    }OS_FLAG_GRP;

事件标志等待链表结点

   typedefstructos_flag_node{

    void*OSFlagNodeNext;

    void*OSFlagNodePrev;

    void*OSFlagNodeTCB;

    void*OSFlagNodeFlagGrp;

//指向此任务所等待的事件组标志

    OS_FLAGSOSFlagNodeFlags;

//等待的事件

    INT8UOSFlagNodeWaitType;

//等待方式

    }OS_FLAG_NODE;

OS_EXTOS_FLAG_GRPOSFlagTbl[OS_MAX_FLAGS];

OS_EXTOS_FLAG_GRP*OSFlagFreeList;

OS_FLAG_GRP*OSFlagCreate(OS_FLAGSflags,INT8U*err);

OS_FLAGSOSFlagPend(OS_FLAG_GRP*pgrp,OS_FLAGSflags,

(3)Flag管理函数

INT8Uwait_type,INT16Utimeout,INT8U*err);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 中考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1