module_win32.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  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. * 2013-02-26 prife first version for win32
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtm.h>
  13. #ifdef RT_USING_MODULE
  14. #define DBG_TAG "simulator.module.win32"
  15. #define DBG_LVL DBG_INFO
  16. #include <rtdbg.h>
  17. void rt_module_init_object_container(struct rt_module *module)
  18. {
  19. RT_ASSERT(module != RT_NULL);
  20. /* initialize object container - thread */
  21. rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
  22. module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
  23. module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
  24. #ifdef RT_USING_SEMAPHORE
  25. /* initialize object container - semaphore */
  26. rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
  27. module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
  28. module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
  29. #endif
  30. #ifdef RT_USING_MUTEX
  31. /* initialize object container - mutex */
  32. rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
  33. module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
  34. module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
  35. #endif
  36. #ifdef RT_USING_EVENT
  37. /* initialize object container - event */
  38. rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
  39. module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
  40. module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
  41. #endif
  42. #ifdef RT_USING_MAILBOX
  43. /* initialize object container - mailbox */
  44. rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
  45. module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
  46. module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
  47. #endif
  48. #ifdef RT_USING_MESSAGEQUEUE
  49. /* initialize object container - message queue */
  50. rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
  51. module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
  52. module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
  53. #endif
  54. #ifdef RT_USING_MEMHEAP
  55. /* initialize object container - memory heap */
  56. rt_list_init(&(module->module_object[RT_Object_Class_MemHeap].object_list));
  57. module->module_object[RT_Object_Class_MemHeap].object_size = sizeof(struct rt_memheap);
  58. module->module_object[RT_Object_Class_MemHeap].type = RT_Object_Class_MemHeap;
  59. #endif
  60. #ifdef RT_USING_MEMPOOL
  61. /* initialize object container - memory pool */
  62. rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
  63. module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
  64. module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
  65. #endif
  66. #ifdef RT_USING_DEVICE
  67. /* initialize object container - device */
  68. rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
  69. module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
  70. module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
  71. #endif
  72. /* initialize object container - timer */
  73. rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
  74. module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
  75. module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
  76. }
  77. #ifdef RT_USING_HOOK
  78. static void (*rt_module_load_hook)(rt_module_t module);
  79. static void (*rt_module_unload_hook)(rt_module_t module);
  80. /**
  81. * @addtogroup Hook
  82. */
  83. /*@{*/
  84. /**
  85. * This function will set a hook function, which will be invoked when module
  86. * be loaded to system.
  87. *
  88. * @param hook the hook function
  89. */
  90. void rt_module_load_sethook(void (*hook)(rt_module_t module))
  91. {
  92. rt_module_load_hook = hook;
  93. }
  94. /**
  95. * This function will set a hook function, which will be invoked when module
  96. * be unloaded from system.
  97. *
  98. * @param hook the hook function
  99. */
  100. void rt_module_unload_sethook(void (*hook)(rt_module_t module))
  101. {
  102. rt_module_unload_hook = hook;
  103. }
  104. /*@}*/
  105. #endif
  106. /**
  107. * @ingroup SystemInit
  108. *
  109. * This function will initialize system module
  110. */
  111. int rt_system_module_init(void)
  112. {
  113. return 0;
  114. }
  115. /**
  116. * This function will return self module object
  117. *
  118. * @return the self module object
  119. */
  120. rt_module_t rt_module_self(void)
  121. {
  122. rt_thread_t tid;
  123. tid = rt_thread_self();
  124. if (tid == RT_NULL)
  125. return RT_NULL;
  126. /* return current module */
  127. return (rt_module_t)tid->parent.module_id;
  128. }
  129. RTM_EXPORT(rt_module_self);
  130. /**
  131. * This function will find the specified module.
  132. *
  133. * @param name the name of module finding
  134. *
  135. * @return the module
  136. */
  137. rt_module_t rt_module_find(const char *name)
  138. {
  139. struct rt_object_information *information;
  140. struct rt_object *object;
  141. struct rt_list_node *node;
  142. RT_DEBUG_NOT_IN_INTERRUPT;
  143. /* enter critical */
  144. rt_enter_critical();
  145. /* try to find device object */
  146. information = rt_object_get_information(RT_Object_Class_Module);
  147. RT_ASSERT(information != RT_NULL);
  148. for (node = information->object_list.next;
  149. node != &(information->object_list);
  150. node = node->next)
  151. {
  152. object = rt_list_entry(node, struct rt_object, list);
  153. if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
  154. {
  155. /* leave critical */
  156. rt_exit_critical();
  157. return (rt_module_t)object;
  158. }
  159. }
  160. /* leave critical */
  161. rt_exit_critical();
  162. /* not found */
  163. return RT_NULL;
  164. }
  165. RTM_EXPORT(rt_module_find);
  166. #ifdef RT_USING_DFS
  167. #include <windows.h>
  168. #include <dfs_file.h>
  169. #include <unistd.h>
  170. #include <stdio.h>
  171. #include <sys/stat.h>
  172. #include <sys/statfs.h>
  173. extern char * dfs_win32_dirdup(char * path);
  174. static char* _module_name(const char *path)
  175. {
  176. const char *first, *end, *ptr;
  177. char *name;
  178. int size;
  179. ptr = (char *)path;
  180. first = ptr;
  181. end = path + rt_strlen(path);
  182. while (*ptr != '\0')
  183. {
  184. if (*ptr == '/')
  185. first = ptr + 1;
  186. if (*ptr == '.')
  187. end = ptr - 1;
  188. ptr ++;
  189. }
  190. size = end - first + 1;
  191. name = rt_malloc(size);
  192. rt_strncpy(name, first, size);
  193. name[size] = '\0';
  194. return name;
  195. }
  196. typedef int (*appentry_t)(void);
  197. /**
  198. * This function will load a module from a file
  199. *
  200. * @param path the full path of application module
  201. *
  202. * @return the module object
  203. */
  204. rt_module_t rt_module_open(const char *path)
  205. {
  206. struct dfs_filesystem *fs;
  207. appentry_t fptr;
  208. HINSTANCE hinstlib;
  209. rt_module_t module;
  210. char * winpath = RT_NULL;
  211. char * name = RT_NULL;
  212. RT_DEBUG_NOT_IN_INTERRUPT;
  213. /* check parameters */
  214. RT_ASSERT(path != RT_NULL);
  215. /* app module should only in DFS_WIN32 */
  216. fs = dfs_filesystem_lookup(path);
  217. if ((fs == RT_NULL) || (strcmp(fs->ops->name,"wdir") != 0))
  218. {
  219. rt_kprintf("invalid path: %s\n", path);
  220. return RT_NULL;
  221. }
  222. /* change path */
  223. // len = strlen(path+1);
  224. if ((winpath = dfs_win32_dirdup((char *)path)) == RT_NULL)
  225. {
  226. rt_kprintf("out of memory, exit");
  227. return RT_NULL;
  228. }
  229. hinstlib = LoadLibrary(winpath);
  230. if (hinstlib == NULL)
  231. {
  232. rt_kprintf("error: unable to open %s\n", winpath);
  233. return RT_NULL;
  234. }
  235. fptr = (appentry_t)GetProcAddress(hinstlib, "main");
  236. if (fptr == NULL)
  237. {
  238. rt_kprintf("error: unable to find function in %s\n", winpath);
  239. FreeLibrary(hinstlib);
  240. return RT_NULL;
  241. }
  242. /* get the name of the module */
  243. name = _module_name(path);
  244. /* allocate module */
  245. module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, name);
  246. if (!module) return RT_NULL;
  247. module->nref = 0;
  248. module->module_entry = fptr;
  249. /* init module object container */
  250. rt_module_init_object_container(module);
  251. /* increase module reference count */
  252. module->nref ++;
  253. if (module->module_entry != 0)
  254. {
  255. #ifdef RT_USING_SLAB
  256. /* init module memory allocator */
  257. module->mem_list = RT_NULL;
  258. /* create page array */
  259. module->page_array =
  260. (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
  261. module->page_cnt = 0;
  262. #endif
  263. /* create module thread */
  264. module->module_thread =
  265. rt_thread_create(name,
  266. (void(*)(void *))module->module_entry, RT_NULL,
  267. 2048, RT_THREAD_PRIORITY_MAX - 2, 10);
  268. LOG_D("thread entry %#x", module->module_entry);
  269. /* set module id */
  270. module->module_thread->parent.module_id = (void *)module;
  271. module->parent.flag = RT_MODULE_FLAG_WITHENTRY;
  272. /* startup module thread */
  273. rt_thread_startup(module->module_thread);
  274. }
  275. else
  276. {
  277. /* without entry point */
  278. module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
  279. }
  280. #ifdef RT_USING_HOOK
  281. if (rt_module_load_hook != RT_NULL)
  282. {
  283. rt_module_load_hook(module);
  284. }
  285. #endif
  286. rt_free(name);
  287. return module;
  288. /* FreeLibrary(hinstlib); */
  289. }
  290. #if defined(RT_USING_FINSH)
  291. #include <finsh.h>
  292. FINSH_FUNCTION_EXPORT_ALIAS(rt_module_open, exec, exec module from a file);
  293. #endif
  294. #endif
  295. #define RT_MODULE_ARG_MAX 8
  296. static int _rt_module_split_arg(char* cmd, rt_size_t length, char* argv[])
  297. {
  298. int argc = 0;
  299. char *ptr = cmd;
  300. while ((ptr - cmd) < length)
  301. {
  302. /* strip bank and tab */
  303. while ((*ptr == ' ' || *ptr == '\t') && (ptr -cmd)< length)
  304. *ptr++ = '\0';
  305. /* check whether it's the end of line */
  306. if ((ptr - cmd)>= length) break;
  307. /* handle string with quote */
  308. if (*ptr == '"')
  309. {
  310. argv[argc++] = ++ptr;
  311. /* skip this string */
  312. while (*ptr != '"' && (ptr-cmd) < length)
  313. if (*ptr ++ == '\\') ptr ++;
  314. if ((ptr - cmd) >= length) break;
  315. /* skip '"' */
  316. *ptr ++ = '\0';
  317. }
  318. else
  319. {
  320. argv[argc++] = ptr;
  321. while ((*ptr != ' ' && *ptr != '\t') && (ptr - cmd) < length)
  322. ptr ++;
  323. }
  324. if (argc >= RT_MODULE_ARG_MAX) break;
  325. }
  326. return argc;
  327. }
  328. /* module main thread entry */
  329. static void module_main_entry(void* parameter)
  330. {
  331. int argc;
  332. char *argv[RT_MODULE_ARG_MAX];
  333. typedef int (*main_func_t)(int argc, char** argv);
  334. rt_module_t module = (rt_module_t) parameter;
  335. if (module == RT_NULL || module->module_cmd_line == RT_NULL) return;
  336. rt_memset(argv, 0x00, sizeof(argv));
  337. argc = _rt_module_split_arg((char*)module->module_cmd_line, module->module_cmd_size, argv);
  338. if (argc == 0) return ;
  339. /* do the main function */
  340. ((main_func_t)module->module_entry)(argc, argv);
  341. return;
  342. }
  343. /**
  344. * This function will do a executable program with main function and parameters.
  345. *
  346. * @param path the full path of application module
  347. * @param cmd_line the command line of program
  348. * @param size the size of command line of program
  349. *
  350. * @return the module object
  351. */
  352. rt_module_t rt_module_exec_cmd(const char *path, const char* cmd_line, int line_size)
  353. {
  354. struct dfs_filesystem *fs;
  355. appentry_t fptr;
  356. HINSTANCE hinstlib;
  357. rt_module_t module;
  358. char * winpath = RT_NULL;
  359. char * name = RT_NULL;
  360. char *full_path = RT_NULL;
  361. RT_DEBUG_NOT_IN_INTERRUPT;
  362. /* check parameters */
  363. RT_ASSERT(path != RT_NULL);
  364. if (*path != '/')
  365. {
  366. full_path = dfs_normalize_path(RT_NULL, path);
  367. }
  368. else
  369. {
  370. full_path = (const char*)path;
  371. }
  372. /* app module should only in DFS_WIN32 */
  373. fs = dfs_filesystem_lookup(full_path);
  374. if ((fs == RT_NULL) || (strcmp(fs->ops->name,"wdir") != 0))
  375. {
  376. rt_kprintf("invalid path: %s\n", path);
  377. goto __exit;
  378. }
  379. /* change path */
  380. // len = strlen(full_path + 1);
  381. if ((winpath = dfs_win32_dirdup((char *)full_path)) == RT_NULL)
  382. {
  383. rt_kprintf("out of memory, exit", path);
  384. goto __exit;
  385. }
  386. hinstlib = LoadLibrary(winpath);
  387. if (hinstlib == NULL)
  388. {
  389. rt_kprintf("error: unable to open %s\n", winpath);
  390. goto __exit;
  391. }
  392. fptr = (appentry_t)GetProcAddress(hinstlib, "main");
  393. if (fptr == NULL)
  394. {
  395. rt_kprintf("error: unable to find function in %s\n", winpath);
  396. FreeLibrary(hinstlib);
  397. goto __exit;
  398. }
  399. /* release winpath */
  400. rt_free(winpath);
  401. /* get the name of the module */
  402. name = _module_name(path);
  403. /* allocate module */
  404. module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, name);
  405. if (!module)
  406. {
  407. goto __exit;
  408. }
  409. module->nref = 0;
  410. module->module_entry = fptr;
  411. /* init module object container */
  412. rt_module_init_object_container(module);
  413. /* increase module reference count */
  414. module->nref ++;
  415. if (module->module_entry != 0)
  416. {
  417. /* set module argument */
  418. module->module_cmd_line = (rt_uint8_t*)rt_malloc(line_size + 1);
  419. rt_memcpy(module->module_cmd_line, cmd_line, line_size);
  420. module->module_cmd_line[line_size] = '\0';
  421. module->module_cmd_size = line_size;
  422. #ifdef RT_USING_SLAB
  423. /* init module memory allocator */
  424. module->mem_list = RT_NULL;
  425. /* create page array */
  426. module->page_array =
  427. (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
  428. module->page_cnt = 0;
  429. #endif
  430. /* create module thread */
  431. module->module_thread = rt_thread_create(name,
  432. module_main_entry, module,
  433. 2048, RT_THREAD_PRIORITY_MAX - 2, 10);
  434. /* set module id */
  435. module->module_thread->parent.module_id = (void *)module;
  436. module->parent.flag = RT_MODULE_FLAG_WITHENTRY;
  437. /* startup module thread */
  438. rt_thread_startup(module->parent.module_thread);
  439. }
  440. else
  441. {
  442. /* without entry point */
  443. module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
  444. }
  445. #ifdef RT_USING_HOOK
  446. if (rt_module_load_hook != RT_NULL)
  447. {
  448. rt_module_load_hook(module);
  449. }
  450. #endif
  451. rt_free(name);
  452. return module;
  453. __exit:
  454. if (full_path != path) rt_free(full_path);
  455. if (name != RT_NULL) rt_free(full_path);
  456. if (winpath != RT_NULL)rt_free(winpath);
  457. return RT_NULL;
  458. /* FreeLibrary(hinstlib); */
  459. }
  460. rt_err_t rt_module_destroy(rt_module_t module)
  461. {
  462. return 0;
  463. }
  464. rt_err_t rt_module_unload(rt_module_t module)
  465. {
  466. return 0;
  467. }
  468. #endif