搜索
bottom↓
回复: 37

原创:我跟你一起学MQX(四):事件

[复制链接]

出0入0汤圆

发表于 2014-9-11 14:38:44 | 显示全部楼层 |阅读模式
话说我们小区管理处挺给力的,以前大门常开,谁想进就进,想出就出,给把钥匙吧就是个样子!但最近由于大家反映,小区常有陌生人出入,管理处也头大啊,天天盯着陌生人,工作量大多了!于是,管理处发了个通知,增加门禁功能!这回好了,进出小区必须拿卡刷,没卡,不好意思,你进不来!正好我去管理处领卡,碰到一个大妈,他也来拿卡,手上还拎着个菜蓝子!

回来的路上我就想啊,这门禁不就是我们系统中的事件吗?

什么是事件呢?
事件是操作系统中的一种触发机制,在特定的时间或者情况下,可以对特定的动作进行触发,它可以应用在不同的任务或者任务与中断函数中进行任务同步!

我就根据小区的事情做个例子,大家一起讨论一下!事件的API函数见MQX中的event.h文件中!

假设,我们小区有三个住户,一个白领,一个是大妈,而另一个呢,比较烦人,做安利的!

现在呢,我先做个门禁的任务,门禁的任务比较简单,就是别人要拿卡开门,它就给开:
  1. void MainTask(uint32_t para)
  2. {
  3.     void    *event_ptr;
  4.     if (_event_create("door") != MQX_OK)                                 //创建个门禁系统(事件)
  5.     {
  6.         printf("\nMake event failed");
  7.         _task_block();
  8.     }
  9.     if (_event_open("door", &event_ptr) != MQX_OK)            //获得门禁系统的控制权(打开事件)
  10.     {
  11.         printf("\nOpen event failed");
  12.         _task_block();
  13.     }
  14.     /* Create the print tasks */
  15.     _task_create(0, WHIT_TASK, 0);                                     //白领搬进小区了                     
  16.     _task_create(0, AUNT_TASK, 0);                             //大妈搬进小区了
  17.     _task_create(0, AMWA_TASK, 0);                            //安利也搬进小区了
  18.    
  19.     while(1)
  20.     {        
  21.         if (_event_wait_all_ticks(event_ptr, 0x01, 0) != MQX_OK)         //等待有人拿卡开门
  22.         {
  23.             printf("\nEvent Wait failed");
  24.             _task_block();
  25.         }
  26.         printf("The door is open! \n\n");
  27.         if (_event_clear(event_ptr,0x01) != MQX_OK)                   //自动关门
  28.         {
  29.             printf("\nEvent Clear failed");
  30.             _task_block();
  31.         }
  32.     }
  33. }
复制代码


有门禁系统了,区民也都搬进来了,我们看看居民一天的交通情况吧:

我们先看白领,白领呢,生活比较有规律,朝9晚6,早上去上班,下午回来。它的任务如下:
  1. void WhiteCollarTask(uint32_t para)
  2. {
  3.     void   *event_ptr;

  4.     if (_event_open("door",&event_ptr) != MQX_OK)                 //先领到门禁卡(打开事件)
  5.    {
  6.       printf("\nOpen Event failed");
  7.       _task_block();
  8.     }
  9.          
  10.     printf("White Collar go to work!\n");
  11.     if (_event_set(event_ptr,0x01) != MQX_OK)                    //上班要出去,开门(设置事件)
  12.     {
  13.         printf("\nSet Event failed");
  14.         _task_block();
  15.     }
  16.     _time_delay(1000);
  17.     printf("White Collar go home!\n");
  18.     if (_event_set(event_ptr,0x01) != MQX_OK)            //下班要回来,开门(设置事件)
  19.     {
  20.         printf("\nSet Event failed");
  21.         _task_block();
  22.     }     
  23. }
复制代码


