1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-06-04     WillianChan  first version
9  * 2021-06-08     WillianChan  support to MS VC++ compiler
10  */
11 
12 #ifndef _VAR_EXPORT_H__
13 #define _VAR_EXPORT_H__
14 
15 #include <rtthread.h>
16 
17 /* exported object */
18 struct ve_exporter
19 {
20     const char *module;             /* module name */
21     const char *identifier;         /* module identifier */
22     rt_base_t   value;              /* module value */
23 };
24 typedef struct ve_exporter ve_exporter_t;
25 
26 /* module object */
27 struct ve_module
28 {
29     const ve_exporter_t *begin;     /* the first module of the same name */
30     const ve_exporter_t *end;       /* the last module of the same */
31 };
32 typedef struct ve_module ve_module_t;
33 
34 /* iterator object */
35 struct ve_iterator
36 {
37     const ve_exporter_t *exp_index; /* iterator index */
38     const ve_exporter_t *exp_end;   /* iterate over exporter */
39 };
40 typedef struct ve_iterator ve_iterator_t;
41 
42 #define VE_NOT_FOUND (0xFFFFFFFFu)  /* not found */
43 
44 /* exporter's export command */
45 #if defined(__ARMCC_VERSION) || defined(__IAR_SYSTEMS_ICC__)
46 #define VAR_EXPORT(module, identi, value)                                       \
47     const char _vexp_##identi##_module[] rt_section(".rodata.vexp") = #module;  \
48     const char _vexp_##identi##_identi[] rt_section(".rodata.vexp") = #identi;  \
49     rt_used const struct ve_exporter _vexp_##module##identi                     \
50     rt_section("1."#module".VarExpTab."#identi) =                               \
51     {                                                                           \
52         _vexp_##identi##_module,                                                \
53         _vexp_##identi##_identi,                                                \
54         value,                                                                  \
55     }
56 #elif defined(__GNUC__)
57 #define VAR_EXPORT(module, identi, value)                                       \
58     const char _vexp_##identi##_module[] rt_section(".rodata.vexp") = #module;  \
59     const char _vexp_##identi##_identi[] rt_section(".rodata.vexp") = #identi;  \
60     rt_used const struct ve_exporter _vexp_##module##identi                     \
61     rt_section(#module".VarExpTab."#identi) =                                   \
62     {                                                                           \
63         _vexp_##identi##_module,                                                \
64         _vexp_##identi##_identi,                                                \
65         value,                                                                  \
66     }
67 #elif defined(_MSC_VER)
68 #pragma section("VarExpTab$f",read)
69 #define VAR_EXPORT(module, identi, value)                                       \
70     const char _vexp_##identi##_module[] rt_section(".rodata.vexp") = #module;  \
71     const char _vexp_##identi##_identi[] rt_section(".rodata.vexp") = #identi;  \
72     __declspec(allocate("VarExpTab$f"))                                         \
73     rt_used const struct ve_exporter _vexp_##module##identi =                   \
74     {                                                                           \
75         _vexp_##identi##_module,                                                \
76         _vexp_##identi##_identi,                                                \
77         value,                                                                  \
78     }
79 #endif
80 
81 /* initialize var export */
82 int ve_exporter_init(void);
83 /* initialize module */
84 int ve_module_init(ve_module_t *mod, const char *module);
85 /* initialize iterator */
86 void ve_iter_init(ve_module_t *mod, ve_iterator_t *iter);
87 /* iterate backward */
88 const ve_exporter_t *ve_iter_next(ve_iterator_t *iter);
89 /* get the value by identifier */
90 rt_base_t ve_value_get(ve_module_t *mod, const char *identifier);
91 /* check if this value exists in the module*/
92 rt_bool_t ve_value_exist(ve_module_t *mod, const char *identifier);
93 rt_size_t ve_value_count(ve_module_t *mod);
94 const ve_exporter_t *ve_binary_search(ve_module_t *mod, const char *identifier);
95 
96 #endif /* _VAR_EXPORT_H__ */
97