module.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. /*
  2. * File : module.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2010, 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. * 2010-01-09 Bernard first version
  13. * 2010-04-09 yi.qiu implement based on first version
  14. * 2010-10-23 yi.qiu implement module memory allocator
  15. */
  16. #include <rthw.h>
  17. #include <rtthread.h>
  18. #include <rtm.h>
  19. #include "string.h"
  20. #include "kservice.h"
  21. #ifdef RT_USING_MODULE
  22. #include "module.h"
  23. #define elf_module ((Elf32_Ehdr *)module_ptr)
  24. #define shdr ((Elf32_Shdr *)((rt_uint8_t *)module_ptr + elf_module->e_shoff))
  25. #define phdr ((Elf32_Phdr *)((rt_uint8_t *)module_ptr + elf_module->e_phoff))
  26. #define IS_PROG(s) (s.sh_type == SHT_PROGBITS)
  27. #define IS_NOPROG(s) (s.sh_type == SHT_NOBITS)
  28. #define IS_REL(s) (s.sh_type == SHT_REL)
  29. #define IS_RELA(s) (s.sh_type == SHT_RELA)
  30. #define IS_ALLOC(s) (s.sh_flags == SHF_ALLOC)
  31. #define IS_AX(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_EXECINSTR))
  32. #define IS_AW(s) ((s.sh_flags & SHF_ALLOC) && (s.sh_flags & SHF_WRITE))
  33. /* module memory allocator */
  34. struct rt_module_page
  35. {
  36. rt_uint8_t *ptr; /* address of memory block */
  37. rt_size_t npage; /* number of pages */
  38. rt_list_t list;
  39. };
  40. /* module memory allocator */
  41. struct rt_mem_head
  42. {
  43. rt_size_t size; /* size of memory block */
  44. struct rt_mem_head *next; /* next valid memory block */
  45. };
  46. extern void *rt_malloc_page(rt_size_t npages);
  47. extern void rt_free_page(void *page_ptr, rt_size_t npages);
  48. static rt_module_t rt_current_module = RT_NULL;
  49. rt_list_t rt_module_symbol_list;
  50. struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL, *_rt_module_symtab_end = RT_NULL;
  51. /**
  52. * @ingroup SystemInit
  53. *
  54. * This function will initialize system module
  55. *
  56. */
  57. void rt_system_module_init(void)
  58. {
  59. #ifdef __GNUC__
  60. extern int __rtmsymtab_start;
  61. extern int __rtmsymtab_end;
  62. _rt_module_symtab_begin = (struct rt_module_symtab *)&__rtmsymtab_start;
  63. _rt_module_symtab_end = (struct rt_module_symtab *)&__rtmsymtab_end;
  64. #elif defined (__CC_ARM)
  65. extern int RTMSymTab$$Base;
  66. extern int RTMSymTab$$Limit;
  67. _rt_module_symtab_begin = (struct rt_module_symtab *)&RTMSymTab$$Base;
  68. _rt_module_symtab_end = (struct rt_module_symtab *)&RTMSymTab$$Limit;
  69. #endif
  70. rt_list_init(&rt_module_symbol_list);
  71. /* init current module */
  72. rt_current_module = RT_NULL;
  73. }
  74. static rt_uint32_t rt_module_symbol_find(const char* sym_str)
  75. {
  76. /* find in kernel symbol table */
  77. struct rt_module_symtab* index;
  78. for (index = _rt_module_symtab_begin; index != _rt_module_symtab_end; index ++)
  79. {
  80. if (rt_strcmp(index->name, sym_str) == 0)
  81. return (rt_uint32_t)index->addr;
  82. }
  83. return 0;
  84. }
  85. /**
  86. * This function will return self module object
  87. *
  88. * @return the self module object
  89. *
  90. */
  91. rt_module_t rt_module_self (void)
  92. {
  93. /* return current module */
  94. return rt_current_module;
  95. }
  96. /**
  97. * This function will set current module object
  98. *
  99. * @return RT_EOK
  100. */
  101. rt_err_t rt_module_set (rt_module_t module)
  102. {
  103. /* set current module */
  104. rt_current_module = module;
  105. return RT_EOK;
  106. }
  107. static int rt_module_arm_relocate(struct rt_module* module, Elf32_Rel *rel, Elf32_Addr sym_val)
  108. {
  109. Elf32_Addr *where, tmp;
  110. Elf32_Sword addend;
  111. where = (Elf32_Addr *)((rt_uint8_t*)module->module_space + rel->r_offset);
  112. switch (ELF32_R_TYPE(rel->r_info))
  113. {
  114. case R_ARM_NONE:
  115. break;
  116. case R_ARM_ABS32:
  117. *where += (Elf32_Addr)sym_val;
  118. RT_DEBUG_LOG(RT_DEBUG_MODULE,
  119. ("R_ARM_ABS32: %x -> %x\n", where, *where));
  120. break;
  121. case R_ARM_PC24:
  122. case R_ARM_PLT32:
  123. case R_ARM_CALL:
  124. case R_ARM_JUMP24:
  125. addend = *where & 0x00ffffff;
  126. if (addend & 0x00800000)
  127. addend |= 0xff000000;
  128. tmp = sym_val - (Elf32_Addr)where + (addend << 2);
  129. tmp >>= 2;
  130. *where = (*where & 0xff000000) | (tmp & 0x00ffffff);
  131. RT_DEBUG_LOG(RT_DEBUG_MODULE,("R_ARM_PC24: %x -> %x\n", where, *where));
  132. break;
  133. case R_ARM_V4BX:
  134. *where &= 0xf000000f;
  135. *where |= 0x01a0f000;
  136. break;
  137. case R_ARM_GLOB_DAT:
  138. case R_ARM_JUMP_SLOT:
  139. *where = (Elf32_Addr)sym_val;
  140. RT_DEBUG_LOG(RT_DEBUG_MODULE,
  141. ("R_ARM_JUMP_SLOT: 0x%x -> 0x%x 0x%x\n", where, *where, sym_val));
  142. break;
  143. case R_ARM_RELATIVE:
  144. *where += (Elf32_Addr)sym_val;
  145. RT_DEBUG_LOG(RT_DEBUG_MODULE,
  146. ("R_ARM_RELATIVE: 0x%x -> 0x%x 0x%x\n", where, *where, sym_val));
  147. break;
  148. default:
  149. return -1;
  150. }
  151. return 0;
  152. }
  153. static void rt_module_init_object_container(struct rt_module* module)
  154. {
  155. RT_ASSERT(module != RT_NULL);
  156. /* initialize object container - thread */
  157. rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
  158. module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
  159. module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
  160. #ifdef RT_USING_SEMAPHORE
  161. /* initialize object container - semaphore */
  162. rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
  163. module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
  164. module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
  165. #endif
  166. #ifdef RT_USING_MUTEX
  167. /* initialize object container - mutex */
  168. rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
  169. module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
  170. module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
  171. #endif
  172. #ifdef RT_USING_EVENT
  173. /* initialize object container - event */
  174. rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
  175. module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
  176. module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
  177. #endif
  178. #ifdef RT_USING_MAILBOX
  179. /* initialize object container - mailbox */
  180. rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
  181. module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
  182. module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
  183. #endif
  184. #ifdef RT_USING_MESSAGEQUEUE
  185. /* initialize object container - message queue */
  186. rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
  187. module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
  188. module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
  189. #endif
  190. #ifdef RT_USING_MEMPOOL
  191. /* initialize object container - memory pool */
  192. rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
  193. module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
  194. module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
  195. #endif
  196. #ifdef RT_USING_DEVICE
  197. /* initialize object container - device */
  198. rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
  199. module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
  200. module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
  201. #endif
  202. /* initialize object container - timer */
  203. rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
  204. module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
  205. module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
  206. }
  207. /**
  208. * This function will load a module from memory and create a thread for it
  209. *
  210. * @param name the name of module, which shall be unique
  211. * @param module_ptr the memory address of module image
  212. *
  213. * @return the module object
  214. *
  215. */
  216. rt_module_t rt_module_load(const char* name, void* module_ptr)
  217. {
  218. rt_uint8_t *ptr = RT_NULL;
  219. rt_module_t module = RT_NULL;
  220. rt_bool_t linked = RT_FALSE;
  221. rt_uint32_t index, module_size = 0;
  222. RT_DEBUG_NOT_IN_INTERRUPT;
  223. rt_kprintf("rt_module_load: %s ,", name);
  224. /* check ELF header */
  225. if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) == 0)
  226. {
  227. /* rtmlinke finished */
  228. linked = RT_TRUE;
  229. }
  230. else if (rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0)
  231. {
  232. rt_kprintf(" module magic error\n");
  233. return RT_NULL;
  234. }
  235. /* check ELF class */
  236. if(elf_module->e_ident[EI_CLASS] != ELFCLASS32)
  237. {
  238. rt_kprintf(" module class error\n");
  239. return RT_NULL;
  240. }
  241. /* get the ELF image size */
  242. for (index = 0; index < elf_module->e_phnum; index++)
  243. {
  244. if(phdr[index].p_type == PT_LOAD)
  245. module_size += phdr[index].p_memsz;
  246. }
  247. if (module_size == 0)
  248. {
  249. rt_kprintf(" module size error\n");
  250. return module;
  251. }
  252. /* allocate module */
  253. module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, (const char*)name);
  254. if (!module) return RT_NULL;
  255. /* allocate module space */
  256. module->module_space = rt_malloc(module_size);
  257. if (module->module_space == RT_NULL)
  258. {
  259. rt_object_delete(&(module->parent));
  260. return RT_NULL;
  261. }
  262. /* zero all space */
  263. ptr = module->module_space;
  264. rt_memset(ptr, 0, module_size);
  265. rt_kprintf(" load address at 0x%x\n", ptr);
  266. for (index = 0; index < elf_module->e_phnum; index++)
  267. {
  268. if(phdr[index].p_type == PT_LOAD)
  269. {
  270. rt_memcpy(ptr, (rt_uint8_t*)elf_module + phdr[index].p_offset, phdr[index].p_filesz);
  271. ptr += phdr[index].p_memsz;
  272. }
  273. }
  274. /* set module entry */
  275. module->module_entry = module->module_space + elf_module->e_entry;
  276. /* handle relocation section */
  277. for (index = 0; index < elf_module->e_shnum; index ++)
  278. {
  279. if (IS_REL(shdr[index]))
  280. {
  281. rt_uint32_t i, nr_reloc;
  282. Elf32_Sym *symtab;
  283. Elf32_Rel *rel;
  284. rt_uint8_t *strtab;
  285. static rt_bool_t unsolved = RT_FALSE;
  286. /* get relocate item */
  287. rel = (Elf32_Rel *) ((rt_uint8_t*)module_ptr + shdr[index].sh_offset);
  288. /* locate .rel.plt and .rel.dyn section */
  289. symtab =(Elf32_Sym *) ((rt_uint8_t*)module_ptr + shdr[shdr[index].sh_link].sh_offset);
  290. strtab = (rt_uint8_t*) module_ptr + shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
  291. nr_reloc = (rt_uint32_t) (shdr[index].sh_size / sizeof(Elf32_Rel));
  292. /* relocate every items */
  293. for (i = 0; i < nr_reloc; i ++)
  294. {
  295. Elf32_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
  296. RT_DEBUG_LOG(RT_DEBUG_MODULE,
  297. ("relocate symbol %s shndx %d\n", strtab + sym->st_name, sym->st_shndx));
  298. if((sym->st_shndx != SHT_NULL) || (ELF_ST_BIND(sym->st_info) == STB_LOCAL))
  299. rt_module_arm_relocate(module, rel, (Elf32_Addr)(module->module_space + sym->st_value));
  300. else if(!linked)
  301. {
  302. Elf32_Addr addr;
  303. RT_DEBUG_LOG(RT_DEBUG_MODULE,
  304. ("unresolved relocate symbol: %s\n", strtab + sym->st_name));
  305. /* need to resolve symbol in kernel symbol table */
  306. addr = rt_module_symbol_find((const char*)(strtab + sym->st_name));
  307. if (addr == 0)
  308. {
  309. rt_kprintf("can't find %s in kernel symbol table\n", strtab + sym->st_name);
  310. unsolved = RT_TRUE;
  311. }
  312. else rt_module_arm_relocate(module, rel, addr);
  313. }
  314. rel ++;
  315. }
  316. if(unsolved)
  317. {
  318. rt_object_delete(&(module->parent));
  319. rt_free(module);
  320. return RT_NULL;
  321. }
  322. }
  323. }
  324. /* construct module symbol table */
  325. for (index = 0; index < elf_module->e_shnum; index ++)
  326. {
  327. /* find .dynsym section */
  328. rt_uint8_t* shstrab = (rt_uint8_t*) module_ptr + shdr[elf_module->e_shstrndx].sh_offset;
  329. if (rt_strcmp((const char *)(shstrab + shdr[index].sh_name), ELF_DYNSYM) == 0) break;
  330. }
  331. /* found .dynsym section */
  332. if(index != elf_module->e_shnum)
  333. {
  334. int i, count = 0;
  335. Elf32_Sym *symtab = RT_NULL;
  336. rt_uint8_t *strtab = RT_NULL;
  337. symtab =(Elf32_Sym *) ((rt_uint8_t*)module_ptr + shdr[index].sh_offset);
  338. strtab = (rt_uint8_t*) module_ptr + shdr[shdr[index].sh_link].sh_offset;
  339. for(i=0; i<shdr[index].sh_size/sizeof(Elf32_Sym); i++)
  340. {
  341. if((ELF_ST_BIND(symtab[i].st_info) == STB_GLOBAL) && (ELF_ST_TYPE(symtab[i].st_info) == STT_FUNC))
  342. count++;
  343. }
  344. module->symtab = (struct rt_module_symtab*)rt_malloc(count * sizeof(struct rt_module_symtab));
  345. module->nsym = count;
  346. for(i=0, count=0; i<shdr[index].sh_size/sizeof(Elf32_Sym); i++)
  347. {
  348. if((ELF_ST_BIND(symtab[i].st_info) == STB_GLOBAL) && (ELF_ST_TYPE(symtab[i].st_info) == STT_FUNC))
  349. {
  350. rt_size_t length = rt_strlen((const char*)(strtab + symtab[i].st_name)) + 1;
  351. module->symtab[count].addr = (void*)(module->module_space + symtab[i].st_value);
  352. module->symtab[count].name = rt_malloc(length);
  353. rt_memset((void*)module->symtab[count].name, 0, length);
  354. rt_memcpy((void*)module->symtab[count].name, strtab + symtab[i].st_name, length);
  355. count++;
  356. }
  357. }
  358. }
  359. /* init module object container */
  360. rt_module_init_object_container(module);
  361. /* increase module reference count */
  362. module->nref++;
  363. if(elf_module->e_entry != 0)
  364. {
  365. /* init module page list */
  366. rt_list_init(&module->page_list);
  367. /* init module memory allocator */
  368. module->mem_list = RT_NULL;
  369. /* create mpool for page node */
  370. module->mpool = rt_mp_create(name, 256, sizeof(struct rt_module_page));
  371. /* create module thread */
  372. module->stack_size = 2048;
  373. module->thread_priority = 90;
  374. module->module_thread = rt_thread_create(name,
  375. module->module_entry, RT_NULL,
  376. module->stack_size,
  377. module->thread_priority, 10);
  378. module->module_thread->module_id = (void*)module;
  379. /* startup module thread */
  380. rt_thread_startup(module->module_thread);
  381. }
  382. else
  383. {
  384. /* without entry point */
  385. module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
  386. }
  387. return module;
  388. }
  389. #ifdef RT_USING_DFS
  390. #include <dfs_posix.h>
  391. /**
  392. * This function will load a module from a file
  393. *
  394. * @param filename the file name of application module
  395. *
  396. * @return the module object
  397. *
  398. */
  399. rt_module_t rt_module_open(const char* filename)
  400. {
  401. int fd, length;
  402. struct rt_module* module;
  403. struct stat s;
  404. char *buffer, *offset_ptr;;
  405. RT_DEBUG_NOT_IN_INTERRUPT;
  406. /* check parameters */
  407. RT_ASSERT(filename != RT_NULL);
  408. if (stat(filename, &s) !=0)
  409. {
  410. rt_kprintf("access file failed\n");
  411. return RT_NULL;
  412. }
  413. buffer = (char *)rt_malloc(s.st_size);
  414. if (buffer == RT_NULL)
  415. {
  416. rt_kprintf("out of memory\n");
  417. return RT_NULL;
  418. }
  419. offset_ptr = buffer;
  420. fd = open(filename, O_RDONLY, 0);
  421. if (fd < 0)
  422. {
  423. rt_kprintf("open file failed\n");
  424. rt_free(buffer);
  425. return RT_NULL;
  426. }
  427. do
  428. {
  429. length = read(fd, offset_ptr, 4096);
  430. if (length > 0)
  431. {
  432. offset_ptr += length;
  433. }
  434. }while (length > 0);
  435. /* close fd */
  436. close(fd);
  437. if ((rt_uint32_t)offset_ptr - (rt_uint32_t)buffer != s.st_size)
  438. {
  439. rt_kprintf("check: read file failed\n");
  440. rt_free(buffer);
  441. return RT_NULL;
  442. }
  443. module = rt_module_load(filename, (void *)buffer);
  444. rt_free(buffer);
  445. return module;
  446. }
  447. #if defined(RT_USING_FINSH)
  448. #include <finsh.h>
  449. FINSH_FUNCTION_EXPORT_ALIAS(rt_module_open, exec, exec module from file);
  450. #endif
  451. #endif
  452. /**
  453. * This function will unload a module from memory and release resources
  454. *
  455. * @param module the module to be unloaded
  456. *
  457. * @return the operation status, RT_EOK on OK; -RT_ERROR on error
  458. *
  459. */
  460. rt_err_t rt_module_unload(rt_module_t module)
  461. {
  462. int i;
  463. struct rt_object* object;
  464. struct rt_list_node *list;
  465. RT_DEBUG_NOT_IN_INTERRUPT;
  466. rt_kprintf("rt_module_unload: %s\n", module->parent.name);
  467. /* check parameter */
  468. RT_ASSERT(module != RT_NULL);
  469. /* module has entry point */
  470. if(!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
  471. {
  472. /* suspend module main thread */
  473. if(module->module_thread != RT_NULL)
  474. {
  475. if (module->module_thread->stat == RT_THREAD_READY)
  476. rt_thread_suspend(module->module_thread);
  477. }
  478. /* delete threads */
  479. list = &module->module_object[RT_Object_Class_Thread].object_list;
  480. while(list->next != list)
  481. {
  482. object = rt_list_entry(list->next, struct rt_object, list);
  483. if (rt_object_is_systemobject(object) == RT_EOK)
  484. {
  485. /* detach static object */
  486. rt_thread_detach((rt_thread_t)object);
  487. }
  488. else
  489. {
  490. /* delete dynamic object */
  491. rt_thread_delete((rt_thread_t)object);
  492. }
  493. }
  494. #ifdef RT_USING_SEMAPHORE
  495. /* delete semaphores */
  496. list = &module->module_object[RT_Object_Class_Thread].object_list;
  497. while(list->next != list)
  498. {
  499. object = rt_list_entry(list->next, struct rt_object, list);
  500. if (rt_object_is_systemobject(object) == RT_EOK)
  501. {
  502. /* detach static object */
  503. rt_sem_detach((rt_sem_t)object);
  504. }
  505. else
  506. {
  507. /* delete dynamic object */
  508. rt_sem_delete((rt_sem_t)object);
  509. }
  510. }
  511. #endif
  512. #ifdef RT_USING_MUTEX
  513. /* delete mutexs*/
  514. list = &module->module_object[RT_Object_Class_Mutex].object_list;
  515. while(list->next != list)
  516. {
  517. object = rt_list_entry(list->next, struct rt_object, list);
  518. if (rt_object_is_systemobject(object) == RT_EOK)
  519. {
  520. /* detach static object */
  521. rt_mutex_detach((rt_mutex_t)object);
  522. }
  523. else
  524. {
  525. /* delete dynamic object */
  526. rt_mutex_delete((rt_mutex_t)object);
  527. }
  528. }
  529. #endif
  530. #ifdef RT_USING_EVENT
  531. /* delete mailboxs */
  532. list = &module->module_object[RT_Object_Class_Event].object_list;
  533. while(list->next != list)
  534. {
  535. object = rt_list_entry(list->next, struct rt_object, list);
  536. if (rt_object_is_systemobject(object) == RT_EOK)
  537. {
  538. /* detach static object */
  539. rt_event_detach((rt_event_t)object);
  540. }
  541. else
  542. {
  543. /* delete dynamic object */
  544. rt_event_delete((rt_event_t)object);
  545. }
  546. }
  547. #endif
  548. #ifdef RT_USING_MAILBOX
  549. /* delete mailboxs */
  550. list = &module->module_object[RT_Object_Class_MailBox].object_list;
  551. while(list->next != list)
  552. {
  553. object = rt_list_entry(list->next, struct rt_object, list);
  554. if (rt_object_is_systemobject(object) == RT_EOK)
  555. {
  556. /* detach static object */
  557. rt_mb_detach((rt_mailbox_t)object);
  558. }
  559. else
  560. {
  561. /* delete dynamic object */
  562. rt_mb_delete((rt_mailbox_t)object);
  563. }
  564. }
  565. #endif
  566. #ifdef RT_USING_MESSAGEQUEUE
  567. /* delete msgqueues */
  568. list = &module->module_object[RT_Object_Class_MessageQueue].object_list;
  569. while(list->next != list)
  570. {
  571. object = rt_list_entry(list->next, struct rt_object, list);
  572. if (rt_object_is_systemobject(object) == RT_EOK)
  573. {
  574. /* detach static object */
  575. rt_mq_detach((rt_mq_t)object);
  576. }
  577. else
  578. {
  579. /* delete dynamic object */
  580. rt_mq_delete((rt_mq_t)object);
  581. }
  582. }
  583. #endif
  584. #ifdef RT_USING_MEMPOOL
  585. /* delete mempools */
  586. list = &module->module_object[RT_Object_Class_MemPool].object_list;
  587. while(list->next != list)
  588. {
  589. object = rt_list_entry(list->next, struct rt_object, list);
  590. if (rt_object_is_systemobject(object) == RT_EOK)
  591. {
  592. /* detach static object */
  593. rt_mp_detach((rt_mp_t)object);
  594. }
  595. else
  596. {
  597. /* delete dynamic object */
  598. rt_mp_delete((rt_mp_t)object);
  599. }
  600. }
  601. #endif
  602. #ifdef RT_USING_DEVICE
  603. /* delete devices */
  604. list = &module->module_object[RT_Object_Class_Device].object_list;
  605. while(list->next != list)
  606. {
  607. object = rt_list_entry(list->next, struct rt_object, list);
  608. rt_device_unregister((rt_device_t)object);
  609. }
  610. #endif
  611. /* delete timers */
  612. list = &module->module_object[RT_Object_Class_Timer].object_list;
  613. while(list->next != list)
  614. {
  615. object = rt_list_entry(list->next, struct rt_object, list);
  616. if (rt_object_is_systemobject(object) == RT_EOK)
  617. {
  618. /* detach static object */
  619. rt_timer_detach((rt_timer_t)object);
  620. }
  621. else
  622. {
  623. /* delete dynamic object */
  624. rt_timer_delete((rt_timer_t)object);
  625. }
  626. }
  627. /* free module pages */
  628. list = &module->page_list;
  629. while(list->next != list)
  630. {
  631. struct rt_module_page* page;
  632. /* free page */
  633. page = rt_list_entry(list->next, struct rt_module_page, list);
  634. rt_free_page(page->ptr, page->npage);
  635. rt_list_remove(list->next);
  636. }
  637. /* delete mpool */
  638. if(module->mpool) rt_mp_delete(module->mpool);
  639. }
  640. /* release module space memory */
  641. rt_free(module->module_space);
  642. /* release module symbol table */
  643. for(i=0; i<module->nsym; i++) rt_free((void *)module->symtab[i].name);
  644. if(module->symtab != RT_NULL) rt_free(module->symtab);
  645. /* delete module object */
  646. rt_object_delete((rt_object_t)module);
  647. return RT_EOK;
  648. }
  649. /**
  650. * This function will find the specified module.
  651. *
  652. * @param name the name of module finding
  653. *
  654. * @return the module
  655. */
  656. rt_module_t rt_module_find(const char* name)
  657. {
  658. struct rt_object_information *information;
  659. struct rt_object* object;
  660. struct rt_list_node* node;
  661. extern struct rt_object_information rt_object_container[];
  662. RT_DEBUG_NOT_IN_INTERRUPT;
  663. /* enter critical */
  664. rt_enter_critical();
  665. /* try to find device object */
  666. information = &rt_object_container[RT_Object_Class_Module];
  667. for (node = information->object_list.next; node != &(information->object_list); node = node->next)
  668. {
  669. object = rt_list_entry(node, struct rt_object, list);
  670. if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
  671. {
  672. /* leave critical */
  673. rt_exit_critical();
  674. return (rt_module_t)object;
  675. }
  676. }
  677. /* leave critical */
  678. rt_exit_critical();
  679. /* not found */
  680. return RT_NULL;
  681. }
  682. static struct rt_mem_head *morepage(rt_size_t nu)
  683. {
  684. rt_uint8_t *cp;
  685. rt_uint32_t npage;
  686. struct rt_mem_head *up;
  687. struct rt_module_page *node;
  688. RT_DEBUG_NOT_IN_INTERRUPT;
  689. RT_ASSERT (nu != 0);
  690. /* allocate pages from system heap */
  691. npage = (nu * sizeof(struct rt_mem_head) + RT_MM_PAGE_SIZE - 1)/RT_MM_PAGE_SIZE;
  692. cp = rt_malloc_page(npage);
  693. if(!cp) return RT_NULL;
  694. /* allocate page list node from mpool */
  695. node = rt_mp_alloc(rt_current_module->mpool, RT_WAITING_FOREVER);
  696. node->ptr = cp;
  697. node->npage = npage;
  698. /* insert page list node to moudle's page list */
  699. rt_list_insert_after (&rt_current_module->page_list, &node->list);
  700. up = (struct rt_mem_head *) cp;
  701. up->size = npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head);
  702. rt_module_free(rt_current_module, (void *)(up+1));
  703. return up;
  704. }
  705. /*
  706. rt_module_malloc - allocate memory block in free list
  707. */
  708. void *rt_module_malloc(rt_size_t size)
  709. {
  710. struct rt_mem_head *b, *n;
  711. struct rt_mem_head **prev;
  712. rt_size_t nunits;
  713. RT_DEBUG_NOT_IN_INTERRUPT;
  714. nunits = (size + sizeof(struct rt_mem_head) -1)/sizeof(struct rt_mem_head) + 1;
  715. RT_ASSERT(size != 0);
  716. RT_ASSERT(nunits != 0);
  717. prev = (struct rt_mem_head **)&rt_current_module->mem_list;
  718. /* if size can be divided by page, allocate page directly */
  719. if(size % RT_MM_PAGE_SIZE == 0)
  720. {
  721. rt_uint8_t *cp;
  722. struct rt_module_page *node;
  723. rt_uint32_t npage = size / RT_MM_PAGE_SIZE;
  724. /* allocate pages from system heap */
  725. cp = rt_malloc_page(npage);
  726. if(!cp) return RT_NULL;
  727. /* allocate page list node from mpool */
  728. node = rt_mp_alloc(rt_current_module->mpool, RT_WAITING_FOREVER);
  729. node->ptr = cp;
  730. node->npage = npage;
  731. /* insert page list node to moudle's page list */
  732. rt_list_insert_after (&rt_current_module->page_list, &node->list);
  733. }
  734. while(RT_TRUE)
  735. {
  736. b = *prev;
  737. if(!b)
  738. {
  739. if ((b = morepage(nunits)) == RT_NULL) return RT_NULL;
  740. else return rt_module_malloc(size); /* To be improved */
  741. }
  742. if (b->size > nunits)
  743. {
  744. /* split memory */
  745. n = b + nunits;
  746. n->next = b->next;
  747. n->size = b->size - nunits;
  748. b->size = nunits;
  749. *prev = n;
  750. break;
  751. }
  752. if (b->size == nunits)
  753. {
  754. /* this node fit, remove this node */
  755. *prev = b->next;
  756. break;
  757. }
  758. prev = &(b->next);
  759. }
  760. return (void *)(b + 1);
  761. }
  762. /*
  763. rt_module_free - insert memory block in free list
  764. */
  765. void rt_module_free(rt_module_t module, void *addr)
  766. {
  767. struct rt_mem_head *b, *n;
  768. struct rt_mem_head **prev;
  769. RT_DEBUG_NOT_IN_INTERRUPT;
  770. RT_ASSERT(addr);
  771. RT_ASSERT((((rt_uint32_t)addr) & (sizeof(struct rt_mem_head) -1)) == 0);
  772. n = (struct rt_mem_head *)addr - 1;
  773. prev = (struct rt_mem_head **)&module->mem_list;
  774. while ((b = *prev) != RT_NULL)
  775. {
  776. RT_ASSERT(b->size > 0);
  777. RT_ASSERT(b > n || b + b->size <= n);
  778. if (b + b->size == n)
  779. {
  780. if (b + (b->size += n->size) == b->next)
  781. {
  782. b->size += b->next->size;
  783. b->next = b->next->next;
  784. }
  785. return;
  786. }
  787. if (b == n + n->size)
  788. {
  789. n->size = b->size + n->size;
  790. n->next = b->next;
  791. *prev = n;
  792. return;
  793. }
  794. if (b > n + n->size) break;
  795. prev = &(b->next);
  796. }
  797. n->next = b;
  798. *prev = n;
  799. /* free page, TODO */
  800. }
  801. /*
  802. rt_module_realloc - realloc memory block in free list
  803. */
  804. void *rt_module_realloc(void *ptr, rt_size_t size)
  805. {
  806. struct rt_mem_head *b, *p, *prev, *tmpp;
  807. rt_size_t nunits;
  808. RT_DEBUG_NOT_IN_INTERRUPT;
  809. if (!ptr) return rt_module_malloc(size);
  810. if (size == 0)
  811. {
  812. rt_module_free(rt_current_module, ptr);
  813. return RT_NULL;
  814. }
  815. nunits = (size + sizeof(struct rt_mem_head) - 1) / sizeof(struct rt_mem_head) + 1;
  816. b = (struct rt_mem_head *)ptr - 1;
  817. if (nunits <= b->size)
  818. {
  819. /* new size is smaller or equal then before */
  820. if (nunits == b->size) return ptr;
  821. else
  822. {
  823. p = b + nunits;
  824. p->size = b->size - nunits;
  825. b->size = nunits;
  826. rt_module_free(rt_current_module, (void *)(p + 1));
  827. return (void *)(b + 1);
  828. }
  829. }
  830. else
  831. {
  832. /* more space then required */
  833. prev = (struct rt_mem_head *)rt_current_module->mem_list;
  834. for (p = prev->next; p != (b->size + b) && p != RT_NULL; prev = p, p = p->next) break;
  835. /* available block after ap in freelist */
  836. if (p != RT_NULL && (p->size >= (nunits - (b->size))) && p == (b + b->size))
  837. {
  838. /* perfect match */
  839. if (p->size == (nunits - (b->size)))
  840. {
  841. b->size = nunits;
  842. prev->next = p->next;
  843. }
  844. else /* more space then required, split block*/
  845. {
  846. /* pointer to old header */
  847. tmpp = p;
  848. p = b + nunits;
  849. /* restoring old pointer */
  850. p->next = tmpp->next;
  851. /* new size for p */
  852. p->size = tmpp->size + b->size - nunits;
  853. b->size = nunits;
  854. prev->next = p;
  855. }
  856. rt_current_module->mem_list = (void *)prev;
  857. return (void *) (b + 1);
  858. }
  859. else /* allocate new memory and copy old data */
  860. {
  861. if ((p = rt_module_malloc(size)) == RT_NULL) return RT_NULL;
  862. rt_memmove(p, (b+1), ((b->size) * sizeof(struct rt_mem_head)));
  863. rt_module_free(rt_current_module, (void *)(b + 1));
  864. return (void *) (p);
  865. }
  866. }
  867. }
  868. #endif