再看看大妈,大妈的生活也很有规律,就是事稍稍多了点,早上得去买菜,下午还要去跳广场舞:
  1. void AuntTask(uint32_t para)
  2. {
  3.     void   *event_ptr;

  4.     if (_event_open("door",&event_ptr) != MQX_OK)          //领到门禁卡,拥有门禁控制权 (打开事件)
  5.     {
  6.       printf("\nOpen Event failed");
  7.       _task_block();
  8.     }
  9.       
  10.     printf("Aunt buy food!\n");
  11.     if (_event_set(event_ptr,0x01) != MQX_OK)            //大妈去买菜,开门 (设置事件)
  12.     {
  13.         printf("\nSet Event failed");
  14.         _task_block();
  15.     }
  16.     _time_delay(100);
  17.     printf("Aunt buy food back!\n");
  18.     if (_event_set(event_ptr,0x01) != MQX_OK)               //大妈买菜回来了,开门 (设置事件)
  19.     {
  20.         printf("\nSet Event failed");
  21.         _task_block();
  22.     }
  23.     _time_delay(300);
  24.     printf("Aunt go to dance!\n");
  25.     if (_event_set(event_ptr,0x01) != MQX_OK)              //大妈去跳舞,开门 (设置事件)
  26.     {
  27.         printf("\nSet Event failed");
  28.         _task_block();
  29.     }
  30.     _time_delay(100);
  31.    
  32.     printf("Aunt dance back!\n");
  33.     if (_event_set(event_ptr,0x01) != MQX_OK)             //大妈跳舞回来了,开门 (设置事件)

  34.     {
  35.         printf("\nSet Event failed");
  36.         _task_block();
  37.     }
  38. }
复制代码


还有做安利的,这个挺烦人的,进进出出的客户:
  1. void AmwayTask(uint32_t para)
  2. {
  3.     void   *event_ptr;
  4.     int i;

  5.     if (_event_open("door",&event_ptr) != MQX_OK)                //安利也拿到控制权了
  6.    {
  7.       printf("\nOpen Event failed");
  8.       _task_block();
  9.     }
  10.          
  11.     for(i = 0; i < 2; i++)                                                        //我让他客户少点,只有两个人
  12.     {
  13.         printf("Amway customer come!\n");
  14.         if (_event_set(event_ptr,0x01) != MQX_OK)                  //来客户了,开门
  15.         {
  16.             printf("\nSet Event failed");
  17.             _task_block();
  18.         }
  19.         _time_delay(100);
  20.         printf("Amway customer go!\n");
  21.         if (_event_set(event_ptr,0x01) != MQX_OK)                //客户走了,关门
  22.         {
  23.             printf("\nSet Event failed");
  24.             _task_block();
  25.         }
  26.         _time_delay(200);
  27.     }        
  28. }
复制代码


好吧,现在一切都可以了,还少了Z.F.的安排:
  1. const TASK_TEMPLATE_STRUCT  MQX_template_list[] =
  2. {
  3.     /* Task Index,   Function,          Stack,  Priority, Name,     Attributes,          Param, Time Slice */
  4.     { MAIN_TASK,   MainTask,            1500,   9,        "main",  MQX_AUTO_START_TASK,  0,     0 },
  5.     { WHIT_TASK,   WhiteCollarTask,     1500,   5,        "White",  MQX_USER_TASK      , 0,     0},
  6.     { AUNT_TASK,   AuntTask,            1500,   6,        "Aunt",  MQX_USER_TASK       , 0,     0},
  7.     { AMWA_TASK,   AmwayTask,           1500,   8,        "Amway",  MQX_USER_TASK      , 0,     0},   
  8.     { 0 }
  9. };
复制代码


这回万事齐备了,整个小区开始了他们一天的生活:


从结果来看,我们可以看到:
早上,白领去上班,大妈去买菜,安利客户来了,三个事件碰到一起了,所以事件只响应了一次,门只打开了一次
再到后来呢,大妈买菜回来了,第一个安利客户走了,两个事件又碰到一起了,所以呢,门也只用打开一次
再后来就大家各自进进出出都没碰到,那门就有点累了,每个事件都响应了一次,每个人到门口都各自打开一次

