OpenEdv-开源电子网

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

UCOSIII中消息队列(消息传递)例程中任务切换问题

[复制链接]

6

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2017-9-20
在线时间
27 小时
发表于 2018-5-2 11:45:37 | 显示全部楼层 |阅读模式
2金钱
问题:
1、为什么Keyprocess_task()这个函数没有任务调度的延时函数呢,后面比它优先级低的任务msgdis_task()什么时候运行呢?是不是Keyprocess_task()的OSQPend函数没有请求到消息,然后阻塞后才运行msgdis_task()呢?
2、还有就是OSQPend函数的返回值是多少呢?
p=OSQPend((OS_Q*                )&DATA_Msg,   
                                  (OS_TICK                )0,
                  (OS_OPT                )OS_OPT_PEND_BLOCKING,
                  (OS_MSG_SIZE*        )&size,       
                  (CPU_TS*                )0,
                  (OS_ERR*                )&err);
                LCD_ShowString(5,270,100,16,16,p);
咋返回值可以超出消息队列数量4而一直在不停的增加呢?

/任务优先级
#define START_TASK_PRIO                3
//任务堆栈大小       
#define START_STK_SIZE                 128
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈       
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);

//任务优先级
#define MAIN_TASK_PRIO                4
//任务堆栈大小       
#define MAIN_STK_SIZE                 128
//任务控制块
OS_TCB Main_TaskTCB;
//任务堆栈       
CPU_STK MAIN_TASK_STK[MAIN_STK_SIZE];
void main_task(void *p_arg);


//任务优先级
#define KEYPROCESS_TASK_PRIO         5
//任务堆栈大小       
#define KEYPROCESS_STK_SIZE         128
//任务控制块
OS_TCB Keyprocess_TaskTCB;
//任务堆栈       
CPU_STK KEYPROCESS_TASK_STK[KEYPROCESS_STK_SIZE];
//任务函数
void Keyprocess_task(void *p_arg);

//任务优先级
#define MSGDIS_TASK_PRIO        6
//任务堆栈
#define MSGDIS_STK_SIZE                128
//任务控制块
OS_TCB        Msgdis_TaskTCB;
//任务堆栈
CPU_STK        MSGDIS_TASK_STK[MSGDIS_STK_SIZE];
//任务函数
void msgdis_task(void *p_arg);


//定时器1的回调函数
void tmr1_callback(void *p_tmr,void *p_arg)
{
        u8 *pbuf;
        static u8 msg_num;
        OS_ERR err;
        pbuf = mymalloc(SRAMIN,10);        //申请10个字节
        if(pbuf)        //申请内存成功
        {
                msg_num++;
                sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
                //发送消息
                OSQPost((OS_Q*                )&DATA_Msg,               
                                (void*                )pbuf,
                                (OS_MSG_SIZE)10,
                                (OS_OPT                )OS_OPT_POST_FIFO,
                                (OS_ERR*        )&err);
                if(err != OS_ERR_NONE)
                {
                        myfree(SRAMIN,pbuf);        //释放内存
                        OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
                        tmr1sta = !tmr1sta;
                        LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
                }
        }       
}

//主任务的任务函数
void main_task(void *p_arg)
{
        u8 key,num;
        OS_ERR err;
        u8 *p;
        while(1)
        {
                key = KEY_Scan(0);  //扫描按键
                if(key)
                {
                        //发送消息
                        OSQPost((OS_Q*                )&KEY_Msg,               
                                        (void*                )&key,
                                        (OS_MSG_SIZE)1,
                                        (OS_OPT                )OS_OPT_POST_FIFO,
                                        (OS_ERR*        )&err);
                }
                num++;
                if(num%10==0) check_msg_queue(p);//检查DATA_Msg消息队列的容量
                if(num==50)
                {
                        num=0;
                        LED0 = ~LED0;
                }
                OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);   //延时10ms
        }
}

//按键处理任务的任务函数
void Keyprocess_task(void *p_arg)
{       
        u8 num;
        u8 *key;
        OS_MSG_SIZE size;
        OS_ERR err;
        while(1)
        {
                //请求消息KEY_Msg
                key=OSQPend((OS_Q*                        )&KEY_Msg,   
                                        (OS_TICK                )0,
                    (OS_OPT                        )OS_OPT_PEND_BLOCKING,
                    (OS_MSG_SIZE*        )&size,               
                    (CPU_TS*                )0,
                    (OS_ERR*                )&err);
                switch(*key)
                {
                        case WKUP_PRES:                //KEY_UP控制LED1
                                LED1 = ~LED1;
                                break;
                        case KEY2_PRES:                //KEY2控制蜂鸣器
                                BEEP = ~BEEP;
                                break;
                        case KEY0_PRES:                //KEY0刷新LCD背景
                                num++;
                                LCD_Fill(126,111,233,313,lcd_discolor[num%14]);
                                break;
                        case KEY1_PRES:                //KEY1控制定时器1
                                tmr1sta = !tmr1sta;
                                if(tmr1sta)
                                {
                                        OSTmrStart(&tmr1,&err);
                                        LCD_ShowString(10,150,100,16,16,"TMR1 START!");
                                }
                                else
                                {
                                        OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err); //停止定时器1
                                        LCD_ShowString(10,150,100,16,16,"TMR1 STOP! ");
                                }
                                break;
                }
        }
}

//显示消息队列中的消息
void msgdis_task(void *p_arg)
{
        u8 *p;
        OS_MSG_SIZE size;
        OS_ERR err;
        while(1)
        {
                //请求消息
                p=OSQPend((OS_Q*                )&DATA_Msg,   
                                  (OS_TICK                )0,
                  (OS_OPT                )OS_OPT_PEND_BLOCKING,
                  (OS_MSG_SIZE*        )&size,       
                  (CPU_TS*                )0,
                  (OS_ERR*                )&err);
                LCD_ShowString(5,270,100,16,16,p);
                myfree(SRAMIN,p);        //释放内存
                OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
        }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-5-3 01:50:27 | 显示全部楼层
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2017-8-18
在线时间
8 小时
发表于 2018-8-9 17:52:04 | 显示全部楼层
兄弟,我也在疑惑这点,问题解决了吗
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2017-8-18
在线时间
8 小时
发表于 2018-8-9 17:56:40 | 显示全部楼层
但是针对你的第二个问题,它的返回值就是一个地址啊,就是你那个消息的地址,我主要的疑惑就是msgdis_task这个函数的运行情况,他应该是一有消息就就开始接受,但是我不知道为什么例程里面消息队列的剩余空间会减到0之后再增加,我感觉的大小顺序应该是4-3-2-3-4-...这样的
回复

使用道具 举报

10

主题

33

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2018-8-2
在线时间
73 小时
发表于 2018-12-16 13:51:19 | 显示全部楼层
在你创建消息队列的时候就已经设置好了消息队列的最大数量了,你发送完消息之后如果超过消息数量最大值就不能插入消息队列了,好好看 OS_MsgQPut()函数 在OSQPost()里面
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 20:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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