位置:51电子网 » 技术资料 » 测试测量

构造一个51单片机的实时操作系统

发布时间:2008/5/27 0:00:00 访问次数:769

        

    

    

    摘 要:从keil c51的内存空间管理方式入手,着重讨论实时操作系统在任务调度时的重入问题,分析一些解决重入的基本方式与方法:分析实时操作系统任务调度的占先性,提出非占先的任务调度是能更适合于keil c51的一种调度方式。为此,构造这一实时操作系统,并有针对性地介绍此系统的堆管理方法、任务的建立以厦任务的切换等。

    关键词:51单片机 实时操作系统 任务重八调度

    目前,大多数的产品开发是在基于一些小容量的单片机上进行的。51系列单片机,是我国目前使用最多的单片机系列之一,有非常广大的应用环境与前景,多年来的资源积累,使51系列单片机仍是许多开发者的首选。针对这种情况,近几年涌现出许多基于51内核的扩展芯片,功能越来越齐全,速度越来越快,也从一个侧面说明了51系列单片机在国内的生命力。

    多年来我们一直想找一个合适的实时操作系统,作为自己的开发基础。根据开发需求,整合一些常用的嵌入式构件,以节约开发时间,尽最大可能地减少开发工作量;另外,要求这个实时操作系统能非常容易地嵌入到小容量的芯片中。毕竟,大系统是少数的,而小应用是多数而广泛的。显而易见,μc/os—ii是不太适合于以上要求的,而keil c所带的rtx tiny不带源代码,不具透明性,至于其full版本就更不用说了。

    1 keii c51与重入问题

    说到实时操作系统,就不能不考虑重入问题。对于pc机这样的大内存处理器而言,这似乎并不是一个很麻烦的问题,借用μc/os—ii rtos的说法,即要求在重入的函数内,使用局部变量。但5l系列单片机堆栈空间很小,仅局限在256字节之内,无法为每个函数都分配一个局部堆空间。正是由于这个原因,keil c51使用了所谓的可覆盖技术:

    ①局部变量存储在全局ram空间(不考虑扩展外部存储器的情况);

    ②在编译链接时,即已经完成局部变量的定位;

    ③如果各函数之间没有直接或间接的调用关系,则其局部变量空间便可覆盖。

    正是由于以上的原因,在keil c51环境下,纯粹的函数如果不加处理(如增加一个模拟栈),是无法重人的。那么在keil c5l环境下,如何使其函数具有可重人性呢?下面分析在实时操作系统下面,任务的基本结构与模式:

    vold taska(void*ptr){

    uint8 val_a;

    //其他一些变量定义

    do{

    //实际的用户任务处理代码

    }while(1);

    }

    void taskb(void*ptr){

    uint8 valb;

    //其他一些变量定义

    do{

    funcl();

    //其他实际的用户任务处理代码

    )while(1);

    void funcl(){

    ulnt8 v al_fa;

    //其他变量的定义

    //函数的处理代码

    }

    

    在上面的代码中,taska与taskb并不存在直接或间接的调用关系,因而其局部变量val_a与val_b便是可以被互相覆盖的,即其可能都被定位于某一个相同的ram空间。这样,当taska运行一段时间,改变了val_a后,taskb取得cpu控制权并运行时,便可能会改变val_b。由于其指向相同的ram空间,导致taska重新取得cpu控制权时,val—a的值已经改变,从而导致程序运行不正确,反过来亦然。另一方面,funcl()与taskb有直接的调用关系,因而其局部变量val_fa与val_b不会被互相覆盖,但也不能保证其局部变量val_fa不会与taska或其他任务的局部变量形成可覆盖关系。

    

    将val_a、val_b以及val_fa等局部变量定义为静态变量(加上static指示符)可以解决这一问题。但问题是,定义大量的static类型变量,将导致ram空间的大量占用,有可能直接导致ram空间不够用。尤其是在一些小容量的单片机内,一般只有128或256字节,大量的静态变量定义,在如此小的ram资源状况下显然就不太合适了。由此而有了另一种的解决方法,如下代码所示:

    void taskc(void){

    uint8 x,v;

   &nbs

        

    

    

    摘 要:从keil c51的内存空间管理方式入手,着重讨论实时操作系统在任务调度时的重入问题,分析一些解决重入的基本方式与方法:分析实时操作系统任务调度的占先性,提出非占先的任务调度是能更适合于keil c51的一种调度方式。为此,构造这一实时操作系统,并有针对性地介绍此系统的堆管理方法、任务的建立以厦任务的切换等。

    关键词:51单片机 实时操作系统 任务重八调度

    目前,大多数的产品开发是在基于一些小容量的单片机上进行的。51系列单片机,是我国目前使用最多的单片机系列之一,有非常广大的应用环境与前景,多年来的资源积累,使51系列单片机仍是许多开发者的首选。针对这种情况,近几年涌现出许多基于51内核的扩展芯片,功能越来越齐全,速度越来越快,也从一个侧面说明了51系列单片机在国内的生命力。

    多年来我们一直想找一个合适的实时操作系统,作为自己的开发基础。根据开发需求,整合一些常用的嵌入式构件,以节约开发时间,尽最大可能地减少开发工作量;另外,要求这个实时操作系统能非常容易地嵌入到小容量的芯片中。毕竟,大系统是少数的,而小应用是多数而广泛的。显而易见,μc/os—ii是不太适合于以上要求的,而keil c所带的rtx tiny不带源代码,不具透明性,至于其full版本就更不用说了。

    1 keii c51与重入问题

    说到实时操作系统,就不能不考虑重入问题。对于pc机这样的大内存处理器而言,这似乎并不是一个很麻烦的问题,借用μc/os—ii rtos的说法,即要求在重入的函数内,使用局部变量。但5l系列单片机堆栈空间很小,仅局限在256字节之内,无法为每个函数都分配一个局部堆空间。正是由于这个原因,keil c51使用了所谓的可覆盖技术:

    ①局部变量存储在全局ram空间(不考虑扩展外部存储器的情况);

    ②在编译链接时,即已经完成局部变量的定位;

    ③如果各函数之间没有直接或间接的调用关系,则其局部变量空间便可覆盖。

    正是由于以上的原因,在keil c51环境下,纯粹的函数如果不加处理(如增加一个模拟栈),是无法重人的。那么在keil c5l环境下,如何使其函数具有可重人性呢?下面分析在实时操作系统下面,任务的基本结构与模式:

    vold taska(void*ptr){

    uint8 val_a;

    //其他一些变量定义

    do{

    //实际的用户任务处理代码

    }while(1);

    }

    void taskb(void*ptr){

    uint8 valb;

    //其他一些变量定义

    do{

    funcl();

    //其他实际的用户任务处理代码

    )while(1);

    void funcl(){

    ulnt8 v al_fa;

    //其他变量的定义

    //函数的处理代码

    }

    

    在上面的代码中,taska与taskb并不存在直接或间接的调用关系,因而其局部变量val_a与val_b便是可以被互相覆盖的,即其可能都被定位于某一个相同的ram空间。这样,当taska运行一段时间,改变了val_a后,taskb取得cpu控制权并运行时,便可能会改变val_b。由于其指向相同的ram空间,导致taska重新取得cpu控制权时,val—a的值已经改变,从而导致程序运行不正确,反过来亦然。另一方面,funcl()与taskb有直接的调用关系,因而其局部变量val_fa与val_b不会被互相覆盖,但也不能保证其局部变量val_fa不会与taska或其他任务的局部变量形成可覆盖关系。

    

    将val_a、val_b以及val_fa等局部变量定义为静态变量(加上static指示符)可以解决这一问题。但问题是,定义大量的static类型变量,将导致ram空间的大量占用,有可能直接导致ram空间不够用。尤其是在一些小容量的单片机内,一般只有128或256字节,大量的静态变量定义,在如此小的ram资源状况下显然就不太合适了。由此而有了另一种的解决方法,如下代码所示:

    void taskc(void){

    uint8 x,v;

   &nbs

相关IC型号

热门点击

 

推荐技术资料

音频变压器DIY
    笔者在本刊今年第六期上着重介绍了“四夹三”音频变压器的... [详细]
版权所有:51dzw.COM
深圳服务热线:13692101218  13751165337
粤ICP备09112631号-6(miitbeian.gov.cn)
公网安备44030402000607
深圳市碧威特网络技术有限公司
付款方式


 复制成功!