在真正开始分析源代码前,先来看使用uC/OS-II的三个例子

1)使用信号量

#define  TASK_STK_SIZE                 512       /* 每个任务堆栈的大小(以字计算)*/
#define  N_TASKS                        10       /* 任务数*/

OS_STK        TaskStk[N_TASKS][TASK_STK_SIZE];        /*任务堆栈*/
OS_STK        TaskStartStk[TASK_STK_SIZE];            //开始任务的堆栈    
char          TaskData[N_TASKS];                      /*传给每个任务的数据*/
OS_EVENT     *RandomSem;                            //互斥型信号量

void  main (void)
{
    PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);      /*清空屏幕*/

OSInit();                                              /* 初始化uC/OS-II*/

PC_DOSSaveReturn();                                    /* 保存环境以便稍后可以返回DOS环境*/
    PC_VectSet(uCOS, OSCtxSw);                             /*设置uC/OS-II的切换处理函数*/
    RandomSem   = OSSemCreate(1);                          /* 建立一个信号量*/
    OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 0);//创建第一个任务,优先级设置为最大值
    OSStart();                                             /* 开始多任务*/
}
void  TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3                                /* 为CPU的状态寄存器分配内存*/
    OS_CPU_SR  cpu_sr;
#endif
    char       s[100];
    INT16S     key;
    pdata = pdata;                                         /* 这步是为了防止编译错误*/
    TaskStartDispInit();                                   /* 初始化显示屏*/
    OS_ENTER_CRITICAL();
    PC_VectSet(0x08, OSTickISR);                           /*替换机器的时钟中断函数为uC/OS-II所需要的中断函数*/
    PC_SetTickRate(OS_TICKS_PER_SEC);                      /* 调整时钟频率*/
    OS_EXIT_CRITICAL();
    OSStatInit();                                          /* 初始化统计任务*/
    TaskStartCreateTasks();                                /*创建其他任务*/
    for (;;) {
        TaskStartDisp();

if (PC_GetKey(&key) == TRUE) {                     /* 是否按键*/
            if (key == 0x1B) {                             /* ESCAPE按下了*/
                PC_DOSReturn();                            /* 返回DOS*/
            }
        }

OSCtxSwCtr = 0;                                    /* 切换次数计数器清零*/
        OSTimeDlyHMSM(0, 0, 1, 0);                         /*挂起秒,让给其他任务运行*/
    }
}
static  void  TaskStartCreateTasks (void)
{
    INT8U  i;
    for (i = 0; i < N_TASKS; i++) {                        /* 创建N_TASKS个任务*/
        TaskData[i] = '0' + i;                             /* 每个任务显示其数据*/
        OSTaskCreate(Task, (void *)&TaskData[i], &TaskStk[i][TASK_STK_SIZE - 1], i + 1);
    }
}

void  Task (void *pdata)
{
    INT8U  x;
    INT8U  y;
    INT8U  err;
    for (;;) {
        OSSemPend(RandomSem, 0, &err);           /* 获取信号量*/
        x = random(80);                          /* 计算X坐标*/
        y = random(16);                          /* 计算Y坐标*/
        OSSemPost(RandomSem);                    /* 释放信号量*/
        /* Display the task number on the screen              */
        PC_DispChar(x, y + 5, *(char *)pdata, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
        OSTimeDly(1);                            /* 挂起秒,让给其他任务运行*/
    }
}

2)使用消息邮箱

#define          TASK_STK_SIZE     512               
#define          TASK_START_ID       0                /* 任务ID*/
#define          TASK_CLK_ID         1
#define          TASK_1_ID           2
#define          TASK_2_ID           3
#define          TASK_3_ID           4
#define          TASK_4_ID           5
#define          TASK_5_ID           6

#define          TASK_START_PRIO    10                /* 任务优先级*/
#define          TASK_CLK_PRIO      11
#define          TASK_1_PRIO        12
#define          TASK_2_PRIO        13
#define          TASK_3_PRIO        14
#define          TASK_4_PRIO        15
#define          TASK_5_PRIO        16
OS_STK        TaskStartStk[TASK_STK_SIZE];            
OS_STK        TaskClkStk[TASK_STK_SIZE];             
OS_STK        Task1Stk[TASK_STK_SIZE];                
OS_STK        Task2Stk[TASK_STK_SIZE];                
OS_STK        Task3Stk[TASK_STK_SIZE];               
OS_STK        Task4Stk[TASK_STK_SIZE];              
OS_STK        Task5Stk[TASK_STK_SIZE];               
OS_EVENT     *AckMbox;                                /* 任务和使用的消息邮箱*/
OS_EVENT     *TxMbox;