呵呵!不错,希望我们小区管理处以后能坚持这样管理啊,减少不必要的情况发生!

最后照例是例程:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2014-9-11 14:54:35 | 显示全部楼层
又一次征服了我,可以在加上,要是他们没按时回来,会是怎么样的一个情况呢。

出0入0汤圆

 楼主| 发表于 2014-9-11 14:56:00 | 显示全部楼层
rockyyangyang 发表于 2014-9-11 14:54
又一次征服了我,可以在加上,要是他们没按时回来,会是怎么样的一个情况呢。 ...

把事件撤消掉,让他们进不了门!

出100入101汤圆

发表于 2014-9-11 14:59:39 | 显示全部楼层
通俗易懂,可以考虑出书。”大话XX“之类。

出0入0汤圆

 楼主| 发表于 2014-9-11 15:03:13 | 显示全部楼层
fengyunyu 发表于 2014-9-11 14:59
通俗易懂,可以考虑出书。”大话XX“之类。

谢谢夸奖,呵呵,出书之类的事情就拉倒吧,只是想跟坛子里的朋友一起讨论!

出0入0汤圆

发表于 2014-9-11 15:18:35 | 显示全部楼层
面向对象的写法,还没有怎么接触过。楼主正好给举了个好例子。

出0入0汤圆

 楼主| 发表于 2014-9-11 15:39:50 | 显示全部楼层
彼岸花开@ 发表于 2014-9-11 15:18
面向对象的写法,还没有怎么接触过。楼主正好给举了个好例子。

这个不是面像对像,呵呵,你要学面向对像可以参考一下C++,你要能想明白如何用C实现C++中类的部分功能,基本就可以了

出0入0汤圆

发表于 2014-9-11 16:10:14 | 显示全部楼层
这个不顶下。没有道理。

出0入0汤圆

发表于 2014-9-11 21:18:43 | 显示全部楼层
楼主的学习已经进入到第四篇了,看完这一篇后,我提个疑问。
为什么不联系前面学习的内容来写这一篇?
举个例子:互斥量,而且加入互斥量后会让程序更加合理。
如果A去开门了,那么B同时到来,是接收不到B刷卡开门的信息的。因为你在这里没有进行关门操作。你的开门后到关门这之间是有时间的。
我们在做程序时应该想到实际情况中所有的情况
还是用上面的例子:
//大妈去买菜
//大妈买菜回来
如果上面两个事件在程序中写成组合出现,也就是【大妈去买菜】后,必须执行【大妈买菜回来】事件,那么实际出现出现【大妈买菜回来】和【白领回来】一起,大妈没有刷卡触发事件,那么下次大妈想再执行【大妈去买菜事件】怎么解决。
上面描述的这种情况实际出现在我们平时乘坐地铁时。

所以我们就要去限定到底能不能【大妈买菜回来】和【白领回来】其中任意一个触发事件,导致门开。
知识本身就是一个相互运用的过程,写程序时运用各种知识储备将程序写的更加健壮周密,更加符合实际运用,更加人性化,或者说更加优美,很重要。
如果觉的我说的不对,请拍砖。

出0入0汤圆

发表于 2014-9-11 21:53:51 | 显示全部楼层
学习啦,等板子到手开始跟着学习。

出0入0汤圆

发表于 2014-9-11 22:04:46 | 显示全部楼层
看完之后更糊涂了,究竟什么是事件,这个事件和信号量又有什么不同呢

出0入0汤圆

发表于 2014-9-11 22:07:16 | 显示全部楼层
楼主描述的事件,我不晓得MQX中是不是这样玩的,但UCOS貌似不是这样玩的,难道我记忆有错?事件不是事件标志位吗?

出0入0汤圆

 楼主| 发表于 2014-9-11 23:36:57 | 显示全部楼层
kinsno 发表于 2014-9-11 22:07
楼主描述的事件,我不晓得MQX中是不是这样玩的,但UCOS貌似不是这样玩的,难道我记忆有错?事件不是事件标 ...

