UCOSII 是一个可以基于 ROM 运行的、可裁减的、抢占式、实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统(RTOS)。为了提供最好的移植性能, UCOSII 最大程度上使用 ANSI C 语言进行开发,并且已经移植到近 40 多种处理器体系上,涵盖了从 8 位到 64 位各种 CPU(包括 DSP)。
UCOSII 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用 C 语言编写的。 CPU 硬件相关部分是用汇编语言编写的、总量约 200 行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的 CPU 上。用户只要有标准的 ANSI 的 C 交叉编译器,有汇编器、连接器等软件工具,就可以将 UCOSII 嵌人到开发的产品中。 UCOSII 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。
UCOS主要有:
任务管理:
建立任务OSTaskCreat()/OSTaskCreatExt();
任务堆栈OS_STK()
堆栈检验OSTaskStkChk()
删除任务OSTaskDel()
请求删除任务OSTaskDelReq()
改变任务的优先级OSTaskChangePrio()
挂起任务OSTaskSuspend()
恢复任务OSTaskResume()
时间管理:
任务延迟函数OSTimeDly()
按时,分,秒延时函数OSRimeDLyHMSM()
恢复延时的任务OSTimeDlyResume()
系统时间OSTimeGet()和OSTimeSet()
内存管理:
Typedef struct
{
void *osmemaddr ;指向内存分区起始地址的指针。
Void *osmemfreelist ;指向下一个空余内存控制块或者下一个空余内存块的指针,
Int32u osmemblksize ;内存分区中内存块的大小,是建立内存分区时定义的。
Int32u osmemnblks ;内存分区中总的内存块数量,也是建立该内存分区时定义的。
Int32u osmemnfree ;内存分区块中当前获得的空余块数量。
}os_mem;
建立一个内存分区,OSMemCreate()
分配一个内存块,OSMemGet()
释放一个内存块,OSMemPut()
任务调度:
任务控制块TCB(Task Control Block)
最高级就绪任务的TCB 地址OSTCBHighRdy
OS_TASK_SW()函数来进行任务切换
任务间通信与同步:信号、邮箱、队列
使用UCOS最重要的还是了解信号量,信号量集,邮箱,消息队列等的用法。在这里我主要以自己的理解来说明这个相关函数的用法。
1.信号量:用于从一个任务向另一个任务传递一个开关量的BOOL信号。
创建信号量指针:OS_EVENT *OSSemFlag。
创建信号量函数:OS_EVENT *OSSemCreate (INT16U cnt)。
发送信号量函数:INT8U OSSemPost(OS_EVENT *pevent)。
请求信号量函数:void OSSemPend( OS_EVENT *pevent, INT16U timeout, INT8U *err);其中需要注意的是Timeout,这个参数为0的时候表示无限等待,大于0就为表示演示多少个时钟节拍。
2.邮箱 :用于从一个任务向另一个任务传递一个字节的数据。
创建邮箱指针:OS_EVENT *OSMbox;
创建邮箱函数:OSMboxPost (OS_EVENT *pevent,void *msg)
请求邮箱函数:void *OSMboxPend (OS_EVENT *pevent, INT16U timeout,INT8U *err)其中需要注意的是Timeout,这个参数为0的时候表示无限等待,大于0就为表示演示多少个时钟节拍。
查询邮箱状态函数:OSMboxQuery(OS_EVENT *pevent,OS_MBOX_DATA *pdata) 。
删除邮箱函数:OS_EVENT *OSMboxDel(OS_EVENT *pevent,INT8U opt,INT8U *err)。
3.信号量集:用于从一个任务向另一个任务传递最多32个开关量的BOOL信号集。
创建信号量集指针:OS_FLAG_GRP *OutEnableCfgFlag。
创建信号量集函数:OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags,INT8U *err )
发送信号量集函数:OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *err)
请求信号量集函数:OS_FLAGS OSFlagPend(OS_FLAG_GRP*pgrp, OS_FLAGS flags, INT8U wait_type, INT16Utimeout, INT8U *err)。注意:为了防止请求失效,一般使用OS_FLAGS+OS_FLAG_CONSUME的组合。
查询信号量状态函数:OS_FLAG_GRP *OSFlagQuery(OS_FLAG_GRP *pgrp,INT8U *err ),我们可以使用这个函数来不断查询这个信号量集的状态来做一些开关量的控制。
4.消息队列:用于从一个任务向另一个任务传递多个字节的数据。
创建消息队列指针:OS_EVENT * MainMenuUI;
创建消息队列存储数组:void * MsgGrp[16];
创建消息队列函数:OS_EVENT *OSQCreate(void**start,INT16U size)
请求消息队列函数:void*OSQPend(OS_EVENT*pevent,INT16U timeout,INT8U *err)
查询消息队列函数: INT8U OSQQuery(OS_EVENT*pevent,OS_Q_DATA *pdata)
发送消息队列函数:INT8U OSQPost(OS_EVENT*pevent,void *msg)和 INT8U OSQPost(OS_EVENT*pevent,void*msg)
清空消息队列函数: INT8U OSQFlush(OS_EVENT*pevent)
删除消息队列函数:OS_EVENT *OSQDel(OS_EVENT*pevent)
5.软件定时器:用于产生非硬件的定时器中断,可以用计时。
创建软件定时器指针:OS_TMR * ADCheckTime
创建软件定时器函数:OS_TMR *OSTmrCreateINT32U dly, INT32U period, INT8U opt, OS_TMR_CALLBACK callback,void *callback_arg, INT8U *pname, INT8U *perr)
打开软件定时器函数:BOOLEAN OSTmrStart (OS_TMR *ptmr, INT8U *perr)
关闭软件定时器函数:BOOLEAN OSTmrStop (OS_TMR *ptmr,INT8U opt,void *callback_arg,INT8U *perr)