硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2704|回复: 19
收起左侧

[RL-RTX] 多个串口中断中发送多个不同的信号量,怎么在一个任务中处理这多个信号量呢?

[复制链接]

18

主题

285

回帖

339

积分

高级会员

积分
339
发表于 2018-11-6 22:08:05 | 显示全部楼层 |阅读模式

如题,3个串口中断中发送了3个信号量,我的做法是建立了3个任务来处理这3个信号量,见下面的程序
这样做的好处是简单,明了。只要某个信号量send了相关任务就执行,缺点是建立了3个任务。有没有其他的方式实现下面的功能呢?即把3个任务合成1个,信号send后能及时的执行相关操作
  1. void USART1_IRQHandler(void)
  2. {
  3.   if(USART1->SR & (BIT5))                  //接收到数据
  4.   {
  5.     isr_sem_send (&semaphore1);
  6.   }
  7. }
  8. void USART2_IRQHandler(void)
  9. {
  10.   if(USART2->SR & (BIT5))                  //接收到数据
  11.   {
  12.     isr_sem_send (&semaphore2);
  13.   }
  14. }
  15. void USART3_IRQHandler(void)
  16. {
  17.   if(USART3->SR & (BIT5))                  //接收到数据
  18.   {
  19.     isr_sem_send (&semaphore3);
  20.   }
  21. }

  22. __task void task1(void)
  23. {
  24.   while(1)
  25.   {
  26.     os_sem_wait (&semaphore1, 0xffff);
  27.     //执行相关操作
  28.     ......
  29.   }
  30. }
  31. __task void task2(void)
  32. {
  33.   while(1)
  34.   {
  35.     os_sem_wait (&semaphore2, 0xffff);
  36.     //执行相关操作
  37.     ......
  38.   }
  39. }
  40. __task void task3(void)
  41. {
  42.   while(1)
  43.   {
  44.     os_sem_wait (&semaphore3, 0xffff);
  45.     //执行相关操作
  46.     ......
  47.   }
  48. }
复制代码


回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-7 09:51:20 | 显示全部楼层
呼叫各位OS的高手啊
回复

使用道具 举报

36

主题

2039

回帖

2147

积分

至尊会员

积分
2147
发表于 2018-11-7 11:05:53 | 显示全部楼层
一个任务处理就好了,发事件标志。
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

5

主题

578

回帖

593

积分

版主

Rank: 7Rank: 7Rank: 7

积分
593
发表于 2018-11-7 11:32:41 | 显示全部楼层
byccc 发表于 2018-11-7 11:05
一个任务处理就好了,发事件标志。

完美
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-7 11:44:07 | 显示全部楼层
byccc 发表于 2018-11-7 11:05
一个任务处理就好了,发事件标志。


改成这个样子?
这样的话3个消息是轮询每个100ms处理一次的,时效性上比建立3个任务是不是差了点呢?
  1. void USART1_IRQHandler(void)
  2. {
  3.   if(USART1->SR & (BIT5))                  //接收到数据
  4.   {
  5.     isr_evt_set (0x0001,&task_id);
  6.   }
  7. }
  8. void USART2_IRQHandler(void)
  9. {
  10.   if(USART2->SR & (BIT5))                  //接收到数据
  11.   {
  12.     isr_evt_set (0x0002,&task_id);
  13.   }
  14. }
  15. void USART3_IRQHandler(void)
  16. {
  17.   if(USART3->SR & (BIT5))                  //接收到数据
  18.   {
  19.     isr_evt_set (0x0004,&task_id);
  20.   }
  21. }

  22. __task void task(void)
  23. {
  24.   OS_RESULT result;
  25.   while(1)
  26.   {
  27.     result=os_evt_wait_and (0x0001, 0);
  28.     if(result == OS_R_EVT)
  29.     {
  30.       //执行相关操作1
  31.       ......
  32.     }
  33.    
  34.     result=os_evt_wait_and (0x0002, 0);
  35.     if(result == OS_R_EVT)
  36.     {
  37.       //执行相关操作2
  38.       ......
  39.     }
  40.    
  41.     result=os_evt_wait_and (0x0004, 0);
  42.     if(result == OS_R_EVT)
  43.     {
  44.       //执行相关操作3
  45.       ......
  46.     }
  47.     os_dly_wait(100);
  48.   }
  49. }
复制代码


回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-7 11:46:17 | 显示全部楼层

这样做效率和时效性上似乎没有建立多个任务要好啊,见我楼上的代码。。
回复

使用道具 举报

36

主题

2039

回帖

2147

积分

至尊会员

积分
2147
发表于 2018-11-7 11:54:41 | 显示全部楼层
本帖最后由 byccc 于 2018-11-7 11:56 编辑
木兰花 发表于 2018-11-7 11:44
改成这个样子?
这样的话3个消息是轮询每个100ms处理一次的,时效性上比建立3个任务是不是差了点呢?
...

os_evt_wait_or (标志1 | 标志2 | 标志3 | 标志4 .......,  延迟时间);

把你的os_dly_wait(100);删掉。
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-7 12:02:48 | 显示全部楼层
byccc 发表于 2018-11-7 11:54
os_evt_wait_or (标志1 | 标志2 | 标志3 | 标志4 .......,  延迟时间);

把你的os_dly_wait(100);删掉 ...

使用这个函数的话,我不知道具体是哪个标志置位了呢,os_evt_wait_or 只返回:OS_R_EVT,不返回触发这个函数的是哪个标志呢?
result=os_evt_wait_or (标志1 | 标志2 | 标志3 | 标志4 .......,  延迟时间);

