嵌入式实时操作系统small RTOS51原理及应用 ----笔记 前言 绪论

本文详细介绍了围绕DP-51单片机仿真实验仪的硬件电路,阐述了SmallRTOS51操作系统的设计原理。深入探讨了RS232、I2C、USB1.1和CANBUS等外围器件的应用设计,同时提供了三种串行通信协议处理方法,包括中断处理、队列使用和信号量机制。

围绕 DP-51 单片机仿真实验仪的硬件电路,
阐述Small RTOS51 操作系统的设计原理。
详细的介绍了RS232 ,I2C,USB1.1和CANBUS等一系列外围器件及其功能部件的应用设计。

本书的原理篇,以Small RTOS V1.12.1版本为基础,

微型嵌入式实时操作系统的网址为: http://www.smallrtos.org/

数据包长度为NBYTE,起始字节为STARTBYTE1,
STARTBYTE2,最后一个字节为校验和,中间字节,不可能连续出现,STARTBYTE1,STARTBYTE2.

第一种方法---- 在中断中处理协议.

程序清单 0.1

#define NBYTE 20 
unsigned char Buf[NBYTE-2];

unsigned char GetRight  = 0 ;

#define STARTBYTE1  0xAA
#define STARTBYTE2  0x77


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 ; 

        }
    }

}

第2种方法 ,使用队列

void comm(void) interrupt 4 
{
    //串口中断

    if(RI ==1){

        RI = 0 ;
        SBUF_In ;//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;
    }

    SBUF 出队列 ;

    if(temp != STARTBYTE1){

        return 0 ;
    }

    temp = 队列首字节;

    if(temp != STARTBYTE2){

        return 0;
    }

    .......

    
}

第3种方法:

void comm(void ) interrupt 4
{
    //串口中断

    OS_INT_ENTER();

    if(RI == 1){

        RI = 0 ;
        OSIntSendSignal(RECIVE_TASK_ID);
        
    }

    OSIntExit();
}

void Receive(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");            
        }
        
    }
}


为啥要用队列

情况1:接收超时处理
情况2:如果数据来得太快,命令处理程序来不及处理,丢弃数据