void main (void)
{
    OS_STK *ptos;
    OS_STK *pbos;
    INT32U  size;
    PC_DispClrScr(DISP_FGND_WHITE);                       
    OSInit();                                            
    PC_DOSSaveReturn();                                  
    PC_VectSet(uCOS, OSCtxSw);                            
    PC_ElapsedInit();                                     
    ptos        = &TaskStartStk[TASK_STK_SIZE - 1];        
    pbos        = &TaskStartStk[0];
    size        = TASK_STK_SIZE;
    OSTaskStkInit_FPE_x86(&ptos, &pbos, &size);            
    OSTaskCreateExt(TaskStart,
        (void *)0,
        ptos,
        TASK_START_PRIO,
        TASK_START_ID,
        pbos,
        size,
        (void *)0,
        OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
    OSStart();                                             
}
void  TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3                               
    OS_CPU_SR  cpu_sr;
#endif
    INT16S     key;
    pdata = pdata;                                       
    TaskStartDispInit();                                
    OS_ENTER_CRITICAL();                                
    PC_VectSet(0x08, OSTickISR);
    PC_SetTickRate(OS_TICKS_PER_SEC);                    
    OS_EXIT_CRITICAL();
    OSStatInit();                                          
    AckMbox = OSMboxCreate((void *)0);                     /* 创建两个消息邮箱*/
    TxMbox  = OSMboxCreate((void *)0);
    TaskStartCreateTasks();                               
    for (;;) {
        TaskStartDisp();

if (PC_GetKey(&key)) {                           
            if (key == 0x1B) {                            
                PC_DOSReturn();                           
            }
        }
        OSCtxSwCtr = 0;                                    
        OSTimeDly(OS_TICKS_PER_SEC);                      
    }
}
void  Task1 (void *pdata)
{
    INT8U       err;
    OS_STK_DATA data;                       /* 任务堆栈数据*/
    INT16U      time;                      
    INT8U       i;
    char        s[80];
    pdata = pdata;
    for (;;) {
        for (i = 0; i < 7; i++) {
            PC_ElapsedStart();
            err  = OSTaskStkChk(TASK_START_PRIO + i, &data);//执行堆栈检查
            time = PC_ElapsedStop();
            if (err == OS_NO_ERR) {
                sprintf(s, "%4ld        %4ld        %4ld        %6d",
                    data.OSFree + data.OSUsed,
                    data.OSFree,
                    data.OSUsed,
                    time);
                PC_DispStr(19, 12 + i, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
            }
        }
        OSTimeDlyHMSM(0, 0, 0, 100);                       /* 挂起mS*/
    }
}
void  Task4 (void *data)
{
    char   txmsg;
    INT8U  err;
    data  = data;
    txmsg = 'A';
    for (;;) {
        OSMboxPost(TxMbox, (void *)&txmsg);      /* 发消息给Task #5*/
        OSMboxPend(AckMbox, 0, &err);            /* 等待Task #5的应答消息*/
        txmsg++;                                 /*下一个要发的消息数据*/
        if (txmsg == 'Z') {
            txmsg = 'A';                         /* 循环发送A-Z*/
        }
    }
}
void  Task5 (void *data)
{
    char  *rxmsg;
    INT8U  err;
    data = data;
    for (;;) {
        rxmsg = (char *)OSMboxPend(TxMbox, 0, &err); /* 等待来自Task #4的数据*/
        PC_DispChar(70, 18, *rxmsg, DISP_FGND_YELLOW + DISP_BGND_BLUE);
        OSTimeDlyHMSM(0, 0, 1, 0); /* 挂起秒,让给其他任务运行*/
        OSMboxPost(AckMbox, (void *)1); /*发送接收到数据的应答消息*/
    }
}

运行结果:

3)使用消息队列

