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

Added memory heap object implementation; Added RT_LIST_OBJECT_INIT macro.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2046 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 13 роки тому
батько
коміт
87195cf84e
6 змінених файлів з 682 додано та 323 видалено
  1. 4 0
      include/rtdebug.h
  2. 259 221
      include/rtdef.h
  3. 107 102
      include/rtservice.h
  4. 12 0
      include/rtthread.h
  5. 296 0
      src/memheap.c
  6. 4 0
      src/object.c

+ 4 - 0
include/rtdebug.h

@@ -21,6 +21,10 @@
 #define RT_DEBUG_MEM        0
 #endif
 
+#ifndef RT_DEBUG_MEMHEAP
+#define RT_DEBUG_MEMHEAP	0
+#endif
+
 #ifndef RT_DEBUG_MODULE
 #define RT_DEBUG_MODULE     0
 #endif

+ 259 - 221
include/rtdef.h

@@ -38,7 +38,7 @@ extern "C" {
 
 /* RT-Thread version */
 #define RTTHREAD_VERSION                ((RT_VERSION * 10000) + \
-	(RT_SUBVERSION * 100) + RT_REVISION)
+    (RT_SUBVERSION * 100) + RT_REVISION)
 
 /* RT-Thread basic data type definitions */
 typedef signed   char                   rt_int8_t;      /**<  8bit integer type */
@@ -62,8 +62,8 @@ typedef rt_ubase_t                      rt_dev_t;       /**< Type for device
 typedef rt_base_t                       rt_off_t;       /**< Type for offset            */
 
 /* boolean type definitions */
-#define RT_TRUE                         1   /**< boolean true  */
-#define RT_FALSE                        0   /**< boolean fails */
+#define RT_TRUE                         1               /**< boolean true  */
+#define RT_FALSE                        0               /**< boolean fails */
 
 /*@}*/
 
@@ -75,57 +75,57 @@ typedef rt_base_t                       rt_off_t;       /**< Type for offset
 
 /* Compiler Related Definitions */
 #ifdef __CC_ARM                         /* ARM Compiler */
-	#include <stdarg.h>
-	#define SECTION(x)                  __attribute__((section(x)))
-	#define UNUSED                      __attribute__((unused))
-	#define ALIGN(n)                    __attribute__((aligned(n)))
-	#define rt_inline                   static __inline
-	/* module compiling */
-	#ifdef RT_USING_MODULE
-		#define RTT_API __declspec(dllimport)
-	#else
-		#define RTT_API __declspec(dllexport)
-	#endif
+    #include <stdarg.h>
+    #define SECTION(x)                  __attribute__((section(x)))
+    #define UNUSED                      __attribute__((unused))
+    #define ALIGN(n)                    __attribute__((aligned(n)))
+    #define rt_inline                   static __inline
+    /* module compiling */
+    #ifdef RT_USING_MODULE
+        #define RTT_API __declspec(dllimport)
+    #else
+        #define RTT_API __declspec(dllexport)
+    #endif
 
 #elif defined (__IAR_SYSTEMS_ICC__)     /* for IAR Compiler */
-	#include <stdarg.h>
-	#define SECTION(x)                  @ x
-	#define UNUSED
-	#define PRAGMA(x)                   _Pragma(#x)
-	#define ALIGN(n)                    PRAGMA(data_alignment=n)
-	#define rt_inline                   static inline
-	#define RTT_API
+    #include <stdarg.h>
+    #define SECTION(x)                  @ x
+    #define UNUSED
+    #define PRAGMA(x)                   _Pragma(#x)
+    #define ALIGN(n)                    PRAGMA(data_alignment=n)
+    #define rt_inline                   static inline
+    #define RTT_API
 
 #elif defined (__GNUC__)                /* GNU GCC Compiler */
