Embedded 嵌入式代码中的事件处理

Embedded 嵌入式代码中的事件处理,embedded,event-handling,Embedded,Event Handling,我想知道嵌入式系统代码中如何使用事件 主要目的是了解如何准确地在代码中设置/重置事件标志。以及如何识别哪个任务正在使用哪个事件标志,以及每个任务正在设置/重置标志的哪些位 请提出你的建议或意见 提前谢谢 (编辑1:从以下答案中的澄清中复制) 抱歉,没有指定所需的详细信息。实际上,我对使用vxworks/Itron/OSEK操作系统用C语言编写的任何应用程序的分析都感兴趣。例如,vxworks中有支持事件处理的eventLib库。我想知道如何利用这样的系统例程来处理任务中的事件。什么是事件标志(

我想知道嵌入式系统代码中如何使用事件

主要目的是了解如何准确地在代码中设置/重置事件标志。以及如何识别哪个任务正在使用哪个事件标志,以及每个任务正在设置/重置标志的哪些位

请提出你的建议或意见

提前谢谢


(编辑1:从以下答案中的澄清中复制)


抱歉,没有指定所需的详细信息。实际上,我对使用vxworks/Itron/OSEK操作系统用C语言编写的任何应用程序的分析都感兴趣。例如,vxworks中有支持事件处理的eventLib库。我想知道如何利用这样的系统例程来处理任务中的事件。什么是事件标志(是全局/本地…还是什么?),如何设置任何事件标志的位,以及任务和事件标志之间的可能关系

任务如何在AND或模式下等待多个事件?? 我遇到了一个例子,下面给出的场景看起来很危险,但为什么

            Scenarios is ==> *[Task1 : Set(e1), Task2 : Wait(e1) and Set(e2), Task3 : Wait(e2) ]*                                             
我知道一个任务等待的多个事件标志或多个任务之间的循环依赖(死锁)在任务-事件关系中是危险的情况,但上述情况有多危险,我不明白……请解释一下

                (Are there any more such scenarios possible in task-event handling which should be reviewed in code ?? ) 

我希望以上信息足够……

这个问题需要提供更多的背景。嵌入式系统可以使用多种语言、操作系统(包括非操作系统)、框架等创建。嵌入式系统中事件的创建和处理方式没有通用性,正如在一般的计算中如何创建和处理事件并没有通用性一样。

这个问题需要提供更多的上下文。嵌入式系统可以使用多种语言、操作系统(包括非操作系统)、框架等创建。嵌入式系统中事件的创建和处理方式没有通用性,正如在一般的计算中如何创建和处理事件没有通用性一样。

许多嵌入式系统使用中断服务例程(ISR)来处理事件。您可以为给定的“标志”定义ISR,并在处理事件后重置该标志

例如,假设您有一个执行模数转换(ADC)的设备。在设备上,您可以有一个ISR,每次ADC完成转换时触发,然后在ISR内处理,或者通知其他任务数据可用(如果您希望通过某些通信协议发送数据)。完成后,您将重置ADC标志,以便它可以在下一次转换时再次触发


通常,设备手册中定义了一组ISR。有时,它们提供通用标志,您也可以根据需要处理这些标志。每次重置导致例程触发的标志时。

许多嵌入式系统使用中断服务例程(ISR)来处理事件。您可以为给定的“标志”定义ISR,并在处理事件后重置该标志

例如,假设您有一个执行模数转换(ADC)的设备。在设备上,您可以有一个ISR,每次ADC完成转换时触发,然后在ISR内处理,或者通知其他任务数据可用(如果您希望通过某些通信协议发送数据)。完成后,您将重置ADC标志,以便它可以在下一次转换时再次触发


通常,设备手册中定义了一组ISR。有时,它们提供通用标志,您也可以根据需要处理这些标志。每次重置导致例程触发的标志时。

很抱歉没有指定所需的详细信息。实际上,我对使用vxworks/Itron/OSEK操作系统用C语言编写的任何应用程序的分析都感兴趣。 例如,vxworks中有支持事件处理的eventLib库。 我想知道如何利用这样的系统例程来处理任务中的事件。什么是事件标志(是全局/本地…还是什么?),如何设置任何事件标志的位,以及任务和事件标志之间的可能关系


我希望以上信息足够……

很抱歉没有指定所需的详细信息。实际上,我对使用vxworks/Itron/OSEK操作系统用C语言编写的任何应用程序的分析都感兴趣。 例如,vxworks中有支持事件处理的eventLib库。 我想知道如何利用这样的系统例程来处理任务中的事件。什么是事件标志(是全局/本地…还是什么?),如何设置任何事件标志的位,以及任务和事件标志之间的可能关系


我希望上面的信息足够了……

VxWorks中的eventLib类似于unix中的signal()——它可以向不同的线程指示发生了什么。如果需要随事件传递数据,则可能需要使用消息队列

事件在发送方和接收方之间是“全局”的。由于每个发送方都指示事件用于哪个任务,因此系统中可能有多个事件掩码,每个发送方/接收方对都有自己的解释

一个基本的例子:

 #define EVENT1       0x00000001
 #define EVENT2       0x00000002
 #define EVENT3       0x00000004
 ...
 #define EVENT_EXIT   0x80000000

 /* Spawn the event handler task (event receiver) */
 rcvTaskId = taskSpawn("tRcv",priority,0,stackSize,handleEvents,0,0,0,0,0,0,0,0,0,0);
 ...

 /* Receive thread: Loop to receive events */
 STATUS handleEvents(void)
 {
     UINT32 rcvEventMask = 0xFFFFFFFF;

     while(1)
     {
         UINT32 events = 0;

         if (eventReceive(rcvEventMask. EVENTS_WAIT_ANY, WAIT_FOREVER, &events) == OK)
         {
             /* Process events */
             if (events & EVENT1)
                 handleEvent1();
             if (events & EVENT2)
                 handleEvent2();
             ...
             if (events & EVENT_EXIT)
                 break;
         }
     }

     return OK;
 }
事件发送器通常是硬件驱动程序(BSP)或其他线程。当期望的操作发生时,驱动程序构建所有相关事件的掩码,并将它们发送给接收方任务

发送方需要获取接收方的taskID。taskID可以是全局

int RcvTaskID = ERROR;
...
eventSend(RcvTaskID, eventMask);
接收方可以将其注册到驱动程序/发送方任务中

static int RcvTaskID = ERROR;

void DRIVER_setRcvTaskID(int rcvTaskID)
{
    RcvTaskID = rcvTaskID;
}
...
eventSend(RcvTaskID, eventMask);
或者,驱动程序/发送方任务可以调用接收方API方法来发送事件(包装器)


VxWorks中的eventLib类似于unix中的signal()——它可以向不同的线程指示发生了什么。如果需要随事件传递数据,可能需要使用消息队列
static int RcvTaskID;
void RECV_sendEvents(UINT32 eventMask)
{
    eventSend(RcvTaskID, eventMask);
}
unsigned char bit_flags = 0;
#define TIMER_EXPIRED   0x01   // 0000 0001
#define DATA_READY      0x02   // 0000 0010
#define BUFFER_OVERFLOW 0x04   // 0000 0100
// Bitwise OR: bit_flags | 00000001 sets the first bit.
bit_flags |=  TIMER_EXPIRED;  // Set TIMER_EXPIRED bit.

// Bitwise AND w/complement clears bits: flags & 11111101 clears the 2nd bit.
bit_flags &= ~DATA_READY;     // Clear DATA_READY bit.

// Bitwise AND tests a bit.  The result is BUFFER_OVERFLOW
// if the bit is set, 0 if the bit is clear.
had_ovflow = bit_flags & BUFFER_OVERFLOW;
// Set DATA_READY and BUFFER_OVERFLOW bits.
bit_flags |=  (DATA_READY | BUFFER_OVERFLOW);
#define SET_BITS(bits, data)    data |=  (bits)
#define CLEAR_BITS(bits, data)  data &= ~(bits)
#define CHECK_BITS(bits, data)  (data & (bits))