搜索
bottom↓
回复: 28

ucos怎么尽量减少全局变量的使用以及传递结构体数据方法

[复制链接]

出0入0汤圆

发表于 2014-11-27 12:30:59 | 显示全部楼层 |阅读模式
如题,在ucos如何尽量减少全局变量的使用,以及任务之间需要传递结构体数据有什么方法,求大神指教~

出0入0汤圆

发表于 2014-11-27 12:36:36 | 显示全部楼层
不是有消息邮箱么

出0入0汤圆

发表于 2014-11-27 12:47:49 | 显示全部楼层
申请内存
RfCanForm *cfmsg;
CanRxMsg *crxmsg;
crxmsg = (CanRxMsg *)OSQPend(RfQCDataRecv, 0, &qerr);//等待CAN接收
cfmsg->pr  = CAN_ID2F_PRIOTITY(crxmsg->ExtId);       //取出优先级
cfmsg->s   = CAN_ID2F_S_MODULE(crxmsg->ExtId);       //取出源ID

OSQPost(RfQSysCtl, (void *)cfmsg);//传输数据
OSMemPut(RfQCanRxBuf,crxmsg);//释放CAN接收内存

出0入0汤圆

发表于 2014-11-27 12:49:54 | 显示全部楼层
另一函数里
RfCanForm * can_msg;   
while (1)
{
    can_msg = (RfCanForm *)OSQPend(RfQSysCtl, 0, &merr);//等待CAN接收发送的消息

}

RfCanForm和CanRxMsg都是结构体

出0入0汤圆

 楼主| 发表于 2014-11-27 13:01:02 | 显示全部楼层
didadida 发表于 2014-11-27 12:36
不是有消息邮箱么

邮箱不是只能传数据或者数组吗?

出0入0汤圆

 楼主| 发表于 2014-11-27 13:07:11 | 显示全部楼层
silence_sky 发表于 2014-11-27 12:49
另一函数里
RfCanForm * can_msg;   
while (1)

不错的方法,学习了

出0入10汤圆

发表于 2014-11-27 13:07:44 | 显示全部楼层
tian_zi 发表于 2014-11-27 13:01
邮箱不是只能传数据或者数组吗?

消息队列可以传递数据结构的指针

出0入0汤圆

 楼主| 发表于 2014-11-27 13:53:21 | 显示全部楼层
10xjzheng 发表于 2014-11-27 13:07
消息队列可以传递数据结构的指针

消息队列可以传递结构体信息,像这样有问题吗
创建了两个任务task1 和 task2,同时创建消息队列,在task1中发送消息给task2,如在task1中创建一个消息队列
#define MSG_QUEUE_SIZE 3                //消息队列长度
OS_EVENT *g_pOS_MsgQ_Task1;                //消息名
void *MboxQ_Table[MSG_QUEUE_SIZE];//队列排队
任务task1在发送消息的时候,发送自定义的一个结构体
typedef struct {
        INT32U ulMsgID;                         //消息ID
        INT8U aucData[4];                         //消息内容
}STRU_MSG
void task1(void *pvData)
{
       STRU_MSG pMsg;
        pMsg.ulMsgID=1;
        g_pOS_MsgQ_Task1=OSQCreate (&MboxQ_Table[0],MSG_QUEUE_SIZE);
       while(1)
       {  
           INT32U addr;
           addr = & pMsg;   
           OSQPost(g_pOS_MsgQ_Task1, addr);
       }
}
下面是task2接收接收消息的处理。
void task2(void *pvData)
{
       STRU_MSG * msgRcvd;
       INT8U  ucOSError;
       while(1)
       {  
           msgRcvd = (STRU_MSG *)OSQPend(g_pOS_MsgQ_Task1,0, &ucOSError);     
       }
}
然后,*msgRcvd 就是刚才过来的结构体了
这样可以实现每个MboxQ_Table传递一个STRU_MSG类型结构体数据吗?

出0入0汤圆