是标志位啊,置位也是为了解决问题啊!

出0入0汤圆

 楼主| 发表于 2014-9-11 23:38:02 | 显示全部楼层
wxfje 发表于 2014-9-11 22:04
看完之后更糊涂了,究竟什么是事件,这个事件和信号量又有什么不同呢

信号量是接收一次处理一次,事件不一样,事件可以有好几个来进行触发

出0入0汤圆

 楼主| 发表于 2014-9-11 23:41:43 | 显示全部楼层
步之道 发表于 2014-9-11 21:18
楼主的学习已经进入到第四篇了,看完这一篇后,我提个疑问。
为什么不联系前面学习的内容来写这一篇?
举个 ...

刚好相反,在ABC三个同时进行触发的时候它并不是没有接收到,而是都接收到了,但它只会执行一次,相当于一个标志位,三个去置位,但是结果是或的关系!在事件清除之前任意触发都无效!

出0入0汤圆

发表于 2014-9-12 00:04:13 来自手机 | 显示全部楼层
那有关门的命令吗?比如开门到关门30秒,第一个人开了,第二个人29秒的时候来触发一次那门什么时候关?两个事件可以用事件标记,但事件标记是持续变量,还是瞬态变量呢?

出0入93汤圆

发表于 2014-9-12 00:09:04 | 显示全部楼层
事件就类似硬件上的中断

出0入0汤圆

发表于 2014-9-12 00:33:22 | 显示全部楼层
进来学习一下

出0入0汤圆

 楼主| 发表于 2014-9-12 10:50:38 | 显示全部楼层
步之道 发表于 2014-9-12 00:04
那有关门的命令吗?比如开门到关门30秒,第一个人开了,第二个人29秒的时候来触发一次那门什么时候关?两个 ...

事件有清除事件标志,你可以看看程序中开门后有一个清除事件函数,那个是用来清除事件的,另个,事件在创建的时候也可选择自己清除事件,即事件置位后,等等触发,触发后自动清除!

出0入0汤圆

 楼主| 发表于 2014-9-12 10:51:20 | 显示全部楼层
tim 发表于 2014-9-12 00:09
事件就类似硬件上的中断

跟中断不一样,中断是硬件实时的,事件只有等任务切换后才能触发!

出0入93汤圆

发表于 2014-9-12 10:59:13 | 显示全部楼层
wangpengcheng 发表于 2014-9-12 10:51
跟中断不一样,中断是硬件实时的,事件只有等任务切换后才能触发!

我的意思是“什么时候发生不确定”这一点类似

出0入0汤圆

 楼主| 发表于 2014-9-12 11:12:29 | 显示全部楼层
tim 发表于 2014-9-12 10:59
我的意思是“什么时候发生不确定”这一点类似

呵呵,有点那个意思!

出0入0汤圆

发表于 2014-9-12 12:23:24 | 显示全部楼层
MQZ 事件   

出0入0汤圆

发表于 2014-9-12 12:23:46 | 显示全部楼层
mark ~~~     

出0入0汤圆

发表于 2014-9-12 12:43:39 | 显示全部楼层
wangpengcheng 发表于 2014-9-12 10:50
事件有清除事件标志,你可以看看程序中开门后有一个清除事件函数,那个是用来清除事件的,另个,事件在创 ...

原来如此,不过你用这个小区门禁的例子来讲解事件,但是又区分了出去和回来,这两个个人觉的不需要被区分,只要定义一个开门事件就可以了,然后通过卡的区分,来定义不同的人的开门事件。这样是否更友好呢。

出0入0汤圆

 楼主| 发表于 2014-9-12 14:59:50 来自手机 | 显示全部楼层
步之道 发表于 2014-9-12 12:43
原来如此,不过你用这个小区门禁的例子来讲解事件,但是又区分了出去和回来,这两个个人觉的不需要被区分 ...

你说的很对,举例时没想清楚,其实只是需要开门就可以,不用管进出

出0入0汤圆

