新闻  |   论坛  |   博客  |   在线研讨会
快速学习uc/os ii _资料收集
sheji105 | 2010-01-22 12:13:10    阅读:3260   发布文章

uCOS-II移植其实十分简单。对于一个处理器,需要做的工作只有:修改三个文件――os_cpu_c.c、os_cpu.h、os_cpu_a.asm(ASM文件根据编译器不同而又有一些不同)。

 

用另一种方式说,需要做的工作就是修改五个函数:

 

1、os_cpu_c.c:OSTaskStkInit;

 

2、os_cpu_a.asm:OSStartHighRdy、OSCtxSw、OSIntCtxSw、OSTickISR;

 

OSTaskStkInit函数是针对CPU压栈的函数,需要模仿出CPU初始化后的寄存器状况。也使需要修改的唯一一个C语言函数。其他的都是汇编函数。

 

http://www.cnblogs.com/jiangxinghui/archive/2009/09/04/1560449.html

 

第三章 内核结构
1. 临界段
      uc为了处理临界段代码,需要开关中断。 因为不同的系统硬件,有不同的实现方法,uc定义了os_enter_critical 和 os_exit_critical宏,放在os_cpu.h文件中
2.任务
      任务就是一个无限的循环,永不返回。(所以返回值为void).  任务可以传入参数。这样可以建立多个相同代码的任务,但是可以有不同的参数。


      void xxxTask(void *pData)

      uc/os总是执行进入就绪态的最高优先级的任务,(如果有高优先级的任务一直在执行,别的任务就没有办法执行了,所以如果要共享cpu,就要让出来,等待一段时间,让别的任务有机会执行。)


当所有任务都在等待中时,就会运行idle任务。
3.任务控制块

ucos用它来保存任务的当前状态,当任务重新执行的时候,tcb能够确保任务返回到中断时的状态
OSTcbStkPtr 当前任务的堆栈的指针
OSTcbPrev OSTcbNext 双向链表使得建立任务时,ostcb能够被快速的插入和删除

OS_MAX_TASKS 在OS_CFG.H中,定义少些,可以省掉tcb所占用的内存

第五章 时间管理

OSTimeDly(INT16U ticks)

延时以时钟节拍记。

×:如果要延时一个时钟节拍,任务挂起后会在一个时钟到来时就要执行(如果没有其他就绪的高优先级任务),这之间的间隔是不定的,因为任务挂起与时钟节拍非同步的,因此中间的间隔会在一个时钟节拍之间变化。
      因此,如果要延时一个时钟节拍,必须至少延迟2个时钟节拍。
--OSTimeDlyHMSM()
可以按直接指定时分秒延时,最多256小时

 

 

 

 

http://blog.21ic.com/user1/5930/archives/2009/62174.html

先列一下比较重要的几个量(MAX_TASKS表示最大任务个数,LOWEST_PRIO指最低优先级数):
OSRunning:用于标识多任务环境是否已经开启运行,在OSStart()函数里启动任务后就置为True。

OSIntNesting:用于标识中断嵌套层数。产生一次中断可以调用OSIntEnter()函数使该值自增1,处理完一次中断再调用OSIntExit()自减1。

OS_TCB:一个结构体变量,每建立一个任务都会为该任务指定一个OS_TCB,包含该任务的栈顶指针,任务优先级,任务状态字,延时节拍等所有相关信息。每个任务的OS_TCB都存在于一个双向链表内,并使变量OSTCBList指向最后建立的那个任务的OS_TCB。

OS_STK:任务堆栈,每个任务都有一个自己的堆栈空间,用于保存寄存器,状态值,和任务的入口地址。这个堆栈与系统栈没有什么关系,只是用户为一个任务分配的存储任务信息的空间,只需要是一个连续的存储空间即可。

OSRdyGrp,OSRdyTbl[ ]:用于标识就绪的任务。uC/OS根据优先级唯一确定一个任务,也即一个优先级只能分配给一个任务。OSRdyTbl[ ]里保存(MAX_TASKS/8+1)个字节,每个字节又有8个Bit,从最低位开始分别对应0~LOWEST_PRIO优先级的任务,任务就绪时就将该任务的优先级所在Bit置1,否则清0。
OSRdyGrp完全是为了找到最高优先级方便而设立的,将OSRdyTbl[ ]里每个字节代表的8个任务划为一个组,只要某一组内有就绪任务时,OSRdyGrp的相应位就置1。比如,只要OSRdyTbl[0]不为0,则OSRdyGrp的第0位就置1,依次类推。