发表于 2014-11-27 13:53:45 | 显示全部楼层
只看书学习过UCOS,没实战经验。标记就下。以后可能会用到。

出0入0汤圆

 楼主| 发表于 2014-11-28 10:54:54 | 显示全部楼层
10xjzheng 发表于 2014-11-27 13:07
消息队列可以传递数据结构的指针

测试了一下,消息邮箱也是可以像消息队列一样传送结构体参数的

出25入84汤圆

发表于 2014-11-28 11:06:02 | 显示全部楼层
我一般都用全局变量传递,简单好操作,ucos只用到任务创建,同时跑四个任务。

出0入0汤圆

 楼主| 发表于 2014-11-28 11:12:14 | 显示全部楼层
chun2495 发表于 2014-11-28 11:06
我一般都用全局变量传递,简单好操作,ucos只用到任务创建,同时跑四个任务。 ...

全局变量太多就不好了吧,太容易发生资源共享冲突,还得加互斥信号或者开关中断

出100入101汤圆

发表于 2014-11-28 11:20:51 | 显示全部楼层
chun2495 发表于 2014-11-28 11:06
我一般都用全局变量传递,简单好操作,ucos只用到任务创建,同时跑四个任务。 ...

这样的话,用pt thread就可以了。

出25入84汤圆

发表于 2014-11-28 11:25:06 | 显示全部楼层
tian_zi 发表于 2014-11-28 11:12
全局变量太多就不好了吧,太容易发生资源共享冲突,还得加互斥信号或者开关中断 ...

我的任务没有那么复杂,任务和任务之间通信比较简单,你的通信机制很复杂吗

出0入0汤圆

 楼主| 发表于 2014-11-28 11:55:30 | 显示全部楼层
chun2495 发表于 2014-11-28 11:25
我的任务没有那么复杂,任务和任务之间通信比较简单,你的通信机制很复杂吗 ...

其中一个主任务传递的接收数据结构类型比较多,要等待其余的多个任务传递的各种数据,比如字符命令类,数组数据(数据长度,数据内容,校验)。这些任务传递的数据都不一样,但是我的主任务要收集这些任务的全部数据打包处理,你有什么好的方法?

出0入0汤圆

发表于 2014-11-28 11:56:13 | 显示全部楼层
现在一直在裸跑,之所以没上系统就是因为全局变量太多,又怕处理不好各任务的通信、信号互斥之类的

出25入84汤圆

发表于 2014-11-28 12:32:12 | 显示全部楼层
tian_zi 发表于 2014-11-28 11:55
其中一个主任务传递的接收数据结构类型比较多,要等待其余的多个任务传递的各种数据,比如字符命令类,数 ...

不知道你的分任务复杂不?要是不复杂的话可以整合到一个任务里,循环扫描就行。主任务查询各个任务。全局结构体{task[number], length,crc,...ready},通过ready来判断是否就绪。不知可否?

出0入0汤圆

 楼主| 发表于 2014-11-28 13:37:59 | 显示全部楼层
chun2495 发表于 2014-11-28 12:32
不知道你的分任务复杂不?要是不复杂的话可以整合到一个任务里,循环扫描就行。主任务查询各个任务。全局 ...

这样子不就是状态机模式了,而且全部变量放在一起,程序可读性太差了

出0入0汤圆

发表于 2014-11-28 13:51:26 | 显示全部楼层
mark  ucos  只看过,米有实战经验~~~~

出0入0汤圆

发表于 2014-11-28 20:47:04 | 显示全部楼层
zhongjp85 发表于 2014-11-28 13:51
mark  ucos  只看过,米有实战经验~~~~

奇怪呢  刚才试了下 就出错了

typedef  struct
{
                uint8_t  type;        //
                uint8_t  param;      
                
}CMD_t;

CMD_t Cmd1,*pCmd1=&Cmd1;

