uC/OS-II源码分析(二)

在真正开始分析源代码前,先来看使用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。

转载于:https://www.cnblogs.com/xumaojun/p/8541665.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466476.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TRACE (VC)

TRACE 1、TRACE和TRACK是用来调试web服务器连接的HTTP方式。 2、TRACE宏对于VC下程序调试来说是很有用的东西&#xff0c;有着类似printf的功能。 3、MATLAB函数&#xff0c;用于求二维方阵的迹&#xff0c;即该方阵对角线上元素之和。4、Flex中的调试信息显示函数&#xff0c;…

你的年终奖有多少?

辛苦一年&#xff0c;最期待的就是发年终奖了。我哥在我们老家工厂上班&#xff0c;过年的时候&#xff0c;瞄了一眼他手下那些人的年终福利&#xff0c;很多人都是几千几千的奖金。小云嘲笑我说&#xff0c;你们码农真差劲&#xff0c;都没有年终奖&#xff0c;我说&#xff0…

Linux下打印调试管理

#ifndef _DEBUG_MANAGE_H_ #define _DEBUG_MANAGE_H_/* 信息的调试级别,数值起小级别越高 */ #define APP_EMERG "<0>" /* system is unusable */ #define APP_ALERT "<1>" /* action must be taken immediately */ #define APP_CRIT …

未来十大技能职场吃香

一个人掌握何种技能取决于他的兴趣、能力和聪明程度&#xff0c;也取决于他所能支配的资源以及制定的事业目标&#xff0c;拥有过硬技能的人有更多的工作机会。但是&#xff0c;由于经济发展前景不确定&#xff0c;掌握对你的事业有所帮助的技能显得尤为重要。相关网站通过多年…

linux学习一个服务(未完)

学习一个服务的过程 1.了解服务的作用&#xff1a;名字 功能&#xff0c;特点 2.安装 3.配置文件位置&#xff0c;端口 4.服务启动关闭的脚本 5.此服务的使用方法 6.修改配置文件&#xff0c;实战举例 7.排错&#xff08;从下到上&#xff0c;从内到外&#xff09; 转载于:http…

ReverseFind

函数原型&#xff1a;int ReverseFind( TCHAR ch ) const;   返回值: 返回此CString 对象中与要求的字符匹配的最后一个字符的索引&#xff1b;如果没有找到需要的字符则返回-1。   参数: ch 要搜索的字符。   说明:此成员函数在此CString 对象中搜索与一个子串匹配的最后…

Qt值得学习吗?详解Qt的几种开发方式

qt值得学习吗&#xff1f;嵌入式要学的东西真的很多&#xff0c;我们可能会说不写界面的话就不用学qt了&#xff1f;我不赞同。Qt的实现主要是采用p-impl手法&#xff0c;实现接口与实现分离&#xff0c;它有很好的消息循环机制&#xff0c;有的对象与线程的相关性&#xff0c;…

技术QA:如何安装并启用BITS和WebDAV?

引子&#xff1a; 在安装SCCM 2007 SP1时&#xff0c;必须要安装并启用BITS和WebDAV&#xff0c;否则在SCCM 2007 SP1安装先决条件检查时将会报错。它们以前都是IIS的功能组件&#xff0c;但是在IIS 7中变动很大&#xff0c;特别是在 Windows Server 2008 操作系统中现在已经不…

Linux下XPath对xml解析

#ifndef CONF_XML_H #define CONF_XML_H // xml文件Z在《Linux下获取xml调试信息等级》里有 #include <stdio.h> #include <string.h> #include <unistd.h> #include <assert.h>#include <libxml/parser.h> #include <libxml/tree.h> #inc…

LEFT函数

LEFT函数 函数执行成功时返回string字符串左边n个字符&#xff0c;发生错误时返回空字符串&#xff08;""&#xff09;。如果任何参数的值为NULL&#xff0c;Left()函数返回NULL。如果n的值大于string字符串的长度&#xff0c;那么Left()函数返回整个string字符串&a…