#define          TASK_STK_SIZE     512               
#define          TASK_START_ID       0               
#define          TASK_CLK_ID         1
#define          TASK_1_ID           2
#define          TASK_2_ID           3
#define          TASK_3_ID           4
#define          TASK_4_ID           5
#define          TASK_5_ID           6
#define          TASK_START_PRIO    10               
#define          TASK_CLK_PRIO      11
#define          TASK_1_PRIO        12
#define          TASK_2_PRIO        13
#define          TASK_3_PRIO        14
#define          TASK_4_PRIO        15
#define          TASK_5_PRIO        16
#define          MSG_QUEUE_SIZE     20                /* 消息队列大小*/
typedef struct {
    char    TaskName[30];
    INT16U  TaskCtr;
    INT16U  TaskExecTime;
    INT32U  TaskTotExecTime;
} TASK_USER_DATA;
OS_STK          TaskStartStk[TASK_STK_SIZE];         
OS_STK          TaskClkStk[TASK_STK_SIZE];            
OS_STK          Task1Stk[TASK_STK_SIZE];              
OS_STK          Task2Stk[TASK_STK_SIZE];            
OS_STK          Task3Stk[TASK_STK_SIZE];             
OS_STK          Task4Stk[TASK_STK_SIZE];            
OS_STK          Task5Stk[TASK_STK_SIZE];             
TASK_USER_DATA  TaskUserData[7];
OS_EVENT       *MsgQueue;                             /*消息队列指针*/
void           *MsgQueueTbl[20];                      /*消息存储*/
void  main (void)
{
    PC_DispClrScr(DISP_BGND_BLACK);                        
    OSInit();                                            
    PC_DOSSaveReturn();                                    
    PC_VectSet(uCOS, OSCtxSw);                            
    PC_ElapsedInit();                                      
    strcpy(TaskUserData[TASK_START_ID].TaskName, "StartTask");
    OSTaskCreateExt(TaskStart,
        (void *)0,
        &TaskStartStk[TASK_STK_SIZE - 1],
        TASK_START_PRIO,
        TASK_START_ID,
        &TaskStartStk[0],
        TASK_STK_SIZE,
        &TaskUserData[TASK_START_ID],
        0);
    OSStart();                                          
}
void  TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3                                
    OS_CPU_SR  cpu_sr;
