8.3. Event callback mechanism

    Note: requires kernel version no less than: v1.8.7

    8.3.2. Headers

    8.3.3. Data types

    The event callback mechanism relies on the PikaEventListener event listener, which records the ID of each registered event. When a signal is sent to the event listener, the event listener will call the corresponding Python callback function based on the event ID, and pass the semaphore.

    The core of the event model is the PikaEventListener event listener.

    The PikaEventListener model is shown above. After registering an event to the event listener, an event item Event Item will be recorded inside the PikaEventListener, including.

    • Event ID the unique ID of the event

    • Event Handler Object event object, which records all the information about the event item

    • Event CallBack event callback function ( Python function )

    When the Event Signal event signal arrives, the event listener will match the Event ID to find the corresponding event item, then pass the signal code Event Code to Event CallBak to trigger the callback function.

    _images/image-20220619104053576.png

    8.3.5. Event callback mechanism flow

    1. Initialize the event listener

    2. register callback functions in Python

    3. the callback function registered in Python is executed

    8.3.6. Support event callbacks via PikaStdDevice

    Inheriting PikaStdDevice is the easiest way to support event callbacks, the PikaStdDevice.BaseDev device base class already supports the event registration method addEventCallBack.

    1. class BaseDev:
    2. def addEventCallBack(self, eventCallback: any): ...
    3. # need override
    4. def platformGetEventId(self): ...
    • The device classes in PikaStdDevice (e.g. GPIO) all inherit from BaseDev, so they all get the addEventCallBack method and can register callbacks.

    /package/PikaStdDevice/PikaStdDevice.pyi

    After the platform driver inherits from PikaStdDevice.GPIO, it also gets the addEventCallBack method.

    1. # TemplateDevice.pyi
    2. class GPIO(PikaStdDevice.GPIO):
    3. # overrid
    4. ...
    5. ...

    Just override the platformGetEventId platform method to be able to support registration callbacks.

    For example.

    /package/TemplateDevice/TemplateDevice_GPIO.c

    1. const uint32_t GPIO_PA8_EVENT_ID = 0x08;
    2. char* pin = obj_getStr(self, "pin");
    3. if (strEqu(pin, "PA8")) {
    4. obj_setInt(self, "eventId", GPIO_PA8_EVENT_ID);
    5. }
    6. }
    • Define a callback function callBack1 that takes an input parameter signal, signal can receive the incoming signal number.

    /examples/TemplateDevice/gpio_cb.py

    8.3.8. Signal triggering

    Send a signal to PikaEventListener when an event callback needs to be triggered.

    Example: /port/linux/test/event-test.cpp

    • Get the event listener provided by PikaStdDevice via extern PikaEventListener* g_pika_device_event_listener.

    1. extern PikaEventListener* g_pika_device_event_listener;
    2. #define EVENT_SIGAL_IO_RISING_EDGE 0x01
    3. #define EVENT_SIGAL_IO_FALLING_EDGE 0x02
    4. #define GPIO_PA8_EVENT_ID 0x08
    5. TEST(event, gpio) {
    6. /* init */
    7. PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
    8. /* run */
    9. pikaVM_runFile(pikaMain, "... /... /examples/TemplateDevice/gpio_cb.py");
    10. /* simulate run in the call back */
    11. pks_eventLisener_sendSignal(g_pika_device_event_listener, GPIO_PA8_EVENT_ID,
    12. EVENT_SIGAL_IO_RISING_EDGE);
    13. pks_eventLisener_sendSignal(g_pika_device_event_listener, GPIO_PA8_EVENT_ID,
    14. EVENT_SIGAL_IO_FALLING_EDGE);
    15. ...
    16. }
    1. get rising edge!
    2. get falling edg!

    8.3.9. Advanced: Custom event registration functions

    • In addition to event callbacks supported by , you can also customize event registration functions, which is an advanced part.

    • Custom event registration requires a better understanding of PikaScript’s C-module mechanism and object mechanism.

    • Define a Python interface to a C module that receives incoming event callback functions.

    For example.

    /package/PikaStdDevice/PikaStdDevice.pyi

    The type annotation for the event callback function is any.

    • Registering events in the C module implementation

    Example:

    1. PikaEventListener* g_pika_device_event_listener;
    2. void PikaStdDevice_BaseDev_addEventCallBack(PikaObj* self, Arg* eventCallBack) {
    3. obj_setArg(self, "eventCallBack", eventCallBack);
    4. /* init event_listener for the first time */
    5. if (NULL == g_pika_device_event_listener) {
    6. pks_eventLisener_init(&g_pika_device_event_listener);
    7. }
    8. if (PIKA_RES_OK != obj_runNativeMethod(self, "platformGetEventId", NULL)) {
    9. obj_setErrorCode(self, 1);
    10. __platform_printf("Error: Method %s no found.\r\n",
    11. "platformGetEventId");
    12. }
    13. uint32_t eventId = obj_getInt(self, "eventId");
    14. pks_eventLicener_registEvent(g_pika_device_event_listener, eventId, self);
    15. }
    • Create a global PikaEventListener: g_pika_device_event_listener.

    • Pass self as event handler object and evnetCallBack into self.

    • Get evnetID.

      • This example gets the eventID by calling the platformGetEventId() platform function, which requires BaseDev inheritance, then rewrites platformGetEventId() and sets self. eventId in the overridden platformGetEventId().

      • For example: /package/TemplateDevice/TemplateDevice_GPIO.c