一个操作系统的实现(3)

文件系统 文件系统是建立在硬盘上的一个程序&#xff0c;所以由2部分组成&#xff1a;驱动和管理文件系统的进程FS。 首先看一下驱动是如何工作的&#xff1a; 通常&#xff0c;主板上面有2个IDE插槽&#xff0c;分别叫做IDE0/IDE1。每个IDE通道又可以接2个设备。驱动进程的目的…

C语言,谁都能看得懂的归并排序

喜欢看排序算法动态效果的&#xff0c;可以看看这个网站https://visualgo.net/zh/sorting里面很多算法的动画解释&#xff0c;可以看到算法的排序效果&#xff0c;而且还附带了伪代码的实现过程。本来想录制几张动图放上来&#xff0c;但是因为图片较大&#xff0c;传不上来&am…

一份详细的服务器安全解决方案

一、操作系统配置 1.安装操作系统(NTFS分区)后&#xff0c;装杀毒软件&#xff0c;我选用的是卡巴。 2.安装系统补丁。扫描漏洞全面杀毒 3.删除Windows Server 2003默认共享 首先编写如下内容的批处理文件&#xff1a; echo off net share C$ /del net share D$ /del net …

GetModuleFileName

GetModuleFileName 获取当前进程已加载模块的文件的完整路径&#xff0c;该模块必须由当前进程加载。如果想要获取另一个已加载模块的文件路径&#xff0c;可以使用GetModuleFileNameEx函数。 声明GetModuleFileName(VB) Declare Function GetModuleFileName Lib “kernel32”…

jQuery load() 中文乱码

1、使用editplus创建了demo.txt (ANSI保存的)&#xff0c; $("#div1").load("demo.txt");//div显示中文乱码--->html5中定义<meta charset"utf-8"/>,编码解码不一致造成中文乱码&#xff0c;将文本文件demo.txt另存为utf-8格式&#xf…

内核链表list.h文件剖析

内核链表list.h文件剖析 一、内核链表的结构【双向循环链表】 内核链表的好主要体现为两点&#xff0c;1是可扩展性&#xff0c;2是封装。可以将内核链表复用到用户态编程中&#xff0c;以后在用户态下编程就不需要写一些关于链表的代码了&#xff0c;直接将内核中list.h中的代…

CAN总线很难吗?CAN总线看不懂是不可能的!

CAN&#xff08;Controller Area Network&#xff09;即控制器局域网&#xff0c;是一种能够实现分布式实时控制的串行通信网络。想到CAN就要想到德国的Bosch公司&#xff0c;因为CAN就是这个公司开发的&#xff08;和Intel&#xff09;CAN有很多优秀的特点&#xff0c;使得它能…

GetDlgItem

GetDlgItemText() GetDlgItemText是C中的函数&#xff0c;调用这个函数以获得与对话框中的控件相关的标题或文本。GetDlgItemText成员函数将文本拷贝到lpStr指向的位置并返回拷贝的字节的数目。 函数说明 CWnd类的成员函数。 函数原型 int GetDlgItemText( HWND hDlg , int n…

开放课程管理系统(Moodle)的介绍(转)

一、虚拟学习环境 关于虚拟学习环境&#xff0c;很难用一个简单的定义来描述。可以说是&#xff0c;支持和管理教与学的各项活动的基于网络的环境。也可以认为是学习管理系统的组成部分。当应用于远程教育时&#xff0c;通常认为它包括“任何用于创造一个统一的、类似于面对面的…

C语言必须写main函数?最简单的 Hello world 你其实一点都不懂!

我们在刚写程序的时候&#xff0c;第一个都是 hello world&#xff0c;而在这里&#xff0c;完整的代码就是&#xff1a;我们打眼一看&#xff0c;其实很简单&#xff0c;就是引入头文件&#xff0c;写一个主函数&#xff0c;然后输出一句话&#xff0c;但是当我们编译出来ELF的…