123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2013-02-26 prife first version for win32
- */
- #include <rthw.h>
- #include <rtthread.h>
- #include <rtm.h>
- #ifdef RT_USING_MODULE
- void rt_module_init_object_container(struct rt_module *module)
- {
- RT_ASSERT(module != RT_NULL);
- /* initialize object container - thread */
- rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
- module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
- module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
- #ifdef RT_USING_SEMAPHORE
- /* initialize object container - semaphore */
- rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
- module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
- module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
- #endif
- #ifdef RT_USING_MUTEX
- /* initialize object container - mutex */
- rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
- module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
- module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
- #endif
- #ifdef RT_USING_EVENT
- /* initialize object container - event */
- rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
- module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
- module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
- #endif
- #ifdef RT_USING_MAILBOX
- /* initialize object container - mailbox */
- rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
- module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
- module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
- #endif
- #ifdef RT_USING_MESSAGEQUEUE
- /* initialize object container - message queue */
- rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
- module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
- module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
- #endif
- #ifdef RT_USING_MEMHEAP
- /* initialize object container - memory heap */
- rt_list_init(&(module->module_object[RT_Object_Class_MemHeap].object_list));
- module->module_object[RT_Object_Class_MemHeap].object_size = sizeof(struct rt_memheap);
- module->module_object[RT_Object_Class_MemHeap].type = RT_Object_Class_MemHeap;
- #endif
- #ifdef RT_USING_MEMPOOL
- /* initialize object container - memory pool */
- rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
- module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
- module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
- #endif
- #ifdef RT_USING_DEVICE
- /* initialize object container - device */
- rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
- module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
- module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
- #endif
- /* initialize object container - timer */
- rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
- module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
- module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
- }
- #ifdef RT_USING_HOOK
- static void (*rt_module_load_hook)(rt_module_t module);
- static void (*rt_module_unload_hook)(rt_module_t module);
- /**
- * @addtogroup Hook
- */
- /*@{*/
- /**
- * This function will set a hook function, which will be invoked when module
- * be loaded to system.
- *
- * @param hook the hook function
- */
- void rt_module_load_sethook(void (*hook)(rt_module_t module))
- {
- rt_module_load_hook = hook;
- }
- /**
- * This function will set a hook function, which will be invoked when module
- * be unloaded from system.
- *
- * @param hook the hook function
- */
- void rt_module_unload_sethook(void (*hook)(rt_module_t module))
- {
- rt_module_unload_hook = hook;
- }
- /*@}*/
- #endif
- /**
- * @ingroup SystemInit
- *
- * This function will initialize system module
- */
- int rt_system_module_init(void)
- {
- return 0;
- }
- /**
- * This function will return self module object
- *
- * @return the self module object
- */
- rt_module_t rt_module_self(void)
- {
- rt_thread_t tid;
- tid = rt_thread_self();
- if (tid == RT_NULL)
- return RT_NULL;
- /* return current module */
- return (rt_module_t)tid->module_id;
- }
- RTM_EXPORT(rt_module_self);
- /**
- * This function will find the specified module.
- *
- * @param name the name of module finding
- *
- * @return the module
- */
- rt_module_t rt_module_find(const char *name)
- {
- struct rt_object_information *information;
- struct rt_object *object;
- struct rt_list_node *node;
- RT_DEBUG_NOT_IN_INTERRUPT;
- /* enter critical */
- rt_enter_critical();
- /* try to find device object */
- information = rt_object_get_information(RT_Object_Class_Module);
- RT_ASSERT(information != RT_NULL);
- for (node = information->object_list.next;
- node != &(information->object_list);
- node = node->next)
- {
- object = rt_list_entry(node, struct rt_object, list);
- if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
- {
- /* leave critical */
- rt_exit_critical();
- return (rt_module_t)object;
- }
- }
- /* leave critical */
- rt_exit_critical();
- /* not found */
- return RT_NULL;
- }
- RTM_EXPORT(rt_module_find);
- #ifdef RT_USING_DFS
- #include <windows.h>
- #include <dfs_file.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <sys/stat.h>
- #include <sys/statfs.h>
- extern char * dfs_win32_dirdup(char * path);
- static char* _module_name(const char *path)
- {
- const char *first, *end, *ptr;
- char *name;
- int size;
- ptr = (char *)path;
- first = ptr;
- end = path + rt_strlen(path);
- while (*ptr != '\0')
- {
- if (*ptr == '/')
- first = ptr + 1;
- if (*ptr == '.')
- end = ptr - 1;
- ptr ++;
- }
- size = end - first + 1;
- name = rt_malloc(size);
- rt_strncpy(name, first, size);
- name[size] = '\0';
- return name;
- }
- typedef int (*appentry_t)(void);
- /**
- * This function will load a module from a file
- *
- * @param path the full path of application module
- *
- * @return the module object
- */
- rt_module_t rt_module_open(const char *path)
- {
- struct dfs_filesystem *fs;
- appentry_t fptr;
- HINSTANCE hinstlib;
- rt_module_t module;
- char * winpath = RT_NULL;
- char * name = RT_NULL;
- RT_DEBUG_NOT_IN_INTERRUPT;
- /* check parameters */
- RT_ASSERT(path != RT_NULL);
- /* app module should only in DFS_WIN32 */
- fs = dfs_filesystem_lookup(path);
- if ((fs == RT_NULL) || (strcmp(fs->ops->name,"wdir") != 0))
- {
- rt_kprintf("invalid path: %s\n", path);
- return RT_NULL;
- }
- /* change path */
- // len = strlen(path+1);
- if ((winpath = dfs_win32_dirdup((char *)path)) == RT_NULL)
- {
- rt_kprintf("out of memory, exit");
- return RT_NULL;
- }
- hinstlib = LoadLibrary(winpath);
- if (hinstlib == NULL)
- {
- rt_kprintf("error: unable to open %s\n", winpath);
- return RT_NULL;
- }
- fptr = (appentry_t)GetProcAddress(hinstlib, "main");
- if (fptr == NULL)
- {
- rt_kprintf("error: unable to find function in %s\n", winpath);
- FreeLibrary(hinstlib);
- return RT_NULL;
- }
- /* get the name of the module */
- name = _module_name(path);
- /* allocate module */
- module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, name);
- if (!module) return RT_NULL;
- module->nref = 0;
- module->module_entry = fptr;
- /* init module object container */
- rt_module_init_object_container(module);
- /* increase module reference count */
- module->nref ++;
- if (module->module_entry != 0)
- {
- #ifdef RT_USING_SLAB
- /* init module memory allocator */
- module->mem_list = RT_NULL;
- /* create page array */
- module->page_array =
- (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
- module->page_cnt = 0;
- #endif
- /* create module thread */
- module->module_thread =
- rt_thread_create(name,
- (void(*)(void *))module->module_entry, RT_NULL,
- 2048, RT_THREAD_PRIORITY_MAX - 2, 10);
- RT_DEBUG_LOG(RT_DEBUG_MODULE, ("thread entry 0x%x\n",
- module->module_entry));
- /* set module id */
- module->module_thread->module_id = (void *)module;
- module->parent.flag = RT_MODULE_FLAG_WITHENTRY;
- /* startup module thread */
- rt_thread_startup(module->module_thread);
- }
- else
- {
- /* without entry point */
- module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
- }
- #ifdef RT_USING_HOOK
- if (rt_module_load_hook != RT_NULL)
- {
- rt_module_load_hook(module);
- }
- #endif
- rt_free(name);
- return module;
- /* FreeLibrary(hinstlib); */
- }
- #if defined(RT_USING_FINSH)
- #include <finsh.h>
- FINSH_FUNCTION_EXPORT_ALIAS(rt_module_open, exec, exec module from a file);
- #endif
- #endif
- #define RT_MODULE_ARG_MAX 8
- static int _rt_module_split_arg(char* cmd, rt_size_t length, char* argv[])
- {
- int argc = 0;
- char *ptr = cmd;
- while ((ptr - cmd) < length)
- {
- /* strip bank and tab */
- while ((*ptr == ' ' || *ptr == '\t') && (ptr -cmd)< length)
- *ptr++ = '\0';
- /* check whether it's the end of line */
- if ((ptr - cmd)>= length) break;
- /* handle string with quote */
- if (*ptr == '"')
- {
- argv[argc++] = ++ptr;
- /* skip this string */
- while (*ptr != '"' && (ptr-cmd) < length)
- if (*ptr ++ == '\\') ptr ++;
- if ((ptr - cmd) >= length) break;
- /* skip '"' */
- *ptr ++ = '\0';
- }
- else
- {
- argv[argc++] = ptr;
- while ((*ptr != ' ' && *ptr != '\t') && (ptr - cmd) < length)
- ptr ++;
- }
- if (argc >= RT_MODULE_ARG_MAX) break;
- }
- return argc;
- }
- /* module main thread entry */
- static void module_main_entry(void* parameter)
- {
- int argc;
- char *argv[RT_MODULE_ARG_MAX];
- typedef int (*main_func_t)(int argc, char** argv);
- rt_module_t module = (rt_module_t) parameter;
- if (module == RT_NULL || module->module_cmd_line == RT_NULL) return;
- rt_memset(argv, 0x00, sizeof(argv));
- argc = _rt_module_split_arg((char*)module->module_cmd_line, module->module_cmd_size, argv);
- if (argc == 0) return ;
- /* do the main function */
- ((main_func_t)module->module_entry)(argc, argv);
- return;
- }
- /**
- * This function will do a executable program with main function and parameters.
- *
- * @param path the full path of application module
- * @param cmd_line the command line of program
- * @param size the size of command line of program
- *
- * @return the module object
- */
- rt_module_t rt_module_exec_cmd(const char *path, const char* cmd_line, int line_size)
- {
- struct dfs_filesystem *fs;
- appentry_t fptr;
- HINSTANCE hinstlib;
- rt_module_t module;
- char * winpath = RT_NULL;
- char * name = RT_NULL;
- char *full_path = RT_NULL;
- RT_DEBUG_NOT_IN_INTERRUPT;
- /* check parameters */
- RT_ASSERT(path != RT_NULL);
- if (*path != '/')
- {
- full_path = dfs_normalize_path(RT_NULL, path);
- }
- else
- {
- full_path = (const char*)path;
- }
- /* app module should only in DFS_WIN32 */
- fs = dfs_filesystem_lookup(full_path);
- if ((fs == RT_NULL) || (strcmp(fs->ops->name,"wdir") != 0))
- {
- rt_kprintf("invalid path: %s\n", path);
- goto __exit;
- }
- /* change path */
- // len = strlen(full_path + 1);
- if ((winpath = dfs_win32_dirdup((char *)full_path)) == RT_NULL)
- {
- rt_kprintf("out of memory, exit", path);
- goto __exit;
- }
- hinstlib = LoadLibrary(winpath);
- if (hinstlib == NULL)
- {
- rt_kprintf("error: unable to open %s\n", winpath);
- goto __exit;
- }
- fptr = (appentry_t)GetProcAddress(hinstlib, "main");
- if (fptr == NULL)
- {
- rt_kprintf("error: unable to find function in %s\n", winpath);
- FreeLibrary(hinstlib);
- goto __exit;
- }
- /* release winpath */
- rt_free(winpath);
- /* get the name of the module */
- name = _module_name(path);
- /* allocate module */
- module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, name);
- if (!module)
- {
- goto __exit;
- }
- module->nref = 0;
- module->module_entry = fptr;
- /* init module object container */
- rt_module_init_object_container(module);
- /* increase module reference count */
- module->nref ++;
- if (module->module_entry != 0)
- {
- /* set module argument */
- module->module_cmd_line = (rt_uint8_t*)rt_malloc(line_size + 1);
- rt_memcpy(module->module_cmd_line, cmd_line, line_size);
- module->module_cmd_line[line_size] = '\0';
- module->module_cmd_size = line_size;
- #ifdef RT_USING_SLAB
- /* init module memory allocator */
- module->mem_list = RT_NULL;
- /* create page array */
- module->page_array =
- (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
- module->page_cnt = 0;
- #endif
- /* create module thread */
- module->module_thread = rt_thread_create(name,
- module_main_entry, module,
- 2048, RT_THREAD_PRIORITY_MAX - 2, 10);
- /* set module id */
- module->module_thread->module_id = (void *)module;
- module->parent.flag = RT_MODULE_FLAG_WITHENTRY;
- /* startup module thread */
- rt_thread_startup(module->module_thread);
- }
- else
- {
- /* without entry point */
- module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
- }
- #ifdef RT_USING_HOOK
- if (rt_module_load_hook != RT_NULL)
- {
- rt_module_load_hook(module);
- }
- #endif
- rt_free(name);
- return module;
- __exit:
- if (full_path != path) rt_free(full_path);
- if (name != RT_NULL) rt_free(full_path);
- if (winpath != RT_NULL)rt_free(winpath);
- return RT_NULL;
- /* FreeLibrary(hinstlib); */
- }
- rt_err_t rt_module_destroy(rt_module_t module)
- {
- return 0;
- }
- rt_err_t rt_module_unload(rt_module_t module)
- {
- return 0;
- }
- #endif
|