#endif
    INT16S     key;
    pdata = pdata;                                      
    TaskStartDispInit();                                
    OS_ENTER_CRITICAL();                                  
    PC_VectSet(0x08, OSTickISR);
    PC_SetTickRate(OS_TICKS_PER_SEC);                    
    OS_EXIT_CRITICAL();
    OSStatInit();                                         
    MsgQueue = OSQCreate(&MsgQueueTbl[0], MSG_QUEUE_SIZE); /*创建消息队列,大小为*/
    TaskStartCreateTasks();
    for (;;) {
        TaskStartDisp();                               
        if (PC_GetKey(&key)) {                           
            if (key == 0x1B) {                         
                PC_DOSReturn();                         
            }
        }
        OSCtxSwCtr = 0;                                   
        OSTimeDly(OS_TICKS_PER_SEC);                      
    }
}
void  Task1 (void *pdata)
{
    char  *msg;
    INT8U  err;
    pdata = pdata;
    for (;;) {
        msg = (char *)OSQPend(MsgQueue, 0, &err);//从消息队列中取消息
        PC_DispStr(70, 13, msg, DISP_FGND_YELLOW + DISP_BGND_BLUE);
        OSTimeDlyHMSM(0, 0, 0, 100);
    }
}
void  Task2 (void *pdata)
{
    char  msg[20];
    pdata = pdata;
    strcpy(&msg[0], "Task 2");
    for (;;) {
        OSQPost(MsgQueue, (void *)&msg[0]);//发送消息到队列中
        OSTimeDlyHMSM(0, 0, 0, 500);
    }
}
void  Task3 (void *pdata)
{
    char  msg[20];
    pdata = pdata;
    strcpy(&msg[0], "Task 3");
    for (;;) {
        OSQPost(MsgQueue, (void *)&msg[0]);//发送消息到队列中
        OSTimeDlyHMSM(0, 0, 0, 500);
    }
}
void  Task4 (void *pdata)
{
    char  msg[20];
    pdata = pdata;
    strcpy(&msg[0], "Task 4");
    for (;;) {
        OSQPost(MsgQueue, (void *)&msg[0]);//发送消息到队列中
        OSTimeDlyHMSM(0, 0, 0, 500);
    }
}
void  OSTaskStatHook (void)
{
    char    s[80];
    INT8U   i;
    INT32U  total;
    INT8U   pct;
    total = 0L;                                          /* Totalize TOT. EXEC. TIME for each task 
    for (i = 0; i < 7; i++) {
        total += TaskUserData[i].TaskTotExecTime;
        DispTaskStat(i);                                 /* Display task data                      
    }
    if (total > 0) {
        for (i = 0; i < 7; i++) {                        /* Derive percentage of each task         */
            pct = 100 * TaskUserData[i].TaskTotExecTime / total;
            sprintf(s, "%3d %%", pct);
            PC_DispStr(62, i + 11, s, DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY);
        }
    }
    if (total > 1000000000L) {                           /* Reset total time counters at 1 billion 
        for (i = 0; i < 7; i++) {
            TaskUserData[i].TaskTotExecTime = 0L;
        }
    }
}

void  OSTaskSwHook (void)
{
    INT16U           time;
    TASK_USER_DATA  *puser;
    time  = PC_ElapsedStop();                    /* This task is done                                  
    PC_ElapsedStart();                           /* Start for next task                                
    puser = OSTCBCur->OSTCBExtPtr;               /* Point to used data                                 
    if (puser != (TASK_USER_DATA *)0) {
        puser->TaskCtr++;                        /* Increment task counter                             
        puser->TaskExecTime     = time;          /* Update the task's execution time                   
        puser->TaskTotExecTime += time;          /* Update the task's total execution time             
    }
}

运行结果:

作者:洞庭散人

出处:http://phinecos.cnblogs.com/    

本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。

uC/OS-II源码分析(二)的更多相关文章

  1. Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题

    4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...

  2. 框架-springmvc源码分析(二)

    框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...

  3. Tomcat源码分析二:先看看Tomcat的整体架构

    Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...

  4. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

  5. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  6. 多线程之美8一 AbstractQueuedSynchronizer源码分析<二>

    目录 AQS的源码分析 该篇主要分析AQS的ConditionObject,是AQS的内部类,实现等待通知机制. 1.条件队列 条件队列与AQS中的同步队列有所不同,结构图如下: 两者区别: 1.链表 ...

  7. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

  8. spring源码分析(二)Aop

    创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...

  9. ConcurrenHashMap源码分析(二)

    本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...

  10. Docker源码分析(二):Docker Client创建与命令执行

    1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...

随机推荐

  1. Bootstrap学习速查表(四) 栅格系统

    Bootstrap框架的网格系统工作原理如下: 1.数据行(.row)必须包含在容器(.container)中,以便为其赋予合适的对齐方式和内距(padding).如: 2.在行(.row)中可以添加 ...

  2. 底部TabsFooter

    Demo简单描述:点击底部菜单可切换页面,并且底部为共用. 这个是在设置好导航Navigator之后进行的步骤,只是我个人进行Tab切换的一种思路方法,或许不是最好的,仅供参考一下. 首先我们需要一个 ...

  3. 常用string函数分析

    string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...

  4. difference between VM, Docker and Vagrant区别

    VM:  VirtualBox, VMware Docker Vagrant using which you can create VMs or container. It interacts wit ...

  5. linux memcached php 整合

    http://blog.csdn.net/liruxing1715/article/details/8269563

  6. C++复习:位运算

    与          a&b :    1010&1100=1000  或          a|b  :  1010|1100=1110 异或       a^b :     101 ...

  7. MySQL mysqlbinlog

    MySQL binlog日志记录了MySQL数据库从启用日志以来所有对当前数据库的变更.binlog日志属于二进制文件,我们可以从binlog提取出来生成可读的文本或者SQL语句来重建当前数据库以及根 ...

  8. 继续封装DBDA.php 加入ajax

    <?php class DBDA { public $host = "localhost"; //服务器地址 public $uid = "root"; ...

  9. 如果数据需要被多个应用程序消费的话,推荐使用 Kafka,如果数据只是面向 Hadoop 的,可以使用 Flume

    https://www.ibm.com/developerworks/cn/opensource/os-cn-kafka/index.html Kafka 与 Flume 很多功能确实是重复的.以下是 ...

  10. PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析(转)

    sort() 函数用于对数组单元从低到高进行排序. rsort() 函数用于对数组单元从高到低进行排序. asort() 函数用于对数组单元从低到高进行排序并保持索引关系. arsort() 函数用于 ...