专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

详解基于51单片机的small rtos(1)

作者:佚名   来源:本站原创   点击数:  更新时间:2012年01月13日   【字体:

      陈明计,这个人有必要要认识下,因为small rtos 是他写的,他根据ucos的原理写的。这个small rtos是可以再51单片机上运行的,但是受ARM内存的限制。 作为单片机开发的时刻都得想着内存的问题,因为51芯片资源有限。  好了不废话开始学习的旅程
 
        首先你可以在51hei下个small rtos 源代码 http://www.51hei.com/f/small_rtos1.12.1.zip   或者跟我一步一步写。  keil51的工具编译代码后会生成一个.m51的文件,这个文件要学会去看,因为他把你的一些内存分配的地址和函数的地址都会以列表显示出来。  
      操作系统的任务其实都是一个死循环。我们写的操作系统其实就是把$P单片机的指针指向任务的首地址而已。那么首地址我们必须要保存下来以便任务切换的时候使用在small rtos 中时保存在  OSTsakStackBotton[]这个数组内部的。那么我们怎样获取到任务的首地址呢,在这里 他是静态存放到数组内的。即  void  (* code TaskFuction[OS_MAX_TASKS])(void)={TaskA,TaskB,TaskC};  这个事一个函数指针存放的数组,看不明白的你可以查下资料。  这里他保存了3个函数的地址  。 
 通过编译后查看.m51文件也可以看到相关信息。 (这个是我编译后的文件默认是在E:\temp当然你可以改下路径)
             CODE    03A4H     000AH     UNIT         ?PR?TASKA?EXT1
            CODE    03AEH     000AH     UNIT         ?PR?TASKB?EXT1
            CODE    03B8H     000AH     UNIT         ?PR?TASKC?EXT1
            C:03B7H         PUBLIC        TaskFuction
    通过上述的可以看出  TaskFuction 首地址在   C:03CBH   那么程序运行后可以直接翻看C:03B7H 地址 看接下来的地址内是否存放  
    核对下应该是和.m51一致的。   任务首地址有了,然后我们看下他的代码。mian()里面没什么代码就是定时器0的初始化,还有就是OSStart() 这个函数 .这个函数其实就是初始化堆栈并把系统切到任务A  的函数。至于怎么处理关键的堆栈如何处理。我们来仔细看下.  我这里运行到mian()函数栈顶指针
  至于你想知道为什么是0x15看下.m51 
 


这里其实已经告诉你了。第0组工作寄存器8个+8个DATA数据定义。然后mian()调用 OSStart()


跳转到OSStart() 里
这里看出压入了2个字节(51是字节),
  从内存中可以看出压入的是下个代码的地址。 聪明的可能已经看出来了,吧任务A的地址替换这里的86 03 ,那么执行RET就可以跳转到任务A中去执行代码。到这里是不是让你来劲了?  然后我们继续。  这个STACK 是什么,呵呵在汇编部分的代码如下:  


这里重定位堆栈,并定义了一个内存单元,至于他的位置看.m51 
  是不是很巧合,刚好在存放main()函数指针的RAM地址那,但是仔细想想这是理所当然的,但是你也可以也可以想办法不怎么巧合,但是这样充分利用 RAM空间吧任务A的覆盖main入栈的指针式最好的。  然后下面代码应该很好理解。吧任务的首地址存到随机变动的OSTsakStackBotton中,这里还加了个空闲任务的函数指针。然后开始部署各个任务的堆栈空间。 他压入任务A的首地址然后把栈顶指针知道任务A的高地址中,然后从尾部开始存放底0,优先级任务,0,任务C,0,任务B。那么中间的空代码部分就可以作为任务A可以使用的内存块。    然后就跳转到任务A中执行代码

     至此我已经把第一个任务切换,解析出来了。 

关闭窗口

相关文章