Ch7 uC/OS-II分析(2) 宋健建 南京大学软件学院 2006/11
Content 任务间通信 内存管理
任务间通信的机制 POSIX IPC uC/OS-II
1、两个实体之间,不管是进程还是线程,要通信就必须有共享资源。 2、在象uC/OS-II这样全部代码都在同一个空间中运行的系统,这似乎易如反掌,因为每个全局量都是所有任务(以及中断服务程序)能访问的共享资源。 发送端、接收端。发送端不会阻塞,接收端可能因受阻要进入等待态。这样的设计简化了任务间通信机制的实现。 发送端:任务、中断服务程序 接收端:任务(注意:接收端不能是ISR。Why?提问)
ECB OS_EVENT (ucos-ii.h) #if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0) typedef struct { INT8U OSEventType; INT8U OSEventGrp; INT16U OSEventCnt; void *OSEventPtr; INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; } OS_EVENT; #endif 该结构两个主要部分: 1、事件本身的定义; 2、等待该事件的任务的列表
uC/OS-II IPC类型 Event Types (ucos-ii.h) #define OS_EVENT_TYPE_UNUSED 0 #define OS_EVENT_TYPE_MBOX 1 #define OS_EVENT_TYPE_Q 2 #define OS_EVENT_TYPE_SEM 3 #define OS_EVENT_TYPE_MUTEX 4 #define OS_EVENT_TYPE_FLAG 5
ECB的操作 数据结构 操作 空余事件控制块列表 初始化一个事件控制块 使一个任务进入就绪态 使一个任务(当前任务)进入等待某事件发生的状态 OSEventFreeList (ucos-ii.h) OSInit() 操作 初始化一个事件控制块 OS_EventWaitListInit() (OS_Core.c) 使一个任务进入就绪态 OS_EventTaskRdy() (OS_Core.c) 使一个任务(当前任务)进入等待某事件发生的状态 OS_EventTaskWait() (OS_Core.c) 由于等待超时而将任务置为就绪态 OS_EventTO() (OS_Core.c) 针对每一项操作可以问很多问题,让学生思考该项操作怎么实现。
Semaphore 创建一个信号量 删除一个信号量 等待一个信号量 发出一个信号量 无等待地请求一个信号量 OSSemCreate() (OS_sem.c) 删除一个信号量 OSSemDel() 等待一个信号量 OSSemPend() 发出一个信号量 OSSemPost() 无等待地请求一个信号量 OSSemAccept()
MBox OSMboxCreate() (os_mbox.c) OSMboxPost() OSMboxPend() Addition: OSMboxAccept() OSMboxQuery()
Message Queue (Queue) 数据结构OS_Q (os_q.c) OSQCreate() OSQPost() OSQPend()
Mutex Semaphore的“优先级倒转”问题 Priority Inheritance Priority (PIP) OSMutexCreate (os_mutex.c) PIP作为参数传入 OSMutexPend OSMutexPost
Event Flags 功能最强的同步机制 进程同步 逻辑或同步 逻辑与同步 UNIX中的select系统调用 对多个共享资源的互斥访问,为预防死锁,“全有或全无” 逻辑与同步,预防死锁,all or nothing.
内存管理 Malloc()和free()动态分配内存 不足 内存碎片 执行时间不确定 嵌入式系统软件教程7.4
按分区进行内存管理 每个分区包含整数个大小相同的块; 不同分区块的大小可能不同 特定的内存块在释放时必须重新放回它以前所属于的内存分区
内存控制块 数据结构 操作 内存控制块OS_MEM OSInit() -> OSMemInit() OSMemCreate() 建立一个内存分区 OSMemGet() 分配一个内存块 OSMemPut() 释放一个内存块 OSMemQuery() 查询一个内存块
内存控制块 OS_MEM typedef struct { void *OSMemAddr; void *OSMemFreeList; INT32U OSMemBlkSize; INT32U OSMemNBlks; INT32U OSMemNFree; } OS_MEM; typedef struct { /* MEMORY CONTROL BLOCK */ void *OSMemAddr; /* Pointer to beginning of memory partition */ void *OSMemFreeList; /* Pointer to list of free memory blocks */ INT32U OSMemBlkSize; /* Size (in bytes) of each block of memory */ INT32U OSMemNBlks; /* Total number of blocks in this partition */ INT32U OSMemNFree; /* Number of memory blocks remaining in this partition */ } OS_MEM;