void Task1(void *pdata)
{         
        while(1)
        {       
                               
                                 printf("\r\n task1");
                                pCmd1->param++;
                                 pCmd1->type++;
                                   OSMboxPost(Mbox_Cmd, (void *)(pCmd1));
                OSTimeDlyHMSM(0,0,0,20);       
        }
}


void Task2(void *pdata)
{         
        while(1)
        {       
                               
                                 printf("\r\n task2");
        
                                  pCmd1=(CMD_t *)OSMboxPend(Mbox_Cmd, 1, &err);
                                  printf("\r\n pCmd1->type = %x",pCmd1->type);
                                    printf("\r\n pCmd1->param = %x",pCmd1->param);
                OSTimeDlyHMSM(0,0,0,20);       
        }
}





运行结果过:
task1
task1
task2
pCmd1->type = 1
pCmd1->param = 1
task1
task2
pCmd1->type = 2
pCmd1->param = 2
task1
task2
pCmd1->type = 3
pCmd1->param = 3
task1
task2
pCmd1->type = 4
pCmd1->param = 4
task1
task2
pCmd1->type = 58
pCmd1->param = 37
task1  然后就卡死了。

出0入0汤圆

发表于 2014-11-28 20:56:07 | 显示全部楼层
消息队列没用过吗?

出0入0汤圆

发表于 2014-11-30 17:37:36 | 显示全部楼层
队列,信号量。呵呵,楼上的名字

出0入0汤圆

发表于 2014-11-30 17:53:39 | 显示全部楼层
zhenghe 发表于 2014-11-30 17:37
队列,信号量。呵呵,楼上的名字

怎么了? 楼主关注我后续发的帖子

出0入0汤圆

发表于 2014-12-1 09:26:44 | 显示全部楼层
MARK!!!!!!!!

出0入0汤圆

 楼主| 发表于 2014-12-1 13:43:56 | 显示全部楼层
yxylxj 发表于 2014-11-28 20:47
奇怪呢  刚才试了下 就出错了

typedef  struct

试一下这样:
CMD_t Cmd1;
void Task1(void *pdata)
{         
        while(1)
        {                              
                printf("\r\n task1");
                Cmd1.param=1;
                Cmd1.type=2;
                OSMboxPost(Mbox_Cmd, &Cmd1);
                OSTimeDlyHMSM(0,0,0,20);        
        }
}

void Task2(void *pdata)
{         
        u8 err;
        CMD_t *pCmd2;
        while(1)
        {        
                printf("\r\n task2");
                pCmd2=(CMD_t *)OSMboxPend(Mbox_Cmd, 0, &err);
                printf("\r\n pCmd2.type = %x",pCmd2->type);
                printf("\r\n pCmd2.param = %x",pCmd2->param);
                OSTimeDlyHMSM(0,0,0,20);        
        }
}

出0入0汤圆

发表于 2014-12-1 19:15:00 | 显示全部楼层
全局变量简单,不容易出错

出0入0汤圆

 楼主| 发表于 2014-12-2 09:25:46 | 显示全部楼层
xiaozuowei118 发表于 2014-12-1 19:15
全局变量简单,不容易出错

全局变量不是不可重入吗,如果多任务访问全局变量还得加互斥信号和开关中断处理。而且全局变量多,程序的内聚和耦合怎么考虑呢?

出0入0汤圆

发表于 2014-12-2 12:45:00 | 显示全部楼层
tian_zi 发表于 2014-12-2 09:25
全局变量不是不可重入吗,如果多任务访问全局变量还得加互斥信号和开关中断处理。而且全局变量多,程序的 ...

我觉得立标志位可行,首先每个程序其实都是轮循的机制,说从微观上,同一时间只能有一个任务被执行

出0入0汤圆

发表于 2014-12-27 11:52:15 | 显示全部楼层
tian_zi 发表于 2014-12-2 09:25
全局变量不是不可重入吗,如果多任务访问全局变量还得加互斥信号和开关中断处理。而且全局变量多,程序的 ...

楼主百度:基于uCOS的电梯控制 这个详细的代码里有很多变量的处理 可以参考。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-8 13:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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