/**
|
* @file Ems_export.c
|
* @author your name (you@domain.com)
|
* @brief
|
* @version 0.1
|
* @date 2023-04-05
|
*
|
* @copyright Copyright (c) 2023
|
*
|
*/
|
|
/* include ------------------------------------------------------------------ */
|
#include <stdlib.h>
|
#include <stdint.h>
|
#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 -------------------------------- */
|