module_win32.c 14 KB

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