ethan
2023-04-08 f5e277c240b9211a1f047b88788f34f3dd5a97c2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/**
 * @file Ems_export.h
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2023-04-05
 * 
 * @copyright Copyright (c) 2023
 * 
 */
 
#ifndef __EMS_EXPORT_H__
#define __EMS_EXPORT_H__
 
/* include ------------------------------------------------------------------ */
#include <stdint.h>
#include "ems_def.h"
#if (EMS_RTOS_CMSIS_OS_EN != 0)
#include "ems_port.h"
#endif
 
#if (EMS_QPC_EN != 0)
#include "qpc.h"
#endif
 
/* public define ------------------------------------------------------------ */
#define EXPORT_ID_INIT                  (0xa5a5a5a5)
#define EXPORT_ID_POLL                  (0xbeefbeef)
 
/* public define ------------------------------------------------------------ */
enum ems_export_level
{
    EXPORT_BSP = 0,
    EXPORT_IO_DRIVER,
    EXPORT_COMPONENT,
    EXPORT_DEVICE,
    EXPORT_APP,
#if (EMS_RTOS_CMSIS_OS_EN != 0)
    EXPORT_THREAD,
#endif
#if (EMS_QPC_EN != 0)
    EXPORT_HSM,
#endif
    EXPORT_TEST,
 
    EXPORT_MAX,
};
 
/* public typedef ----------------------------------------------------------- */
typedef struct ems_export_poll_data
{
    uint32_t timeout_ms;
} ems_export_poll_data_t;
 
typedef struct ems_export
{
    uint32_t magic_head;
    const char *name;
    void *data;
    void *stack;
    void *object;
    void *func;
    uint16_t stack_size;
    uint16_t queue_size;
    uint16_t priority;
    uint16_t level;
    uint32_t period_ms;
    uint32_t temp[6];
    uint32_t magic_tail;
} ems_export_t;
 
/* private function --------------------------------------------------------- */
void ems_unit_test(void);
void ems_run(void);
 
/* public export ------------------------------------------------------------ */
/**
  * @brief  Initialization function exporting macro.
  * @param  _func   The polling function.
  * @param  _level  The export level. See enum ems_export_level.
  * @retval None.
  */
#define INIT_EXPORT(_func, _level)                                             \
EMS_USED const ems_export_t init_##_func EMS_SECTION("ems_export") =   \
    {                                                                          \
        .name = "init",                                                        \
        .func = (void *)&_func,                                                \
        .level = _level,                                                       \
        .magic_head = EXPORT_ID_INIT,                                          \
        .magic_tail = EXPORT_ID_INIT,                                          \
    }
 
#if (EMS_QPC_EN != 0)
#if (EMS_RTOS_CMSIS_OS_EN != 0)
/**
  * @brief  State machine exporting macro.
  * @param  _name       name of the state machine.
  * @param  me          The state machine object.
  * @param  _state_init The initial state of the state machine.
  * @param  _priority   The priority of the state machine.
  * @param  _queue_size The queue size of the state machine.
  * @param  _stack_size The stack size of the state machine's internal thread.
  * @retval None.
  */
#define HSM_EXPORT(_name, me, _state_init, _priority, _queue_size, _stack_size)\
    static QEvt const * sm_##_name##_queue[_queue_size];                       \
    static uint8_t sm_##_name##_stack[_stack_size];                            \
    EMS_USED const ems_export_t sm_##_name EMS_SECTION("ems_export") =     \
    {                                                                          \
        .name = (const char *)#_name,                                          \
        .object = (void *)me,                                                  \
        .func = (void *)(&_state_init),                                        \
        .data = (void *)sm_##_name##_queue,                                    \
        .queue_size = _queue_size,                                             \
        .stack = (void *)sm_##_name##_stack,                                   \
        .stack_size = _stack_size,                                             \
        .priority = _priority,                                                 \
        .level = EXPORT_HSM,                                                   \
        .magic_head = EXPORT_ID_INIT,                                          \
        .magic_tail = EXPORT_ID_INIT,                                          \
    }
#else
 
/**
  * @brief  State machine exporting macro.
  * @param  _name       name of the state machine.
  * @param  me          The state machine object.
  * @param  _state_init The initial state of the state machine.
  * @param  _priority   The priority of the state machine.
  * @param  _queue_size The queue size of the state machine.
  * @retval None.
  */
