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
This commit is contained in:
bernard.xiong@gmail.com 2012-10-22 03:12:21 +00:00
parent b45dfd0a15
commit 1c425607c3
6 changed files with 182 additions and 29 deletions

View File

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

View File

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

View File

@ -83,12 +83,27 @@ void finsh_syscall_append(const char* name, syscall_func func)
} }
#endif #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* finsh_syscall_lookup(const char* name)
{ {
struct finsh_syscall* index; struct finsh_syscall* index;
struct finsh_syscall_item* item; 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) if (strcmp(index->name, name) == 0)
return index; return index;

View File

@ -304,7 +304,17 @@ rt_bool_t finsh_handle_history(struct finsh_shell* shell, char ch)
if (shell->use_history) 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"); rt_kprintf("\033[2K\r");
#endif
rt_kprintf("%s%s", FINSH_PROMPT, shell->line); rt_kprintf("%s%s", FINSH_PROMPT, shell->line);
return RT_TRUE;; 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_start;
extern "asm" int __vsymtab_end; extern "asm" int __vsymtab_end;
#endif #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 #endif
/* /*
@ -493,6 +523,16 @@ void finsh_system_init(void)
#elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */ #elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end); finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
finsh_system_var_init(&__vsymtab_start, &__vsymtab_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
#endif #endif

View File

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

View File

@ -10,6 +10,7 @@
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2012-04-10 Bernard first implementation * 2012-04-10 Bernard first implementation
* 2012-10-16 Bernard add the mutex lock for heap object.
*/ */
#include <rtthread.h> #include <rtthread.h>
@ -96,6 +97,9 @@ rt_err_t rt_memheap_init(struct rt_memheap *memheap, const char *name,
/* not in free list */ /* not in free list */
item->next_free = item->prev_free = RT_NULL; 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", 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))); 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_err_t rt_memheap_detach(struct rt_memheap *heap)
{ {
RT_ASSERT(heap);
rt_object_detach(&(heap->lock.parent.parent));
rt_object_detach(&(heap->parent)); rt_object_detach(&(heap->parent));
/* Return a successful completion. */ /* Return a successful completion. */
@ -112,12 +119,13 @@ rt_err_t rt_memheap_detach(struct rt_memheap *heap)
} }
RTM_EXPORT(rt_memheap_detach); 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; rt_uint32_t free_size;
struct rt_memheap_item *header_ptr; struct rt_memheap_item *header_ptr;
RT_ASSERT(pool_ptr != RT_NULL); RT_ASSERT(heap != RT_NULL);
/* align allocated size */ /* align allocated size */
size = RT_ALIGN(size, RT_ALIGN_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)); RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d", size));
if (size < pool_ptr->available_size) if (size < heap->available_size)
{ {
/* search on free list */ /* search on free list */
free_size = 0; 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 */ /* get the first free memory block */
header_ptr = pool_ptr->free_list->next_free; header_ptr = heap->free_list->next_free;
while (header_ptr != pool_ptr->free_list && free_size < size) while (header_ptr != heap->free_list && free_size < size)
{ {
/* get current freed memory block size */ /* get current freed memory block size */
free_size = (rt_uint32_t)(header_ptr->next) - (rt_uint32_t)header_ptr - RT_MEMHEAP_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; new_ptr->magic = RT_MEMHEAP_MAGIC;
/* put the pool pointer into the new block. */ /* put the pool pointer into the new block. */
new_ptr->pool_ptr = pool_ptr; new_ptr->pool_ptr = heap;
/* break down the block list */ /* break down the block list */
new_ptr->prev = header_ptr; 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; header_ptr->prev_free = RT_NULL;
/* insert new_ptr to free list */ /* insert new_ptr to free list */
new_ptr->next_free = pool_ptr->free_list->next_free; new_ptr->next_free = heap->free_list->next_free;
new_ptr->prev_free = pool_ptr->free_list; new_ptr->prev_free = heap->free_list;
pool_ptr->free_list->next_free->prev_free = new_ptr; heap->free_list->next_free->prev_free = new_ptr;
pool_ptr->free_list->next_free = new_ptr; heap->free_list->next_free = new_ptr;
RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: nf 0x%08x, pf 0x%08x", RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: nf 0x%08x, pf 0x%08x",
new_ptr->next_free, new_ptr->prev_free)); new_ptr->next_free, new_ptr->prev_free));
/* decrement the available byte count. */ /* 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 else
{ {
/* decrement the entire free size from the available bytes count. */ /* 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 */ /* 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, 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; header_ptr->prev_free = RT_NULL;
} }
/* release lock */
rt_mutex_release(&(heap->lock));
/* Mark the allocated block as not available. */ /* Mark the allocated block as not available. */
header_ptr->magic |= RT_MEMHEAP_USED; 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)); 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")); 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) 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; struct rt_memheap_item *header_ptr, *new_ptr;
rt_uint32_t insert_header; 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); RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
/* get pool ptr */ /* 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. */ /* Mark the memory as available. */
header_ptr->magic &= ~RT_MEMHEAP_USED; header_ptr->magic &= ~RT_MEMHEAP_USED;
/* Adjust the available number of bytes. */ /* 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->next) -
(rt_uint32_t)header_ptr) - RT_MEMHEAP_SIZE; (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)); RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: left node 0x%08x", header_ptr->prev));
/* adjust the available number of bytes. */ /* 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. */ /* yes, merge block with previous neighbor. */
(header_ptr->prev)->next = header_ptr->next; (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)) if (!RT_MEMHEAP_IS_USED(header_ptr->next))
{ {
/* adjust the available number of bytes. */ /* 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. */ /* merge block with next neighbor. */
new_ptr = header_ptr->next; new_ptr = header_ptr->next;
@ -291,14 +323,17 @@ void rt_memheap_free(void *ptr)
if (insert_header) if (insert_header)
{ {
/* no left merge, insert to free list */ /* no left merge, insert to free list */
header_ptr->next_free = pool_ptr->free_list->next_free; header_ptr->next_free = heap->free_list->next_free;
header_ptr->prev_free = pool_ptr->free_list; header_ptr->prev_free = heap->free_list;
pool_ptr->free_list->next_free->prev_free = header_ptr; heap->free_list->next_free->prev_free = header_ptr;
pool_ptr->free_list->next_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", RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("insert to free list: nf 0x%08x, pf 0x%08x",
header_ptr->next_free, header_ptr->prev_free)); header_ptr->next_free, header_ptr->prev_free));
} }
/* release lock */
rt_mutex_release(&(heap->lock));
} }
RTM_EXPORT(rt_memheap_free); RTM_EXPORT(rt_memheap_free);