/** * @file Ems_export.c * @author your name (you@domain.com) * @brief * @version 0.1 * @date 2023-04-05 * * @copyright Copyright (c) 2023 * */ /* include ------------------------------------------------------------------ */ #include #include #include "ems_export.h" #include "ems_common.h" #if (EMS_RTOS_CMSIS_OS_EN != 0) #include "cmsis_os.h" #endif #if (EMS_QPC_EN != 0) Q_DEFINE_THIS_FILE #include "qpc.h" #endif /* private function prototype ----------------------------------------------- */ static void module_null_init(void); static void _export_func_execute(uint8_t level); #if (EMS_RTOS_CMSIS_OS_EN != 0) static void _entry_start_poll(void *para); #endif /* private variables -------------------------------------------------------- */ INIT_BSP_EXPORT(module_null_init); POLL_EXPORT(module_null_init, (1000 * 60 * 60)); static const uint32_t export_id_table[EXPORT_MAX + 1] = { EXPORT_ID_INIT, EXPORT_ID_INIT, EXPORT_ID_INIT, EXPORT_ID_INIT, EXPORT_ID_INIT, #if (EMS_RTOS_CMSIS_OS_EN != 0) EXPORT_ID_INIT, #endif #if (EMS_QPC_EN != 0) EXPORT_ID_INIT, #endif EXPORT_ID_INIT, EXPORT_ID_POLL, }; static ems_export_t *export_init_table = NULL; static ems_export_t *export_poll_table = NULL; #if (EMS_RTOS_CMSIS_OS_EN != 0) /** * @brief The thread attribute for testing. */ static const osThreadAttr_t thread_attr_start_poll = { .name = "ThreadStartPoll", .attr_bits = osThreadDetached, .priority = osPriorityNormal, .stack_size = 2048, }; #endif /* public function ---------------------------------------------------------- */ /** * @brief eLab unit test exporting function. * @retval None */ void ems_unit_test(void) { _export_func_execute(EXPORT_TEST); } /** * @brief eLab polling exporting function. * @retval None */ void ems_run(void) { /* Start polling function in metal eLab, or start the RTOS kernel in RTOS eLab. */ #if (EMS_RTOS_CMSIS_OS_EN != 0) osKernelInitialize(); osThreadNew(_entry_start_poll, NULL, &thread_attr_start_poll); osKernelStart(); #else /* Initialize all module in eLab. */ for (uint8_t level = EXPORT_BSP; level <= EXPORT_APP; level ++) { _export_func_execute(level); } /* Start polling function in metal eLab. */ while (1) { _export_func_execute(EXPORT_MAX); } #endif } /* private function --------------------------------------------------------- */ /** * @brief Get the export table. */ static ems_export_t * _get_export_table(uint8_t level) { ems_export_t *func_block = level < EXPORT_MAX ? ((ems_export_t *)&init_module_null_init) : ((ems_export_t *)&poll_module_null_init); while (1) { uint32_t address_last = ((uint32_t)func_block - sizeof(ems_export_t)); ems_export_t *table = (ems_export_t *)address_last; if (table->magic_head != export_id_table[level] || table->magic_tail != export_id_table[level]) { break; } func_block = table; } return func_block; } /** * @brief eLab exporting function executing. * @param level export level. * @retval None */ static void _export_func_execute(uint8_t level) { uint32_t export_id = export_id_table[level]; /* Get the start address of exported poll table. */ if (export_init_table == NULL) { export_init_table = _get_export_table(EXPORT_BSP); } if (export_poll_table == NULL) { export_poll_table = _get_export_table(EXPORT_MAX); } /* Execute the poll function in the specific level. */ ems_export_t *export_table = level < EXPORT_MAX ? export_init_table : export_poll_table; for (uint32_t i = 0; ; i ++) { if (export_table[i].magic_head == export_id && export_table[i].magic_tail == export_id) { if (export_table[i].level == level && level <= EXPORT_APP) { ((void (*)(void))export_table[i].func)(); } #if (EMS_RTOS_CMSIS_OS_EN != 0) else if (export_table[i].level == level && level == EXPORT_THREAD) { ems_thread_init((ems_thread_t *)export_table[i].object, (void (*)(void *))export_table[i].func, export_table[i].name, export_table[i].data, export_table[i].stack, export_table[i].stack_size, export_table[i].priority); } #endif #if (EMS_QPC_EN != 0) else if (export_table[i].level == level && level == EXPORT_HSM) { QActive_ctor((QActive *)export_table[i].object, Q_STATE_CAST(export_table[i].func)); QACTIVE_START((QActive *)export_table[i].object, export_table[i].priority, export_table[i].data, export_table[i].queue_size, export_table[i].stack, export_table[i].stack_size, (QEvt *)0); } #endif else if (export_table[i].level == level && level == EXPORT_MAX) { ems_export_poll_data_t *data = export_table[i].data; while (ems_time_ms() >= data->timeout_ms) { data->timeout_ms += export_table[i].period_ms; ((void (*)(void))export_table[i].func)(); } } } else { break; } } } void ao_led_init(void); #if (EMS_RTOS_CMSIS_OS_EN != 0) /** * @brief eLab startup and poll function. * @retval None */ static void _entry_start_poll(void *para) { /* Initialize all module in eLab. */ for (uint8_t level = EXPORT_BSP; level <= EXPORT_APP; level ++) { _export_func_execute(level); } _export_func_execute(EXPORT_THREAD); #if (EMS_QPC_EN != 0) _export_func_execute(EXPORT_HSM); #endif /* Start polling function in metal eLab. */ while (1) { _export_func_execute(EXPORT_MAX); osDelay(10); } } #endif /** * @brief eLab null exporting function. * @retval None */ static void module_null_init(void) { /* NULL */ } /* ----------------------------- end of file -------------------------------- */