2409|2

480

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

单片机就那点资源,为啥那么多人想用RTOS? [复制链接]

 

最近看到群里面很多朋友在聊着关于单片机用裸机还是RTOS的讨论,于是今天找了一些内容分享一些观点。

对于搞单片机的特别用8051系列工程师来说,谈到单片机的RTOS,很多时候会问一句:“为什么要用RTOS?单片机就这一点资源,使用RTOS能保证效率吗?”

对于这个问题,我会反问:“你用单片机的目的是什么?是为了用单片机的C编程,单片机的汇编编程甚至于用单片机的二进制指令编程?”上个世纪80年代,工程师用二进制指令给Z80编程,现在还有谁在用?现在还有人死抱着汇编不放,但越来越多的人工程师使用C编程(我起初也是使用汇编的),为什么?

因为我们的目的是在有限的时间甚至是不充足的时间内把项目保质保量的完成!使用什么工具和方法是次要的(如果你的项目以成本放在第一位,则另当别论,这时,也是要考虑开发时间的)。时间就是金钱啊,一个产品在单片机上增加些许成本是可以接受的。

况且,使用8051系列单片机时,单片机资源也常有富余,CPU一般情况也只是空转,这就为它使用RTOS创造了条件。那么,使用RTOS的好处呢?

我举一个例子吧。假设我们编一个串行通讯程序,通讯协议如下:数据包长度为NBYTE,起始字节为STARTBYTE1,STARTBYTE2,最后一个字节为检验和,中间字节不可能出现连续出现STARTBYTE1,STARTBYTE2。

第一种方法,在中断中处理协议:

unsigned char Buf[NBYTE-2];
bit GetRight = 0;
void comm(void) interrupt 4//"串行口中断"
{
    static unsigned char Sum,Flag = 0,i;
    unsigned char temp;
    if(RI == 1)
    {
        RI = 0;
        temp = SBUF;
        switch(Flag)
        {
        case 0:
            if(temp == STARTBYTE1)
            {
                Flag = 1;
            }
            break;
        case 1: 
            if(temp == STARTBYTE2)
            {
                Sum = STARTBYTE1 + STARTBYTE2;
                i = 0;
                Flag = 2;
                break;
            }
            if(temp == STARTBYTE1) break;
            Flag = 0;
            break;
        case 2:
            if(temp == STARTBYTE1)
            {
                Flag = 3;
                break;
            }
            Sum += temp;
            if((i >= (NBYTE-3)) && Sum == 0)
            {
                GetRight = 1;
                Flag = 0;
                break;
            }
            Buf[i++] = temp;
            break;
        case 3:
            if(temp == STARTBYTE2)
            {
                Sum = STARTBYTE1 + STARTBYTE2;
                Flag = 2;
                i = 0;
                break;
            }
            Sum += STARTBYTE1;
            if((i >= (NBYTE - 3))&&Sum == 0)
            {
                GetRight = 1;
                Flag = 0;
                break;
            }
            Buf[i++] = STARTBYTE1;
            if(temp == STARTBYTE1)
            {
                break; 
            }
            Sum += temp;
            if((i >= (NBYTE-3))&&Sum == 0)
            {
                GetRight = 1;
                Flag = 0;
                break;
            }
            Buf[i++] = temp;
            Flag = 2;
            break;
        }
    }
}  

 

第二种方法,使用队列中断函数:
void comm(void) interrupt 4//"串行口中断"
{
    if(RI == 1)
    {
        RI=0;
        SBUF 入队;
    }
}  

 

主程序不断调用的函数:
unsigned char Buf[NBYTE-2];
unsigned char ReadSerial(unsigned char *cp)
{
    unsigned char i;
    unsigned char temp,Sum;
    temp = 队列中数据个数;
    if(temp < (NBYTE)) return 0;

    出队 temp;
    if(temp != STARTBYTE1) return 0;

    temp=队列首字节; 
    if(temp != STARTBYTE2) return 0;

    出队 temp;
    sum = STARTBYTE1 + STARTBYTE2;
    for(i = 0;i < NBYTE-3;i++)
    {
        temp = 队列首字节;
        if(temp == STARTBYTE1)
        {
            temp = 队列次首字节;
            if(temp == STARTBYTE2) return 0;
        }
        出队 temp;
        *cp++ = temp;
        Sum += temp;
    }
    temp = 队列首字节;
    Sum += temp;
    if(Sum != 0) return 0;
    出队 temp;
    return 1;
} 

 

第三种方法,使用RTOS中断函数:
 void comm(void) interrupt 4//"串行口中断"
 {
     OS_INT_ENTER();
     if(RI == 1)
     {
        RI = 0;
        OSIntSendSignal(RECIVE_TASK_ID);
     }
     OSIntExit();
} 

 