发表于 2014-9-12 19:04:12 | 显示全部楼层
wangpengcheng 发表于 2014-9-12 14:59
你说的很对,举例时没想清楚,其实只是需要开门就可以,不用管进出

嘿嘿,是的,这样也可以不要用到互斥量了。大家开门是可以同步的,只要将每个人的开门事件记录下来,然后对门状态进行或运算,并以最后一个人的开门时间延时多长时间作为关门动作。其实你举得这个例子肯贴近坐地铁时的情况。

出0入0汤圆

 楼主| 发表于 2014-9-12 21:18:31 | 显示全部楼层
步之道 发表于 2014-9-12 19:04
嘿嘿,是的,这样也可以不要用到互斥量了。大家开门是可以同步的,只要将每个人的开门事件记录下来,然后 ...

三个信号同进到达的原因是其它三个任务的优先级比较高,三个先后完成了置位,触发的任务优先级比较低,在三个置位都完成后才轮到它运行,所以跟你说的那种情况还不一样!

出0入0汤圆

发表于 2014-9-24 13:01:55 | 显示全部楼层
你好 请问你的QQ多少 我想问你一点问题

出0入0汤圆

发表于 2014-9-24 14:13:27 | 显示全部楼层
楼主你太有才了

出0入0汤圆

 楼主| 发表于 2014-9-24 21:48:55 | 显示全部楼层
寻找钢叉的猹 发表于 2014-9-24 13:01
你好 请问你的QQ多少 我想问你一点问题

可以在帖子中把问题说出来,大家给你看啊!

出0入0汤圆

发表于 2014-9-24 21:51:02 | 显示全部楼层
wangpengcheng 发表于 2014-9-24 21:48
可以在帖子中把问题说出来,大家给你看啊!

刚开始搭建环境 问题太多 比较碎  有一个TWR-K60D100M  现在各种下载资料  开始学习的第一天

出0入0汤圆

 楼主| 发表于 2014-9-24 21:52:10 | 显示全部楼层
寻找钢叉的猹 发表于 2014-9-24 21:51
刚开始搭建环境 问题太多 比较碎  有一个TWR-K60D100M  现在各种下载资料  开始学习的第一天  ...

如果你连自己问题在哪都不清楚的话,除了自己深入学习,再没有其它办法啊!

出0入0汤圆

发表于 2014-9-24 21:52:28 | 显示全部楼层
我一定会努力的  勤能补拙 多逛论坛

出0入0汤圆

 楼主| 发表于 2014-9-24 21:53:17 | 显示全部楼层
寻找钢叉的猹 发表于 2014-9-24 21:52
我一定会努力的  勤能补拙 多逛论坛

对的,呵呵,多动手,多逛论坛!主要是动手!

出0入0汤圆

发表于 2014-10-1 21:23:16 | 显示全部楼层
楼主  我有TWR-K60D100M 能否和你一起学习MQX?如果可以的话希望能加下你的QQ   PS:我的QQ---->1113240207  
我刚学4天MQX  苦恼于没人和我一起,希望能找个伴

出0入0汤圆

发表于 2014-10-29 15:24:24 | 显示全部楼层
请问楼主,K60 mqx的例程里用到MQX_HAS_TIME_SLICE
#if ! MQX_HAS_TIME_SLICE
#error This application requires MQX_HAS_TIME_SLICE defined non-zero in user_config.h. Please recompile PSP and BSP with this option.
#endif
我在配置文件里定义MQX_HAS_TIME_SLICE为1后,怎么例程里的串口就通信不上了,不知道你有没有遇到过?

出0入0汤圆

 楼主| 发表于 2014-10-29 17:33:16 | 显示全部楼层
samhws 发表于 2014-10-29 15:24
请问楼主,K60 mqx的例程里用到MQX_HAS_TIME_SLICE
#if ! MQX_HAS_TIME_SLICE
#error This application req ...

我暂时没用到这个功能!你查一下,看看是不是其它地方影响了串口!这两个不应该有冲突!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-23 09:21

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

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