这里result值一直是OS_R_EVT 啊,怎么得到 标志1或2呢?
回复

使用道具 举报

36

主题

2039

回帖

2147

积分

至尊会员

积分
2147
发表于 2018-11-7 12:09:56 | 显示全部楼层
木兰花 发表于 2018-11-7 12:02
使用这个函数的话,我不知道具体是哪个标志置位了呢,os_evt_wait_or 只返回:OS_R_EVT,不返回触发这个 ...

悟性略差一下啊。

肯定有函数啊。
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-7 12:44:37 | 显示全部楼层
byccc 发表于 2018-11-7 12:09
悟性略差一下啊。

肯定有函数啊。

谢谢谢谢,找到这个函数了
这么做也挺好,少建立一个任务
  1. void USART1_IRQHandler(void)
  2. {
  3.   if(USART1->SR & (BIT5))                  //接收到数据
  4.   {
  5.     isr_evt_set (0x0001,&task_id);
  6.   }
  7. }
  8. void USART2_IRQHandler(void)
  9. {
  10.   if(USART2->SR & (BIT5))                  //接收到数据
  11.   {
  12.     isr_evt_set (0x0002,&task_id);
  13.   }
  14. }
  15. void USART3_IRQHandler(void)
  16. {
  17.   if(USART3->SR & (BIT5))                  //接收到数据
  18.   {
  19.     isr_evt_set (0x0004,&task_id);
  20.   }
  21. }

  22. __task void task(void)
  23. {
  24.   u16 flags;
  25.   while(1)
  26.   {
  27.     if(os_evt_wait_or (0x0007, 10) == OS_R_EVT)
  28.     {
  29.       flags=os_evt_get();
  30.       switch(flags)
  31.       {
  32.         case 0x0001:
  33.         {
  34.           //执行相关操作1
  35.           break;
  36.         }
  37.         case 0x0002:
  38.         {
  39.           //执行相关操作2
  40.           break;
  41.         }
  42.         case 0x0004:
  43.         {
  44.           //执行相关操作3
  45.           break;
  46.         }
  47.         default:break;
  48.       }
  49.     }
  50.   }
  51. }
复制代码




回复

使用道具 举报

5

主题

578

回帖

593

积分

版主

Rank: 7Rank: 7Rank: 7

积分
593
发表于 2018-11-8 02:04:00 | 显示全部楼层
木兰花 发表于 2018-11-7 12:44
谢谢谢谢,找到这个函数了
这么做也挺好,少建立一个任务

收到的可能是多个事件组合
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-8 08:50:11 | 显示全部楼层
myxiaonia 发表于 2018-11-8 02:04
收到的可能是多个事件组合

是的,然后再分析是哪个事件发生了,再做相关的动作
回复

使用道具 举报

19

主题

326

回帖

383

积分

高级会员

积分
383
发表于 2018-11-8 09:11:33 | 显示全部楼层
用队列消息,然后不同的消息代码代表不同的串口消息。
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-9 08:56:20 | 显示全部楼层
laofa 发表于 2018-11-8 09:11
用队列消息,然后不同的消息代码代表不同的串口消息。

嗯,这种方法也挺好,和os_evt_wait_or  比哪个更好呢
回复

使用道具 举报

19

主题

326

回帖

383

积分

高级会员

积分
383
发表于 2018-11-9 12:39:29 | 显示全部楼层
木兰花 发表于 2018-11-9 08:56
嗯,这种方法也挺好,和os_evt_wait_or  比哪个更好呢

我目前就是用这种方法处理不同的消息,把不同功能的消息分类,每个任务处理一类消息,当消息处理完成就进入继续等待消息,这时如果没有消息就会自动阻塞而让出CPU给别的任务,效率很高的。
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-9 15:47:17 | 显示全部楼层
laofa 发表于 2018-11-9 12:39
我目前就是用这种方法处理不同的消息,把不同功能的消息分类,每个任务处理一类消息,当消息处理完成就进 ...

是的,和os_evt_wait_or  比呢?
回复

使用道具 举报

19

主题

326

回帖

383

积分

高级会员

积分
383
发表于 2018-11-10 00:04:26 | 显示全部楼层
木兰花 发表于 2018-11-9 15:47
是的,和os_evt_wait_or  比呢?

这个主要是为了同步吧,我只是看过,没有用过这个
回复

使用道具 举报

18

主题

285

回帖

339

积分

高级会员

积分
339
 楼主| 发表于 2018-11-10 22:43:05 | 显示全部楼层
laofa 发表于 2018-11-10 00:04
这个主要是为了同步吧,我只是看过,没有用过这个

嗯,有时间了比较下这2个东西
回复

使用道具 举报

5

主题

28

回帖

43

积分

新手上路

积分
43
发表于 2019-5-23 20:31:02 | 显示全部楼层
效率应该是一样的,都是阻塞,等内核通知有事件到来,然后恢复运行,差别在于队列的消息是有先后之分的,然后队列可以保存大量历史消息,事件标志不能保存,可以把标志组看成有1个成员的队列。。
回复

使用道具 举报

5

主题

28

回帖

43

积分

新手上路

积分
43
发表于 2019-5-23 20:31:42 | 显示全部楼层
木兰花 发表于 2018-11-10 22:43
嗯,有时间了比较下这2个东西

效率应该是一样的,都是阻塞,等内核通知有事件到来,然后恢复运行,差别在于队列的消息是有先后之分的,然后队列可以保存大量历史消息,事件标志不能保存,可以把标志组看成有1个成员的队列。。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 14:01 , Processed in 0.245021 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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