#define HSM_EXPORT(_name, me, _state_init, _priority, _queue_size)             \
    static QEvt const * sm_##_name##_queue[_queue_size];                       \
    EMS_USED const ems_export_t sm_##_name EMS_SECTION("ems_export") =     \
    {                                                                          \
        .name = (const char *)#_name,                                          \
        .object = (void *)me,                                                  \
        .func = (void *)(&_state_init),                                        \
        .data = (void *)sm_##_name##_queue,                                    \
        .queue_size = _queue_size,                                             \
        .priority = _priority,                                                 \
        .level = EXPORT_HSM,                                                   \
        .magic_head = EXPORT_ID_INIT,                                          \
        .magic_tail = EXPORT_ID_INIT,                                          \
    }
#endif
#else
#define HSM_EXPORT(_name, me, _state_init, _priority, _queue_size, _stack_size)
#endif
 
#if (EMS_RTOS_CMSIS_OS_EN != 0)
/**
  * @brief  Thread exporting macro.
  * @param  _name       name of the state machine.
  * @param  _entry      The thread entry function.
  * @param  _priority   The priority of the state machine.
  * @param  _data       user data.
  * @param  _stack_size The stack size of the state machine.
  * @retval None.
  */
#define THREAD_EXPORT(_name, _entry, _priority, _data, _stack_size)            \
    static ems_thread_t thread_##_name;                                       \
    static uint8_t thread_##_name##_stack[_stack_size];                        \
    EMS_USED const ems_export_t thread##_name EMS_SECTION("ems_export") =  \
    {                                                                          \
        .func = (void *)&_entry,                                               \
        .name = #_name,                                                        \
        .data = (void *)_data,                                                 \
        .object = (void *)&thread_##_name,                                     \
        .stack = (void *)thread_##_name##_stack,                               \
        .stack_size = _stack_size,                                             \
        .priority = _priority,                                                 \
        .level = EXPORT_THREAD,                                                \
        .magic_head = EXPORT_ID_INIT,                                          \
        .magic_tail = EXPORT_ID_INIT,                                          \
    }
#else
#define THREAD_EXPORT(_name, _entry, _priority, _data, _stack_size)
#endif
 
/**
  * @brief  Poll function exporting macro.
  * @param  _func       The polling function.
  * @param  _period_ms  The polling period in ms.
  * @retval None.
  */
#define POLL_EXPORT(_func, _period_ms)                                         \
    static ems_export_poll_data_t poll_##_func##_data =                       \
    {                                                                          \
        .timeout_ms = 0,                                                       \
    };                                                                         \
    EMS_USED const ems_export_t poll_##_func EMS_SECTION("expoll") =        \
    {                                                                          \
        .name = "poll", \
        .func = (void *)&_func,                                                \
        .data = (void *)&poll_##_func##_data,                                  \
        .level = EXPORT_MAX,                                                   \
        .period_ms = (uint32_t)(_period_ms),                                   \
        .magic_head = EXPORT_ID_POLL,                                          \
        .magic_tail = EXPORT_ID_POLL,                                          \
    }
 
/* public function ---------------------------------------------------------- */
/**
  * @brief  Initialization function in BSP layer.
  * @param  _func       The initialization function.
  * @retval None.
  */
#define INIT_BSP_EXPORT(_func)              INIT_EXPORT(_func, EXPORT_BSP)
 
/**
  * @brief  Initialization function in IO driver layer.
  * @param  _func       The initialization function.
  * @retval None.
  */
#define INIT_IO_DRIVER_EXPORT(_func)        INIT_EXPORT(_func, EXPORT_IO_DRIVER)
 
/**
  * @brief  Initialization function in component layer.
  * @param  _func       The initialization function.
  * @retval None.
  */
#define INIT_COMPONENT_EXPORT(_func)        INIT_EXPORT(_func, EXPORT_COMPONENT)
 
/**
  * @brief  Initialization function in device layer.
  * @param  _func       The initialization function.
  * @retval None.
  */
#define INIT_DEV_EXPORT(_func)              INIT_EXPORT(_func, EXPORT_DEVICE)
 
/**
  * @brief  Initialization function in appliation layer.
  * @param  _func       The initialization function.
  * @retval None.
  */
#define INIT_APP_EXPORT(_func)              INIT_EXPORT(_func, EXPORT_APP)
 
/**
  * @brief  Testing function in unit test layer.
  * @param  _func       The initialization function.
  * @retval None.
  */
#define INIT_EXPORT_TEST(_func)             INIT_EXPORT(_func, EXPORT_TEST)
 
#endif /* __EMS_EXPORT_H__ */
 
/* ----------------------------- end of file -------------------------------- */