Events limitations Topic is solved

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess

Tuxford
Posts: 25
Joined: Fri Nov 06, 2020 3:28 pm
Location: Salivonky UA
Has thanked: 4 times
Been thanked: 4 times

Events limitations

Postby Tuxford » Sat Apr 02, 2022 1:16 pm

Hi,
I faced with a problem when I use events. I have declared 29 events using macro EVENTSOURCE_DECL. But after adding flag for event I found that chEvtBroadcastFlags doesn't send it or chEvtWaitOne(ALL_EVENTS) doesn't receive one exact event. Other important thing is that if I drop one evtTableHook call for binging with handler in main thread it starts working.

So questions?
0. How many events sources declarations are possible?
1. What the limitations of event handling evtTableHook and is it related with waiting calls?

Chibios 20.3
HW: STM32F103VCT6

Thank you!

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: Events limitations

Postby Giovanni » Sat Apr 02, 2022 1:58 pm

Hi,

Careful that "flags" are one thing, "events masks" are another, note that there are two types eventflags_t and eventmask_t.

You can have as many even sources you want, each event sources can OR "flags" to all registered event listeners objects, you can have up to 32 flags per listener. Threads can then fetch flags from the various listeners (clearing them) then process them.

"Event masks" are masks of event sources that a thread should be listening at, you can have up to 32 distinct event sources for each thread.

Do a search in the forum, in the past the thing has been discussed several times.

Giovanni

Tuxford
Posts: 25
Joined: Fri Nov 06, 2020 3:28 pm
Location: Salivonky UA
Has thanked: 4 times
Been thanked: 4 times

Re: Events limitations

Postby Tuxford » Sun Apr 03, 2022 3:51 pm

I understand difference between events and flags. There no problems. Code is too long to show it.

I was investigating how broadcasting works but I haven't have a clear idea how it's better to find out where event gets lost internally.

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: Events limitations

Postby Giovanni » Sun Apr 03, 2022 4:05 pm

I missed the point then, definitely you should be missing any event, could you post some code showing the problem?

Giovanni

Tuxford
Posts: 25
Joined: Fri Nov 06, 2020 3:28 pm
Location: Salivonky UA
Has thanked: 4 times
Been thanked: 4 times

Re: Events limitations

Postby Tuxford » Sun Apr 03, 2022 5:14 pm

Code: Select all

EVENTSOURCE_DECL(spindle_state_es);
EVENTSOURCE_DECL(spindle_es);

#define EVENT_STATE         EVENT_MASK(0)
#define EVENT_TRIGGER_VALUE EVENT_MASK(1)
#define EVENT_ENC1HS_SLOW   EVENT_MASK(2)

#define SUBEVENT_TICK          EVENT_MASK(0)
#define SUBEVENT_ATTACH        EVENT_MASK(1)
#define SUBEVENT_ATTACH_FAILED EVENT_MASK(2)
#define SUBEVENT_PULL_CANCELED EVENT_MASK(3)
#define SUBEVENT_DETACH        EVENT_MASK(4)
#define SUBEVENT_DETACH_DONE   EVENT_MASK(5)
#define SUBEVENT_ATTACH_MANUAL EVENT_MASK(6)


Code: Select all

void spindle_detach_doneI(void) {
    chEvtBroadcastFlagsI(&spindle_state_es, SUBEVENT_DETACH);
    detach_abort();
}


Code: Select all

static event_listener_t* spindle_state_el_ptr;
static event_listener_t* trigger_value_el_ptr;
static event_listener_t* enc1hs_el_ptr;

