多个串口中断中发送多个不同的信号量,怎么在一个任务中处理这多个信号量呢?
如题,3个串口中断中发送了3个信号量,我的做法是建立了3个任务来处理这3个信号量,见下面的程序
这样做的好处是简单,明了。只要某个信号量send了相关任务就执行,缺点是建立了3个任务。有没有其他的方式实现下面的功能呢?即把3个任务合成1个,信号send后能及时的执行相关操作
void USART1_IRQHandler(void)
{
if(USART1->SR & (BIT5)) //接收到数据
{
isr_sem_send (&semaphore1);
}
}
void USART2_IRQHandler(void)
{
if(USART2->SR & (BIT5)) //接收到数据
{
isr_sem_send (&semaphore2);
}
}
void USART3_IRQHandler(void)
{
if(USART3->SR & (BIT5)) //接收到数据
{
isr_sem_send (&semaphore3);
}
}
__task void task1(void)
{
while(1)
{
os_sem_wait (&semaphore1, 0xffff);
//执行相关操作
......
}
}
__task void task2(void)
{
while(1)
{
os_sem_wait (&semaphore2, 0xffff);
//执行相关操作
......
}
}
__task void task3(void)
{
while(1)
{
os_sem_wait (&semaphore3, 0xffff);
//执行相关操作
......
}
}
呼叫各位OS的高手啊 一个任务处理就好了,发事件标志。 byccc 发表于 2018-11-7 11:05
一个任务处理就好了,发事件标志。
完美 byccc 发表于 2018-11-7 11:05
一个任务处理就好了,发事件标志。
改成这个样子?
这样的话3个消息是轮询每个100ms处理一次的,时效性上比建立3个任务是不是差了点呢?
void USART1_IRQHandler(void)
{
if(USART1->SR & (BIT5)) //接收到数据
{
isr_evt_set (0x0001,&task_id);
}
}
void USART2_IRQHandler(void)
{
if(USART2->SR & (BIT5)) //接收到数据
{
isr_evt_set (0x0002,&task_id);
}
}
void USART3_IRQHandler(void)
{
if(USART3->SR & (BIT5)) //接收到数据
{
isr_evt_set (0x0004,&task_id);
}
}
__task void task(void)
{
OS_RESULT result;
while(1)
{
result=os_evt_wait_and (0x0001, 0);
if(result == OS_R_EVT)
{
//执行相关操作1
......
}
result=os_evt_wait_and (0x0002, 0);
if(result == OS_R_EVT)
{
//执行相关操作2
......
}
result=os_evt_wait_and (0x0004, 0);
if(result == OS_R_EVT)
{
//执行相关操作3
......
}
os_dly_wait(100);
}
}
myxiaonia 发表于 2018-11-7 11:32
完美
这样做效率和时效性上似乎没有建立多个任务要好啊,见我楼上的代码。。 本帖最后由 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);删掉。 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呢? 木兰花 发表于 2018-11-7 12:02
使用这个函数的话,我不知道具体是哪个标志置位了呢,os_evt_wait_or 只返回:OS_R_EVT,不返回触发这个 ...
悟性略差一下啊。:lol
肯定有函数啊。 byccc 发表于 2018-11-7 12:09
悟性略差一下啊。
肯定有函数啊。
谢谢谢谢,找到这个函数了:lol
这么做也挺好,少建立一个任务
void USART1_IRQHandler(void)
{
if(USART1->SR & (BIT5)) //接收到数据
{
isr_evt_set (0x0001,&task_id);
}
}
void USART2_IRQHandler(void)
{
if(USART2->SR & (BIT5)) //接收到数据
{
isr_evt_set (0x0002,&task_id);
}
}
void USART3_IRQHandler(void)
{
if(USART3->SR & (BIT5)) //接收到数据
{
isr_evt_set (0x0004,&task_id);
}
}
__task void task(void)
{
u16 flags;
while(1)
{
if(os_evt_wait_or (0x0007, 10) == OS_R_EVT)
{
flags=os_evt_get();
switch(flags)
{
case 0x0001:
{
//执行相关操作1
break;
}
case 0x0002:
{
//执行相关操作2
break;
}
case 0x0004:
{
//执行相关操作3
break;
}
default:break;
}
}
}
}
木兰花 发表于 2018-11-7 12:44
谢谢谢谢,找到这个函数了
这么做也挺好,少建立一个任务
收到的可能是多个事件组合 myxiaonia 发表于 2018-11-8 02:04
收到的可能是多个事件组合
是的,然后再分析是哪个事件发生了,再做相关的动作 用队列消息,然后不同的消息代码代表不同的串口消息。 laofa 发表于 2018-11-8 09:11
用队列消息,然后不同的消息代码代表不同的串口消息。
嗯,这种方法也挺好,和os_evt_wait_or比哪个更好呢 木兰花 发表于 2018-11-9 08:56
嗯,这种方法也挺好,和os_evt_wait_or比哪个更好呢
我目前就是用这种方法处理不同的消息,把不同功能的消息分类,每个任务处理一类消息,当消息处理完成就进入继续等待消息,这时如果没有消息就会自动阻塞而让出CPU给别的任务,效率很高的。 laofa 发表于 2018-11-9 12:39
我目前就是用这种方法处理不同的消息,把不同功能的消息分类,每个任务处理一类消息,当消息处理完成就进 ...
是的,和os_evt_wait_or比呢? 木兰花 发表于 2018-11-9 15:47
是的,和os_evt_wait_or比呢?
这个主要是为了同步吧,我只是看过,没有用过这个 laofa 发表于 2018-11-10 00:04
这个主要是为了同步吧,我只是看过,没有用过这个
嗯,有时间了比较下这2个东西 效率应该是一样的,都是阻塞,等内核通知有事件到来,然后恢复运行,差别在于队列的消息是有先后之分的,然后队列可以保存大量历史消息,事件标志不能保存,可以把标志组看成有1个成员的队列。。 木兰花 发表于 2018-11-10 22:43
嗯,有时间了比较下这2个东西
效率应该是一样的,都是阻塞,等内核通知有事件到来,然后恢复运行,差别在于队列的消息是有先后之分的,然后队列可以保存大量历史消息,事件标志不能保存,可以把标志组看成有1个成员的队列。。
页:
[1]