-	#ifdef RT_USING_NEWLIB
-		#include <stdarg.h>
-	#else
-		#if __GNUC__ < 4
-			typedef void *__sys_va_list;
-			typedef __sys_va_list va_list;
-			#define __va_rounded_size(type)	\
-				(((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
-			#define va_start(ap, lastarg)	\
-				(ap = ((char *) &(lastarg) + __va_rounded_size(lastarg)))
-			#define va_end(ap)	((void)0)
-			/*	little endian */
-			#define va_arg(ap, type)	\
-				(ap = (__sys_va_list) ((char *)(ap) + __va_rounded_size(type)),  \
-				*((type *) (void *) ((char *)(ap) - __va_rounded_size(type))))
-		#else
-			typedef __builtin_va_list __gnuc_va_list;
-			typedef __gnuc_va_list va_list;
-			#define va_start(v,l)   __builtin_va_start(v,l)
-			#define va_end(v)       __builtin_va_end(v)
-			#define va_arg(v,l)     __builtin_va_arg(v,l)
-		#endif
-	#endif
-
-	#define SECTION(x)                  __attribute__((section(x)))
-	#define UNUSED                      __attribute__((unused))
-	#define ALIGN(n)                    __attribute__((aligned(n)))
-	#define rt_inline                   static __inline
-	#define RTT_API
+    #ifdef RT_USING_NEWLIB
+        #include <stdarg.h>
+    #else
+        #if __GNUC__ < 4
+            typedef void *__sys_va_list;
+            typedef __sys_va_list va_list;
+            #define __va_rounded_size(type) \
+                (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
+            #define va_start(ap, lastarg)   \
+                (ap = ((char *) &(lastarg) + __va_rounded_size(lastarg)))
+            #define va_end(ap)  ((void)0)
+            /*  little endian */
+            #define va_arg(ap, type)    \
+                (ap = (__sys_va_list) ((char *)(ap) + __va_rounded_size(type)),  \
+                *((type *) (void *) ((char *)(ap) - __va_rounded_size(type))))
+        #else
+            typedef __builtin_va_list __gnuc_va_list;
+            typedef __gnuc_va_list va_list;
+            #define va_start(v,l)   __builtin_va_start(v,l)
+            #define va_end(v)       __builtin_va_end(v)
+            #define va_arg(v,l)     __builtin_va_arg(v,l)
+        #endif
+    #endif
+
+    #define SECTION(x)                  __attribute__((section(x)))
+    #define UNUSED                      __attribute__((unused))
+    #define ALIGN(n)                    __attribute__((aligned(n)))
+    #define rt_inline                   static __inline
+    #define RTT_API
 #endif
 
 /* event length */
@@ -151,7 +151,7 @@ typedef rt_base_t                       rt_off_t;       /**< Type for offset
 #define RT_ENOMEM                       5               /**< No memory               */
 #define RT_ENOSYS                       6               /**< No system               */
 #define RT_EBUSY                        7               /**< Busy                    */
-#define RT_EIO							8 				/**< IO error 				 */
+#define RT_EIO                          8               /**< IO error                */
 
 /*@}*/
 
@@ -183,8 +183,8 @@ typedef rt_base_t                       rt_off_t;       /**< Type for offset
 
 struct rt_list_node
 {
-	struct rt_list_node                 *next;          /* point to next node. */
-	struct rt_list_node                 *prev;          /* point to prev node. */
+    struct rt_list_node                 *next;          /* point to next node. */
+    struct rt_list_node                 *prev;          /* point to prev node. */
 };
 typedef struct rt_list_node rt_list_t;                  /* Type for lists.     */
 
@@ -204,14 +204,14 @@ typedef struct rt_list_node rt_list_t;                  /* Type for lists.     *
  */
 struct rt_object
 {
-	char        name[RT_NAME_MAX];                      /**< name of kernel object      */
-	rt_uint8_t  type;                                   /**< type of kernel object      */
-	rt_uint8_t  flag;                                   /**< flag of kernel object      */
+    char        name[RT_NAME_MAX];                      /**< name of kernel object      */
+    rt_uint8_t  type;                                   /**< type of kernel object      */
+    rt_uint8_t  flag;                                   /**< flag of kernel object      */
 
 #ifdef RT_USING_MODULE
-	void        *module_id;                             /**< id of application module   */
+    void        *module_id;                             /**< id of application module   */
 #endif
-	rt_list_t   list;                                   /**< list node of kernel object */
+    rt_list_t   list;                                   /**< list node of kernel object */
 };
 typedef struct rt_object *rt_object_t;                  /* Type for kernel objects.     */
 
@@ -232,34 +232,37 @@ typedef struct rt_object *rt_object_t;                  /* Type for kernel objec
  */
 enum rt_object_class_type
 {
-	RT_Object_Class_Thread = 0,                         /**< The object is a thread.                */
+    RT_Object_Class_Thread = 0,                         /**< The object is a thread.                */
 #ifdef RT_USING_SEMAPHORE
-	RT_Object_Class_Semaphore,                          /**< The object is a semaphore.             */
+    RT_Object_Class_Semaphore,                          /**< The object is a semaphore.             */
 #endif
 #ifdef RT_USING_MUTEX
-	RT_Object_Class_Mutex,                              /**< The object is a mutex.                 */
+    RT_Object_Class_Mutex,                              /**< The object is a mutex.                 */
 #endif
 #ifdef RT_USING_EVENT
-	RT_Object_Class_Event,                              /**< The object is a event.                 */
+    RT_Object_Class_Event,                              /**< The object is a event.                 */
 #endif
 #ifdef RT_USING_MAILBOX
-	RT_Object_Class_MailBox,                            /**< The object is a mail box.              */
+    RT_Object_Class_MailBox,                            /**< The object is a mail box.              */
 #endif
 #ifdef RT_USING_MESSAGEQUEUE
-	RT_Object_Class_MessageQueue,                       /**< The object is a message queue.         */
+    RT_Object_Class_MessageQueue,                       /**< The object is a message queue.         */
+#endif
+#ifdef RT_USING_MEMHEAP
+    RT_Object_Class_MemHeap,                            /**< The object is a memory heap            */
 #endif
 #ifdef RT_USING_MEMPOOL
-	RT_Object_Class_MemPool,                            /**< The object is a memory pool.           */
+    RT_Object_Class_MemPool,                            /**< The object is a memory pool.           */
 #endif
 #ifdef RT_USING_DEVICE
-	RT_Object_Class_Device,                             /**< The object is a device                 */
+    RT_Object_Class_Device,                             /**< The object is a device                 */
 #endif
-	RT_Object_Class_Timer,                              /**< The object is a timer.                 */
+    RT_Object_Class_Timer,                              /**< The object is a timer.                 */
 #ifdef RT_USING_MODULE
-	RT_Object_Class_Module,                             /**< The object is a module.                */
+    RT_Object_Class_Module,                             /**< The object is a module.                */
 #endif
-	RT_Object_Class_Unknown,                            /**< The object is unknown.                 */
-	RT_Object_Class_Static = 0x80                       /**< The object is a static object.         */
+    RT_Object_Class_Unknown,                            /**< The object is unknown.                 */
+    RT_Object_Class_Static = 0x80                       /**< The object is a static object.         */
 };
 
 /**
@@ -267,19 +270,19 @@ enum rt_object_class_type
  */
 struct rt_object_information
 {
-	enum rt_object_class_type type;                     /**< object class type                      */
-	rt_list_t object_list;                              /**< object list                            */
-	rt_size_t object_size;                              /**< object size                            */
+    enum rt_object_class_type type;                     /**< object class type                      */
+    rt_list_t object_list;                              /**< object list                            */
+    rt_size_t object_size;                              /**< object size                            */
 };
 
 /**
  * The hook function call macro
  */
 #ifdef RT_USING_HOOK
-#define RT_OBJECT_HOOK_CALL(func, argv)	\
-	do { if ((func) != RT_NULL) func argv; } while (0)
+#define RT_OBJECT_HOOK_CALL(func, argv) \
+    do { if ((func) != RT_NULL) func argv; } while (0)
 #else
-#define RT_OBJECT_HOOK_CALL(func, argv)	
+#define RT_OBJECT_HOOK_CALL(func, argv) 
 #endif
 
 /*@}*/
@@ -311,15 +314,15 @@ struct rt_object_information
  */
 struct rt_timer
 {
-	struct rt_object parent;                            /**< inherit from rt_object                 */
+    struct rt_object parent;                            /**< inherit from rt_object                 */
 
-	rt_list_t list;                                     /**< the node of timer list                 */
+    rt_list_t list;                                     /**< the node of timer list                 */
 
-	void (*timeout_func)(void *parameter);              /**< timeout function                       */
-	void *parameter;                                    /**< timeout function's parameter           */
+    void (*timeout_func)(void *parameter);              /**< timeout function                       */
+    void *parameter;                                    /**< timeout function's parameter           */
 
-	rt_tick_t init_tick;                                /**< timer timeout tick                     */
-	rt_tick_t timeout_tick;                             /**< timeout tick                           */
+    rt_tick_t init_tick;                                /**< timer timeout tick                     */
+    rt_tick_t timeout_tick;                             /**< timeout tick                           */
 };
 typedef struct rt_timer *rt_timer_t;
 
@@ -358,53 +361,53 @@ typedef struct rt_timer *rt_timer_t;
  */
 struct rt_thread
 {
-	/* rt object */
-	char        name[RT_NAME_MAX];                      /**< the name of thread                     */
-	rt_uint8_t  type;                                   /**< type of object                         */
-	rt_uint8_t  flags;                                  /**< thread's flags                         */
-	
+    /* rt object */
+    char        name[RT_NAME_MAX];                      /**< the name of thread                     */
+    rt_uint8_t  type;                                   /**< type of object                         */
+    rt_uint8_t  flags;                                  /**< thread's flags                         */
+    
 #ifdef RT_USING_MODULE
-	void        *module_id;                             /**< id of application module               */
+    void        *module_id;                             /**< id of application module               */
 #endif
 
-	rt_list_t   list;                                   /**< the object list                        */
-	rt_list_t   tlist;                                  /**< the thread list                        */
+    rt_list_t   list;                                   /**< the object list                        */
+    rt_list_t   tlist;                                  /**< the thread list                        */
 
-	/* stack point and entry */
-	void        *sp;                                    /**< stack point                            */
-	void        *entry;                                 /**< entry                                  */
-	void        *parameter;                             /**< parameter                              */
-	void        *stack_addr;                            /**< stack address                          */
-	rt_uint16_t stack_size;                             /**< stack size                             */
+    /* stack point and entry */
+    void        *sp;                                    /**< stack point                            */
+    void        *entry;                                 /**< entry                                  */
+    void        *parameter;                             /**< parameter                              */
+    void        *stack_addr;                            /**< stack address                          */
+    rt_uint16_t stack_size;                             /**< stack size                             */
 
-	/* error code */
-	rt_err_t    error;                                  /**< error code                             */
+    /* error code */
+    rt_err_t    error;                                  /**< error code                             */
 
-	rt_uint8_t  stat;                                   /**< thread stat                            */
+    rt_uint8_t  stat;                                   /**< thread stat                            */
 
-	/* priority */
-	rt_uint8_t  current_priority;                       /**< current priority                       */
-	rt_uint8_t  init_priority;                          /**< initialized priority                   */
+    /* priority */
+    rt_uint8_t  current_priority;                       /**< current priority                       */
+    rt_uint8_t  init_priority;                          /**< initialized priority                   */
 #if RT_THREAD_PRIORITY_MAX > 32
-	rt_uint8_t  number;
-	rt_uint8_t  high_mask;
+    rt_uint8_t  number;
+    rt_uint8_t  high_mask;
 #endif
-	rt_uint32_t number_mask;
+    rt_uint32_t number_mask;
 
 #if defined(RT_USING_EVENT)
-	/* thread event */
-	rt_uint32_t event_set;
-	rt_uint8_t  event_info;
+    /* thread event */
+    rt_uint32_t event_set;
+    rt_uint8_t  event_info;
 #endif
 
-	rt_ubase_t  init_tick;                              /**< thread's initialized tick              */
-	rt_ubase_t  remaining_tick;                         /**< remaining tick                         */
+    rt_ubase_t  init_tick;                              /**< thread's initialized tick              */
+    rt_ubase_t  remaining_tick;                         /**< remaining tick                         */
 
-	struct rt_timer thread_timer;                       /**< built-in thread timer                   */
+    struct rt_timer thread_timer;                       /**< built-in thread timer                   */
 
-	void (*cleanup)(struct rt_thread *tid);             /**< cleanup function when thread exit      */
+    void (*cleanup)(struct rt_thread *tid);             /**< cleanup function when thread exit      */
 
-	rt_uint32_t user_data;                              /**< private user data beyond this thread  */
+    rt_uint32_t user_data;                              /**< private user data beyond this thread  */
 };
 typedef struct rt_thread *rt_thread_t;
 
@@ -433,9 +436,9 @@ typedef struct rt_thread *rt_thread_t;
  */
 struct rt_ipc_object
 {
-	struct rt_object parent;                            /**< inherit from rt_object                 */
+    struct rt_object parent;                            /**< inherit from rt_object                 */
 
-	rt_list_t suspend_thread;                           /**< threads pended on this resource        */
+    rt_list_t suspend_thread;                           /**< threads pended on this resource        */
 };
 
 #ifdef RT_USING_SEMAPHORE
@@ -444,9 +447,9 @@ struct rt_ipc_object
  */
 struct rt_semaphore
 {
-	struct rt_ipc_object parent;                        /**< inherit from ipc_object                */
+    struct rt_ipc_object parent;                        /**< inherit from ipc_object                */
 
-	rt_uint16_t value;                                  /**< value of semaphore.                    */
+    rt_uint16_t value;                                  /**< value of semaphore.                    */
 };
 typedef struct rt_semaphore *rt_sem_t;
 #endif
@@ -457,14 +460,14 @@ typedef struct rt_semaphore *rt_sem_t;
  */
 struct rt_mutex
 {
-	struct rt_ipc_object    parent;                     /**< inherit from ipc_object                */
+    struct rt_ipc_object    parent;                     /**< inherit from ipc_object                */
 
-	rt_uint16_t             value;                      /**< value of mutex                         */
+    rt_uint16_t             value;                      /**< value of mutex                         */
 
-	rt_uint8_t              original_priority;          /**< priority of last thread hold the mutex */
-	rt_uint8_t              hold;                       /**< numbers of thread hold the mutex       */
+    rt_uint8_t              original_priority;          /**< priority of last thread hold the mutex */
+    rt_uint8_t              hold;                       /**< numbers of thread hold the mutex       */
 
-	struct rt_thread        *owner;                     /**< current owner of mutex                 */
+    struct rt_thread        *owner;                     /**< current owner of mutex                 */
 };
 typedef struct rt_mutex *rt_mutex_t;
 #endif
@@ -482,9 +485,9 @@ typedef struct rt_mutex *rt_mutex_t;
  */
 struct rt_event
 {
-	struct rt_ipc_object parent;                        /**< inherit from ipc_object                */
+    struct rt_ipc_object parent;                        /**< inherit from ipc_object                */
 
-	rt_uint32_t set;                                    /**< event set                              */
+    rt_uint32_t set;                                    /**< event set                              */
 };
 typedef struct rt_event *rt_event_t;
 #endif
@@ -496,16 +499,16 @@ typedef struct rt_event *rt_event_t;
  */
 struct rt_mailbox
 {
-	struct rt_ipc_object parent;                        /**< inherit from ipc_object                */
+    struct rt_ipc_object parent;                        /**< inherit from ipc_object                */
 
-	rt_uint32_t *msg_pool;                              /**< start address of message buffer        */
+    rt_uint32_t *msg_pool;                              /**< start address of message buffer        */
 
-	rt_uint16_t size;                                   /**< size of message pool                   */
+    rt_uint16_t size;                                   /**< size of message pool                   */
 
-	rt_uint16_t entry;                                  /**< index of messages in msg_pool          */
-	rt_uint16_t in_offset, out_offset;                  /**< in/output offset of the message buffer */
+    rt_uint16_t entry;                                  /**< index of messages in msg_pool          */
+    rt_uint16_t in_offset, out_offset;                  /**< in/output offset of the message buffer */
 
-	rt_list_t suspend_sender_thread;                    /**< sender thread suspended on this mailbox */
+    rt_list_t suspend_sender_thread;                    /**< sender thread suspended on this mailbox */
 };
 typedef struct rt_mailbox *rt_mailbox_t;
 #endif
@@ -516,18 +519,18 @@ typedef struct rt_mailbox *rt_mailbox_t;
  */
 struct rt_messagequeue
 {
-	struct rt_ipc_object parent;                        /**< inherit from ipc_object                */
+    struct rt_ipc_object parent;                        /**< inherit from ipc_object                */
 
-	void *msg_pool;                                     /**< start address of message queue         */
+    void *msg_pool;                                     /**< start address of message queue         */
 
-	rt_uint16_t msg_size;                               /**< message size of each message           */
-	rt_uint16_t max_msgs;                               /**< max number of messages                 */
+    rt_uint16_t msg_size;                               /**< message size of each message           */
+    rt_uint16_t max_msgs;                               /**< max number of messages                 */
 
-	rt_uint16_t entry;                                  /**< index of messages in the queue         */
+    rt_uint16_t entry;                                  /**< index of messages in the queue         */
 
-	void *msg_queue_head;                               /**< list head                              */
-	void *msg_queue_tail;                               /**< list tail                              */
-	void *msg_queue_free;                               /**< pointer indicated the free node of queue */
+    void *msg_queue_head;                               /**< list head                              */
+    void *msg_queue_tail;                               /**< list tail                              */
+    void *msg_queue_free;                               /**< pointer indicated the free node of queue */
 };
 typedef struct rt_messagequeue *rt_mq_t;
 #endif
@@ -546,24 +549,57 @@ typedef struct rt_messagequeue *rt_mq_t;
  * heap & partition
  */
 
+/**
+ * memory item on the heap
+ */
+struct rt_memheap_item
+{
+    rt_uint32_t magic;
+    struct rt_memheap_item *next, *prev;
+    struct rt_memheap_item *next_free, *prev_free;
+
+    struct rt_memheap* pool_ptr;
+};
+
+/**
+ * Base structure of memory heap object
+ */
+struct rt_memheap
+{
+    struct rt_object parent;
+
+    /* pool start address and size */
+    void *start_addr;
+
+    rt_uint32_t pool_size;
+    rt_uint32_t available_size;
+
+    /* used block list */
+    struct rt_memheap_item* block_list;
+
+    /* free block list and free block list header */
+    struct rt_memheap_item* free_list;
+    struct rt_memheap_item  free_header;
+};
+
 /**
  * Base structure of Memory pool object
  */
 struct rt_mempool
 {
-	struct rt_object parent;                        /**< inherit from rt_object                     */
+    struct rt_object parent;                        /**< inherit from rt_object                     */
 
-	void        *start_address;                     /**< memory pool start                          */
-	rt_size_t   size;                               /**< size of memory pool                        */
+    void        *start_address;                     /**< memory pool start                          */
+    rt_size_t   size;                               /**< size of memory pool                        */
 
-	rt_size_t   block_size;                         /**< size of memory blocks                      */
-	rt_uint8_t  *block_list;                        /**< memory blocks list                         */
+    rt_size_t   block_size;                         /**< size of memory blocks                      */
+    rt_uint8_t  *block_list;                        /**< memory blocks list                         */
 
-	rt_size_t   block_total_count;                  /**< numbers of memory block                    */
-	rt_size_t   block_free_count;                   /**< numbers of free memory block               */
+    rt_size_t   block_total_count;                  /**< numbers of memory block                    */
+    rt_size_t   block_free_count;                   /**< numbers of free memory block               */
 
-	rt_list_t   suspend_thread;                     /**< threads pended on this resource            */
-	rt_size_t   suspend_thread_count;               /**< numbers of thread pended on this resource  */
+    rt_list_t   suspend_thread;                     /**< threads pended on this resource            */
+    rt_size_t   suspend_thread_count;               /**< numbers of thread pended on this resource  */
 };
 typedef struct rt_mempool *rt_mp_t;
 
@@ -582,21 +618,21 @@ typedef struct rt_mempool *rt_mp_t;
  */
 enum rt_device_class_type
 {
-	RT_Device_Class_Char = 0,                       /**< character device                           */
-	RT_Device_Class_Block,                          /**< block device                               */
-	RT_Device_Class_NetIf,                          /**< net interface                              */
-	RT_Device_Class_MTD,                            /**< memory device                              */
-	RT_Device_Class_CAN,                            /**< CAN device                                 */
-	RT_Device_Class_RTC,                            /**< RTC device                                 */
-	RT_Device_Class_Sound,                          /**< Sound device                               */
-	RT_Device_Class_Graphic,                        /**< Graphic device                             */
-	RT_Device_Class_I2C,                            /**< I2C device                                 */
-	RT_Device_Class_USBDevice,                      /**< USB slave device                           */
-	RT_Device_Class_USBHost,                        /**< USB host bus                               */
-	RT_Device_Class_SPIBUS, 						/**< SPI bus device                             */
-	RT_Device_Class_SPIDevice,                      /**< SPI device                                 */
-	RT_Device_Class_SDIO, 							/**< SDIO bus device                            */
-	RT_Device_Class_Unknown                         /**< unknown device                             */
+    RT_Device_Class_Char = 0,                       /**< character device                           */
+    RT_Device_Class_Block,                          /**< block device                               */
+    RT_Device_Class_NetIf,                          /**< net interface                              */
+    RT_Device_Class_MTD,                            /**< memory device                              */
+    RT_Device_Class_CAN,                            /**< CAN device                                 */
+    RT_Device_Class_RTC,                            /**< RTC device                                 */
+    RT_Device_Class_Sound,                          /**< Sound device                               */
+    RT_Device_Class_Graphic,                        /**< Graphic device                             */
+    RT_Device_Class_I2C,                            /**< I2C device                                 */
+    RT_Device_Class_USBDevice,                      /**< USB slave device                           */
+    RT_Device_Class_USBHost,                        /**< USB host bus                               */
+    RT_Device_Class_SPIBUS,                         /**< SPI bus device                             */
+    RT_Device_Class_SPIDevice,                      /**< SPI device                                 */
+    RT_Device_Class_SDIO,                           /**< SDIO bus device                            */
+    RT_Device_Class_Unknown                         /**< unknown device                             */
 };
 
 /**
@@ -647,29 +683,31 @@ typedef struct rt_device *rt_device_t;
  */
 struct rt_device
 {
-	struct rt_object parent;                        /**< inherit from rt_object                     */
+    struct rt_object parent;                        /**< inherit from rt_object                     */
+
+    enum rt_device_class_type type;                 /**< device type                                */
+    rt_uint16_t flag, open_flag;                    /**< device flag and device open flag           */
 
-	enum rt_device_class_type type;                 /**< device type                                */
-	rt_uint16_t flag, open_flag;                    /**< device flag and device open flag           */
+    rt_uint8_t device_id;                           /* 0 - 255 */
 
-	/* device call back */
-	rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
-	rt_err_t (*tx_complete)(rt_device_t dev, void* buffer);
+    /* device call back */
+    rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
+    rt_err_t (*tx_complete)(rt_device_t dev, void* buffer);
 
-	/* common device interface */
-	rt_err_t  (*init)   (rt_device_t dev);
-	rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
-	rt_err_t  (*close)  (rt_device_t dev);
-	rt_size_t (*read)   (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
-	rt_size_t (*write)  (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
-	rt_err_t  (*control)(rt_device_t dev, rt_uint8_t cmd, void *args);
+    /* common device interface */
+    rt_err_t  (*init)   (rt_device_t dev);
+    rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
+    rt_err_t  (*close)  (rt_device_t dev);
+    rt_size_t (*read)   (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
+    rt_size_t (*write)  (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
+    rt_err_t  (*control)(rt_device_t dev, rt_uint8_t cmd, void *args);
 
 #ifdef RT_USING_DEVICE_SUSPEND
-	rt_err_t (*suspend) (rt_device_t dev);
-	rt_err_t (*resumed) (rt_device_t dev);
+    rt_err_t (*suspend) (rt_device_t dev);
+    rt_err_t (*resumed) (rt_device_t dev);
 #endif
 
-	void *user_data;                                /**< device private data                        */
+    void *user_data;                                /**< device private data                        */
 };
 
 /**
@@ -677,9 +715,9 @@ struct rt_device
  */
 struct rt_device_blk_geometry
 {
-	rt_uint32_t sector_count;                       /**< count of sectors                           */
-	rt_uint32_t bytes_per_sector;                   /**< number of bytes per sector                 */
-	rt_uint32_t block_size;                         /**< size to erase one block                    */
+    rt_uint32_t sector_count;                       /**< count of sectors                           */
+    rt_uint32_t bytes_per_sector;                   /**< number of bytes per sector                 */
+    rt_uint32_t block_size;                         /**< size to erase one block                    */
 };
 
 /**
@@ -694,36 +732,36 @@ struct rt_device_blk_geometry
 /* graphic deice */
 enum
 {
-	RTGRAPHIC_PIXEL_FORMAT_MONO = 0,
-	RTGRAPHIC_PIXEL_FORMAT_GRAY4,
-	RTGRAPHIC_PIXEL_FORMAT_GRAY16,
-	RTGRAPHIC_PIXEL_FORMAT_RGB332,
-	RTGRAPHIC_PIXEL_FORMAT_RGB444,
-	RTGRAPHIC_PIXEL_FORMAT_RGB565,
-	RTGRAPHIC_PIXEL_FORMAT_RGB565P,
-	RTGRAPHIC_PIXEL_FORMAT_RGB666,
-	RTGRAPHIC_PIXEL_FORMAT_RGB888,
-	RTGRAPHIC_PIXEL_FORMAT_ARGB888
+    RTGRAPHIC_PIXEL_FORMAT_MONO = 0,
+    RTGRAPHIC_PIXEL_FORMAT_GRAY4,
+    RTGRAPHIC_PIXEL_FORMAT_GRAY16,
+    RTGRAPHIC_PIXEL_FORMAT_RGB332,
+    RTGRAPHIC_PIXEL_FORMAT_RGB444,
+    RTGRAPHIC_PIXEL_FORMAT_RGB565,
+    RTGRAPHIC_PIXEL_FORMAT_RGB565P,
+    RTGRAPHIC_PIXEL_FORMAT_RGB666,
+    RTGRAPHIC_PIXEL_FORMAT_RGB888,
+    RTGRAPHIC_PIXEL_FORMAT_ARGB888
 };
 
 /**
  * build a pixel position according to (x, y) coordinates.
  */
-#define RTGRAPHIC_PIXEL_POSITION(x, y)	((x << 16) | y)
+#define RTGRAPHIC_PIXEL_POSITION(x, y)  ((x << 16) | y)
 
 /**
  * graphic device information structure
  */
 struct rt_device_graphic_info
 {
-	rt_uint8_t  pixel_format;       /**< graphic format           */
-	rt_uint8_t  bits_per_pixel;     /**< bits per pixel           */
-	rt_uint16_t reserved;           /**< reserved field           */
+    rt_uint8_t  pixel_format;       /**< graphic format           */
+    rt_uint8_t  bits_per_pixel;     /**< bits per pixel           */
+    rt_uint16_t reserved;           /**< reserved field           */
 
-	rt_uint16_t width;              /**< width of graphic device  */
-	rt_uint16_t height;             /**< height of graphic device */
+    rt_uint16_t width;              /**< width of graphic device  */
+    rt_uint16_t height;             /**< height of graphic device */
 
-	rt_uint8_t *framebuffer;        /**< frame buffer             */
+    rt_uint8_t *framebuffer;        /**< frame buffer             */
 };
 
 /**
@@ -731,8 +769,8 @@ struct rt_device_graphic_info
  */
 struct rt_device_rect_info
 {
-	rt_uint16_t x, y;               /**< x, y coordinate          */
-	rt_uint16_t width, height;      /**< width and height         */
+    rt_uint16_t x, y;               /**< x, y coordinate          */
+    rt_uint16_t width, height;      /**< width and height         */
 };
 
 /**
@@ -740,13 +778,13 @@ struct rt_device_rect_info
  */
 struct rt_device_graphic_ops
 {
-	void (*set_pixel) (const char *pixel, int x, int y);
-	void (*get_pixel) (char *pixel, int x, int y);
+    void (*set_pixel) (const char *pixel, int x, int y);
+    void (*get_pixel) (char *pixel, int x, int y);
 
-	void (*draw_hline)(const char *pixel, int x1, int x2, int y);
-	void (*draw_vline)(const char *pixel, int x, int y1, int y2);
+    void (*draw_hline)(const char *pixel, int x1, int x2, int y);
+    void (*draw_vline)(const char *pixel, int x, int y1, int y2);
 
-	void (*blit_line) (const char *pixel, int x, int y, rt_size_t size);
+    void (*blit_line) (const char *pixel, int x, int y, rt_size_t size);
 };
 #define rt_graphix_ops(device)    ((struct rt_device_graphic_ops *)(device->user_data))
 
@@ -772,29 +810,29 @@ struct rt_device_graphic_ops
  */
 struct rt_module
 {
-	struct rt_object parent;                        /**< inherit from object                        */
+    struct rt_object parent;                        /**< inherit from object                        */
 
-	rt_uint8_t  *module_space;                      /**< module memory space                        */
+    rt_uint8_t  *module_space;                      /**< module memory space                        */
 
-	void        *module_entry;                      /**< entry address of module's thread           */
-	rt_thread_t module_thread;                      /**< stack size of module's thread              */
-	rt_uint32_t stack_size;                         /**< priority of module's thread                */
-	rt_uint32_t thread_priority;
+    void        *module_entry;                      /**< entry address of module's thread           */
+    rt_thread_t module_thread;                      /**< stack size of module's thread              */
+    rt_uint32_t stack_size;                         /**< priority of module's thread                */
+    rt_uint32_t thread_priority;
 
 #ifdef RT_USING_SLAB
-	/* module memory allocator */
-	void        *mem_list;                          /**< module's free memory list                  */
-	void        *page_array;                        /**< module's using pages                       */
-	rt_uint32_t page_cnt;                           /**< module's using pages count                 */
+    /* module memory allocator */
+    void        *mem_list;                          /**< module's free memory list                  */
+    void        *page_array;                        /**< module's using pages                       */
+    rt_uint32_t page_cnt;                           /**< module's using pages count                 */
 #endif
 
-	rt_uint32_t nsym;                               /**< number of symbol in the module             */
-	struct rt_module_symtab *symtab;                /**< module symbol table                        */
+    rt_uint32_t nsym;                               /**< number of symbol in the module             */
+    struct rt_module_symtab *symtab;                /**< module symbol table                        */
 
-	rt_uint32_t nref;                               /**< reference count                            */
-	
-	/**< object in this module, module object is the last basic object type */
-	struct rt_object_information module_object[RT_Object_Class_Unknown];
+    rt_uint32_t nref;                               /**< reference count                            */
+    
+    /**< object in this module, module object is the last basic object type */
+    struct rt_object_information module_object[RT_Object_Class_Unknown];
 };
 typedef struct rt_module *rt_module_t;
 

+ 107 - 102
include/rtservice.h

@@ -1,102 +1,107 @@
-/*
- * File      : rtservice.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2006-03-16     Bernard      the first version
- * 2006-09-07     Bernard      move the kservice APIs to rtthread.h
- * 2007-06-27     Bernard      fix the rt_list_remove bug
- * 2012-03-22     Bernard      rename kservice.h to rtservice.h
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @addtogroup KernelService
- */
-
-/*@{*/
-
-/**
- * @brief initialize a list
- *
- * @param l list to be initialized
- */
-rt_inline void rt_list_init(rt_list_t *l)
-{
-	l->next = l->prev = l;
-}
-
-/**
- * @brief insert a node after a list
- *
- * @param l list to insert it
- * @param n new node to be inserted
- */
-rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
-{
-	l->next->prev = n;
-	n->next = l->next;
-
-	l->next = n;
-	n->prev = l;
-}
-
-/**
- * @brief insert a node before a list
- *
- * @param n new node to be inserted
- * @param l list to insert it
- */
-rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
-{
-	l->prev->next = n;
-	n->prev = l->prev;
-
-	l->prev = n;
-	n->next = l;
-}
-
-/**
- * @brief remove node from list.
- * @param n the node to remove from the list.
- */
-rt_inline void rt_list_remove(rt_list_t *n)
-{
-	n->next->prev = n->prev;
-	n->prev->next = n->next;
-
-	n->next = n->prev = n;
-}
-
-/**
- * @brief tests whether a list is empty
- * @param l the list to test.
- */
-rt_inline int rt_list_isempty(const rt_list_t *l)
-{
-	return l->next == l;
-}
-
-/**
- * @brief get the struct for this entry
- * @param node the entry point
- * @param type the type of structure
- * @param member the name of list in structure
- */
-#define rt_list_entry(node, type, member) \
-    ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
-
-/*@}*/
-
-#ifdef __cplusplus
-}
-#endif
+/*
+ * File      : rtservice.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-16     Bernard      the first version
+ * 2006-09-07     Bernard      move the kservice APIs to rtthread.h
+ * 2007-06-27     Bernard      fix the rt_list_remove bug
+ * 2012-03-22     Bernard      rename kservice.h to rtservice.h
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup KernelService
+ */
+
+/*@{*/
+
+/**
+ * @brief initialize a list object
+ */
+#define RT_LIST_OBJECT_INIT(object) { &(object), &(object) }
+
+/**
+ * @brief initialize a list
+ *
+ * @param l list to be initialized
+ */
+rt_inline void rt_list_init(rt_list_t *l)
+{
+	l->next = l->prev = l;
+}
+
+/**
+ * @brief insert a node after a list
+ *
+ * @param l list to insert it
+ * @param n new node to be inserted
+ */
+rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
+{
+	l->next->prev = n;
+	n->next = l->next;
+
+	l->next = n;
+	n->prev = l;
+}
+
+/**
+ * @brief insert a node before a list
+ *
+ * @param n new node to be inserted
+ * @param l list to insert it
+ */
+rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
+{
+	l->prev->next = n;
+	n->prev = l->prev;
+
+	l->prev = n;
+	n->next = l;
+}
+
+/**
+ * @brief remove node from list.
+ * @param n the node to remove from the list.
+ */
+rt_inline void rt_list_remove(rt_list_t *n)
+{
+	n->next->prev = n->prev;
+	n->prev->next = n->next;
+
+	n->next = n->prev = n;
+}
+
+/**
+ * @brief tests whether a list is empty
+ * @param l the list to test.
+ */
+rt_inline int rt_list_isempty(const rt_list_t *l)
+{
+	return l->next == l;
+}
+
+/**
+ * @brief get the struct for this entry
+ * @param node the entry point
+ * @param type the type of structure
+ * @param member the name of list in structure
+ */
+#define rt_list_entry(node, type, member) \
+    ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
+
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif

+ 12 - 0
include/rtthread.h

@@ -207,6 +207,18 @@ void rt_free_sethook(void (*hook)(void *ptr));
 
 #endif
 
+#ifdef RT_USING_MEMHEAP
+/**
+ * memory heap object interface
+ */
+rt_err_t rt_memheap_init(struct rt_memheap* memheap, const char* name,
+	void *start_addr, rt_uint32_t size);
+rt_err_t rt_memheap_detach(struct rt_memheap* heap);
+void* rt_memheap_alloc(struct rt_memheap *heap, 	rt_uint32_t size);
+void rt_memheap_free(void* ptr);
+
+#endif
+
 /*@}*/
 
 /**

+ 296 - 0
src/memheap.c

@@ -0,0 +1,296 @@
+/*
+ * File      : memheap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-04-10     Bernard      first implementation
+ */
+#include <rtthread.h>
+
+#ifdef RT_USING_MEMHEAP
+
+/* dynamic pool magic and mask */
+#define RT_MEMHEAP_MAGIC		0x1ea01ea0
+#define RT_MEMHEAP_MASK		0xfffffffe
+#define RT_MEMHEAP_USED		0x01
+#define RT_MEMHEAP_FREED		0x00
+
+#define RT_MEMHEAP_IS_USED(i)	((i)->magic & RT_MEMHEAP_USED)
+#define RT_MEMHEAP_MINIALLOC	12
+
+#define RT_MEMHEAP_SIZE		RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE)
+
+/*
+ * The initialized memory pool will be:
+ * +-----------------------------------+--------------------------+
+ * | whole freed memory block          | Used Memory Block Tailer |
+ * +-----------------------------------+--------------------------+
+ *
+ * block_list --> whole freed memory block
+ *
+ * The length of Used Memory Block Tailer is 0, which is prevents block merging across list
+ */
+rt_err_t rt_memheap_init(struct rt_memheap* memheap, const char* name,
+	void *start_addr,
+	rt_uint32_t size)
+{
+	struct rt_memheap_item *item;
+
+	RT_ASSERT(memheap != RT_NULL);
+
+	/* initialize pool object */
+	rt_object_init(&(memheap->parent), RT_Object_Class_MemHeap, name);
+
+	memheap->start_addr = start_addr;
+	memheap->pool_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
+    memheap->available_size = memheap->pool_size - (2 * RT_MEMHEAP_SIZE);
+
+	/* initialize the free list header */
+	item = &(memheap->free_header);
+    item->magic = RT_MEMHEAP_MAGIC;
+    item->pool_ptr = memheap;
+    item->next = RT_NULL;
+    item->prev = RT_NULL;
+    item->next_free = item;
+    item->prev_free = item;
+
+	/* set the free list to free list header */
+	memheap->free_list = item;
+
+	/* initialize the first big memory block */
+	item = (struct rt_memheap_item*) start_addr;
+    item->magic = RT_MEMHEAP_MAGIC;
+    item->pool_ptr = memheap;
+    item->next = RT_NULL;
+    item->prev = RT_NULL;
+    item->next_free = item;
+    item->prev_free = item;
+
+    item->next = (struct rt_memheap_item *)
+           ((rt_uint8_t*) item + memheap->available_size + RT_MEMHEAP_SIZE);
+    item->prev =  item->next;
+
+	/* block list header */
+	memheap->block_list = item;
+
+	/* place the big memory block to free list */
+	item->next_free = memheap->free_list->next_free;
+	item->prev_free = memheap->free_list;
+	memheap->free_list->next_free->prev_free = item;
+	memheap->free_list->next_free = item;
+
+	/* move to the end of memory pool to build a small tailer block, which prevents block merging */
+    item =  item->next;
+	/* it's a used memory block */
+    item->magic = RT_MEMHEAP_MAGIC | RT_MEMHEAP_USED;
+    item->pool_ptr = memheap;
+    item->next = (struct rt_memheap_item *) start_addr;
+    item->prev = (struct rt_memheap_item *) start_addr;
+	/* not in free list */
+    item->next_free = item->prev_free = RT_NULL;
+
+    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)));
+
+    return RT_EOK;
+}
+
+rt_err_t rt_memheap_detach(struct rt_memheap* heap)
+{
+	rt_object_detach(&(heap->parent));
+
+    /* Return a successful completion.  */
+    return RT_EOK;
+}
+
+void* rt_memheap_alloc(struct rt_memheap *pool_ptr, rt_uint32_t size)
+{
+	rt_uint32_t free_size;
+	struct rt_memheap_item *header_ptr;
+
+	RT_ASSERT(pool_ptr != RT_NULL);
+
+	/* align allocated size */
+	size = RT_ALIGN(size, RT_ALIGN_SIZE);
+	if (size < RT_MEMHEAP_MINIALLOC) size = RT_MEMHEAP_MINIALLOC;
+
+	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate %d", size));
+
+	if (size < pool_ptr->available_size)
+	{
+		/* search on free list */
+		free_size = 0;
+		/* get the first free memory block */
+		header_ptr = pool_ptr->free_list->next_free;
+		while (header_ptr != pool_ptr->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;
+
+			if (free_size < size)
+			{
+				/* move to next free memory block */
+				header_ptr = header_ptr->next_free;
+			}
+		}
+
+		/* determine if the memory is available.  */
+		if (free_size >= size)
+		{
+			/* a block that satisfies the request has been found.  */
+
+			/* determine if the block needs to be split.  */
+			if (free_size >= (size + RT_MEMHEAP_SIZE + RT_MEMHEAP_MINIALLOC))
+			{
+				struct rt_memheap_item* new_ptr;
+
+				/* split the block.  */
+				new_ptr =  (struct rt_memheap_item*) (((rt_uint8_t*) header_ptr) + size + RT_MEMHEAP_SIZE);
+
+				RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("split: h[0x%08x] nm[0x%08x] pm[0x%08x] to n[0x%08x]", header_ptr,
+					header_ptr->next, header_ptr->prev,
+					new_ptr));
+
+				/* mark the new block as a memory block and freed. */
+				new_ptr->magic = RT_MEMHEAP_MAGIC;
+
+				/* put the pool pointer into the new block.  */
+				new_ptr->pool_ptr = pool_ptr;
+
+				/* break down the block list */
+				new_ptr->prev = header_ptr;
+				new_ptr->next = header_ptr->next;
+				header_ptr->next->prev = new_ptr;
+				header_ptr->next = new_ptr;
+
+				/* remove header ptr from free list */
+				header_ptr->next_free->prev_free = header_ptr->prev_free;
+				header_ptr->prev_free->next_free = header_ptr->next_free;
+				header_ptr->next_free = RT_NULL;
+				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;
+				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;
+			}
+			else
+			{
+				/* decrement the entire free size from the available bytes count.  */
+				pool_ptr->available_size =  pool_ptr->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,
+					header_ptr->next_free, header_ptr->prev_free));
+
+				header_ptr->next_free->prev_free = header_ptr->prev_free;
+				header_ptr->prev_free->next_free = header_ptr->next_free;
+				header_ptr->next_free = RT_NULL;
+				header_ptr->prev_free = RT_NULL;
+			}
+
+			/* Mark the allocated block as not available.  */
+			header_ptr->magic |=  RT_MEMHEAP_USED;
+
+			/* Return a memory address to the caller.  */
+			RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("am: m[0x%08x], h[0x%08x], size: %d",
+					(void*) ((rt_uint8_t*)header_ptr + RT_MEMHEAP_SIZE), header_ptr, size);
+			return (void*) ((rt_uint8_t*)header_ptr + RT_MEMHEAP_SIZE));
+		}
+	}
+
+	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate memory: failed\n"));
+
+    /* Return the completion status.  */
+    return RT_NULL;
+}
+
+void rt_memheap_free(void* ptr)
+{
+	struct rt_memheap *pool_ptr;
+	struct rt_memheap_item *header_ptr, *new_ptr;
+	rt_uint32_t insert_header;
+
+	/* set initial status as OK */
+	insert_header = 1; new_ptr = RT_NULL;
+	header_ptr = (struct rt_memheap_item*)((rt_uint8_t*)ptr - RT_MEMHEAP_SIZE);
+
+	RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: m[0x%08x], h[0x%08x]", ptr, header_ptr));
+
+	/* check magic */
+	RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
+
+	/* get pool ptr */
+	pool_ptr = header_ptr->pool_ptr;
+
+    /* 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 +
+                        ((rt_uint32_t)(header_ptr->next) -
+                        (rt_uint32_t)header_ptr) - RT_MEMHEAP_SIZE;
+
+    /* Determine if the block can be merged with the previous neighbor.  */
+    if (!RT_MEMHEAP_IS_USED(header_ptr->prev))
+    {
+    	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;
+
+        /* yes, merge block with previous neighbor.  */
+        (header_ptr->prev)->next = header_ptr->next;
+        (header_ptr->next)->prev = header_ptr->prev;
+
+        /* move header pointer to previous.  */
+        header_ptr = header_ptr->prev;
+		insert_header = 0;	/* don't insert header to free list */
+    }
+
+    /* determine if the block can be merged with the next neighbor.  */
+    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;
+
+        /* merge block with next neighbor.  */
+        new_ptr =  header_ptr->next;
+
+        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("merge: right node 0x%08x, nf 0x%08x, pf 0x%08x",
+        		new_ptr, new_ptr->next_free, new_ptr->prev_free));
+
+        new_ptr->next->prev = header_ptr;
+        header_ptr->next = new_ptr->next;
+
+		/* remove new ptr from free list */
+		new_ptr->next_free->prev_free = new_ptr->prev_free;
+		new_ptr->prev_free->next_free = new_ptr->next_free;
+    }
+
+	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;
+
+		RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("insert to free list: nf 0x%08x, pf 0x%08x",
+				header_ptr->next_free, header_ptr->prev_free));
+	}
+}
+
+#endif

+ 4 - 0
src/object.c

@@ -46,6 +46,10 @@ struct rt_object_information rt_object_container[RT_Object_Class_Unknown] =
 	/* initialize object container - message queue */
 	{RT_Object_Class_MessageQueue, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MessageQueue), sizeof(struct rt_messagequeue)},
 #endif
+#ifdef RT_USING_MEMHEAP
+	/* initialize object container - memory heap */
+	{RT_Object_Class_MemHeap, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemHeap), sizeof(struct rt_memheap)},
+#endif
 #ifdef RT_USING_MEMPOOL
 	/* initialize object container - memory pool */
 	{RT_Object_Class_MemPool, _OBJ_CONTAINER_LIST_INIT(RT_Object_Class_MemPool), sizeof(struct rt_mempool)},