OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3573|回复: 1

关于任哲嵌入式实时系统ucos-II原理及应用第4章例题4-2的疑问

[复制链接]

0

主题

4

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2023-4-3
在线时间
7 小时
发表于 2023-4-3 22:01:18 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 xiaoyuba 于 2023-4-3 22:48 编辑

例题4-2  设计一个有3个任务的应用程序Test。这3个任务分别是MyTask,YouTask和InterTask。其中,任务InterTask是在时钟节拍中断服务程序中用钩子函数OSTimeTickHook()中断了1000次时使用一个信号量InterKey激活的。运行并分析由中断服务程序激活任务的工作特点。
/******************************Test*******************************/
#include "includes.h"
#define  TASK_STK_SIZE   512                                //任务堆栈长度
OS_STK   MyTaskStk[TASK_STK_SIZE];                        //定义任务堆栈区
OS_STK   YouTaskStk[TASK_STK_SIZE];                        //定义任务堆栈区
OS_STK   InterTaskStk[TASK_STK_SIZE];                        //定义任务堆栈区
INT16S   key;                                                //用于退出uCOS_II的键
INT8U         x=0,y=0;                                        //字符显示位置
BOOLEAN  InterKey=FALSE;
void  MyTask(void *data);                                //声明任务
void  YouTask(void *data);                                //声明任务
void  InterTask(void *data);                                //声明任务
/************************主函数*********************************/
void  main (void)
{
    char* s_M="M";                                        //定义要显示的字符
    OSInit( );                                                //初始化uCOS_II
    PC_DOSSaveReturn( );                                //保存Dos环境
    PC_VectSet(uCOS, OSCtxSw);                                //安装uCOS_II中断
    OSTaskCreate(
                MyTask,                                        //创建任务MyTask
                s_M,                                        //给任务传递参数
                &MyTaskStk[TASK_STK_SIZE - 1],                //设置任务堆栈栈顶指针
                0                                        //任务的优先级别为0
                );                                
    OSStart( );                                                //启动多任务管理
}

/*******************任务MyTask**********************************/

void  MyTask (void *pdata)
{
    char* s_Y="Y";                                        //定义要显示的字符
    char* s_H="H";
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
#endif
    pdata = pdata;
    OS_ENTER_CRITICAL( );
    PC_VectSet(0x08, OSTickISR);                        //安装时钟中断向量
    PC_SetTickRate(OS_TICKS_PER_SEC);                        //设置时钟频率
    OS_EXIT_CRITICAL( );
    OSStatInit( );                                        //初始化统计任务
    OSTaskCreate(
                YouTask,                                //创建任务YouTask
                s_Y,                                        //给任务传递参数
                &YouTaskStk[TASK_STK_SIZE - 1],                //设置任务堆栈栈顶指针
                1                                        // YouTask的优先级别为1
                );        
        OSTaskCreate(
                        InterTask,                        //创建任务InterTask
                        s_H,                                //给任务传递参数
                        &InterTaskStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针
                        2                                // InterTask的优先级别为2
                        );
    for (;;)
    {
        if (x>79)
                {
                           x=0;
                           y+=1;
        }                                                
        PC_DispChar(x, y,                                //字符的显示位置
                *(char*)pdata,
                DISP_BGND_BLACK+DISP_FGND_WHITE );
                       x += 1;   
                //如果按下Esc键则退出uCOS_II
                if (PC_GetKey(&key) == TRUE)
                {
                if (key == 0x1B)
                    {
                    PC_DOSReturn( );                        //恢复Dos环境
                }
            }
            OSTimeDlyHMSM(0, 0, 3, 0);                        //等待3秒
}
}

/************************任务YouTask******************************/

void  YouTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
    pdata = pdata;
    for (;;)
    {
        if (x>79)
        {
           x=0;
           y+=1;
        }                                                
        PC_DispChar(
                x, y,                                //字符的显示位置
                *(char*)pdata,
                DISP_BGND_BLACK+DISP_FGND_WHITE
                );
               x += 1;        
        OSTimeDlyHMSM(0, 0, 1, 0);                //等待1秒
    }
}
/***********************InterTask*******************************/
char*s="运行了中断所要求运行的任务InterTask。";
void  InterTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
#endif
    pdata = pdata;

    for (;;)
    {
        if(InterKey)
        {
                if (x>79)
                {
                           x=0;
                           y+=1;
                }                                                
                PC_DispChar(
                        x, y,                        //字符的显示位置
                        *(char*)pdata,
                        DISP_BGND_BLACK+DISP_FGND_WHITE
                        );
                PC_DispStr(5,6,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
                       x += 1;
        }
        InterKey=FALSE;
        OSIntNesting--;
        OSTimeDlyHMSM(0, 0, 1, 0);                //等待1秒
    }
}
程序运行结果如下:
下载.png

不明白在InterTask任务中OSIntNesting--这句起什么作用?我把这句注释掉,程序结果也没有影响。现在我把开头定义程序:
INT16S   key;                                                //用于退出uCOS_II的键
INT8U  x=0,y=0;                                        //字符显示位置
改为:


INT16S   key;                                                //用于退出uCOS_II的键
INT8U  x=0,y=0,x1=0,y1=5;                                        //字符显示位置                                      
char w[8];     再把InterTask任务程序改为:
/***********************InterTask*******************************/
char*s="运行了中断所要求运行的任务InterTask。";
void  InterTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr;
#endif
    pdata = pdata;

    for (;;)
    {
        if(InterKey)
        {
                if (x>79)
                {
                           x=0;
                           y+=1;
                }                                                
                PC_DispChar(
                        x, y,                        //字符的显示位置
                        *(char*)pdata,
                        DISP_BGND_BLACK+DISP_FGND_WHITE
                        );
                PC_DispStr(5,6,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
                       x += 1;
        }
         InterKey=FALSE;
         OSIntNesting--;
   sprintf(w,"%d",OSIntNesting);
     OSTimeDlyHMSM(0, 0, 1, 0);                //等待1秒
PC_DispStr(x1,y1,w,DISP_BGND_BLACK+DISP_FGND_WHITE);
x1+=3;
PC_DispChar(x1,y1,',',DISP_BGND_BLACK+DISP_FGND_WHITE);
x1++;
if(x1>79)
{
  y1+=1;
  x1=0;
}

    }
}

程序一开始运行结果如下:
































下载.png
1.png
1.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2022-1-26
在线时间
18 小时
发表于 2023-5-6 22:26:37 | 显示全部楼层
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-30 07:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表