Working and simple example of Events, Listeners and Flags

Discussions and support about ChibiOS/RT, the free embedded RTOS.
KalRal
Posts: 6
Joined: Tue Feb 12, 2019 9:08 pm
Has thanked: 2 times
Been thanked: 1 time

Working and simple example of Events, Listeners and Flags

Postby KalRal » Thu Apr 16, 2020 7:33 pm

I have seen several forum topics that starts with having doubts about Events, Listeners and Event Flags. I also had some doubts and researched a bit about how they work and the forum topics were also really helpful. So to give something back to community, I have a simple working example that uses

Code: Select all

event_source_t, event_listener_t and eventflags_t
in the same example.

Code: Select all

/*
    ChibiOS - Copyright (C) 2006..2016 Nicolas Reinecke
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
        http://www.apache.org/licenses/LICENSE-2.0
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/
// clang-format off
#include "ch.hpp"
#include "hal.h"
#include "string.h"
#include "usbcfg.h"
#include "chprintf.h"
// clang-format on

///
/// Define an EventSource
///
event_source_t ledEventSource;

///
/// Define event flags
///
#define LED3 (eventflags_t)0
#define LED4 (eventflags_t)1
#define LED5 (eventflags_t)2
#define LED6 (eventflags_t)6
/**
 * @brief chp Stream for printing variables on USB
 */
BaseSequentialStream* chp = (BaseSequentialStream*)(&SDU1);

class BlinkerThread : public chibios_rt::BaseStaticThread<512>
{
  protected:
    void main(void) override
    {
        setName("BlinkerThread");

        // Define an event listener
        event_listener_t ledEventListener;
        // Register for the event
        chEvtRegisterMask(&ledEventSource, &ledEventListener, EVENT_MASK(0));
        eventflags_t flags;
        while(true)
        {
            chEvtWaitAny(EVENT_MASK(0));
            flags = chEvtGetAndClearFlags(&ledEventListener);
            if(flags == LED3)
            {
                palToggleLine(LINE_LED3);
            }
            else if(flags == LED4)
            {
                palToggleLine(LINE_LED4);
            }
            else if(flags == LED5)
            {
                palToggleLine(LINE_LED5);
            }
            else if(flags == LED6)
            {
                palToggleLine(LINE_LED6);
            }
        }
    }

  public:
    BlinkerThread(void)
        : BaseStaticThread<512>()
    {
    }
};

/*
 * Application entry point.
 */
int main(void)
{
    /*
     * System initializations.
     * - HAL initialization, this also initializes the configured device drivers
     *   and performs the board-specific initializations.
     * - Kernel initialization, the main() function becomes a thread and the
     *   RTOS is active.
     */
    chEvtObjectInit(&ledEventSource);
    halInit();
    chibios_rt::System::init();

    // Initialize Serial-USB driver
    sduObjectInit(&SDU1);
    sduStart(&SDU1, &serusbcfg);

    /*
     * Activates the USB driver and then the USB bus pull-up on D+.
     * Note, a delay is inserted in order to not have to disconnect the cable
     * after a reset.
     */
    usbDisconnectBus(serusbcfg.usbp);
    chThdSleepMilliseconds(1500);
    usbStart(serusbcfg.usbp, &usbcfg);
    usbConnectBus(serusbcfg.usbp);

    ///
    /// Start thread
    ///
    BlinkerThread blinkerThread;
    blinkerThread.start(NORMALPRIO + 1);
    while(1)
    {
        chEvtBroadcastFlags(&ledEventSource, LED3);
        chThdSleepMilliseconds(50);
        chEvtBroadcastFlags(&ledEventSource, LED4);
        chThdSleepMilliseconds(50);
        chEvtBroadcastFlags(&ledEventSource, LED5);
        chThdSleepMilliseconds(50);
        chEvtBroadcastFlags(&ledEventSource, LED6);
        chThdSleepMilliseconds(50);
    }
}


I hope, i haven't made any mistakes. Please let me know if I have.
Thanks

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: Working and simple example of Events, Listeners and Flags

Postby Giovanni » Thu Apr 16, 2020 8:22 pm

Hi,

Just a note, flags are bit masks, you should handle those as such, new flags are ORed to existing ones. your code seems to assume that flags are just like messages:

Code: Select all

///
/// Define event flags
///
#define LED3 (eventflags_t)0
#define LED4 (eventflags_t)1
#define LED5 (eventflags_t)2
#define LED6 (eventflags_t)6


LED6 is 6 so it includes flags 4 and 2, 2 is your LED5. Assuming you get events for LED4, LED5 and LED6, you would get 7 (6!2!1). This does not happen in your code because you send events with intervals so those are never ORed together.

In that example you could also have used messages or mailboxes.

Giovanni

KalRal
Posts: 6
Joined: Tue Feb 12, 2019 9:08 pm
Has thanked: 2 times
Been thanked: 1 time

Re: Working and simple example of Events, Listeners and Flags

Postby KalRal » Fri Apr 17, 2020 8:21 am

Cool. Thanks Giovanni. Will keep that in mind. Yeah you are right, I could have gone with the Mailboxes, but just wanted to learn about using events. I also have an example projects repository that contains all the features that I have tried out in Chibios.

Chibios Projects


Return to “ChibiOS/RT”

Who is online

Users browsing this forum: No registered users and 14 guests