编辑推荐 本书主要特点: 分为原理篇和应用篇,原理与实践相结合,两篇相对独立,又紧密联系。 原理篇以分析源码为特色,深入浅出地介绍RTOS的基本概念以及Small RTOS51的工作原理应用篇以DP-51单片综合仿真实验仪为硬件平台,通过对单片机常用和热门外围器件实用驱动程序的分析,详细介绍基于Small RTOS51的编程方法,以及如何为这些外围器件编写中间件,并给出一个完整的例子,让读者全面掌握基于Small RTOS51的编程方法,体会了RTOS下编程的优点。 内容简介 Small RTOS51是为51系列单片机而编写的。它是完全免费的、源代码公开的多任务实时操作系统。它可在无任何外部数据存储器的单片80C51系统上运行,并且是可移植的。全书分两部分。第一部分为基础篇,介绍Small RTOS51和一些基本概念,并详细分析Small RTOS51的工作原理。第二部分为应用篇,给出部分常用硬件在Small RTOS51下驱动程序的源代码。这些源代码在DP—51单片机仿真实验仪上全部调试通过,且只要经过很少的改动,或是不改动,就可以在其他环境下使用。应用篇还通过对这些源代码的分析,让读者理解基于RTOS的编程方法,并给出完整的例子让读者全面掌握基于RTOS的编程方法。 本书可以作为高等院校相关专业的课程教材、实验参考资料或课外读物,对嵌入工应用开发人员也有重要的参考价值。 目录 第一部分 原理篇 第0章 绪论 第1章 Small RTOS51简介 1.1 Small RTOS51的特点 1.2 Small RTOS51的运行条件 1.3 Small RTOS51的存储器需求 1.4 Small RTOS51的任务堆栈的计算 1.5 关于可重入功能 1.6 关于C51的库函数 1.7 关于51系列单片机派生类型的多数据指针和数学单元 1.8 关于51系列单片机的寄存器段 1.9 关于局部变量 第2章 基本概念 2.1 嵌入式系统 2.2 实时系统 2.3 前、后台系统 2.4 操作系统 2.5 实时操作系统 2.6 代码的临界区 2.7 资源 2.8 共享资源 2.9 任务 2.10 任务切换 2.11 内核 2.12 调度 2.13 非占先式内核 2.14 占先式内核 2.15 可重入性 2.16 任务优先级 2.17 信号量 2.18 死锁 2.19 消息队列 2.20 中断 2.21 时钟节拍 第3章 一个简单的例子 3.1 Small RTOS51的安装及目录结构 3.2 例子简介 3.3 Config、h、Os_cfg、h和Os_cpu.h 3.4 与编程器无关的数据类型 3.5 OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL() 3.6 main()函数 3.7 建立任务 3.8 删除任务 3.9 用户任务 3.10 软非屏蔽中断 3.11 中断服务程序的编写 3.12 Os_cpu.h可改变的其他内容 3.13 Small RTOS51的其他注意事项 第4章 任务管理—核心的核心 4.1 临界区 4.2 任务 4.3 任务状态 4.4 与任务相关的数据结构 4.5 任务调度 4.6 Small RTOS51中的中断处理 4.7 时钟节拍 4.8 Small RTOS51初始化和启动 4.9 建立任务 4.10 任务堆栈 4.11 删除任务 4.12 时间服务及任务的挂起和恢复 4.13 获取当前Small RTOS51的版本号 4.14 OSInt…()函数 第5章 如何切换任务 5.1 CPU可以执行多个任务的原因 5.2 CPU怎样运行才能执行多个任务 5.3 何时进行任务切换 5.4 Small RTOS51任务切换时的程序框图 5.5 数组OSTsakStackBotton[]和Small RTOS51的堆栈结构 5.6 变量OSFastSwap 5.7 常量数值OSMapTb[] 5.8 软非屏蔽中断的堆栈SP2[] 5.9 中断切换函数OSIntCtxSw()OSIntCtxSw() 5.10 任务主动放弃CPU-OS_TASK_SW() 5.11 堆栈变换函数C_OSCtxSw() 5.12 恢复新任务环境LoadCtx() 5.13 优先级最低的任务OSIdle() 5.14 Small RTOS51初始化函数OSStart() 5.15 系统时钟节拍中断OSTickISR() 第6章 任务之间的通信和同步之信号量 6.1 概述 6.2 使Keil C51函数具有重入性的特殊方法 6.3 数据结构 6.4 IN_OS_SEM_CHK宏及相关代码 6.5 初始化一个信号量 6.6 等待一个信号量 6.7 发送一个信号量 6.8 无等待地请求一
Small RTOS(51) 1.20.3v 说明文件 编写动机: 就像在嵌入系统中使用C语言替代汇编一样,在嵌入系统中使用RTOS是大势所趋。原因主要是现在在大多数情况下编程效率比执行效率重要(单片机便宜嘛)。但纵观51RTOS,keil c51 所带的RTX Full 太大(6k多),且需要外部ram,又无源代码,很多时候不实用。RTX Tiny虽然小(900多字节),但是任务没有优先级和中断管理,也无源代码,也不太实用。而ucosII虽有源代码,但是它太大,又需要外部ram,所有函数又必须是重入函数,用在51这类小片内RAM的单片机上有点勉强。于是,我借鉴ucosII和RTX Tiny编写了Small RTOS 51,虽然它为51系列编写,但是它还是比较容易移植到其它CPU上。 与作者联系方法: 可以给chenmingji@tom.com(原chenmingji@163.net)写信,或是在www.zlgmcu.com.cn上的论坛ARM与ucosII区提问(目前本人是版主)或是在www.c51bbs.com的论坛上提问(不推荐。c51bbs和21ic网名均为cmj)。 版本号定义方式: a.bc.d a:主版本号,一般重大改变时改变它。 bc:次便本号,一般功能增加时改变它。 d:同一版本的修订序号。 版本升级: 1.20.3版 2004年6月8日 修正Os_q.c的一个BUG,造成FIFO发送数据时,在队列中有大量数据且队列较大时,可能会出错。 1.20.2版 2004年2月4日 修正for Keil c51的Os_cpu_c.c的StkDelB函数的BUG,它会影响任务删除的正确执行。 1.20.1版 2004年2月4日 修改OSWait(K_SIG | K_TMO, x) 只能通过信号唤醒的bug。 1.20.0版 2003年8月3日 支持任务动态建立与删除。函数功能向一般的RTOS靠拢。支持C51的重入函数(用关键字reentrant定义的函数)。支持动态内存分配(使用动态内存分配的任务必须使用重入栈)。 1.12.1版 2003年2月5日 修正OS_MAX_TASKS为8、16时的bug。同时修正一些小bug。 1.12.0版 2003年1月24日 OS_MAX_TASKS就是用户任务数量。同时修正一些小bug。 1.11.0版 2002年12月2日 各个任务具有自己的关中断计数器,不在互相影响(这意味着如果一个任务在任务放弃CPU前关了中断,当它再次进入运行态时中断还是关的)。优先级最低的任务作为系统保留任务不再需要用户编写,同时节约一些内存。增加一些注释。更正在Keil C51下Memory Model为非Small 模式的Bug。 1.10.5版 2002年10月26日 更正许多小Bug。 1.10.4版 2002年10月6日 合并Os_cpu_a.asm和OS_CPU_A_task16.ASM。统一了一下代码风格 1.10.3版 2002年9月16日 修改了Os_cpu_a.asm和OS_CPU_A_task16.ASM的LoadCtx代码使之执行更快,代码更小 1.10.2版 2002年9月9日 更正OSWait()的Bug,在极端情况下,这个Bug可能造成可能锁死任务。 修改OSQIntPost()的Keil C51特殊代码,它会造成阅读障碍。 1.10.1版 2002年9月4日 更正OSTimeTick的Bug,它在keil c51中不会有问题,但移植的其它系统可能出错。 1.10版 2002年9月1日 增加Small RTOS 对消息队列(简化的)和信号量的支持;改变了开关中断的方式;增加可移植的变量定义;修正一些Bug。 1.00版 2002年6月20日 使用户可以进行更多的配置,可以禁止中断管理,51系列支持软的非屏蔽中断,并调整目录结构等. 0.60版 2002年5月10日 修改OS_CORE.c使之在keil c51可以重入。不再需要禁止覆盖分析。 0.52版
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值