/** * This function will create a thread object and allocate thread object memory * and stack. * * @param name the name of thread, which shall be unique * @param entry the entry function of thread * @param parameter the parameter of thread enter function * @param stack_size the size of thread stack * @param priority the priority of thread * @param tick the time slice if there are same priority thread * * @return the created thread object * */ rt_thread_t rt_thread_create(const char *name, void (*entry)(void *parameter), void *parameter, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick) { struct rt_thread *thread; void *stack_start; thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread, name); if (thread == RT_NULL) return RT_NULL; stack_start = (void *)rt_malloc(stack_size); if (stack_start == RT_NULL) { /* allocate stack failure */ rt_object_delete((rt_object_t)thread); return RT_NULL; } _rt_thread_init(thread, name, entry, parameter, stack_start, stack_size, priority, tick); return thread; }
/** * This function will create a mempool object and allocate the memory pool from * heap. * * @param name the name of memory pool * @param block_count the count of blocks in memory pool * @param block_size the size for each block * * @return the created mempool object */ rt_mp_t rt_mp_create(const char *name, rt_size_t block_count, rt_size_t block_size) { rt_uint8_t *block_ptr; struct rt_mempool *mp; register rt_base_t offset; RT_DEBUG_NOT_IN_INTERRUPT; /* allocate object */ mp = (struct rt_mempool *)rt_object_allocate(RT_Object_Class_MemPool, name); /* allocate object failed */ if (mp == RT_NULL) return RT_NULL; /* initialize memory pool */ block_size = RT_ALIGN(block_size, RT_ALIGN_SIZE); mp->block_size = block_size; mp->size = (block_size + sizeof(rt_uint8_t *)) * block_count; /* allocate memory */ mp->start_address = rt_malloc((block_size + sizeof(rt_uint8_t *)) * block_count); if (mp->start_address == RT_NULL) { /* no memory, delete memory pool object */ rt_object_delete(&(mp->parent)); return RT_NULL; } mp->block_total_count = block_count; mp->block_free_count = mp->block_total_count; /* initialize suspended thread list */ rt_list_init(&(mp->suspend_thread)); mp->suspend_thread_count = 0; /* initialize free block list */ block_ptr = (rt_uint8_t *)mp->start_address; for (offset = 0; offset < mp->block_total_count; offset ++) { *(rt_uint8_t **)(block_ptr + offset * (block_size + sizeof(rt_uint8_t *))) = block_ptr + (offset + 1) * (block_size + sizeof(rt_uint8_t *)); } *(rt_uint8_t **)(block_ptr + (offset - 1) * (block_size + sizeof(rt_uint8_t *))) = RT_NULL; mp->block_list = block_ptr; return mp; }
/** * This function will create a timer * * @param name the name of timer * @param timeout the timeout function * @param parameter the parameter of timeout function * @param time the tick of timer * @param flag the flag of timer * * @return the created timer object */ rt_timer_t rt_timer_create(const char *name, void (*timeout)(void *parameter), void *parameter, rt_tick_t time, rt_uint8_t flag) { struct rt_timer *timer; /* allocate a object */ timer = (struct rt_timer *)rt_object_allocate(RT_Object_Class_Timer, name); if (timer == RT_NULL) { return RT_NULL; } _rt_timer_init(timer, timeout, parameter, time, flag); return timer; }
/** * This function will create a semaphore from system resource * * @param name the name of semaphore * @param value the init value of semaphore * @param flag the flag of semaphore * * @return the created semaphore, RT_NULL on error happen * * @see rt_sem_init */ rt_sem_t rt_sem_create (const char* name, rt_uint32_t value, rt_uint8_t flag) { rt_sem_t sem; /* allocate object */ sem = (rt_sem_t) rt_object_allocate(RT_Object_Class_Semaphore, name); if (sem == RT_NULL) return sem; /* init ipc object */ rt_ipc_object_init(&(sem->parent)); /* set init value */ sem->value = value; /* set parent */ sem->parent.parent.flag = flag; return sem; }
/** * This function will create a mutex from system resource * * @param name the name of mutex * @param flag the flag of mutex * * @return the created mutex, RT_NULL on error happen * * @see rt_mutex_init */ rt_mutex_t rt_mutex_create (const char* name, rt_uint8_t flag) { struct rt_mutex *mutex; /* allocate object */ mutex = (rt_mutex_t) rt_object_allocate(RT_Object_Class_Mutex, name); if (mutex == RT_NULL) return mutex; /* init ipc object */ rt_ipc_object_init(&(mutex->parent)); mutex->value = 1; mutex->owner = RT_NULL; mutex->original_priority = 0xFF; mutex->hold = 0; /* set flag */ mutex->parent.parent.flag = flag; return mutex; }
/** * This funciton will initialize a rms thread */ rt_err_t rt_rms_init(struct rt_rms *rms, const char *name, void (*entry)(void *parameter), void *parameter, void *stack_start, rt_uint32_t stack_size, rt_uint8_t period, rt_uint32_t tick, rt_uint8_t wcet) { RT_ASSERT(rms != RT_NULL); RT_ASSERT(stack_start != RT_NULL); rms->thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread, name); #ifndef RT_RMS_ACCURACY #define RT_RMS_ACCURACY 1 #endif RT_ASSERT(rt_thread_init(rms->thread, name, entry, parameter, stack_start, stack_size, period / RT_RMS_ACCURACY, tick) == RT_EOK); return _rt_rms_init(rms, period, wcet); }
/** * This function will create a rms object and allocate rms object memory and stack */ rt_rms_t rt_rms_create(const char *name, void (*entry)(void *parameter), void *parameter, rt_uint32_t stack_size, rt_uint32_t tick, rt_uint8_t period, rt_uint8_t wcet) { struct rt_rms *rms; rms = (struct rt_rms *)rt_object_allocate(RT_Object_Class_Thread, name); if(rms->thread == RT_NULL) return RT_NULL; /* create a thread object */ #ifndef RT_RMS_ACCURACY #define RT_RMS_ACCURACY 1 #endif rms->thread = rt_thread_create(name, entry, parameter, stack_size, period / RT_RMS_ACCURACY, tick); _rt_rms_init(rms, period, wcet); return rms; }
/** * 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); */ }
/** * 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; int len; char * winpath; rt_module_t module; char * name; 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", path); 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) { rt_uint32_t *stack_size; rt_uint8_t *priority; #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 /* get the main thread stack size */ module->stack_size = 2048; module->thread_priority = RT_THREAD_PRIORITY_MAX - 2; /* create module thread */ module->module_thread = rt_thread_create(name, (void(*)(void *))module->module_entry, RT_NULL, module->stack_size, module->thread_priority, 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); */ }