Hongmeng Hi3861 Learning Eight-Huawei LiteOS-M (Event Marker)

1. Introduction

        Events are a mechanism for inter-task communication and can be used to achieve inter-task synchronization . However, event communication can only be event-type communication without data transmission . A task can wait for the occurrence of multiple events : it can wake up the task to process the event when any event occurs; it can also wake up the task to process the event after several events occur. The event set is represented by a 32-bit unsigned integer variable, and each bit represents an event .

        In a multitasking environment, synchronous operations are often required between tasks. Events can provide one-to-many and many-to-many synchronous operations. One-to-many synchronization model: one task waits for the triggering of multiple events; many-to-many synchronization model: multiple tasks wait for the triggering of multiple events.

        Tasks can trigger and wait for events by creating event control blocks. LiteOS events are only used for synchronization between tasks .

        For more concepts of event markers, please refer to: FreeRTOS learning seven (event flag group)_portmax_delay_t_guest's blog-CSDN blog

Event Flags

 2. Operating mechanism

        When reading an event , one or more event types of the event can be read according to the input event mask type uwEventMask. After the event is successfully read, if LOS_WAITMODE_CLR is set, the read event type will be cleared, otherwise the read event type will not be cleared, and it needs to be cleared manually. The read mode can be selected through parameters, whether to read all events in the event mask type or to read any event in the event mask type.

        When writing an event , the specified event type is written to the specified event, and multiple event types can be written at the same time. Write events trigger task scheduling.

        When clearing an event , clear the bit corresponding to the event according to the input event and the event type to be cleared.

3. API introduction

      osEventFlagsNew

        Function function:

        Create event flags. Cannot be called from an interrupt .

        Function prototype:

osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr)

        parameter:

        attr: attribute. Only used when custom memory . The default setting is NULL

        return value:

        NULL: failed

        Other values: event flag ID

        Example:

osEventFlagsId_t evt_id; // event flags id
evt_id = osEventFlagsNew(NULL);

      osEventFlagsSet

        Function function:

        Set event flags. Can be used in interrupts .

        Function prototype:

uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags)

        parameter:

        ef_id: Event ID. Obtained when the event flag group osEventFlagsNew is created .

        flags: event value

        return value:

        If the highest bit is set , returns the set event flag or error code

        Example:

osEventFlagsId_t evt_id; 
uint32_t rst = osEventFlagsSet(evt_id, 0x10001111);

      osEventFlagsWait

        Function function:

        Wait for the event to happen. Can be called in interrupt.

        Function prototype:

uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout)

        parameter:

        ef_id: Event ID. Obtained when the event flag group osEventFlagsNew is created .

        flags: The event value to be triggered.

        options: specify flag options

osFlagsWaitAny 0, wait for any flag (default), that is, satisfy any flag
osFlagsWaitAll 1. Wait for all flags, that is, all flags need to be satisfied.
osFlagsNoClear 2. Do not clear the flags that have been specified to wait. Flags need to be cleared manually with osEventFlagsClear.

        timeout: timeout time. osWaitForever die wait

        return value:

        Error code when clearing previous event flags or setting the highest bit

        Example:

osEventFlagsId_t evt_id; 
uint32_t flags;
flags = osEventFlagsWait(evt_id, 0x000000ff, osFlagsWaitAny, osWaitForever);

      osEventFlagsDelete

        Function function:

        Delete event flag group. cannot be called in interrupt

        Function prototype:

osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id)

        parameter:

        ef_id: event flag ID. Obtained when the event flag group osEventFlagsNew is created.

        return value:

        osOK: success

        Other values: fail

        Example:

osEventFlagsId_t evt_id;
osEventFlagsDelete(evt_id);

4. Example

        Create 2 tasks here, task 1 sets the event group, and task 2 waits for the event group. Among them, after task 1 sets up the event group, it immediately transfers the control right .

#define LOG_I(fmt, args...)   printf("<%8ld> - [TIMER]:"fmt"\r\n",osKernelGetTickCount(),##args);
#define LOG_E(fmt, args...)   printf("<%8ld>-[TIMER_ERR]>>>>>>>>>>>>:"fmt"\r\n",osKernelGetTickCount(), ##args);

osEventFlagsId_t evt_id; // event flags id

/***** 发送事件 *****/
void Thread_EventSender(void *argument)
{
  (void)argument;
  while (1)
  {
    LOG_I("thread1 send event before");
    uint32_t rst = osEventFlagsSet(evt_id, 0x80001111);
    LOG_I("thread1 send event after,rst = 0x%.8x,yield!!",rst);

    //suspend thread
    osThreadYield();

    LOG_I("thread1 send event delay 1S");

    osDelay(100);
  }
}

/***** 接收事件 *****/
void Thread_EventReceiver(void *argument)
{
  (void)argument;
  uint32_t flags;

  while (1)
  {
    flags = osEventFlagsWait(evt_id, 0x000000ff, osFlagsWaitAny, osWaitForever);
    LOG_I("Receive2 Flags is 0x%.8x\n", flags);
  }
}

void Hello_World(void)
{
    LOG_I("Test event");

    evt_id = osEventFlagsNew(NULL);

    if (evt_id == NULL)
    {
        LOG_E("Falied to create EventFlags!");
    }

    osThreadAttr_t attr;

    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 1024 * 4;
    attr.priority = osPriorityNormal;

    attr.name = "Thread_EventSender";
    if (osThreadNew(Thread_EventSender, NULL, &attr) == NULL)
    {
        LOG_E("Falied to create Thread_EventSender!");
    }

    attr.name = "Thread_EventReceiver";

    if (osThreadNew(Thread_EventReceiver, NULL, &attr) == NULL)
    {
        LOG_E("Falied to create Thread_EventReceiver!");
    }
}

        Look at the result:

         As can be seen from the results, task 2 is waiting for the 0x000000ff event. And task 1 releases 0x80001111. At this time, because the wait type set is osFlagsWaitAny, it triggers when any condition is met . Therefore, the event is directly triggered, and the read event group is 0x00000011.

        Task 1 and task 2 have the same priority , but task 1 releases control immediately after setting the event . As a result, task 2 can gain control and execute code.

Guess you like

Origin blog.csdn.net/qq_26226375/article/details/130529833