static THD_WORKING_AREA(wa_spindle, SPINDLE_STACK_SIZE);
static THD_FUNCTION(spindle_thd, arg) {
    (void)arg;
    chRegSetThreadName("spindle");

    event_listener_t spindle_state_el;
    event_listener_t trigger_value_el;
    event_listener_t enc1hs_el;

    spindle_state_el_ptr = &spindle_state_el;
    trigger_value_el_ptr = &trigger_value_el;
    enc1hs_el_ptr = &enc1hs_el;

    chEvtRegisterMask(&spindle_state_es, &spindle_state_el, EVENT_STATE);
    chEvtRegisterMask(&trigger_value_es, &trigger_value_el, EVENT_TRIGGER_VALUE);
    chEvtRegisterMask(&enc1hs_es, &enc1hs_el, EVENT_ENC1HS_SLOW);

    chEvtGetAndClearEvents(ALL_EVENTS);

    while (true) {
        eventmask_t event = chEvtWaitOne(ALL_EVENTS);

        spindle_state_e prev = spindle_context.state;
        switch(spindle_context.state) {
            case INIT:
//... doesn't matter
            case PULLING:
                _spindle_handle_pulling_state(event);
                break;
            default:
                _spindle_handle_undefined_state(event);
                break;
        }

        if (spindle_context.state != prev) {
            logger_log_prio(LOG_INFO,  "Spindle", "new state %d", spindle_context.state );
        }
    }
}

static void _spindle_handle_pulling_state(eventmask_t event) {
    if (event & EVENT_STATE) {
        eventflags_t flags = chEvtGetAndClearFlags(spindle_state_el_ptr);
        switch(flags) {
            case SUBEVENT_PULL_CANCELED: {
//...
                break;
            }
            case SUBEVENT_DETACH: //[b] This case isn't reached even message is sent[/b]
                spindle_context.state = DETACHING;
                logger_log_prio(LOG_DEBUG,  "Spindle", "DETACHING started");
                break;
        }
    }
}


Here is the code with the problem. Events SUBEVENT_TICK and SUBEVENT_ATTACH are handled properly.
So I'm trying to find out the way how to detect the point where it

And an extra info.

Code: Select all

    eventid_t sd_card_event = evtTableHook(events, sd_card_connect_es, sd_card_connect_handler);
    evtTableHook(events, sd_card_remove_es, sd_card_remove_handler);  //If this line or neighborhood is commented then no problem with receiving SUBEVENT_DETACH.
    evtTableHookWithFlags(events, key_press_es, button_click_handler, KEY_MASK_ALL);
    eventid_t app_event         = evtTableHook(events, second_es, app_handler);

    chEvtAddEvents(EVENT_MASK(sd_card_event) | EVENT_MASK(app_event));

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: Events limitations

Postby Giovanni » Sun Apr 03, 2022 5:51 pm

Hi,

Looking at the code I can see two problems:

1) EVENT_MASK() is not meant for flags, it casts to eventmask_t, this would not cause harm anyway.

2) In _spindle_handle_pulling_state() you do a switch testing for the various sub-events values but that is probably not correct, flags could have an OR of various sub-events and that would not be caught by your "switch". That could explain your missing events.

Giovanni

Tuxford
Posts: 25
Joined: Fri Nov 06, 2020 3:28 pm
Location: Salivonky UA
Has thanked: 4 times
Been thanked: 4 times

Re: Events limitations

Postby Tuxford » Mon Apr 04, 2022 6:19 pm

Hi Giovanni,
You are right!
I missed a case when one message was sent twice with different flags that were handled in wrong way.

I case EVENT_MASK it's good. I used it instead of lshift operation.

But I still have a question about chEvtWaitOne.
Does it wait one message and if other of the same id is received on about same time those message are being "added"?

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: Events limitations  Topic is solved

Postby Giovanni » Mon Apr 04, 2022 7:33 pm

Hi,

"wait one" refers to the events mask, it means that it returns only one bit from the mask of pending events. Multiple events raising the same bit are not buffered, it is a bit mask so, for example, 0x00000001 | 0x00000001 is still 0x00000001.

Note that event masks are a per-thread information, each thread has a separate mask independent from all others.

Giovanni


Return to “General Support”

Who is online

Users browsing this forum: No registered users and 20 guests