Переглянути джерело

fixed mutex issue in memheap; fixed compiling issue in kservice.c when COMPILER is not defined; add finsh for win32 porting.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2365 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 12 роки тому
батько
коміт
1c425607c3
6 змінених файлів з 182 додано та 29 видалено
  1. 18 2
      components/finsh/cmd.c
  2. 48 2
      components/finsh/finsh.h
  3. 16 1
      components/finsh/finsh_vm.c
  4. 40 0
      components/finsh/shell.c
  5. 4 3
      src/kservice.c
  6. 56 21
      src/memheap.c

+ 18 - 2
components/finsh/cmd.c

@@ -27,10 +27,26 @@
  * 2010-04-21     yi.qiu       add list_module
  * 2012-04-29     goprife      improve the command line auto-complete feature.
  * 2012-06-02     lgnq         add list_memheap
+ * 2012-10-22     Bernard      add MS VC++ patch.
  */
 
 #include <rtthread.h>
 #include "finsh.h"
+#if defined(_MSC_VER)
+static struct finsh_syscall* _next_syscall(struct finsh_syscall* call)
+{
+	unsigned int *ptr;
+	ptr = (unsigned int*) (call + 1);
+	while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
+		ptr ++;
+
+	return (struct finsh_syscall*)ptr;
+}
+#define _NEXT_SYSCALl(index)  index=_next_syscall(index)
+#else
+#define _NEXT_SYSCALl(index)  index++
+#endif
+
 
 rt_inline unsigned int rt_list_len(const rt_list_t *l)
 {
@@ -548,7 +564,7 @@ long list(void)
     rt_kprintf("--Function List:\n");
     {
         struct finsh_syscall *index;
-        for (index = _syscall_table_begin; index < _syscall_table_end; index ++)
+        for (index = _syscall_table_begin; index < _syscall_table_end;  _NEXT_SYSCALl(index))
         {
 #ifdef FINSH_USING_DESCRIPTION
             rt_kprintf("%-16s -- %s\n", index->name, index->desc);
@@ -632,7 +648,7 @@ void list_prefix(char *prefix)
     /* checks in system function call */
     {
         struct finsh_syscall* index;
-        for (index = _syscall_table_begin; index < _syscall_table_end; index ++)
+        for (index = _syscall_table_begin; index < _syscall_table_end;  _NEXT_SYSCALl(index))
         {
             if (str_is_prefix(prefix, index->name) == 0)
             {

+ 48 - 2
components/finsh/finsh.h

@@ -16,6 +16,11 @@
 
 #include <rtthread.h>
 
+#if defined(_MSC_VER)
+#pragma section("FSymTab$f",read)
+#pragma section("VSymTab",read)
+#endif
+
 /* -- the beginning of option -- */
 #define FINSH_NAME_MAX          16      /* max length of identifier */
 #define FINSH_NODE_MAX          16      /* max number of node */
@@ -119,6 +124,9 @@ struct finsh_syscall
 #endif
 	syscall_func func;		/* the function address of system call */
 };
+#if defined(_MSC_VER)
+#pragma pack(pop)
+#endif
 /* system call item */
 struct finsh_syscall_item
 {
@@ -132,6 +140,7 @@ extern struct finsh_syscall_item *global_syscall_list;
 struct finsh_syscall* finsh_syscall_lookup(const char* name);
 
 /* system variable table */
+
 struct finsh_sysvar
 {
 	const char*		name;		/* the name of variable */
@@ -141,6 +150,7 @@ struct finsh_sysvar
 	u_char		 type;		/* the type of variable */
 	void*		 var ;		/* the address of variable */
 };
+
 /* system variable item */
 struct finsh_sysvar_item
 {
@@ -163,6 +173,18 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
 		 * @param name the name of function.
 		 * @param desc the description of function, which will show in help.
 		 */
+#ifdef _MSC_VER
+		#define FINSH_FUNCTION_EXPORT(name, desc)					 \
+		const char __fsym_##name##_name[] = #name;					 \
+		const char __fsym_##name##_desc[] = #desc;					 \
+		__declspec(allocate("FSymTab$f")) const struct finsh_syscall __fsym_##name = \
+		{							\
+			__fsym_##name##_name,	\
+			__fsym_##name##_desc,	\
+			(syscall_func)&name		\
+		};
+		#pragma comment(linker, "/merge:FSymTab=mytext")
+#else
 		#define FINSH_FUNCTION_EXPORT(name, desc)					 \
 		const char __fsym_##name##_name[] = #name;					 \
 		const char __fsym_##name##_desc[] = #desc;					 \
@@ -172,6 +194,7 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
 			__fsym_##name##_desc,	\
 			(syscall_func)&name		\
 		};
+#endif
 
 		/**
 		 * @ingroup finsh
@@ -182,6 +205,17 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
 		 * @param alias the alias name of function.
 		 * @param desc the description of function, which will show in help.
 		 */
+#ifdef _MSC_VER
+		#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc)		\
+		const char __fsym_##name##_name[] = #alias;					 \
+		const char __fsym_##name##_desc[] = #desc;					 \
+		__declspec(allocate("FSymTab$f")) const struct finsh_syscall __fsym_##name = \
+		{							\
+			__fsym_##name##_name,	\
+			__fsym_##name##_desc,	\
+			(syscall_func)&name		\
+		};
+#else
 		#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc)		\
 		const char __fsym_##name##_name[] = #alias;					 \
 		const char __fsym_##name##_desc[] = #desc;					 \
@@ -191,7 +225,7 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
 			__fsym_##name##_desc,	\
 			(syscall_func)&name		\
 		};
-
+#endif
 		/**
 		 * @ingroup finsh
 		 *
@@ -201,6 +235,18 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
 		 * @param type the type of variable.
 		 * @param desc the description of function, which will show in help.
 		 */
+#ifdef _MSC_VER
+		#define FINSH_VAR_EXPORT(name, type, desc)					\
+		const char __vsym_##name##_name[] = #name;					\
+		const char __vsym_##name##_desc[] = #desc;					\
+		__declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \
+		{							\
+			__vsym_##name##_name,	\
+			__vsym_##name##_desc,	\
+			type, 					\
+			(void*)&name			\
+		};
+#else
 		#define FINSH_VAR_EXPORT(name, type, desc)					\
 		const char __vsym_##name##_name[] = #name;					\
 		const char __vsym_##name##_desc[] = #desc;					\
@@ -211,6 +257,7 @@ struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
 			type, 					\
 			(void*)&name			\
 		};
+#endif
 	#else
 		#define FINSH_FUNCTION_EXPORT(name, desc)					 \
 		const char __fsym_##name##_name[] = #name;					 \
@@ -369,5 +416,4 @@ void finsh_syscall_append(const char* name, syscall_func func);
  */
 void finsh_sysvar_append(const char* name, u_char type, void* addr);
 #endif
-
 #endif

+ 16 - 1
components/finsh/finsh_vm.c

@@ -83,12 +83,27 @@ void finsh_syscall_append(const char* name, syscall_func func)
 }
 #endif
 
+#if defined(_MSC_VER)
+static struct finsh_syscall* _next_syscall(struct finsh_syscall* call)
+{
+	unsigned int *ptr;
+	ptr = (unsigned int*) (call + 1);
+	while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
+		ptr ++;
+
+	return (struct finsh_syscall*)ptr;
+}
+#define _NEXT_SYSCALL(index)  index=_next_syscall(index)
+#else
+#define _NEXT_SYSCALL(index)  index++
+#endif
+
 struct finsh_syscall* finsh_syscall_lookup(const char* name)
 {
 	struct finsh_syscall* index;
 	struct finsh_syscall_item* item;
 
-	for (index = _syscall_table_begin; index < _syscall_table_end; index ++)
+	for (index = _syscall_table_begin; index < _syscall_table_end; _NEXT_SYSCALL(index))
 	{
 		if (strcmp(index->name, name) == 0)
 			return index;

+ 40 - 0
components/finsh/shell.c

@@ -304,7 +304,17 @@ rt_bool_t finsh_handle_history(struct finsh_shell* shell, char ch)
 
 		if (shell->use_history)
 		{
+#if defined(_WIN32)
+			int i;
+			rt_kprintf("\r");
+
+			for(i=0; i<= 60; i++)
+				putchar(' ');
+			rt_kprintf("\r");
+
+#else
 			rt_kprintf("\033[2K\r");
+#endif
 			rt_kprintf("%s%s", FINSH_PROMPT, shell->line);
 			return RT_TRUE;;
 		}
@@ -459,6 +469,26 @@ void finsh_system_var_init(const void* begin, const void* end)
     extern "asm" int __vsymtab_start;
     extern "asm" int __vsymtab_end;
   #endif
+#elif defined(_MSC_VER)
+#pragma section("FSymTab$a", read)
+const char __fsym_begin_name[] = "__start";
+const char __fsym_begin_desc[] = "begin of finsh";
+__declspec(allocate("FSymTab$a")) const struct finsh_syscall __fsym_begin = 
+{
+	__fsym_begin_name,
+	__fsym_begin_desc,
+	NULL
+};
+
+#pragma section("FSymTab$z", read)
+const char __fsym_end_name[] = "__end";
+const char __fsym_end_desc[] = "end of finsh";
+__declspec(allocate("FSymTab$z")) const struct finsh_syscall __fsym_end = 
+{
+	__fsym_end_name,
+	__fsym_end_desc,
+	NULL
+};
 #endif
 
 /*
@@ -493,6 +523,16 @@ void finsh_system_init(void)
 #elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
     finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
     finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
+#elif defined(_MSC_VER)
+	unsigned int *ptr_begin, *ptr_end;
+
+	ptr_begin = (unsigned int*)&__fsym_begin; ptr_begin += (sizeof(struct finsh_syscall)/sizeof(unsigned int));
+	while (*ptr_begin == 0) ptr_begin ++;
+
+	ptr_end = (unsigned int*) &__fsym_end; ptr_end --;
+	while (*ptr_end == 0) ptr_end --;
+
+	finsh_system_function_init(ptr_begin, ptr_end);
 #endif
 #endif
 

+ 4 - 3
src/kservice.c

@@ -1052,9 +1052,10 @@ void rt_hw_console_output(const char *str)
 #elif defined(__CC_ARM)
 __weak void rt_hw_console_output(const char *str)
 #elif defined(__IAR_SYSTEMS_ICC__)
-#if __VER__ > 540
-__weak
-#endif
+    #if __VER__ > 540
+    __weak
+    #endif
+#else
 void rt_hw_console_output(const char *str)
 #endif
 {

+ 56 - 21
src/memheap.c

@@ -10,6 +10,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2012-04-10     Bernard      first implementation
+ * 2012-10-16     Bernard      add the mutex lock for heap object.
  */
 
 #include <rtthread.h>
@@ -96,6 +97,9 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap, const char *name,
 	/* not in free list */
 	item->next_free = item->prev_free = RT_NULL;
 
+	/* initialize mutex lock */
+	rt_mutex_init(&(memheap->lock), name, RT_IPC_FLAG_FIFO);
+
 	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x",
     		start_addr, size, &(memheap->free_header)));
 
@@ -105,6 +109,9 @@ RTM_EXPORT(rt_memheap_init);
 
 rt_err_t rt_memheap_detach(struct rt_memheap *heap)
 {
+	RT_ASSERT(heap);
+
+	rt_object_detach(&(heap->lock.parent.parent));
 	rt_object_detach(&(heap->parent));
 
 	/* Return a successful completion. */
@@ -112,12 +119,13 @@ rt_err_t rt_memheap_detach(struct rt_memheap *heap)
 }
 RTM_EXPORT(rt_memheap_detach);
 
-void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
+void *rt_memheap_alloc(struct rt_memheap *heap, rt_uint32_t size)
 {
+	rt_err_t result;
 	rt_uint32_t free_size;
 	struct rt_memheap_item *header_ptr;
 
-	RT_ASSERT(pool_ptr != RT_NULL);
+	RT_ASSERT(heap != RT_NULL);
 
 	/* align allocated size */
 	size = RT_ALIGN(size, RT_ALIGN_SIZE);
@@ -126,13 +134,22 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
 
 	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d", size));
 
-	if (size < pool_ptr->available_size)
+	if (size < heap->available_size)
 	{
 		/* search on free list */
 		free_size = 0;
+
+		/* lock memheap */
+		result = rt_mutex_take(&(heap->lock), RT_WAITING_FOREVER);
+		if (result != RT_EOK)
+		{
+			rt_set_errno(result);
+			return RT_NULL;
+		}
+
 		/* get the first free memory block */
-		header_ptr = pool_ptr->free_list->next_free;
-		while (header_ptr != pool_ptr->free_list && free_size < size)
+		header_ptr = heap->free_list->next_free;
+		while (header_ptr != heap->free_list && free_size < size)
 		{
 			/* get current freed memory block size */
 			free_size = (rt_uint32_t)(header_ptr->next) - (rt_uint32_t)header_ptr - RT_MEMHEAP_SIZE;
@@ -165,7 +182,7 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
 				new_ptr->magic = RT_MEMHEAP_MAGIC;
 
 				/* put the pool pointer into the new block. */
-				new_ptr->pool_ptr = pool_ptr;
+				new_ptr->pool_ptr = heap;
 
 				/* break down the block list */
 				new_ptr->prev = header_ptr;
@@ -180,20 +197,20 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
 				header_ptr->prev_free = RT_NULL;
 
 				/* insert new_ptr to free list */
-				new_ptr->next_free = pool_ptr->free_list->next_free;
-				new_ptr->prev_free = pool_ptr->free_list;
-				pool_ptr->free_list->next_free->prev_free = new_ptr;
-				pool_ptr->free_list->next_free = new_ptr;
+				new_ptr->next_free = heap->free_list->next_free;
+				new_ptr->prev_free = heap->free_list;
+				heap->free_list->next_free->prev_free = new_ptr;
+				heap->free_list->next_free = new_ptr;
 				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: nf 0x%08x, pf 0x%08x",
 						new_ptr->next_free, new_ptr->prev_free));
 
 				/* decrement the available byte count.  */
-				pool_ptr->available_size = pool_ptr->available_size - size - RT_MEMHEAP_SIZE;
+				heap->available_size = heap->available_size - size - RT_MEMHEAP_SIZE;
 			}
 			else
 			{
 				/* decrement the entire free size from the available bytes count.  */
-				pool_ptr->available_size = pool_ptr->available_size - free_size;
+				heap->available_size = heap->available_size - free_size;
 
 				/* remove header_ptr from free list */
 				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("one block: h[0x%08x], nf 0x%08x, pf 0x%08x", header_ptr,
@@ -205,6 +222,9 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
 				header_ptr->prev_free = RT_NULL;
 			}
 
+			/* release lock */
+			rt_mutex_release(&(heap->lock));
+			
 			/* Mark the allocated block as not available.  */
 			header_ptr->magic |= RT_MEMHEAP_USED;
 
@@ -214,6 +234,9 @@ void *rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
 
 			return (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE));
 		}
+
+		/* release lock */
+		rt_mutex_release(&(heap->lock));
 	}
 
 	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate memory: failed\n"));
@@ -225,7 +248,8 @@ RTM_EXPORT(rt_memheap_alloc);
 
 void rt_memheap_free(void *ptr)
 {
-	struct rt_memheap *pool_ptr;
+	rt_err_t result;
+	struct rt_memheap *heap;
 	struct rt_memheap_item *header_ptr, *new_ptr;
 	rt_uint32_t insert_header;
 
@@ -240,13 +264,21 @@ void rt_memheap_free(void *ptr)
 	RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
 
 	/* get pool ptr */
-	pool_ptr = header_ptr->pool_ptr;
+	heap = header_ptr->pool_ptr;
+
+	/* lock memheap */
+	result = rt_mutex_take(&(heap->lock), RT_WAITING_FOREVER);
+	if (result != RT_EOK)
+	{
+		rt_set_errno(result);
+		return ;
+	}
 
 	/* Mark the memory as available. */
 	header_ptr->magic &= ~RT_MEMHEAP_USED;
 
 	/* Adjust the available number of bytes. */
-	pool_ptr->available_size =  pool_ptr->available_size +
+	heap->available_size =  heap->available_size +
 			((rt_uint32_t)(header_ptr->next) -
 			(rt_uint32_t)header_ptr) - RT_MEMHEAP_SIZE;
 
@@ -256,7 +288,7 @@ void rt_memheap_free(void *ptr)
 		RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x", header_ptr->prev));
 
 		/* adjust the available number of bytes. */
-		pool_ptr->available_size = pool_ptr->available_size + RT_MEMHEAP_SIZE;
+		heap->available_size = heap->available_size + RT_MEMHEAP_SIZE;
 
 		/* yes, merge block with previous neighbor. */
 		(header_ptr->prev)->next = header_ptr->next;
@@ -272,7 +304,7 @@ void rt_memheap_free(void *ptr)
 	if (!RT_MEMHEAP_IS_USED(header_ptr->next))
 	{
 		/* adjust the available number of bytes. */
-		pool_ptr->available_size =  pool_ptr->available_size + RT_MEMHEAP_SIZE;
+		heap->available_size =  heap->available_size + RT_MEMHEAP_SIZE;
 
 		/* merge block with next neighbor. */
 		new_ptr =  header_ptr->next;
@@ -291,14 +323,17 @@ void rt_memheap_free(void *ptr)
 	if (insert_header)
 	{
 		/* no left merge, insert to free list */
-		header_ptr->next_free = pool_ptr->free_list->next_free;
-		header_ptr->prev_free = pool_ptr->free_list;
-		pool_ptr->free_list->next_free->prev_free = header_ptr;
-		pool_ptr->free_list->next_free = header_ptr;
+		header_ptr->next_free = heap->free_list->next_free;
+		header_ptr->prev_free = heap->free_list;
+		heap->free_list->next_free->prev_free = header_ptr;
+		heap->free_list->next_free = header_ptr;
 
 		RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("insert to free list: nf 0x%08x, pf 0x%08x",
 				header_ptr->next_free, header_ptr->prev_free));
 	}
+
+	/* release lock */
+	rt_mutex_release(&(heap->lock));
 }
 RTM_EXPORT(rt_memheap_free);