From 85ece20f4c10fe97f9e090ae748b4c61eb101a5c Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 5 Nov 2022 12:34:18 +0800 Subject: [PATCH] support cq for evnet, get res from event --- .../TemplateDevice/TemplateDevice_GPIO.c | 13 ++-- src/PikaObj.c | 46 ++++++++------ src/PikaObj.h | 4 +- src/PikaPlatform.h | 1 + src/PikaVM.c | 63 ++++++++++++++----- src/PikaVM.h | 19 ++++-- test/compile-test.cpp | 2 +- test/event-test.cpp | 9 ++- 8 files changed, 110 insertions(+), 47 deletions(-) diff --git a/port/linux/package/pikascript/pikascript-lib/TemplateDevice/TemplateDevice_GPIO.c b/port/linux/package/pikascript/pikascript-lib/TemplateDevice/TemplateDevice_GPIO.c index 733f3b45f..f7c398841 100644 --- a/port/linux/package/pikascript/pikascript-lib/TemplateDevice/TemplateDevice_GPIO.c +++ b/port/linux/package/pikascript/pikascript-lib/TemplateDevice/TemplateDevice_GPIO.c @@ -15,13 +15,14 @@ void TemplateDevice_GPIO_platformGetEventId(PikaObj* self) { } } - extern PikaEventListener* g_pika_device_event_listener; -#define EVENT_SIGAL_IO_RISING_EDGE 0x01 -#define EVENT_SIGAL_IO_FALLING_EDGE 0x02 +#define EVENT_SIGNAL_IO_RISING_EDGE 0x01 +#define EVENT_SIGNAL_IO_FALLING_EDGE 0x02 #define GPIO_PA8_EVENT_ID 0x08 -void TemplateDevice_GPIO_eventTest(PikaObj *self){ -pks_eventLisener_sendSignal(g_pika_device_event_listener, GPIO_PA8_EVENT_ID, - EVENT_SIGAL_IO_FALLING_EDGE); +void TemplateDevice_GPIO_eventTest(PikaObj* self) { + pks_eventLisener_sendSignal(g_pika_device_event_listener, GPIO_PA8_EVENT_ID, + EVENT_SIGNAL_IO_FALLING_EDGE); + pks_eventLisener_sendSignal(g_pika_device_event_listener, GPIO_PA8_EVENT_ID, + EVENT_SIGNAL_IO_RISING_EDGE); } diff --git a/src/PikaObj.c b/src/PikaObj.c index be9c99c0c..2a1ab9cec 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -1427,40 +1427,50 @@ void pks_eventLisener_deinit(PikaEventListener** p_self) { } } -void __eventLisener_runEvent(PikaObj* eventHandleObj) { +Arg* __eventLisener_runEvent(PikaEventListener* lisener, + uint32_t eventId, + int eventSignal) { + PikaObj* handler = pks_eventLisener_getEventHandleObj(lisener, eventId); + if (NULL == handler) { + __platform_printf( + "Error: can not find event handler by id: [0x%02x]\r\n", eventId); + return NULL; + } + obj_setInt(handler, "eventSignal", eventSignal); /* clang-format off */ PIKA_PYTHON( - eventCallBack(eventSignal) + _res = eventCallBack(eventSignal) ) /* clang-format on */ const uint8_t bytes[] = { - 0x08, 0x00, 0x00, 0x00, /* instruct array size */ - 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0d, 0x00, /* instruct array */ - 0x1b, 0x00, 0x00, 0x00, /* const pool size */ - 0x00, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x00, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x61, 0x63, 0x6b, 0x00, /* const pool */ + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x04, 0x1b, 0x00, + /* instruct array */ + 0x20, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, + 0x00, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x61, + 0x63, 0x6b, 0x00, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ }; - pikaVM_runByteCode(eventHandleObj, (uint8_t*)bytes); + pikaVM_runByteCode(handler, (uint8_t*)bytes); + Arg* res = obj_getArg(handler, "_res"); + res = arg_copy(res); + obj_removeArg(handler, "_res"); + return res; } void pks_eventLisener_sendSignal(PikaEventListener* self, uint32_t eventId, int eventSignal) { - PikaObj* eventHandleObj = pks_eventLisener_getEventHandleObj(self, eventId); - if (NULL == eventHandleObj) { - __platform_printf( - "Error: can not find event handler by id: [0x%02x]\r\n", eventId); - return; - } - obj_setInt(eventHandleObj, "eventSignal", eventSignal); if (0 == VMSignal_getVMCnt()) { /* no vm is running, run event handler directly */ - __eventLisener_runEvent(eventHandleObj); + Arg* res = __eventLisener_runEvent(self, eventId, eventSignal); + if (NULL != res) { + arg_deinit(res); + } return; } /* push event handler to vm event list */ - if (PIKA_RES_OK != VMSignal_pushEvent(eventHandleObj)) { + if (PIKA_RES_OK != VMSignal_pushEvent(self, eventId, eventSignal)) { __platform_printf( "OverflowError: event list is full, please use bigger " "PIKA_EVENT_LIST_SIZE\r\n"); diff --git a/src/PikaObj.h b/src/PikaObj.h index ee882a546..98f0989e7 100644 --- a/src/PikaObj.h +++ b/src/PikaObj.h @@ -470,6 +470,8 @@ void _obj_updateProxyFlag(PikaObj* self); _obj_updateProxyFlag((_self)) Arg* _obj_getProp(PikaObj* obj, char* name); -void __eventLisener_runEvent(PikaObj* eventHandleObj); +Arg* __eventLisener_runEvent(PikaEventListener* lisener, + uint32_t eventId, + int eventSignal); #endif diff --git a/src/PikaPlatform.h b/src/PikaPlatform.h index eb12f88fb..54ddd22b8 100644 --- a/src/PikaPlatform.h +++ b/src/PikaPlatform.h @@ -96,6 +96,7 @@ typedef enum { PIKA_RES_ERR_IO, PIKA_RES_ERR_ASSERT, PIKA_RES_ERR_SIGNAL_EVENT_FULL, + PIKA_RES_ERR_SIGNAL_EVENT_EMPTY, } PIKA_RES; /* clang-format off */ diff --git a/src/PikaVM.c b/src/PikaVM.c index ee4a40ea0..f545a4329 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -36,29 +36,51 @@ #include #endif -static volatile VMSignal PikaVMSignal = { - .signal_ctrl = VM_SIGNAL_CTRL_NONE, - .vm_cnt = 0, - .event_top = 0, -}; +static volatile VMSignal PikaVMSignal = {.signal_ctrl = VM_SIGNAL_CTRL_NONE, + .vm_cnt = 0, + .cq = { + .head = 0, + .tail = 0, + }}; int VMSignal_getVMCnt(void) { return PikaVMSignal.vm_cnt; } -PIKA_RES VMSignal_pushEvent(PikaObj* eventHandleObj) { - if (PikaVMSignal.event_top >= PIKA_EVENT_LIST_SIZE) { +static PIKA_BOOL _cq_isEmpty(volatile VMSignal* signal) { + return signal->cq.head == signal->cq.tail; +} + +static PIKA_BOOL _cq_isFull(volatile VMSignal* signal) { + return (signal->cq.tail + 1) % PIKA_EVENT_LIST_SIZE == signal->cq.head; +} + +PIKA_RES VMSignal_pushEvent(PikaEventListener* lisener, + uint32_t eventId, + int eventSignal) { + /* push to event_cq_buff */ + if (_cq_isFull(&PikaVMSignal)) { return PIKA_RES_ERR_SIGNAL_EVENT_FULL; } - PikaVMSignal.event_obj_list[PikaVMSignal.event_top++] = eventHandleObj; + PikaVMSignal.cq.id[PikaVMSignal.cq.tail] = eventId; + PikaVMSignal.cq.signal[PikaVMSignal.cq.tail] = eventSignal; + PikaVMSignal.cq.lisener[PikaVMSignal.cq.tail] = lisener; + PikaVMSignal.cq.tail = (PikaVMSignal.cq.tail + 1) % PIKA_EVENT_LIST_SIZE; return PIKA_RES_OK; } -PikaObj* VMSignal_popEvent(void) { - if (PikaVMSignal.event_top <= 0) { - return NULL; +PIKA_RES VMSignal_popEvent(PikaEventListener** lisener_p, + uint32_t* id, + int* signal) { + /* pop from event_cq_buff */ + if (_cq_isEmpty(&PikaVMSignal)) { + return PIKA_RES_ERR_SIGNAL_EVENT_EMPTY; } - return PikaVMSignal.event_obj_list[--PikaVMSignal.event_top]; + *id = PikaVMSignal.cq.id[PikaVMSignal.cq.head]; + *signal = PikaVMSignal.cq.signal[PikaVMSignal.cq.head]; + *lisener_p = PikaVMSignal.cq.lisener[PikaVMSignal.cq.head]; + PikaVMSignal.cq.head = (PikaVMSignal.cq.head + 1) % PIKA_EVENT_LIST_SIZE; + return PIKA_RES_OK; } VM_SIGNAL_CTRL VMSignal_getCtrl(void) { @@ -2824,6 +2846,8 @@ void instructArray_printAsArray(InstructArray* self) { uint8_t* ins_size_p = (uint8_t*)&self->size; __platform_printf("0x%02x, ", *(ins_size_p)); __platform_printf("0x%02x, ", *(ins_size_p + (uintptr_t)1)); + __platform_printf("0x%02x, ", *(ins_size_p + (uintptr_t)2)); + __platform_printf("0x%02x, ", *(ins_size_p + (uintptr_t)3)); __platform_printf("/* instruct array size */\n"); while (1) { InstructUnit* ins_unit = instructArray_getNow(self); @@ -2943,9 +2967,16 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState( __pks_hook_instruct(); } #endif - PikaObj* eventHandleObj = VMSignal_popEvent(); - if (NULL != eventHandleObj) { - __eventLisener_runEvent(eventHandleObj); + PikaObj* event_lisener; + uint32_t event_id; + int event_signal; + if (PIKA_RES_OK == + VMSignal_popEvent(&event_lisener, &event_id, &event_signal)) { + Arg* res = + __eventLisener_runEvent(event_lisener, event_id, event_signal); + if (NULL != res) { + arg_deinit(res); + } } if (0 != vm.error_code) { vm.line_error_code = vm.error_code; @@ -2999,6 +3030,8 @@ void constPool_printAsArray(ConstPool* self) { uint8_t* const_size_str = (uint8_t*)&(self->size); __platform_printf("0x%02x, ", *(const_size_str)); __platform_printf("0x%02x, ", *(const_size_str + (uintptr_t)1)); + __platform_printf("0x%02x, ", *(const_size_str + (uintptr_t)2)); + __platform_printf("0x%02x, ", *(const_size_str + (uintptr_t)3)); __platform_printf("/* const pool size */\n"); uint16_t ptr_befor = self->content_offset_now; uint8_t line_num = 12; diff --git a/src/PikaVM.h b/src/PikaVM.h index 6b4a1637e..850e70c41 100644 --- a/src/PikaVM.h +++ b/src/PikaVM.h @@ -104,12 +104,19 @@ typedef enum VM_SIGNAL_CTRL { VM_SIGNAL_CTRL_EXIT, } VM_SIGNAL_CTRL; +typedef struct EventCQ { + uint32_t id[PIKA_EVENT_LIST_SIZE]; + int signal[PIKA_EVENT_LIST_SIZE]; + PikaEventListener* lisener[PIKA_EVENT_LIST_SIZE]; + int head; + int tail; +} EventCQ; + typedef struct VMSignal VMSignal; struct VMSignal { VM_SIGNAL_CTRL signal_ctrl; int vm_cnt; - PikaObj* event_obj_list[PIKA_EVENT_LIST_SIZE]; - int event_top; + EventCQ cq; }; VMParameters* pikaVM_run(PikaObj* self, char* pyLine); @@ -233,7 +240,11 @@ VM_SIGNAL_CTRL VMSignal_getCtrl(void); void pks_vm_exit(void); void pks_vmSignal_setCtrlElear(void); int VMSignal_getVMCnt(void); -PikaObj* VMSignal_popEvent(void); -PIKA_RES VMSignal_pushEvent(PikaObj* eventHandleObj); +PIKA_RES VMSignal_popEvent(PikaEventListener** lisener_p, + uint32_t* id, + int* signal); +PIKA_RES VMSignal_pushEvent(PikaEventListener* lisener, + uint32_t eventId, + int eventSignal); #endif diff --git a/test/compile-test.cpp b/test/compile-test.cpp index 4dd09c0c1..92dcbdeda 100644 --- a/test/compile-test.cpp +++ b/test/compile-test.cpp @@ -573,7 +573,7 @@ TEST(compiler, event_cb) { } TEST(compiler, event_cb_lvgl) { - char* lines = "eventCallBack(eventSignal)"; + char* lines = "_res = eventCallBack(eventSignal)"; Parser_linesToArray(lines); EXPECT_EQ(pikaMemNow(), 0); } diff --git a/test/event-test.cpp b/test/event-test.cpp index b45f37ff6..c0ea5f72b 100644 --- a/test/event-test.cpp +++ b/test/event-test.cpp @@ -22,10 +22,15 @@ TEST(event, gpio) { obj_run(pikaMain, "io1.eventTest()"); - EXPECT_STREQ(log_buff[2], "get rising edge!\r\n"); - EXPECT_STREQ(log_buff[1], "get falling edge!\r\n"); + EXPECT_STREQ(log_buff[3], "get rising edge!\r\n"); + EXPECT_STREQ(log_buff[2], "get falling edge!\r\n"); + EXPECT_STREQ(log_buff[1], "get rising edge!\r\n"); EXPECT_STREQ(log_buff[0], "get falling edge!\r\n"); + for (int i = 0; i < 255; i++) { + obj_run(pikaMain, "io1.eventTest()"); + } + /* deinit */ obj_deinit(pikaMain);