OSPrioCur:这是一个整型数,表示当前执行任务的优先级数。

OSPrioHighRdy:一个整型数,表示当前最高级别的就绪任务的优先级数。

OSTCBHighRdy:这是一个指针,它指向最高优先级就绪任务的OS_TCB。

OSTCBCur:一个指针,指向当前执行任务的OS_TCB。

OSTCBTbl[ ]:初始化时建立的一块存储空间,一共建立了MAX_TASKS个OS_TCB空间。并令变量OSTCBFreeList总是指向下一个可用的OS_TCB空间。当新建立一个任务时,就将一个空的OS_TCB空间分配给它使用。

OSTCBPrioTbl[]:这是一个指针数组,用于保存就绪任务的OS_TCB地址,一共有MAX_TASKS个值,依次对应0~LOWEST_PRIO优先级的任务。当某一优先级未分配给一个任务时,该数组对应元素的值为(void *)0,当某优先级的任务分配给一个处于就绪态的任务时,对应元素的内容就被写入该任务的OS_TCB所在地址。

拿到没用过的系统,首先就想知道它是怎么用的,对于一个实时操作系统,先要解决以下几个问题:
如何切换任务
uC/OS多任务的原理是,在某个任务重新获得CPU控制权的时候,先把上一个执行的任务的所有寄存器以及它的返回地址保存起来,然后把现在要执行的任务的所有变量恢复到操作寄存器里,然后使PC指向这个任务的处理函数。而保存和恢复变量的重要媒介就是每个任务独有的堆栈空间,这点跟中断处理的过程几乎一样,重新获得CPU的任务可以看成是中断函数,原先执行的看成是被中断的函数,只不过uC/OS是模拟中断来切换任务,所有堆栈的保存和恢复要在移植不同处理器的时候根据实际情况来完成,目的只有一个,就是模拟中断的压栈和出栈操作。
uC/OS引起任务切换的功能函数主要是两个,任务级的切换是OSSched(),中断级的切换由OSIntExit()完成。而前者中真正实现切换操作的是OS_TASK_SW()宏,后者真正实现切换功能的是OSIntCtxSw(),这个宏如何实现,移植不同的处理器有不同的处理方法,目的仍然是,把现场处理的跟真正发生了中断一样,该保存的保存,该恢复的恢复。
因此可以得到,uC/OS切换任务时可以有两种方法,第一种是拥有CPU控制权的任务主动调用函数OSTimeDly()、OSTaskSuspend()等这类函数把控制权交出来,重新分配给下一个优先级高的任务,实际上是依靠OSSched()调度任务。第二种方法是CPU产生中断,把当前任务的控制权剥夺掉,令它挂起,从而使下一优先级的任务得以执行,当然,如果中断没有令当前任务挂起,中断返回后它依然是最高优先级的话,CPU将继续被它控制。

如何查找最高优先级
uC/OS把一个字节可能的256个值的所有优先级状况都做成一个表OSUnMapTbl[ ],比如,如果字节的值为7,即0000 0111,那么任务0,1,2都处于就绪态,最高优先级当然是0,那么OSUnMapTbl[7] == 0,因此,先通过y = OSUnMapTbl[OSRdyGrp]找到最高优先级的组y,然后通过x = OSUnMapTbl[OSRdyTbl[OSRdyGrp]]得到这个组里的最高优先级任务号x。因为uC/OS最大任务数不超过64,可以把优先级数看成是一个六位的二进制数,高三位表示所在组,低三位表示组内的号,因此y<<3+x就是找到的最高优先级数了,实在佩服OSUnMapTbl[ ]的设计。

 

 

  最近空余时间,一直想自己动手做开发板,学习板,一来可以巩固之前学的东西,二来可以增加收入,现在工资的钱越来越不够花了;三来,可以学习新技术。很久前就想学学嵌入式系统,uc/os入门简单点,还是免费的。最近要把uc/os用的熟练起来。
  如果哪位感兴趣的,可以到我网店瞧瞧,留点意见。

 


QQ:1260899819我的网店:http://shop59770701.taobao.com/

愿与大家共同学习,共同享受电子世界

 

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客