ID为RECIVE_TASK_ID的任务.

 

 void Recive(void)
 {
     unsigned char temp,temp1,Sum,i; 
     OSWait(K_SIG,0);
     temp = SBUF;
     while(1)
     {
         while(1)
         {
             OSWait(K_SIG,0);
             temp1 = SBUF;
             if((temp == STARTBYTE1)&&(temp1 == STARTBYTE2)) break;
             temp = temp1;
         }
         Sum = STARTBYTE1 + STARTBYTE2;
         OSWait(K_SIG,0);
         temp = SBUF;
         for(i = 0;i < NBYTE-3;i++)
         {
             OSWait(K_SIG,0);
             temp1 = SBUF;
             if((temp == STARTBYTE1)&&(temp1 == STARTBYTE2))
             {
                 OSWait(K_SIG,0);
                 temp=SBUF;
                 i = -1;
                 Sum = STARTBYTE1 + STARTBYTE2;
                 continue;
             }
             Buf[i] = temp;
             Sum += temp;
             temp = temp1;
         }
         Sum += temp1;
         if(Sum == 0) OSSendSignal(命令解释任务 ID);
     }
}

以下为这几种方法的比较可读性和编程容易性方面
第三钟方法最好(如果允许使用goto语句,程序更加简单易读)
第二种次之(因为要编队列程序)
第一种相对较差,如果协议更加复杂,这方面更加明显。
程序简单易读,自然出错机会小了。
RAM占用方面,第三种方法较少,第二种最多(因为队列占用大量空间),第一种最少。
中断执行时间方面,第三种方法最长,第二种最短,第一种较长。
从功能方面,第三种方法最强,它还可以进行超时处理(虽然例子程序没有),其它方法均不行。
如果数据来的太快,命令处理程序来不及处理,三种方法处理方式不太一样,第一种和第三种方法类似:丢弃以前数据,第二种则是丢弃后到的数据。而且,第二种方法必须等命令处理程序完成后才处理下一个数据包,而第一种和第三种方只需命令处理程序将数据收取后就可处理下一个数据包。也就是说,第一种和第三种与命令处理程序并行处理,第二种方法为串行处理。
现在,一般情况下,开发的效率第一,执行的效率(包括执行时间和资源占用)第二。在这种情况下,降低些许效率换取开发的效率的较大提高,何乐而不为?
何况,单个模块的执行的效率高不等于整个程序执行效率高。例如,如果程序需要等待一段时间,一般用程序延时或定时器延时。无论何种方法,CPU不再处理其它工作,效率很低。而用RTOS,等待的时候CPU可以处理其它工作,效率得到提高。
以下摘自《uC/OS-II--源码公开的实时嵌入式操作系统》

“实时内核也称为实时操作系统或RTOS。使用它使得实时应用程序的设计和扩展变得容易。不需要大的改动就可以增加新的功能。通过应用程序分割为若干独立的任务,RTOS使得应用程序的设计过程大为简化。使用可剥夺性的内核时,所有时间要求苛刻的事件都得到了尽可能快捷、有效的处理。通过有效的服务;如信号量、邮箱、队列、延时、超时等;RTOS使得资源得到更好的利用。“如果应用项目对额外的需求可以承受,应该考虑使用实时内核。这些额外的需求是:内核的价格,额外ROM/RAM开销,2至4百分点的CPU额外负担。“还有没提到的一个因素是使用实时内核增加的价格成本。在一些应用中,价格就是一切,以至于对使用RTOS连想都不敢想。”

总而言之,适用的就是最好的,不要拒绝RTOS,在它适用的情况下,它工作得很好。
作者 : 陈明,bug菌整理。

最新回复

和系统复杂度相关的,一个128k的rom可以放不少二进制代码了。简单的东西裸不裸无所谓,复杂之后如果还是裸机,那要么你十分牛逼,要么是自己给自己找不自在。这个道理和pc上跑windows或linux是一个道理的。   详情 回复 发表于 2021-5-31 14:55
点赞 关注
 

回复
举报

1942

帖子

2

TA的资源

版主

沙发
 

我觉得RTOS的好处比裸编多的多,而且上要往上走,一直停留在裸编没有什么好处,学会RTOS的思想会觉得嵌入式原来还能这么奇妙!

 
 
 

回复

7608

帖子

2

TA的资源

五彩晶圆(高级)

板凳
 

和系统复杂度相关的,一个128k的rom可以放不少二进制代码了。简单的东西裸不裸无所谓,复杂之后如果还是裸机,那要么你十分牛逼,要么是自己给自己找不自在。这个道理和pc上跑windows或linux是一个道理的。

 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表