finsh.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2010-03-22 Bernard first version
  9. */
  10. #ifndef __FINSH_H__
  11. #define __FINSH_H__
  12. #include <rtdef.h>
  13. #ifdef _MSC_VER
  14. #pragma section("FSymTab$f",read)
  15. #endif /* _MSC_VER */
  16. #ifdef FINSH_USING_OPTION_COMPLETION
  17. #define FINSH_COND(opt) opt,
  18. #else
  19. #define FINSH_COND(opt)
  20. #endif
  21. #ifdef FINSH_USING_DESCRIPTION
  22. #define FINSH_DESC(cmd, desc) __fsym_##cmd##_desc,
  23. #else
  24. #define FINSH_DESC(cmd, desc)
  25. #endif
  26. typedef long (*syscall_func)(void);
  27. #ifdef FINSH_USING_SYMTAB
  28. #ifdef __TI_COMPILER_VERSION__
  29. #define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
  30. #endif /* __TI_COMPILER_VERSION__ */
  31. #ifdef _MSC_VER
  32. #define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
  33. const char __fsym_##cmd##_name[] = #cmd; \
  34. const char __fsym_##cmd##_desc[] = #desc; \
  35. __declspec(allocate("FSymTab$f")) \
  36. const struct finsh_syscall __fsym_##cmd = \
  37. { \
  38. __fsym_##cmd##_name, \
  39. FINSH_DESC(cmd, desc) \
  40. FINSH_COND(opt) \
  41. (syscall_func)&name \
  42. };
  43. #pragma comment(linker, "/merge:FSymTab=mytext")
  44. #elif defined(__TI_COMPILER_VERSION__)
  45. #ifdef __TMS320C28XX__
  46. #define RT_NOBLOCKED __attribute__((noblocked))
  47. #else
  48. #define RT_NOBLOCKED
  49. #endif
  50. #define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
  51. __TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
  52. const char __fsym_##cmd##_name[] = #cmd; \
  53. const char __fsym_##cmd##_desc[] = #desc; \
  54. rt_used RT_NOBLOCKED const struct finsh_syscall __fsym_##cmd = \
  55. { \
  56. __fsym_##cmd##_name, \
  57. FINSH_DESC(cmd, desc) \
  58. FINSH_COND(opt) \
  59. (syscall_func)&name \
  60. };
  61. #else
  62. #define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc, opt) \
  63. const char __fsym_##cmd##_name[] rt_section(".rodata.name") = #cmd; \
  64. const char __fsym_##cmd##_desc[] rt_section(".rodata.name") = #desc; \
  65. rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \
  66. { \
  67. __fsym_##cmd##_name, \
  68. FINSH_DESC(cmd, desc) \
  69. FINSH_COND(opt) \
  70. (syscall_func)&name \
  71. };
  72. #endif /* _MSC_VER */
  73. #endif /* end of FINSH_USING_SYMTAB */
  74. #define __MSH_GET_MACRO(_1, _2, _3, _FUN, ...) _FUN
  75. #define __MSH_GET_EXPORT_MACRO(_1, _2, _3, _4, _FUN, ...) _FUN
  76. #define _MSH_FUNCTION_CMD2(a0, a1) \
  77. MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, 0)
  78. #define _MSH_FUNCTION_CMD3_OPT(a0, a1, a2) \
  79. MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, a0##_msh_options)
  80. #define _MSH_FUNCTION_CMD3_NO_OPT(a0, a1, a2) \
  81. MSH_FUNCTION_EXPORT_CMD(a0, a0, a1, 0)
  82. #define _MSH_FUNCTION_EXPORT_CMD3(a0, a1, a2) \
  83. MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, 0)
  84. #define _MSH_FUNCTION_EXPORT_CMD4_OPT(a0, a1, a2, a3) \
  85. MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, a0##_msh_options)
  86. #define _MSH_FUNCTION_EXPORT_CMD4_NO_OPT(a0, a1, a2, a3) \
  87. MSH_FUNCTION_EXPORT_CMD(a0, a1, a2, 0)
  88. /**
  89. * @ingroup finsh
  90. *
  91. * This macro exports a system function to finsh shell.
  92. *
  93. * @param name the name of function.
  94. * @param desc the description of function, which will show in help.
  95. */
  96. #define FINSH_FUNCTION_EXPORT(name, desc)
  97. /**
  98. * @ingroup finsh
  99. *
  100. * This macro exports a system function with an alias name to finsh shell.
  101. *
  102. * @param name the name of function.
  103. * @param alias the alias name of function.
  104. * @param desc the description of function, which will show in help.
  105. */
  106. #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc)
  107. /**
  108. * @ingroup msh
  109. *
  110. * This macro exports a command to module shell.
  111. *
  112. * @param command is the name of the command.
  113. * @param desc is the description of the command, which will show in help list.
  114. * @param opt This is an option, enter any content to enable option completion
  115. */
  116. /* MSH_CMD_EXPORT(command, desc) or MSH_CMD_EXPORT(command, desc, opt) */
  117. #ifdef FINSH_USING_OPTION_COMPLETION
  118. #define MSH_CMD_EXPORT(...) \
  119. __MSH_GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD3_OPT, \
  120. _MSH_FUNCTION_CMD2)(__VA_ARGS__)
  121. #else
  122. #define MSH_CMD_EXPORT(...) \
  123. __MSH_GET_MACRO(__VA_ARGS__, _MSH_FUNCTION_CMD3_NO_OPT, \
  124. _MSH_FUNCTION_CMD2)(__VA_ARGS__)
  125. #endif /* FINSH_USING_OPTION_COMPLETION */
  126. /**
  127. * @ingroup msh
  128. *
  129. * This macro exports a command with alias to module shell.
  130. *
  131. * @param command is the name of the command.
  132. * @param alias is the alias of the command.
  133. * @param desc is the description of the command, which will show in help list.
  134. * @param opt This is an option, enter any content to enable option completion
  135. */
  136. /* #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) or
  137. #define MSH_CMD_EXPORT_ALIAS(command, alias, desc, opt) */
  138. #ifdef FINSH_USING_OPTION_COMPLETION
  139. #define MSH_CMD_EXPORT_ALIAS(...) \
  140. __MSH_GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD4_OPT, \
  141. _MSH_FUNCTION_EXPORT_CMD3)(__VA_ARGS__)
  142. #else
  143. #define MSH_CMD_EXPORT_ALIAS(...) \
  144. __MSH_GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD4_NO_OPT, \
  145. _MSH_FUNCTION_EXPORT_CMD3)(__VA_ARGS__)
  146. #endif /* FINSH_USING_OPTION_COMPLETION */
  147. /* system call table */
  148. struct finsh_syscall
  149. {
  150. const char *name; /* the name of system call */
  151. #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
  152. const char *desc; /* description of system call */
  153. #endif
  154. #ifdef FINSH_USING_OPTION_COMPLETION
  155. struct msh_cmd_opt *opt;
  156. #endif
  157. syscall_func func; /* the function address of system call */
  158. };
  159. /* system call item */
  160. struct finsh_syscall_item
  161. {
  162. struct finsh_syscall_item *next; /* next item */
  163. struct finsh_syscall syscall; /* syscall */
  164. };
  165. #ifdef FINSH_USING_OPTION_COMPLETION
  166. typedef struct msh_cmd_opt
  167. {
  168. rt_uint32_t id;
  169. const char *name;
  170. const char *des;
  171. } msh_cmd_opt_t;
  172. #define CMD_OPTIONS_STATEMENT(command) static struct msh_cmd_opt command##_msh_options[];
  173. #define CMD_OPTIONS_NODE_START(command) static struct msh_cmd_opt command##_msh_options[] = {
  174. #define CMD_OPTIONS_NODE(_id, _name, _des) {.id = _id, .name = #_name, .des = #_des},
  175. #define CMD_OPTIONS_NODE_END {0},};
  176. void msh_opt_list_dump(void *options);
  177. int msh_cmd_opt_id_get(int argc, char *argv[], void *options);
  178. #define MSH_OPT_ID_GET(fun) msh_cmd_opt_id_get(argc, argv, (void*) fun##_msh_options)
  179. #define MSH_OPT_DUMP(fun) msh_opt_list_dump((void*) fun##_msh_options)
  180. #else
  181. #define CMD_OPTIONS_STATEMENT(command)
  182. #define CMD_OPTIONS_NODE_START(command)
  183. #define CMD_OPTIONS_NODE(_id, _name, _des)
  184. #define CMD_OPTIONS_NODE_END
  185. #endif
  186. extern struct finsh_syscall_item *global_syscall_list;
  187. extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
  188. #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
  189. struct finsh_syscall *finsh_syscall_next(struct finsh_syscall *call);
  190. #define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
  191. #else
  192. #define FINSH_NEXT_SYSCALL(index) index++
  193. #endif
  194. /* find out system call, which should be implemented in user program */
  195. struct finsh_syscall *finsh_syscall_lookup(const char *name);
  196. #if !defined(RT_USING_POSIX_STDIO) && defined(RT_USING_DEVICE)
  197. void finsh_set_device(const char *device_name);
  198. #endif
  199. #endif