浏览代码

Merge pull request #1521 from RT-Thread/feature_v310

Feature v310
Bernard Xiong 7 年之前
父节点
当前提交
b110d77d8f
共有 71 个文件被更改,包括 4500 次插入1289 次删除
  1. 19 2
      bsp/qemu-vexpress-a9/drivers/drv_clcd.c
  2. 16 9
      bsp/qemu-vexpress-a9/drivers/drv_smc911x.c
  3. 5 0
      bsp/stm32f411-nucleo/Kconfig
  4. 0 9
      bsp/stm32f411-nucleo/drivers/stm32f4xx_it.c
  5. 6 0
      bsp/stm32f411-nucleo/stm32_rom.ld
  6. 2 0
      components/Kconfig
  7. 8 0
      components/dfs/include/dfs.h
  8. 117 16
      components/dfs/src/dfs.c
  9. 21 5
      components/drivers/audio/audio.c
  10. 18 2
      components/drivers/audio/audio_pipe.c
  11. 17 0
      components/drivers/can/can.c
  12. 20 4
      components/drivers/hwtimer/hwtimer.c
  13. 17 0
      components/drivers/i2c/fm24clxx.c
  14. 16 0
      components/drivers/i2c/i2c_dev.c
  15. 18 0
      components/drivers/misc/pin.c
  16. 16 0
      components/drivers/mtd/mtd_nand.c
  17. 16 0
      components/drivers/mtd/mtd_nor.c
  18. 16 0
      components/drivers/rtc/soft_rtc.c
  19. 21 4
      components/drivers/sdio/block_dev.c
  20. 16 0
      components/drivers/serial/serial.c
  21. 16 0
      components/drivers/spi/enc28j60.c
  22. 33 1
      components/drivers/spi/spi_dev.c
  23. 17 1
      components/drivers/spi/spi_flash_gd.c
  24. 17 1
      components/drivers/spi/spi_flash_sfud.c
  25. 16 0
      components/drivers/spi/spi_flash_sst25vfxx.c
  26. 16 0
      components/drivers/spi/spi_flash_w25qxx.c
  27. 38 0
      components/drivers/spi/spi_msd.c
  28. 16 0
      components/drivers/spi/spi_wifi_rw009.c
  29. 16 0
      components/drivers/src/pipe.c
  30. 13 0
      components/drivers/usb/usbdevice/class/ecm.c
  31. 20 1
      components/drivers/usb/usbdevice/class/hid.c
  32. 19 2
      components/drivers/usb/usbdevice/class/rndis.c
  33. 18 0
      components/drivers/usb/usbdevice/class/winusb.c
  34. 97 81
      components/drivers/usb/usbhost/class/adk.c
  35. 90 70
      components/drivers/usb/usbhost/class/udisk.c
  36. 16 0
      components/drivers/watchdog/watchdog.c
  37. 0 107
      components/finsh/cmd.c
  38. 1 1
      components/finsh/msh.c
  39. 2 0
      components/libc/compilers/newlib/libc.c
  40. 2 0
      components/libc/compilers/newlib/stdio.c
  41. 6 29
      components/libc/compilers/newlib/syscalls.c
  42. 7 0
      components/lwp/Kconfig
  43. 20 0
      components/lwp/SConscript
  44. 176 0
      components/lwp/arch/arm/cortex-m3/lwp_gcc.S
  45. 176 0
      components/lwp/arch/arm/cortex-m3/lwp_iar.S
  46. 184 0
      components/lwp/arch/arm/cortex-m3/lwp_rvds.S
  47. 210 0
      components/lwp/arch/arm/cortex-m4/lwp_gcc.S
  48. 215 0
      components/lwp/arch/arm/cortex-m4/lwp_iar.S
  49. 219 0
      components/lwp/arch/arm/cortex-m4/lwp_rvds.S
  50. 210 0
      components/lwp/arch/arm/cortex-m7/lwp_gcc.S
  51. 215 0
      components/lwp/arch/arm/cortex-m7/lwp_iar.S
  52. 219 0
      components/lwp/arch/arm/cortex-m7/lwp_rvds.S
  53. 364 0
      components/lwp/lwp.c
  54. 83 0
      components/lwp/lwp.h
  55. 232 0
      components/lwp/lwp_mem.c
  56. 34 0
      components/lwp/lwp_mem.h
  57. 590 0
      components/lwp/lwp_memheap.c
  58. 74 0
      components/lwp/lwp_memheap.h
  59. 242 0
      components/lwp/lwp_syscall.c
  60. 78 0
      components/lwp/lwp_syscall.h
  61. 16 0
      components/utilities/logtrace/log_file.c
  62. 16 0
      components/utilities/logtrace/log_trace.c
  63. 17 2
      include/rtdef.h
  64. 4 0
      src/Kconfig
  65. 33 15
      src/device.c
  66. 2 26
      src/idle.c
  67. 4 18
      src/ipc.c
  68. 2 9
      src/mempool.c
  69. 2 773
      src/module.c
  70. 2 82
      src/object.c
  71. 0 19
      src/slab.c

+ 19 - 2
bsp/qemu-vexpress-a9/drivers/drv_clcd.c

@@ -5,8 +5,8 @@
 #include <rtthread.h>
 #include "drv_clcd.h"
 
-#define CLCD_WIDTH  480
-#define CLCD_HEIGHT 320
+#define CLCD_WIDTH  640
+#define CLCD_HEIGHT 480
 
 #define CLCD_DEVICE(dev)    (struct drv_clcd_device*)(dev)
 
@@ -78,6 +78,18 @@ static rt_err_t drv_clcd_control(struct rt_device *device, int cmd, void *args)
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops clcd_ops = 
+{
+    drv_clcd_init,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    drv_clcd_control
+};
+#endif
+
 int drv_clcd_hw_init(void)
 {
     PL111MMIO   *plio;
@@ -107,8 +119,13 @@ int drv_clcd_hw_init(void)
     plio->control = 0x1921 | (0x6 << 1);
 
     device->type    = RT_Device_Class_Graphic;
+#ifdef RT_USING_DEVICE_OPS
+    device->ops     = &clcd_ops;
+#else
     device->init    = drv_clcd_init;
     device->control = drv_clcd_control;
+#endif
+
     rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR);
 
     return 0;

+ 16 - 9
bsp/qemu-vexpress-a9/drivers/drv_smc911x.c

@@ -485,6 +485,18 @@ struct pbuf *smc911x_emac_rx(rt_device_t dev)
     return p;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops smc911x_emac_ops = 
+{
+    smc911x_emac_init,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    smc911x_emac_control
+};
+#endif
+
 int smc911x_emac_hw_init(void)
 {
     _emac.iobase = VEXPRESS_ETH_BASE;
@@ -507,12 +519,16 @@ int smc911x_emac_hw_init(void)
     _emac.enetaddr[4] = 0x22;
     _emac.enetaddr[5] = 0x33;
 
+#ifdef RT_USING_DEVICE_OPS
+    _emac.parent.parent.ops        = &smc911x_emac_ops;
+#else
     _emac.parent.parent.init       = smc911x_emac_init;
     _emac.parent.parent.open       = RT_NULL;
     _emac.parent.parent.close      = RT_NULL;
     _emac.parent.parent.read       = RT_NULL;
     _emac.parent.parent.write      = RT_NULL;
     _emac.parent.parent.control    = smc911x_emac_control;
+#endif
     _emac.parent.parent.user_data  = RT_NULL;
     _emac.parent.eth_rx     = smc911x_emac_rx;
     _emac.parent.eth_tx     = smc911x_emac_tx;
@@ -540,12 +556,3 @@ int smc911x_emac_hw_init(void)
     return 0;
 }
 INIT_APP_EXPORT(smc911x_emac_hw_init);
-
-#include <finsh.h>
-int emac(int argc, char** argv)
-{
-    rt_hw_interrupt_umask(_emac.irqno);
-
-    return 0;
-}
-MSH_CMD_EXPORT(emac, emac dump);

+ 5 - 0
bsp/stm32f411-nucleo/Kconfig

@@ -15,6 +15,11 @@ config $PKGS_DIR
     option env="PKGS_ROOT"
     default "packages"
 
+config BOARD_STM32F411_NUCLEO
+    bool 
+    select ARCH_ARM_CORTEX_M4
+    default y
+
 source "$RTT_DIR/Kconfig"
 source "$PKGS_DIR/Kconfig"
 

+ 0 - 9
bsp/stm32f411-nucleo/drivers/stm32f4xx_it.c

@@ -93,15 +93,6 @@ void UsageFault_Handler(void)
   }
 }
 
-/**
-  * @brief  This function handles SVCall exception.
-  * @param  None
-  * @retval None
-  */
-void SVC_Handler(void)
-{
-}
-
 /**
   * @}
   */

+ 6 - 0
bsp/stm32f411-nucleo/stm32_rom.ld

@@ -39,6 +39,12 @@ SECTIONS
         __vsymtab_end = .;
         . = ALIGN(4);
 
+        /* section information for modules */
+        . = ALIGN(4);
+        __rtmsymtab_start = .;
+        KEEP(*(RTMSymTab))
+        __rtmsymtab_end = .;
+
         /* section information for initial. */
         . = ALIGN(4);
         __rt_init_start = .;

+ 2 - 0
components/Kconfig

@@ -26,6 +26,8 @@ source "$RTT_DIR/components/drivers/Kconfig"
 
 source "$RTT_DIR/components/libc/Kconfig"
 
+source "$RTT_DIR/components/lwp/Kconfig"
+
 source "$RTT_DIR/components/net/Kconfig"
 
 source "$RTT_DIR/components/vbus/Kconfig"

+ 8 - 0
components/dfs/include/dfs.h

@@ -95,6 +95,12 @@ struct dirent
     char d_name[DFS_PATH_MAX];   /* The null-terminated file name */
 };
 
+struct dfs_fdtable
+{
+    uint32_t maxfd;
+    struct dfs_fd **fds;
+};
+
 /* Initialization of dfs */
 int dfs_init(void);
 
@@ -110,6 +116,8 @@ struct dfs_fd *fd_get(int fd);
 void fd_put(struct dfs_fd *fd);
 int fd_is_open(const char *pathname);
 
+struct dfs_fdtable* dfs_fdtable_get(void);
+
 #ifdef __cplusplus
 }
 #endif

+ 117 - 16
components/dfs/src/dfs.c

@@ -21,12 +21,16 @@
  * Date           Author       Notes
  * 2005-02-22     Bernard      The first version.
  * 2017-12-11     Bernard      Use rt_free to instead of free in fd_is_open().
+ * 2018-03-20     Heyuanjie    dynamic allocation FD
  */
 
 #include <dfs.h>
 #include <dfs_fs.h>
 #include <dfs_file.h>
 #include "dfs_private.h"
+#ifdef RT_USING_LWP
+#include <lwp.h>
+#endif
 
 /* Global variables */
 const struct dfs_filesystem_ops *filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX];
@@ -39,7 +43,8 @@ static struct rt_mutex fslock;
 char working_directory[DFS_PATH_MAX] = {"/"};
 #endif
 
-struct dfs_fd fd_table[DFS_FD_MAX];
+static struct dfs_fdtable _fdtab;
+static int  fd_alloc(struct dfs_fdtable *fdt, int startfd);
 
 /**
  * @addtogroup DFS
@@ -57,7 +62,7 @@ int dfs_init(void)
     /* clear filesystem table */
     memset(filesystem_table, 0, sizeof(filesystem_table));
     /* clean fd table */
-    memset(fd_table, 0, sizeof(fd_table));
+    memset(&_fdtab, 0, sizeof(_fdtab));
 
     /* create device filesystem lock */
     rt_mutex_init(&fslock, "fslock", RT_IPC_FLAG_FIFO);
@@ -90,9 +95,13 @@ INIT_PREV_EXPORT(dfs_init);
  */
 void dfs_lock(void)
 {
-    rt_err_t result;
+    rt_err_t result = -RT_EBUSY;
+
+    while (result == -RT_EBUSY)
+    {
+        result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
+    }
 
-    result = rt_mutex_take(&fslock, RT_WAITING_FOREVER);
     if (result != RT_EOK)
     {
         RT_ASSERT(0);
@@ -109,6 +118,54 @@ void dfs_unlock(void)
     rt_mutex_release(&fslock);
 }
 
+static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
+{
+    int idx;
+
+    /* find an empty fd entry */
+    for (idx = startfd; idx < fdt->maxfd; idx++)
+    {
+        if (fdt->fds[idx] == RT_NULL)
+            break;
+        if (fdt->fds[idx]->ref_count == 0)
+            break;
+    }
+
+    /* allocate a larger FD container */
+    if (idx == fdt->maxfd && fdt->maxfd < DFS_FD_MAX)
+    {
+        int cnt, index;
+        struct dfs_fd **fds;
+
+        /* increase the number of FD with 4 step length */
+        cnt = fdt->maxfd + 4;
+        cnt = cnt > DFS_FD_MAX? DFS_FD_MAX : cnt;
+
+        fds = rt_realloc(fdt->fds, cnt * sizeof(struct dfs_fd *));
+        if (fds == NULL) goto __out; /* return fdt->maxfd */
+
+        /* clean the new allocated fds */
+        for (index = fdt->maxfd; index < cnt; index ++)
+        {
+            fds[index] = NULL;
+        }
+
+        fdt->fds   = fds;
+        fdt->maxfd = cnt;
+    }
+
+    /* allocate  'struct dfs_fd' */
+    if (idx < fdt->maxfd &&fdt->fds[idx] == RT_NULL)
+    {
+        fdt->fds[idx] = rt_malloc(sizeof(struct dfs_fd));
+        if (fdt->fds[idx] == RT_NULL)
+            idx = fdt->maxfd;
+    }
+
+__out:
+    return idx;
+}
+
 /**
  * @ingroup Fd
  * This function will allocate a file descriptor.
@@ -119,21 +176,23 @@ int fd_new(void)
 {
     struct dfs_fd *d;
     int idx;
+    struct dfs_fdtable *fdt;
 
+    fdt = dfs_fdtable_get();
     /* lock filesystem */
     dfs_lock();
 
     /* find an empty fd entry */
-    for (idx = 0; idx < DFS_FD_MAX && fd_table[idx].ref_count > 0; idx++);
+    idx = fd_alloc(fdt, 0);
 
     /* can't find an empty fd entry */
-    if (idx == DFS_FD_MAX)
+    if (idx == fdt->maxfd)
     {
         idx = -(1 + DFS_FD_OFFSET);
         goto __result;
     }
 
-    d = &(fd_table[idx]);
+    d = fdt->fds[idx];
     d->ref_count = 1;
     d->magic = DFS_FD_MAGIC;
 
@@ -154,13 +213,15 @@ __result:
 struct dfs_fd *fd_get(int fd)
 {
     struct dfs_fd *d;
+    struct dfs_fdtable *fdt;
 
+    fdt = dfs_fdtable_get();
     fd = fd - DFS_FD_OFFSET;
-    if (fd < 0 || fd >= DFS_FD_MAX)
+    if (fd < 0 || fd >= fdt->maxfd)
         return NULL;
 
     dfs_lock();
-    d = &fd_table[fd];
+    d = fdt->fds[fd];
 
     /* check dfs_fd valid or not */
     if (d->magic != DFS_FD_MAGIC)
@@ -186,12 +247,25 @@ void fd_put(struct dfs_fd *fd)
     RT_ASSERT(fd != NULL);
 
     dfs_lock();
+
     fd->ref_count --;
 
     /* clear this fd entry */
     if (fd->ref_count == 0)
     {
-        memset(fd, 0, sizeof(struct dfs_fd));
+        int index;
+        struct dfs_fdtable *fdt;
+
+        fdt = dfs_fdtable_get();
+        for (index = 0; index < fdt->maxfd; index ++)
+        {
+            if (fdt->fds[index] == fd)
+            {
+                rt_free(fd);
+                fdt->fds[index] = 0;
+                break;
+            }
+        }
     }
     dfs_unlock();
 }
@@ -211,7 +285,9 @@ int fd_is_open(const char *pathname)
     unsigned int index;
     struct dfs_filesystem *fs;
     struct dfs_fd *fd;
+    struct dfs_fdtable *fdt;
 
+    fdt = dfs_fdtable_get();
     fullpath = dfs_normalize_path(NULL, pathname);
     if (fullpath != NULL)
     {
@@ -233,11 +309,10 @@ int fd_is_open(const char *pathname)
 
         dfs_lock();
 
-        for (index = 0; index < DFS_FD_MAX; index++)
+        for (index = 0; index < fdt->maxfd; index++)
         {
-            fd = &(fd_table[index]);
-            if (fd->fops == NULL)
-                continue;
+            fd = fdt->fds[index];
+            if (fd == NULL) continue;
 
             if (fd->fops == fs->ops->fops && strcmp(fd->path, mountpath) == 0)
             {
@@ -414,17 +489,43 @@ up_one:
     return fullpath;
 }
 RTM_EXPORT(dfs_normalize_path);
+
+/**
+ * This function will get the file descriptor table of current process.
+ */
+struct dfs_fdtable* dfs_fdtable_get(void)
+{
+    struct dfs_fdtable *fdt;
+#ifdef RT_USING_LWP
+	struct rt_lwp *lwp;
+
+	lwp = (struct rt_lwp *)rt_thread_self()->user_data;
+    if (lwp)
+		fdt = &lwp->fdt;
+	else
+		fdt = &_fdtab;
+#else
+    fdt = &_fdtab;
+#endif
+
+    return fdt;
+}
+
 #ifdef RT_USING_FINSH
 #include <finsh.h>
 int list_fd(void)
 {
     int index;
+    struct dfs_fdtable *fd_table;
+    
+    fd_table = dfs_fdtable_get();
+    if (!fd_table) return -1;
 
     rt_enter_critical();
 
-    for (index = 0; index < DFS_FD_MAX; index ++)
+    for (index = 0; index < fd_table->maxfd; index ++)
     {
-        struct dfs_fd *fd = &(fd_table[index]);
+        struct dfs_fd *fd = fd_table->fds[index];
 
         if (fd->fops)
         {

+ 21 - 5
components/drivers/audio/audio.c

@@ -421,6 +421,18 @@ static rt_err_t _audio_dev_control(struct rt_device *dev, int cmd, void *args)
     return result;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops audio_ops =
+{
+    _audio_dev_init,
+    _audio_dev_open,
+    _audio_dev_close,
+    _audio_dev_read,
+    _audio_dev_write,
+    _audio_dev_control
+};
+#endif
+
 rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data)
 {
     struct rt_device *device;
@@ -431,12 +443,16 @@ rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_u
     device->rx_indicate = RT_NULL;
     device->tx_complete = RT_NULL;
 
-    device->init = _audio_dev_init;
-    device->open = _audio_dev_open;
-    device->close = _audio_dev_close;
-    device->read = _audio_dev_read;
-    device->write = _audio_dev_write;
+#ifdef RT_USING_DEVICE_OPS
+    device->ops  = &audio_ops;
+#else
+    device->init    = _audio_dev_init;
+    device->open    = _audio_dev_open;
+    device->close   = _audio_dev_close;
+    device->read    = _audio_dev_read;
+    device->write   = _audio_dev_write;
     device->control = _audio_dev_control;
+#endif
     device->user_data = data;
 
     //init memory pool for replay

+ 18 - 2
components/drivers/audio/audio_pipe.c

@@ -193,14 +193,26 @@ static rt_size_t rt_pipe_write(rt_device_t dev,
 static rt_err_t rt_pipe_control(rt_device_t dev, int cmd, void *args)
 {
     struct rt_audio_pipe *pipe;
-    
+
     pipe = (struct rt_audio_pipe *)dev;
-    
+
     if (cmd == PIPE_CTRL_GET_SPACE && args)
         *(rt_size_t*)args = rt_ringbuffer_space_len(&pipe->ringbuffer);
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops audio_pipe_ops
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    rt_pipe_read,
+    rt_pipe_write,
+    rt_pipe_control
+};
+#endif
+
 /**
  * This function will initialize a pipe device and put it under control of
  * resource management.
@@ -233,12 +245,16 @@ rt_err_t rt_audio_pipe_init(struct rt_audio_pipe *pipe,
 
     /* create pipe */
     pipe->parent.type    = RT_Device_Class_Pipe;
+#ifdef RT_USING_DEVICE_OPS
+    pipe->parent.ops     = &audio_pipe_ops;
+#else
     pipe->parent.init    = RT_NULL;
     pipe->parent.open    = RT_NULL;
     pipe->parent.close   = RT_NULL;
     pipe->parent.read    = rt_pipe_read;
     pipe->parent.write   = rt_pipe_write;
     pipe->parent.control = rt_pipe_control;
+#endif
 
     return rt_device_register(&(pipe->parent), name, RT_DEVICE_FLAG_RDWR);
 }

+ 17 - 0
components/drivers/can/can.c

@@ -687,6 +687,18 @@ static void cantimeout(void *arg)
     }
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops can_device_ops =
+{
+    rt_can_init,
+    rt_can_open,
+    rt_can_close,
+    rt_can_read,
+    rt_can_write,
+    rt_can_control
+};
+#endif
+
 /*
  * can register
  */
@@ -712,12 +724,17 @@ rt_err_t rt_hw_can_register(struct rt_can_device *can,
 #ifdef RT_CAN_USING_BUS_HOOK
     can->bus_hook       = RT_NULL;
 #endif /*RT_CAN_USING_BUS_HOOK*/
+
+#ifdef RT_USING_DEVICE_OPS
+    device->ops         = &can_device_ops;
+#else
     device->init        = rt_can_init;
     device->open        = rt_can_open;
     device->close       = rt_can_close;
     device->read        = rt_can_read;
     device->write       = rt_can_write;
     device->control     = rt_can_control;
+#endif
     can->ops            = ops;
 
     can->status_indicate.ind  = RT_NULL;

+ 20 - 4
components/drivers/hwtimer/hwtimer.c

@@ -35,13 +35,13 @@ rt_inline rt_uint32_t timeout_calc(rt_hwtimer_t *timer, rt_hwtimerval_t *tv)
     float devi_min = 1;
     float devi;
 
-    /* 把定时器溢出时间和定时时间换算成秒 */
+    /* changed to second */
     overflow = timer->info->maxcnt/(float)timer->freq;
     tv_sec = tv->sec + tv->usec/(float)1000000;
 
     if (tv_sec < (1/(float)timer->freq))
     {
-        /* 定时时间小于计数周期 */
+        /* little timeout */
         i = 0;
         timeout = 1/(float)timer->freq;
     }
@@ -55,7 +55,7 @@ rt_inline rt_uint32_t timeout_calc(rt_hwtimer_t *timer, rt_hwtimerval_t *tv)
             {
                 counter = timeout*timer->freq;
                 devi = tv_sec - (counter/(float)timer->freq)*i;
-                /* 计算最小误差 */
+                /* Minimum calculation error */
                 if (devi > devi_min)
                 {
                     i = index;
@@ -89,7 +89,7 @@ static rt_err_t rt_hwtimer_init(struct rt_device *dev)
     rt_hwtimer_t *timer;
 
     timer = (rt_hwtimer_t *)dev;
-    /* 尝试将默认计数频率设为1Mhz */
+    /* try to change to 1MHz */
     if ((1000000 <= timer->info->maxfreq) && (1000000 >= timer->info->minfreq))
     {
         timer->freq = 1000000;
@@ -330,6 +330,18 @@ void rt_device_hwtimer_isr(rt_hwtimer_t *timer)
     }
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops hwtimer_ops = 
+{
+    rt_hwtimer_init,
+    rt_hwtimer_open,
+    rt_hwtimer_close,
+    rt_hwtimer_read,
+    rt_hwtimer_write,
+    rt_hwtimer_control
+};
+#endif
+
 rt_err_t rt_device_hwtimer_register(rt_hwtimer_t *timer, const char *name, void *user_data)
 {
     struct rt_device *device;
@@ -344,12 +356,16 @@ rt_err_t rt_device_hwtimer_register(rt_hwtimer_t *timer, const char *name, void
     device->rx_indicate = RT_NULL;
     device->tx_complete = RT_NULL;
 
+#ifdef RT_USING_DEVICE_OPS
+    device->ops         = &hwtimer_ops;
+#else
     device->init        = rt_hwtimer_init;
     device->open        = rt_hwtimer_open;
     device->close       = rt_hwtimer_close;
     device->read        = rt_hwtimer_read;
     device->write       = rt_hwtimer_write;
     device->control     = rt_hwtimer_control;
+#endif
     device->user_data   = user_data;
 
     return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);

+ 17 - 0
components/drivers/i2c/fm24clxx.c

@@ -132,6 +132,18 @@ static rt_size_t fm24clxx_write(rt_device_t dev, rt_off_t pos, const void *buffe
     return (ret == 2) ? size : 0;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device fm24clxx_ops =
+{
+    fm24clxx_init,
+    fm24clxx_open,
+    fm24clxx_close,
+    fm24clxx_read,
+    fm24clxx_write,
+    fm24clxx_control
+};
+#endif
+
 rt_err_t fm24clxx_register(const char *fm_device_name, const char *i2c_bus, void *user_data)
 {
     static struct fm24clxx_device fm24clxx_drv;
@@ -145,12 +157,17 @@ rt_err_t fm24clxx_register(const char *fm_device_name, const char *i2c_bus, void
 
     fm24clxx_drv.bus = bus;
     fm24clxx_drv.parent.type      = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+    fm24clxx_drv.parent.ops       = &fm24clxx_ops;
+#else
     fm24clxx_drv.parent.init      = fm24clxx_init;
     fm24clxx_drv.parent.open      = fm24clxx_open;
     fm24clxx_drv.parent.close     = fm24clxx_close;
     fm24clxx_drv.parent.read      = fm24clxx_read;
     fm24clxx_drv.parent.write     = fm24clxx_write;
     fm24clxx_drv.parent.control   = fm24clxx_control;
+#endif
+
     fm24clxx_drv.parent.user_data = user_data;
 
     return rt_device_register(&fm24clxx_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR);

+ 16 - 0
components/drivers/i2c/i2c_dev.c

@@ -102,6 +102,18 @@ static rt_err_t i2c_bus_device_control(rt_device_t dev,
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops i2c_ops = 
+{
+    RT_NULL, 
+    RT_NULL,
+    RT_NULL,
+    i2c_bus_device_read,
+    i2c_bus_device_write,
+    i2c_bus_device_control
+};
+#endif
+
 rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus,
                                        const char               *name)
 {
@@ -115,12 +127,16 @@ rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus,
     /* set device type */
     device->type    = RT_Device_Class_I2CBUS;
     /* initialize device interface */
+#ifdef RT_USING_DEVICE_OPS
+    device->ops     = &i2c_ops;
+#else
     device->init    = RT_NULL;
     device->open    = RT_NULL;
     device->close   = RT_NULL;
     device->read    = i2c_bus_device_read;
     device->write   = i2c_bus_device_write;
     device->control = i2c_bus_device_control;
+#endif
 
     /* register to device manager */
     rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);

+ 18 - 0
components/drivers/misc/pin.c

@@ -76,18 +76,34 @@ static rt_err_t  _pin_control(rt_device_t dev, int cmd, void *args)
     return 0;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops pin_ops =
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    _pin_read,
+    _pin_write,
+    _pin_control
+};
+#endif
+
 int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data)
 {
     _hw_pin.parent.type         = RT_Device_Class_Miscellaneous;
     _hw_pin.parent.rx_indicate  = RT_NULL;
     _hw_pin.parent.tx_complete  = RT_NULL;
 
+#ifdef RT_USING_DEVICE_OPS
+    _hw_pin.parent.ops          = &pin_ops;
+#else
     _hw_pin.parent.init         = RT_NULL;
     _hw_pin.parent.open         = RT_NULL;
     _hw_pin.parent.close        = RT_NULL;
     _hw_pin.parent.read         = _pin_read;
     _hw_pin.parent.write        = _pin_write;
     _hw_pin.parent.control      = _pin_control;
+#endif
 
     _hw_pin.ops                 = ops;
     _hw_pin.parent.user_data    = user_data;
@@ -117,6 +133,7 @@ rt_err_t rt_pin_dettach_irq(rt_int32_t pin)
     }
     return RT_ENOSYS;
 }
+
 rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled)
 {
     RT_ASSERT(_hw_pin.ops != RT_NULL);
@@ -126,6 +143,7 @@ rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled)
     }
     return RT_ENOSYS;
 }
+
 /* RT-Thread Hardware PIN APIs */
 void rt_pin_mode(rt_base_t pin, rt_base_t mode)
 {

+ 16 - 0
components/drivers/mtd/mtd_nand.c

@@ -69,6 +69,18 @@ static rt_err_t _mtd_control(rt_device_t dev, int cmd, void *args)
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops mtd_nand_ops = 
+{
+    _mtd_init,
+    _mtd_open,
+    _mtd_close,
+    _mtd_read,
+    _mtd_write,
+    _mtd_control
+};
+#endif
+
 rt_err_t rt_mtd_nand_register_device(const char                *name,
                                      struct rt_mtd_nand_device *device)
 {
@@ -79,12 +91,16 @@ rt_err_t rt_mtd_nand_register_device(const char                *name,
 
     /* set device class and generic device interface */
     dev->type        = RT_Device_Class_MTD;
+#ifdef RT_USING_DEVICE_OPS
+	dev->ops         = &mtd_nand_ops;
+#else
     dev->init        = _mtd_init;
     dev->open        = _mtd_open;
     dev->read        = _mtd_read;
     dev->write       = _mtd_write;
     dev->close       = _mtd_close;
     dev->control     = _mtd_control;
+#endif
 
     dev->rx_indicate = RT_NULL;
     dev->tx_complete = RT_NULL;

+ 16 - 0
components/drivers/mtd/mtd_nor.c

@@ -65,6 +65,18 @@ static rt_err_t _mtd_control(rt_device_t dev, int cmd, void *args)
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops mtd_nor_ops = 
+{
+    _mtd_init,
+    _mtd_open,
+    _mtd_close,
+    _mtd_read,
+    _mtd_write,
+    _mtd_control
+};
+#endif
+
 rt_err_t rt_mtd_nor_register_device(const char               *name,
                                     struct rt_mtd_nor_device *device)
 {
@@ -75,12 +87,16 @@ rt_err_t rt_mtd_nor_register_device(const char               *name,
 
     /* set device class and generic device interface */
     dev->type        = RT_Device_Class_MTD;
+#ifdef RT_USING_DEVICE_OPS
+    dev->ops         = &mtd_nor_ops;
+#else
     dev->init        = _mtd_init;
     dev->open        = _mtd_open;
     dev->read        = _mtd_read;
     dev->write       = _mtd_write;
     dev->close       = _mtd_close;
     dev->control     = _mtd_control;
+#endif
 
     dev->rx_indicate = RT_NULL;
     dev->tx_complete = RT_NULL;

+ 16 - 0
components/drivers/rtc/soft_rtc.c

@@ -68,6 +68,18 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops soft_rtc_ops = 
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    soft_rtc_control
+};
+#endif
+
 int rt_soft_rtc_init(void)
 {
     static rt_bool_t init_ok = RT_FALSE;
@@ -86,12 +98,16 @@ int rt_soft_rtc_init(void)
     soft_rtc_dev.type    = RT_Device_Class_RTC;
 
     /* register rtc device */
+#ifdef RT_USING_DEVICE_OPS
+    soft_rtc_dev.ops     = &soft_rtc_ops;
+#else
     soft_rtc_dev.init    = RT_NULL;
     soft_rtc_dev.open    = RT_NULL;
     soft_rtc_dev.close   = RT_NULL;
     soft_rtc_dev.read    = RT_NULL;
     soft_rtc_dev.write   = RT_NULL;
     soft_rtc_dev.control = soft_rtc_control;
+#endif
 
     /* no private */
     soft_rtc_dev.user_data = RT_NULL;

+ 21 - 4
components/drivers/sdio/block_dev.c

@@ -319,6 +319,18 @@ static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card)
     return 0;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops mmcsd_blk_ops = 
+{
+    rt_mmcsd_init,
+    rt_mmcsd_open,
+    rt_mmcsd_close,
+    rt_mmcsd_read,
+    rt_mmcsd_write,
+    rt_mmcsd_control
+};
+#endif
+
 rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
 {
     rt_int32_t err = 0;
@@ -366,13 +378,17 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
                 blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
     
                 /* register mmcsd device */
-                blk_dev->dev.type = RT_Device_Class_Block;                  
+                blk_dev->dev.type = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+                blk_dev->dev.ops  = &mmcsd_blk_ops;
+#else
                 blk_dev->dev.init = rt_mmcsd_init;
                 blk_dev->dev.open = rt_mmcsd_open;
                 blk_dev->dev.close = rt_mmcsd_close;
                 blk_dev->dev.read = rt_mmcsd_read;
                 blk_dev->dev.write = rt_mmcsd_write;
                 blk_dev->dev.control = rt_mmcsd_control;
+#endif
                 blk_dev->dev.user_data = blk_dev;
 
                 blk_dev->card = card;
@@ -396,12 +412,16 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
     
                     /* register mmcsd device */
                     blk_dev->dev.type  = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+                    blk_dev->dev.ops  = &mmcsd_blk_ops;
+#else
                     blk_dev->dev.init = rt_mmcsd_init;
                     blk_dev->dev.open = rt_mmcsd_open;
                     blk_dev->dev.close = rt_mmcsd_close;
                     blk_dev->dev.read = rt_mmcsd_read;
                     blk_dev->dev.write = rt_mmcsd_write;
                     blk_dev->dev.control = rt_mmcsd_control;
+#endif
                     blk_dev->dev.user_data = blk_dev;
 
                     blk_dev->card = card;
@@ -482,6 +502,3 @@ int rt_mmcsd_blk_init(void)
     /* nothing */
     return 0;
 }
-
-INIT_PREV_EXPORT(rt_mmcsd_blk_init);
-

+ 16 - 0
components/drivers/serial/serial.c

@@ -1072,6 +1072,18 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
     return ret;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops serial_ops = 
+{
+    rt_serial_init,
+    rt_serial_open,
+    rt_serial_close,
+    rt_serial_read,
+    rt_serial_write,
+    rt_serial_control
+};
+#endif
+
 /*
  * serial register
  */
@@ -1090,12 +1102,16 @@ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
     device->rx_indicate = RT_NULL;
     device->tx_complete = RT_NULL;
 
+#ifdef RT_USING_DEVICE_OPS
+    device->ops         = &serial_ops;
+#else
     device->init        = rt_serial_init;
     device->open        = rt_serial_open;
     device->close       = rt_serial_close;
     device->read        = rt_serial_read;
     device->write       = rt_serial_write;
     device->control     = rt_serial_control;
+#endif
     device->user_data   = data;
 
     /* register a character device */

+ 16 - 0
components/drivers/spi/enc28j60.c

@@ -741,6 +741,18 @@ static struct pbuf *enc28j60_rx(rt_device_t dev)
     return p;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops enc28j60_ops = 
+{
+    enc28j60_init,
+    enc28j60_open,
+    enc28j60_close,
+    enc28j60_read,
+    enc28j60_write,
+    enc28j60_control
+};
+#endif
+
 rt_err_t enc28j60_attach(const char *spi_device_name)
 {
     struct rt_spi_device *spi_device;
@@ -802,12 +814,16 @@ rt_err_t enc28j60_attach(const char *spi_device_name)
 
     /* init rt-thread device struct */
     enc28j60_dev.parent.parent.type    = RT_Device_Class_NetIf;
+#ifdef RT_USING_DEVICE_OPS
+    enc28j60_dev.parent.parent.ops     = &enc28j60_ops;
+#else
     enc28j60_dev.parent.parent.init    = enc28j60_init;
     enc28j60_dev.parent.parent.open    = enc28j60_open;
     enc28j60_dev.parent.parent.close   = enc28j60_close;
     enc28j60_dev.parent.parent.read    = enc28j60_read;
     enc28j60_dev.parent.parent.write   = enc28j60_write;
     enc28j60_dev.parent.parent.control = enc28j60_control;
+#endif
 
     /* init rt-thread ethernet device struct */
     enc28j60_dev.parent.eth_rx  = enc28j60_rx;

+ 33 - 1
components/drivers/spi/spi_dev.c

@@ -69,6 +69,18 @@ static rt_err_t _spi_bus_device_control(rt_device_t dev,
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops spi_bus_ops = 
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    _spi_bus_device_read,
+    _spi_bus_device_write,
+    _spi_bus_device_control
+};
+#endif
+
 rt_err_t rt_spi_bus_device_init(struct rt_spi_bus *bus, const char *name)
 {
     struct rt_device *device;
@@ -79,12 +91,16 @@ rt_err_t rt_spi_bus_device_init(struct rt_spi_bus *bus, const char *name)
     /* set device type */
     device->type    = RT_Device_Class_SPIBUS;
     /* initialize device interface */
+#ifdef RT_USING_DEVICE_OPS
+    device->ops     = &spi_bus_ops;
+#else
     device->init    = RT_NULL;
     device->open    = RT_NULL;
     device->close   = RT_NULL;
     device->read    = _spi_bus_device_read;
     device->write   = _spi_bus_device_write;
     device->control = _spi_bus_device_control;
+#endif
 
     /* register to device manager */
     return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
@@ -134,6 +150,18 @@ static rt_err_t _spidev_device_control(rt_device_t dev,
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops spi_device_ops = 
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    _spidev_device_read,
+    _spidev_device_write,
+    _spidev_device_control
+};
+#endif
+
 rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name)
 {
     struct rt_device *device;
@@ -143,13 +171,17 @@ rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name)
 
     /* set device type */
     device->type    = RT_Device_Class_SPIDevice;
+#ifdef RT_USING_DEVICE_OPS
+    device->ops     = &spi_device_ops;
+#else
     device->init    = RT_NULL;
     device->open    = RT_NULL;
     device->close   = RT_NULL;
     device->read    = _spidev_device_read;
     device->write   = _spidev_device_write;
     device->control = _spidev_device_control;
-    
+#endif
+
     /* register to device manager */
     return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
 }

+ 17 - 1
components/drivers/spi/spi_flash_gd.c

@@ -1,7 +1,7 @@
 /*
  * File      : spi_flash_gd.c
  * This file is part of RT-Thread RTOS
- *  Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd. 
+ *  Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
  *  All rights reserved
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -254,6 +254,18 @@ static rt_size_t w25qxx_flash_write(rt_device_t dev,
     return size;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops gd_device_ops =
+{
+    w25qxx_flash_init,
+    w25qxx_flash_open,
+    w25qxx_flash_close,
+    w25qxx_flash_read,
+    w25qxx_flash_write,
+    w25qxx_flash_control
+};
+#endif
+
 rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name)
 {
     struct rt_spi_device * rt_spi_device;
@@ -330,12 +342,16 @@ rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name)
 
     /* register device */
     spi_flash_device.flash_device.type    = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+    spi_flash_device.flash_device.ops     = &gd_device_ops;
+#else
     spi_flash_device.flash_device.init    = w25qxx_flash_init;
     spi_flash_device.flash_device.open    = w25qxx_flash_open;
     spi_flash_device.flash_device.close   = w25qxx_flash_close;
     spi_flash_device.flash_device.read    = w25qxx_flash_read;
     spi_flash_device.flash_device.write   = w25qxx_flash_write;
     spi_flash_device.flash_device.control = w25qxx_flash_control;
+#endif
     /* no private */
     spi_flash_device.flash_device.user_data = RT_NULL;
 

+ 17 - 1
components/drivers/spi/spi_flash_sfud.c

@@ -228,6 +228,18 @@ sfud_err sfud_spi_port_init(sfud_flash *flash) {
     return result;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops flash_device_ops = 
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    rt_sfud_read,
+    rt_sfud_write,
+    rt_sfud_control
+};
+#endif
+
 /**
  * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device.
  *
@@ -258,7 +270,7 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
         /* initialize lock */
         rt_mutex_init(&(rtt_dev->lock), spi_flash_dev_name, RT_IPC_FLAG_FIFO);
     }
-    
+
     if (rtt_dev && sfud_dev && spi_flash_dev_name_bak && spi_dev_name_bak) {
         rt_memset(sfud_dev, 0, sizeof(sfud_flash));
         rt_strncpy(spi_flash_dev_name_bak, spi_flash_dev_name, rt_strlen(spi_flash_dev_name));
@@ -297,12 +309,16 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
 
         /* register device */
         rtt_dev->flash_device.type = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+        rtt_dev->flash_device.ops  = &flash_device_ops;
+#else
         rtt_dev->flash_device.init = RT_NULL;
         rtt_dev->flash_device.open = RT_NULL;
         rtt_dev->flash_device.close = RT_NULL;
         rtt_dev->flash_device.read = rt_sfud_read;
         rtt_dev->flash_device.write = rt_sfud_write;
         rtt_dev->flash_device.control = rt_sfud_control;
+#endif
 
         rt_device_register(&(rtt_dev->flash_device), spi_flash_dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
 

+ 16 - 0
components/drivers/spi/spi_flash_sst25vfxx.c

@@ -254,6 +254,18 @@ static rt_size_t sst25vfxx_flash_write(rt_device_t dev, rt_off_t pos, const void
     return size;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops sst25vfxx_device_ops =
+{
+    sst25vfxx_flash_init,
+    sst25vfxx_flash_open,
+    sst25vfxx_flash_close,
+    sst25vfxx_flash_read,
+    sst25vfxx_flash_write,
+    sst25vfxx_flash_control
+};
+#endif
+
 rt_err_t sst25vfxx_init(const char * flash_device_name, const char * spi_device_name)
 {
     struct rt_spi_device * rt_spi_device;
@@ -340,12 +352,16 @@ rt_err_t sst25vfxx_init(const char * flash_device_name, const char * spi_device_
 
     /* register device */
     spi_flash->flash_device.type    = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+    spi_flash->flash_device.ops     = &sst25vfxx_device_ops;
+#else
     spi_flash->flash_device.init    = sst25vfxx_flash_init;
     spi_flash->flash_device.open    = sst25vfxx_flash_open;
     spi_flash->flash_device.close   = sst25vfxx_flash_close;
     spi_flash->flash_device.read    = sst25vfxx_flash_read;
     spi_flash->flash_device.write   = sst25vfxx_flash_write;
     spi_flash->flash_device.control = sst25vfxx_flash_control;
+#endif
     /* no private */
     spi_flash->flash_device.user_data = RT_NULL;
 

+ 16 - 0
components/drivers/spi/spi_flash_w25qxx.c

@@ -264,6 +264,18 @@ static rt_size_t w25qxx_flash_write(rt_device_t dev,
     return size;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops w25qxx_device_ops =
+{
+    w25qxx_flash_init,
+    w25qxx_flash_open,
+    w25qxx_flash_close,
+    w25qxx_flash_read,
+    w25qxx_flash_write,
+    w25qxx_flash_control
+};
+#endif
+
 rt_err_t w25qxx_init(const char * flash_device_name, const char * spi_device_name)
 {
     struct rt_spi_device * rt_spi_device;
@@ -375,12 +387,16 @@ rt_err_t w25qxx_init(const char * flash_device_name, const char * spi_device_nam
 
     /* register device */
     spi_flash_device.flash_device.type    = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+    spi_flash_device.flash_device.ops     = &w25qxx_device_ops;
+#else
     spi_flash_device.flash_device.init    = w25qxx_flash_init;
     spi_flash_device.flash_device.open    = w25qxx_flash_open;
     spi_flash_device.flash_device.close   = w25qxx_flash_close;
     spi_flash_device.flash_device.read    = w25qxx_flash_read;
     spi_flash_device.flash_device.write   = w25qxx_flash_write;
     spi_flash_device.flash_device.control = w25qxx_flash_control;
+#endif
     /* no private */
     spi_flash_device.flash_device.user_data = RT_NULL;
 

+ 38 - 0
components/drivers/spi/spi_msd.c

@@ -47,10 +47,14 @@ static void MSD_release_cs(struct rt_spi_device *device);
 
 static rt_err_t _wait_token(struct rt_spi_device *device, uint8_t token);
 static rt_err_t _wait_ready(struct rt_spi_device *device);
+static rt_err_t  rt_msd_init(rt_device_t dev);
+static rt_err_t  rt_msd_open(rt_device_t dev, rt_uint16_t oflag);
+static rt_err_t  rt_msd_close(rt_device_t dev);
 static rt_size_t rt_msd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
 static rt_size_t rt_msd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
 static rt_size_t rt_msd_sdhc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
 static rt_size_t rt_msd_sdhc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
+static rt_err_t rt_msd_control(rt_device_t dev, int cmd, void *args);
 
 static rt_err_t MSD_take_owner(struct rt_spi_device *spi_device)
 {
@@ -461,6 +465,28 @@ static rt_err_t _write_block(struct rt_spi_device *device, const void *buffer, u
     return _wait_ready(device);
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops msd_ops = 
+{
+    rt_msd_init,
+    rt_msd_open,
+    rt_msd_close,
+    rt_msd_read,
+    rt_msd_write,
+    rt_msd_control
+};
+
+const static struct rt_device_ops msd_sdhc_ops = 
+{
+    rt_msd_init,
+    rt_msd_open,
+    rt_msd_close,
+    rt_msd_sdhc_read,
+    rt_msd_sdhc_write,
+    rt_msd_control
+};
+#endif
+
 /* RT-Thread Device Driver Interface */
 static rt_err_t rt_msd_init(rt_device_t dev)
 {
@@ -893,13 +919,21 @@ static rt_err_t rt_msd_init(rt_device_t dev)
 
     if (msd->card_type == MSD_CARD_TYPE_SD_SDHC)
     {
+#ifdef RT_USING_DEVICE_OPS
+        dev->ops   = &msd_sdhc_ops;
+#else
         dev->read  = rt_msd_sdhc_read;
         dev->write = rt_msd_sdhc_write;
+#endif
     }
     else
     {
+#ifdef RT_USING_DEVICE_OPS
+        dev->ops   = &msd_ops;
+#else
         dev->read  = rt_msd_read;
         dev->write = rt_msd_write;
+#endif
     }
 
     /* set CRC */
@@ -1674,12 +1708,16 @@ rt_err_t msd_init(const char *sd_device_name, const char *spi_device_name)
     _msd_device.geometry.sector_count = 0;
     _msd_device.geometry.block_size = 0;
 
+#ifdef RT_USING_DEVICE_OPS
+    _msd_device.parent.ops     = &msd_ops;
+#else
     _msd_device.parent.init    = rt_msd_init;
     _msd_device.parent.open    = rt_msd_open;
     _msd_device.parent.close   = rt_msd_close;
     _msd_device.parent.read    = RT_NULL;
     _msd_device.parent.write   = RT_NULL;
     _msd_device.parent.control = rt_msd_control;
+#endif
 
     /* no private, no callback */
     _msd_device.parent.user_data = RT_NULL;

+ 16 - 0
components/drivers/spi/spi_wifi_rw009.c

@@ -629,6 +629,18 @@ static void spi_wifi_data_thread_entry(void *parameter)
     }
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops rw009_ops =
+{
+    rw009_wifi_init,
+    rw009_wifi_open,
+    rw009_wifi_close,
+    rw009_wifi_read,
+    rw009_wifi_write,
+    rw009_wifi_control
+};
+#endif
+
 rt_err_t rt_hw_wifi_init(const char *spi_device_name, wifi_mode_t mode)
 {
     /* align and struct size check. */
@@ -654,12 +666,16 @@ rt_err_t rt_hw_wifi_init(const char *spi_device_name, wifi_mode_t mode)
         rt_spi_configure(rw009_wifi_device.rt_spi_device, &cfg);
     }
 
+#ifdef RT_USING_DEVICE_OPS
+    rw009_wifi_device.parent.parent.ops        = &rw009_ops;
+#else
     rw009_wifi_device.parent.parent.init       = rw009_wifi_init;
     rw009_wifi_device.parent.parent.open       = rw009_wifi_open;
     rw009_wifi_device.parent.parent.close      = rw009_wifi_close;
     rw009_wifi_device.parent.parent.read       = rw009_wifi_read;
     rw009_wifi_device.parent.parent.write      = rw009_wifi_write;
     rw009_wifi_device.parent.parent.control    = rw009_wifi_control;
+#endif
     rw009_wifi_device.parent.parent.user_data  = RT_NULL;
 
     rw009_wifi_device.parent.eth_rx     = rw009_wifi_rx;

+ 16 - 0
components/drivers/src/pipe.c

@@ -416,6 +416,18 @@ rt_err_t  rt_pipe_control(rt_device_t dev, int cmd, void *args)
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops pipe_ops = 
+{
+    RT_NULL,
+    rt_pipe_open,
+    rt_pipe_close,
+    rt_pipe_read,
+    rt_pipe_write,
+    rt_pipe_control,
+};
+#endif
+
 rt_pipe_t *rt_pipe_create(const char *name, int bufsz)
 {
     rt_pipe_t *pipe;
@@ -434,12 +446,16 @@ rt_pipe_t *rt_pipe_create(const char *name, int bufsz)
 
     dev = &(pipe->parent);
     dev->type = RT_Device_Class_Pipe;
+#ifdef RT_USING_DEVICE_OPS
+    dev->ops         = &pipe_ops;
+#else
     dev->init        = RT_NULL;
     dev->open        = rt_pipe_open;
     dev->read        = rt_pipe_read;
     dev->write       = rt_pipe_write;
     dev->close       = rt_pipe_close;
     dev->control     = rt_pipe_control;
+#endif
 
     dev->rx_indicate = RT_NULL;
     dev->tx_complete = RT_NULL;

+ 13 - 0
components/drivers/usb/usbdevice/class/ecm.c

@@ -327,6 +327,19 @@ static rt_err_t rt_ecm_eth_control(rt_device_t dev, int cmd, void *args)
 
     return RT_EOK;
 }
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops ecm_device_ops =
+{
+    rt_ecm_eth_init,
+    rt_ecm_eth_open,
+    rt_ecm_eth_close,
+    rt_ecm_eth_read,
+    rt_ecm_eth_write,
+    rt_ecm_eth_control
+};
+#endif
+
 struct pbuf *rt_ecm_eth_rx(rt_device_t dev)
 {
     struct pbuf* p = RT_NULL;

+ 20 - 1
components/drivers/usb/usbdevice/class/hid.c

@@ -592,14 +592,33 @@ static void hid_thread_entry(void* parameter)
 		HID_Report_Received(&report);
 	}
 }
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops hid_device_ops =
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    _hid_write,
+    RT_NULL,
+};
+#endif
+
 static rt_uint8_t hid_mq_pool[(sizeof(struct hid_report)+sizeof(void*))*8];
 static void rt_usb_hid_init(struct ufunction *func)
 {
     struct hid_s *hiddev;
     hiddev = (struct hid_s *)func->user_data;
     rt_memset(&hiddev->parent, 0, sizeof(hiddev->parent));
+
+#ifdef RT_USING_DEVICE_OPS
+    hiddev->parent.ops   = &hid_device_ops;
+#else
     hiddev->parent.write = _hid_write;
-	hiddev->func = func;
+#endif
+    hiddev->func = func;
+
     rt_device_register(&hiddev->parent, "hidd", RT_DEVICE_FLAG_RDWR);
     rt_mq_init(&hiddev->hid_mq, "hiddmq", hid_mq_pool, sizeof(struct hid_report),
                             sizeof(hid_mq_pool), RT_IPC_FLAG_FIFO);

+ 19 - 2
components/drivers/usb/usbdevice/class/rndis.c

@@ -1180,6 +1180,19 @@ rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p)
 
     return result;
 }
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops rndis_device_ops =
+{
+    rt_rndis_eth_init,
+    rt_rndis_eth_open,
+    rt_rndis_eth_close,
+    rt_rndis_eth_read,
+    rt_rndis_eth_write,
+    rt_rndis_eth_control
+};
+#endif
+
 #endif /* RT_USING_LWIP */
 
 #ifdef  RNDIS_DELAY_LINK_UP
@@ -1307,20 +1320,24 @@ ufunction_t rt_usbd_function_rndis_create(udevice_t device)
     _rndis->host_addr[4]                = 0xEA;//*(const rt_uint8_t *)(0x0FE081F1);
     _rndis->host_addr[5]                = 0x13;//*(const rt_uint8_t *)(0x0FE081F2);
 
+#ifdef RT_USING_DEVICE_OPS
+    _rndis->parent.parent.ops           = &rndis_device_ops;
+#else
     _rndis->parent.parent.init          = rt_rndis_eth_init;
     _rndis->parent.parent.open          = rt_rndis_eth_open;
     _rndis->parent.parent.close         = rt_rndis_eth_close;
     _rndis->parent.parent.read          = rt_rndis_eth_read;
     _rndis->parent.parent.write         = rt_rndis_eth_write;
     _rndis->parent.parent.control       = rt_rndis_eth_control;
+#endif
     _rndis->parent.parent.user_data     = device;
 
     _rndis->parent.eth_rx               = rt_rndis_eth_rx;
     _rndis->parent.eth_tx               = rt_rndis_eth_tx;
 
-	/* register eth device */
+    /* register eth device */
     eth_device_init(&((rt_rndis_eth_t)cdc->user_data)->parent, "u0");
-   
+
 #endif /* RT_USING_LWIP */
 
     return cdc;

+ 18 - 0
components/drivers/usb/usbdevice/class/winusb.c

@@ -246,16 +246,34 @@ static rt_err_t  win_usb_control(rt_device_t dev, int cmd, void *args)
     }
     return RT_EOK;
 }
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops winusb_device_ops =
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    win_usb_read,
+    win_usb_write,
+    win_usb_control,
+};
+#endif
+
 static rt_err_t rt_usb_winusb_init(ufunction_t func)
 {
     winusb_device_t winusb_device   = (winusb_device_t)func->user_data;
     winusb_device->parent.type      = RT_Device_Class_Miscellaneous;
+
+#ifdef RT_USING_DEVICE_OPS
+    winusb_device->parent.ops       = &winusb_device_ops;
+#else
     winusb_device->parent.init      = RT_NULL;
     winusb_device->parent.open      = RT_NULL;
     winusb_device->parent.close     = RT_NULL;
     winusb_device->parent.read      = win_usb_read;
     winusb_device->parent.write     = win_usb_write;
     winusb_device->parent.control   = win_usb_control;
+#endif
 
     winusb_device->parent.user_data = func;
 

+ 97 - 81
components/drivers/usb/usbhost/class/adk.c

@@ -37,7 +37,7 @@ static const char* _adk_uri = RT_NULL;
 static const char* _adk_serial = RT_NULL;
 
 rt_err_t rt_usbh_adk_set_string(const char* manufacturer, const char* model,
-    const char* description, const char* _version, const char* uri, 
+    const char* description, const char* _version, const char* uri,
     const char* serial)
 {
     _adk_manufacturer = manufacturer;
@@ -62,31 +62,31 @@ RTM_EXPORT(rt_usbh_adk_set_string);
  * @param intf the interface instance.
  * @duration the idle period of requesting data.
  * @report_id the report id
- * 
+ *
  * @return the error code, RT_EOK on successfully.
 */
 static rt_err_t rt_usbh_adk_get_protocol(struct uintf* intf, rt_uint16_t *protocol)
 {
     struct urequest setup;
-    uinst_t device;    
+    uinst_t device;
     int timeout = 100;
-            
+
         /* parameter check */
     RT_ASSERT(intf != RT_NULL);
     RT_ASSERT(intf->device != RT_NULL);
 
     device = intf->device;
 
-    setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_VENDOR | 
+    setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_VENDOR |
         USB_REQ_TYPE_DEVICE;
     setup.request = USB_REQ_GET_PROTOCOL;
     setup.index = 0;
     setup.length = 2;
     setup.value = 0;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, (void*)protocol, 2, 
+    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, (void*)protocol, 2,
         timeout) == 0) return RT_EOK;
-    else return -RT_FALSE;    
+    else return -RT_FALSE;
 }
 
 /**
@@ -95,32 +95,32 @@ static rt_err_t rt_usbh_adk_get_protocol(struct uintf* intf, rt_uint16_t *protoc
  * @param intf the interface instance.
  * @duration the idle period of requesting data.
  * @report_id the report id
- * 
+ *
  * @return the error code, RT_EOK on successfully.
 */
-static rt_err_t rt_usbh_adk_send_string(struct uintf* intf, rt_uint16_t index, 
+static rt_err_t rt_usbh_adk_send_string(struct uintf* intf, rt_uint16_t index,
     const char* str)
 {
     struct urequest setup;
-    uinst_t device;    
+    uinst_t device;
     int timeout = 100;
-            
+
         /* parameter check */
     RT_ASSERT(intf != RT_NULL);
     RT_ASSERT(intf->device != RT_NULL);
 
     device = intf->device;
 
-    setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_VENDOR | 
+    setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_VENDOR |
         USB_REQ_TYPE_DEVICE;
     setup.request = USB_REQ_SEND_STRING;
     setup.index = index;
     setup.length = rt_strlen(str) + 1;
     setup.value = 0;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, (void*)str, 
+    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, (void*)str,
         rt_strlen(str) + 1, timeout) == 0) return RT_EOK;
-    else return -RT_FALSE;   
+    else return -RT_FALSE;
 }
 
 /**
@@ -129,41 +129,41 @@ static rt_err_t rt_usbh_adk_send_string(struct uintf* intf, rt_uint16_t index,
  * @param intf the interface instance.
  * @duration the idle period of requesting data.
  * @report_id the report id
- * 
+ *
  * @return the error code, RT_EOK on successfully.
 */
 static rt_err_t rt_usbh_adk_start(struct uintf* intf)
 {
     struct urequest setup;
-    uinst_t device;    
+    uinst_t device;
     int timeout = 100;
-            
+
         /* parameter check */
     RT_ASSERT(intf != RT_NULL);
     RT_ASSERT(intf->device != RT_NULL);
 
     device = intf->device;
 
-    setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_VENDOR | 
+    setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_VENDOR |
         USB_REQ_TYPE_DEVICE;
     setup.request = USB_REQ_START;
     setup.index = 0;
     setup.length = 0;
     setup.value = 0;
 
-    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, 
+    if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0,
         timeout) == 0) return RT_EOK;
-    else return -RT_FALSE;   
+    else return -RT_FALSE;
 }
 
 /**
  * This function will read data from usb adk device
  *
  * @param intf the interface instance.
- * 
+ *
  * @return the error code, RT_EOK on successfully.
 */
-static rt_size_t rt_usbh_adk_read(rt_device_t device, rt_off_t pos, void* buffer, 
+static rt_size_t rt_usbh_adk_read(rt_device_t device, rt_off_t pos, void* buffer,
     rt_size_t size)
 {
     uadk_t adk;
@@ -177,9 +177,9 @@ static rt_size_t rt_usbh_adk_read(rt_device_t device, rt_off_t pos, void* buffer
     intf = (struct uintf*)device->user_data;
     adk = (uadk_t)intf->user_data;
 
-    length = rt_usb_hcd_bulk_xfer(intf->device->hcd, adk->pipe_in, 
+    length = rt_usb_hcd_bulk_xfer(intf->device->hcd, adk->pipe_in,
         buffer, size, 300);
-    
+
     return length;
 
 }
@@ -188,33 +188,45 @@ static rt_size_t rt_usbh_adk_read(rt_device_t device, rt_off_t pos, void* buffer
  * This function will write data to usb adk device
  *
  * @param intf the interface instance.
- * 
+ *
  * @return the error code, RT_EOK on successfully.
 */
-static rt_size_t rt_usbh_adk_write (rt_device_t device, rt_off_t pos, const void* buffer, 
+static rt_size_t rt_usbh_adk_write (rt_device_t device, rt_off_t pos, const void* buffer,
     rt_size_t size)
 {
     uadk_t adk;
     rt_size_t length;
     struct uintf* intf;
 
-    RT_ASSERT(buffer != RT_NULL);    
+    RT_ASSERT(buffer != RT_NULL);
 
     intf = (struct uintf*)device->user_data;
     adk = (uadk_t)intf->user_data;
 
-    length = rt_usb_hcd_bulk_xfer(intf->device->hcd, adk->pipe_out, 
+    length = rt_usb_hcd_bulk_xfer(intf->device->hcd, adk->pipe_out,
         (void*)buffer, size, 300);
-    
+
     return length;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops adk_device_ops =
+{
+    RT_NULL;
+    RT_NULL;
+    RT_NULL;
+    rt_usbh_adk_read;
+    rt_usbh_adk_write;
+    RT_NULL;
+};
+#endif
+
 /**
  * This function will run adk class driver when usb device is detected and identified
  *  as a adk class device, it will continue the enumulate process.
  *
  * @param arg the argument.
- * 
+ *
  * @return the error code, RT_EOK on successfully.
  */
 static rt_err_t rt_usbh_adk_enable(void* arg)
@@ -224,8 +236,8 @@ static rt_err_t rt_usbh_adk_enable(void* arg)
     struct uintf* intf = (struct uintf*)arg;
     udev_desc_t dev_desc;
     rt_uint16_t protocol;
-    rt_err_t ret;    
-    
+    rt_err_t ret;
+
     /* parameter check */
     if(intf == RT_NULL)
     {
@@ -234,72 +246,72 @@ static rt_err_t rt_usbh_adk_enable(void* arg)
     }
 
     RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbh_adk_run\n"));
-        
+
     dev_desc = &intf->device->dev_desc;
-    if(dev_desc->idVendor == USB_ACCESSORY_VENDOR_ID && 
-        (dev_desc->idProduct == USB_ACCESSORY_PRODUCT_ID || 
+    if(dev_desc->idVendor == USB_ACCESSORY_VENDOR_ID &&
+        (dev_desc->idProduct == USB_ACCESSORY_PRODUCT_ID ||
         dev_desc->idProduct == USB_ACCESSORY_ADB_PRODUCT_ID))
     {
         if(intf->intf_desc->bInterfaceSubClass != 0xFF) return -RT_ERROR;
-    
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("found android accessory device\n"));        
+
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("found android accessory device\n"));
     }
     else
     {
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("switch device\n"));        
-        
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("switch device\n"));
+
         if((ret = rt_usbh_adk_get_protocol(intf, &protocol)) != RT_EOK)
         {
             rt_kprintf("rt_usbh_adk_get_protocol failed\n");
             return ret;
         }
 
-        if(protocol != 1) 
+        if(protocol != 1)
         {
             rt_kprintf("read protocol failed\n");
             return -RT_ERROR;
-        }       
+        }
 
-        rt_usbh_adk_send_string(intf, 
+        rt_usbh_adk_send_string(intf,
             ACCESSORY_STRING_MANUFACTURER, _adk_manufacturer);
-        rt_usbh_adk_send_string(intf, 
+        rt_usbh_adk_send_string(intf,
             ACCESSORY_STRING_MODEL, _adk_model);
-        rt_usbh_adk_send_string(intf, 
+        rt_usbh_adk_send_string(intf,
             ACCESSORY_STRING_DESCRIPTION, _adk_description);
-        rt_usbh_adk_send_string(intf, 
+        rt_usbh_adk_send_string(intf,
             ACCESSORY_STRING_VERSION, _adk_version);
-        rt_usbh_adk_send_string(intf, 
-            ACCESSORY_STRING_URI, _adk_uri);        
-        rt_usbh_adk_send_string(intf, 
-            ACCESSORY_STRING_SERIAL, _adk_serial);            
+        rt_usbh_adk_send_string(intf,
+            ACCESSORY_STRING_URI, _adk_uri);
+        rt_usbh_adk_send_string(intf,
+            ACCESSORY_STRING_SERIAL, _adk_serial);
 
         RT_DEBUG_LOG(RT_DEBUG_USB, ("manufacturer %s\n", _adk_manufacturer));
         RT_DEBUG_LOG(RT_DEBUG_USB, ("model %s\n", _adk_model));
         RT_DEBUG_LOG(RT_DEBUG_USB, ("description %s\n", _adk_description));
         RT_DEBUG_LOG(RT_DEBUG_USB, ("version %s\n", _adk_version));
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("uri %s\n", _adk_uri));       
-        RT_DEBUG_LOG(RT_DEBUG_USB, ("serial %s\n", _adk_serial));               
-        
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("uri %s\n", _adk_uri));
+        RT_DEBUG_LOG(RT_DEBUG_USB, ("serial %s\n", _adk_serial));
+
         if((ret = rt_usbh_adk_start(intf)) != RT_EOK)
         {
             rt_kprintf("rt_usbh_adk_start failed\n");
             return ret;
-        }        
+        }
 
         return RT_EOK;
     }
-    
+
     adk = rt_malloc(sizeof(struct uadkinst));
     RT_ASSERT(adk != RT_NULL);
 
     /* initilize the data structure */
-    rt_memset(adk, 0, sizeof(struct uadkinst));    
+    rt_memset(adk, 0, sizeof(struct uadkinst));
     intf->user_data = (void*)adk;
 
     for(i=0; i<intf->intf_desc->bNumEndpoints; i++)
-    {        
+    {
         uep_desc_t ep_desc;
-        
+
         /* get endpoint descriptor from interface descriptor */
         rt_usbh_get_endpoint_descriptor(intf->intf_desc, i, &ep_desc);
         if(ep_desc == RT_NULL)
@@ -307,24 +319,24 @@ static rt_err_t rt_usbh_adk_enable(void* arg)
             rt_kprintf("rt_usb_get_endpoint_descriptor error\n");
             return -RT_ERROR;
         }
-        
-        /* the endpoint type of adk class should be BULK */    
+
+        /* the endpoint type of adk class should be BULK */
         if((ep_desc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_BULK)
             continue;
-        
+
         /* allocate pipes according to the endpoint type */
         if(ep_desc->bEndpointAddress & USB_DIR_IN)
         {
             /* allocate an in pipe for the adk instance */
-            ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &adk->pipe_in, 
+            ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &adk->pipe_in,
                 intf, ep_desc, RT_NULL);
             if(ret != RT_EOK) return ret;
         }
         else
-        {        
+        {
             /* allocate an output pipe for the adk instance */
-            ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &adk->pipe_out, 
-                intf, ep_desc, RT_NULL);            
+            ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &adk->pipe_out,
+                intf, ep_desc, RT_NULL);
             if(ret != RT_EOK) return ret;
         }
     }
@@ -334,33 +346,37 @@ static rt_err_t rt_usbh_adk_enable(void* arg)
     {
         rt_kprintf("pipe error, unsupported device\n");
         return -RT_ERROR;
-    }    
+    }
 
     /* set configuration */
     ret = rt_usbh_set_configure(intf->device, 1);
     if(ret != RT_EOK) return ret;
 
     /* register adk device */
-    adk->device.type  = RT_Device_Class_Char;                         
-    adk->device.init = RT_NULL;         
-    adk->device.open = RT_NULL;         
-    adk->device.close = RT_NULL;                 
-    adk->device.read = rt_usbh_adk_read;
-    adk->device.write = rt_usbh_adk_write;
+    adk->device.type    = RT_Device_Class_Char;
+#ifdef RT_USING_DEVICE_OPS
+    adk->device.ops     = &adk_device_ops;
+#else
+    adk->device.init    = RT_NULL;
+    adk->device.open    = RT_NULL;
+    adk->device.close   = RT_NULL;
+    adk->device.read    = rt_usbh_adk_read;
+    adk->device.write   = rt_usbh_adk_write;
     adk->device.control = RT_NULL;
+#endif
     adk->device.user_data = (void*)intf;
 
     rt_device_register(&adk->device, "adkdev", RT_DEVICE_FLAG_RDWR);
-    
+
     return RT_EOK;
 }
 
 /**
- * This function will be invoked when usb device plug out is detected and it would clean 
+ * This function will be invoked when usb device plug out is detected and it would clean
  * and release all hub class related resources.
  *
  * @param arg the argument.
- * 
+ *
  * @return the error code, RT_EOK on successfully.
  */
 static rt_err_t rt_usbh_adk_disable(void* arg)
@@ -373,12 +389,12 @@ static rt_err_t rt_usbh_adk_disable(void* arg)
     RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbh_adk_stop\n"));
 
     adk = (uadk_t)intf->user_data;
-    if(adk == RT_NULL) 
+    if(adk == RT_NULL)
     {
-        rt_free(intf);    
+        rt_free(intf);
         return RT_EOK;
     }
-    
+
     if(adk->pipe_in != RT_NULL)
         rt_usb_hcd_free_pipe(intf->device->hcd, adk->pipe_in);
 
@@ -389,11 +405,11 @@ static rt_err_t rt_usbh_adk_disable(void* arg)
     rt_device_unregister(&adk->device);
 
     /* free adk instance */
-    if(adk != RT_NULL) 
+    if(adk != RT_NULL)
     {
         rt_free(adk);
     }
-    
+
     /* free interface instance */
     rt_free(intf);
 
@@ -403,13 +419,13 @@ static rt_err_t rt_usbh_adk_disable(void* arg)
 /**
  * This function will register adk class driver to the usb class driver manager.
  * and it should be invoked in the usb system initialization.
- * 
+ *
  * @return the error code, RT_EOK on successfully.
  */
 ucd_t rt_usbh_class_driver_adk(void)
 {
     adk_driver.class_code = USB_CLASS_ADK;
-    
+
     adk_driver.enable = rt_usbh_adk_enable;
     adk_driver.disable = rt_usbh_adk_disable;
 

+ 90 - 70
components/drivers/usb/usbhost/class/udisk.c

@@ -31,7 +31,7 @@ static int udisk_get_id(void)
         if((_udisk_idset & (1 << i)) != 0) continue;
         else break;
     }
-    
+
     /* it should not happen */
     if(i == UDISK_MAX_COUNT) RT_ASSERT(0);
 
@@ -43,14 +43,14 @@ static void udisk_free_id(int id)
 {
     RT_ASSERT(id < UDISK_MAX_COUNT)
 
-    _udisk_idset &= ~(1 << id); 
+    _udisk_idset &= ~(1 << id);
 }
 
 /**
  * This function will initialize the udisk device
  *
  * @param dev the pointer of device driver structure
- * 
+ *
  * @return RT_EOK
  */
 static rt_err_t rt_udisk_init(rt_device_t dev)
@@ -68,7 +68,7 @@ static rt_err_t rt_udisk_init(rt_device_t dev)
  *
  * @return the actually read size on successful, otherwise negative returned.
  */
-static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer, 
+static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer,
     rt_size_t size)
 {
     rt_err_t ret;
@@ -81,18 +81,18 @@ static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer,
     RT_ASSERT(buffer != RT_NULL);
 
     if(size > 4096) timeout = 800;
-    
+
     data = (struct ustor_data*)dev->user_data;
     intf = data->intf;
 
     ret = rt_usbh_storage_read10(intf, (rt_uint8_t*)buffer, pos, size, timeout);
-	
+
     if (ret != RT_EOK)
     {
         rt_kprintf("usb mass_storage read failed\n");
         return 0;
     }
-    
+
     return size;
 }
 
@@ -106,7 +106,7 @@ static rt_size_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer,
  *
  * @return the actually written size on successful, otherwise negative returned.
  */
-static rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buffer, 
+static rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buffer,
     rt_size_t size)
 {
     rt_err_t ret;
@@ -129,7 +129,7 @@ static rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buff
         rt_kprintf("usb mass_storage write %d sector failed\n", size);
         return 0;
     }
-    
+
     return size;
 }
 
@@ -138,9 +138,9 @@ static rt_size_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buff
  *
  * @param intf the interface instance.
  * @param buffer the data buffer to save inquiry data
- * 
+ *
  * @return the error code, RT_EOK on successfully.
- */    
+ */
 static rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args)
 {
     ustor_t stor;
@@ -164,14 +164,26 @@ static rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args)
         geometry->sector_count = stor->capicity[0];
     }
 
-    return RT_EOK;    
+    return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops udisk_device_ops =
+{
+    rt_udisk_init,
+    RT_NULL,
+    RT_NULL,
+    rt_udisk_read,
+    rt_udisk_write,
+    rt_udisk_control
+};
+#endif
+
 /**
  * This function will run udisk driver when usb disk is detected.
  *
  * @param intf the usb interface instance.
- * 
+ *
  * @return the error code, RT_EOK on successfully.
  */
 rt_err_t rt_udisk_run(struct uhintf* intf)
@@ -179,10 +191,10 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
     int i = 0;
     rt_err_t ret;
     char dname[4];
-    char sname[8];    
+    char sname[8];
     rt_uint8_t max_lun, *sector, sense[18], inquiry[36];
-    struct dfs_partition part[MAX_PARTITION_COUNT];    
-    ustor_t stor;    
+    struct dfs_partition part[MAX_PARTITION_COUNT];
+    ustor_t stor;
 
     /* check parameter */
     RT_ASSERT(intf != RT_NULL);
@@ -193,40 +205,40 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
 //        rt_usbh_clear_feature(intf->device, 0, USB_FEATURE_ENDPOINT_HALT);
     /* reset mass storage class device */
     ret = rt_usbh_storage_reset(intf);
-    if(ret != RT_EOK) return ret;    
+    if(ret != RT_EOK) return ret;
 
     stor = (ustor_t)intf->user_data;
 
-    /* get max logic unit number */    
+    /* get max logic unit number */
     ret = rt_usbh_storage_get_max_lun(intf, &max_lun);
-    if(ret != RT_EOK)    
+    if(ret != RT_EOK)
         rt_usbh_clear_feature(intf->device, 0, USB_FEATURE_ENDPOINT_HALT);
 
     /* reset pipe in endpoint */
     if(stor->pipe_in->status == UPIPE_STATUS_STALL)
     {
-        ret = rt_usbh_clear_feature(intf->device, 
+        ret = rt_usbh_clear_feature(intf->device,
         stor->pipe_in->ep.bEndpointAddress, USB_FEATURE_ENDPOINT_HALT);
-        if(ret != RT_EOK) return ret; 
+        if(ret != RT_EOK) return ret;
     }
-       
+
 
     /* reset pipe out endpoint */
     if(stor->pipe_out->status == UPIPE_STATUS_STALL)
     {
-        ret = rt_usbh_clear_feature(intf->device, 
+        ret = rt_usbh_clear_feature(intf->device,
         stor->pipe_out->ep.bEndpointAddress, USB_FEATURE_ENDPOINT_HALT);
-        if(ret != RT_EOK) return ret; 
+        if(ret != RT_EOK) return ret;
     }
 
     while((ret = rt_usbh_storage_inquiry(intf, inquiry)) != RT_EOK)
-    {    
+    {
         if(ret == -RT_EIO) return ret;
 
-        rt_thread_delay(5);        
+        rt_thread_delay(5);
         if(i++ < 10) continue;
         rt_kprintf("rt_usbh_storage_inquiry error\n");
-        return -RT_ERROR;    
+        return -RT_ERROR;
     }
 
     i = 0;
@@ -235,26 +247,26 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
     while((ret = rt_usbh_storage_test_unit_ready(intf)) != RT_EOK)
     {
         if(ret == -RT_EIO) return ret;
-        
+
         ret = rt_usbh_storage_request_sense(intf, sense);
         if(ret == -RT_EIO) return ret;
-        
-        rt_thread_delay(10);        
+
+        rt_thread_delay(10);
         if(i++ < 10) continue;
 
         rt_kprintf("rt_usbh_storage_test_unit_ready error\n");
-        return -RT_ERROR;    
+        return -RT_ERROR;
     }
 
     i = 0;
     rt_memset(stor->capicity, 0, sizeof(stor->capicity));
 
     /* get storage capacity */
-    while((ret = rt_usbh_storage_get_capacity(intf, 
+    while((ret = rt_usbh_storage_get_capacity(intf,
         (rt_uint8_t*)stor->capicity)) != RT_EOK)
-    {        
-        if(ret == -RT_EIO) return ret;    
-        
+    {
+        if(ret == -RT_EIO) return ret;
+
         rt_thread_delay(50);
         if(i++ < 10) continue;
 
@@ -262,16 +274,16 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
         stor->capicity[1] = 0x200;
 
         rt_kprintf("rt_usbh_storage_get_capacity error\n");
-        break;    
+        break;
     }
 
     stor->capicity[0] = uswap_32(stor->capicity[0]);
     stor->capicity[1] = uswap_32(stor->capicity[1]);
     stor->capicity[0] += 1;
-    
-    RT_DEBUG_LOG(RT_DEBUG_USB, ("capicity %d, block size %d\n", 
+
+    RT_DEBUG_LOG(RT_DEBUG_USB, ("capicity %d, block size %d\n",
         stor->capicity[0], stor->capicity[1]));
-    
+
     /* get the first sector to read partition table */
     sector = (rt_uint8_t*) rt_malloc (SECTOR_SIZE);
     if (sector == RT_NULL)
@@ -283,42 +295,46 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
     rt_memset(sector, 0, SECTOR_SIZE);
 
     RT_DEBUG_LOG(RT_DEBUG_USB, ("read partition table\n"));
-    
+
     /* get the partition table */
     ret = rt_usbh_storage_read10(intf, sector, 0, 1, 500);
     if(ret != RT_EOK)
     {
         rt_kprintf("read parition table error\n");
 
-        rt_free(sector);        
-        return -RT_ERROR;    
+        rt_free(sector);
+        return -RT_ERROR;
     }
 
     RT_DEBUG_LOG(RT_DEBUG_USB, ("finished reading partition\n"));
-    
+
     for(i=0; i<MAX_PARTITION_COUNT; i++)
-    {        
+    {
         /* get the first partition */
         ret = dfs_filesystem_get_partition(&part[i], sector, i);
         if (ret == RT_EOK)
-        {                
-            struct ustor_data* data = rt_malloc(sizeof(struct ustor_data));    
+        {
+            struct ustor_data* data = rt_malloc(sizeof(struct ustor_data));
             rt_memset(data, 0, sizeof(struct ustor_data));
-            data->intf = intf;            
+            data->intf = intf;
             data->udisk_id = udisk_get_id();
             rt_snprintf(dname, 6, "ud%d-%d", data->udisk_id, i);
             rt_snprintf(sname, 8, "sem_ud%d",  i);
             data->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
 
             /* register sdcard device */
-            stor->dev[i].type  = RT_Device_Class_Block;
-            stor->dev[i].init = rt_udisk_init;            
-            stor->dev[i].read = rt_udisk_read;
-            stor->dev[i].write = rt_udisk_write;
+            stor->dev[i].type    = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+            stor->dev[i].ops     = &udisk_device_ops;
+#else
+            stor->dev[i].init    = rt_udisk_init;
+            stor->dev[i].read    = rt_udisk_read;
+            stor->dev[i].write   = rt_udisk_write;
             stor->dev[i].control = rt_udisk_control;
+#endif
             stor->dev[i].user_data = (void*)data;
 
-            rt_device_register(&stor->dev[i], dname, RT_DEVICE_FLAG_RDWR | 
+            rt_device_register(&stor->dev[i], dname, RT_DEVICE_FLAG_RDWR |
                 RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
 
             stor->dev_cnt++;
@@ -330,16 +346,16 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
             else
             {
                 RT_DEBUG_LOG(RT_DEBUG_USB, ("udisk part %d mount failed\n", i));
-            }    
+            }
         }
         else
         {
             if(i == 0)
-            {                
-                struct ustor_data* data = rt_malloc(sizeof(struct ustor_data));                
-                rt_memset(data, 0, sizeof(struct ustor_data));                
+            {
+                struct ustor_data* data = rt_malloc(sizeof(struct ustor_data));
+                rt_memset(data, 0, sizeof(struct ustor_data));
                 data->udisk_id = udisk_get_id();
-                
+
                 /* there is no partition table */
                 data->part.offset = 0;
                 data->part.size   = 0;
@@ -349,23 +365,27 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
                 rt_snprintf(dname, 7, "udisk%d", data->udisk_id);
 
                 /* register sdcard device */
-                stor->dev[0].type  = RT_Device_Class_Block;                         
-                stor->dev[0].init = rt_udisk_init;            
-                stor->dev[0].read = rt_udisk_read;
-                stor->dev[0].write = rt_udisk_write;
+                stor->dev[0].type    = RT_Device_Class_Block;
+#ifdef RT_USING_DEVICE_OPS
+                stor->dev[i].ops     = &udisk_device_ops;
+#else
+                stor->dev[0].init    = rt_udisk_init;
+                stor->dev[0].read    = rt_udisk_read;
+                stor->dev[0].write   = rt_udisk_write;
                 stor->dev[0].control = rt_udisk_control;
+#endif
                 stor->dev[0].user_data = (void*)data;
 
                 rt_device_register(&stor->dev[0], dname,
-                    RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE 
+                    RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE
                     | RT_DEVICE_FLAG_STANDALONE);
 
                 stor->dev_cnt++;
-                if (dfs_mount(stor->dev[0].parent.name, UDISK_MOUNTPOINT, 
+                if (dfs_mount(stor->dev[0].parent.name, UDISK_MOUNTPOINT,
                     "elm", 0, 0) == 0)
-                {            
+                {
                     rt_kprintf("Mount FAT on Udisk successful.\n");
-                }                
+                }
                 else
                 {
                     rt_kprintf("Mount FAT on Udisk failed.\n");
@@ -382,31 +402,31 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
 }
 
 /**
- * This function will be invoked when usb disk plug out is detected and it would clean 
+ * This function will be invoked when usb disk plug out is detected and it would clean
  * and release all udisk related resources.
  *
  * @param intf the usb interface instance.
- * 
+ *
  * @return the error code, RT_EOK on successfully.
  */
 rt_err_t rt_udisk_stop(struct uhintf* intf)
 {
     int i;
-    ustor_t stor;    
+    ustor_t stor;
     struct ustor_data* data;
 
     /* check parameter */
     RT_ASSERT(intf != RT_NULL);
     RT_ASSERT(intf->device != RT_NULL);
 
-    stor = (ustor_t)intf->user_data;    
+    stor = (ustor_t)intf->user_data;
     RT_ASSERT(stor != RT_NULL);
 
     for(i=0; i<stor->dev_cnt; i++)
     {
         rt_device_t dev = &stor->dev[i];
         data = (struct ustor_data*)dev->user_data;
-        
+
         /* unmount filesystem */
         dfs_unmount(UDISK_MOUNTPOINT);
 

+ 16 - 0
components/drivers/watchdog/watchdog.c

@@ -78,6 +78,18 @@ static rt_err_t rt_watchdog_control(struct rt_device *dev,
     return (wtd->ops->control(wtd, cmd, args));
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops wdt_ops = 
+{
+    rt_watchdog_init,
+    rt_watchdog_open,
+    rt_watchdog_close,
+    RT_NULL,
+    RT_NULL,
+    rt_watchdog_control,
+};
+#endif
+
 /**
  * This function register a watchdog device
  */
@@ -95,12 +107,16 @@ rt_err_t rt_hw_watchdog_register(struct rt_watchdog_device *wtd,
     device->rx_indicate = RT_NULL;
     device->tx_complete = RT_NULL;
 
+#ifdef RT_USING_DEVICE_OPS
+    device->ops         = &wdt_ops;
+#else
     device->init        = rt_watchdog_init;
     device->open        = rt_watchdog_open;
     device->close       = rt_watchdog_close;
     device->read        = RT_NULL;
     device->write       = RT_NULL;
     device->control     = rt_watchdog_control;
+#endif
     device->user_data   = data;
 
     /* register a character device */

+ 0 - 107
components/finsh/cmd.c

@@ -614,113 +614,6 @@ int list_module(void)
 }
 FINSH_FUNCTION_EXPORT(list_module, list module in system);
 MSH_CMD_EXPORT(list_module, list module in system);
-
-int list_mod_detail(const char *name)
-{
-    int i;
-    struct rt_module *module;
-
-    /* find module */
-    if ((module = rt_module_find(name)) != RT_NULL)
-    {
-        /* module has entry point */
-        if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
-        {
-            struct rt_thread *thread;
-            struct rt_list_node *tlist;
-            rt_uint8_t *ptr;
-
-            /* list main thread in module */
-            if (module->module_thread != RT_NULL)
-            {
-                rt_uint8_t stat;
-
-                rt_kprintf("main thread  pri  status      sp     stack size max used   left tick  error\n");
-                rt_kprintf("------------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
-                thread = module->module_thread;
-                rt_kprintf("%-8.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
-
-                stat = (thread->stat & RT_THREAD_STAT_MASK);
-                if (stat == RT_THREAD_READY)        rt_kprintf(" ready  ");
-                else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
-                else if (stat == RT_THREAD_INIT)    rt_kprintf(" init   ");
-
-                ptr = (rt_uint8_t *)thread->stack_addr;
-                while (*ptr == '#')ptr ++;
-
-                rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
-                           thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
-                           thread->stack_size,
-                           thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
-                           thread->remaining_tick,
-                           thread->error);
-            }
-
-            /* list sub thread in module */
-            tlist = &module->module_object[RT_Object_Class_Thread].object_list;
-            if (!rt_list_isempty(tlist)) _list_thread(tlist);
-#ifdef RT_USING_SEMAPHORE
-            /* list semaphored in module */
-            tlist = &module->module_object[RT_Object_Class_Semaphore].object_list;
-            if (!rt_list_isempty(tlist)) _list_sem(tlist);
-#endif
-#ifdef RT_USING_MUTEX
-            /* list mutex in module */
-            tlist = &module->module_object[RT_Object_Class_Mutex].object_list;
-            if (!rt_list_isempty(tlist)) _list_mutex(tlist);
-#endif
-#ifdef RT_USING_EVENT
-            /* list event in module */
-            tlist = &module->module_object[RT_Object_Class_Event].object_list;
-            if (!rt_list_isempty(tlist)) _list_event(tlist);
-#endif
-#ifdef RT_USING_MAILBOX
-            /* list mailbox in module */
-            tlist = &module->module_object[RT_Object_Class_MailBox].object_list;
-            if (!rt_list_isempty(tlist)) _list_mailbox(tlist);
-#endif
-#ifdef RT_USING_MESSAGEQUEUE
-            /* list message queue in module */
-            tlist = &module->module_object[RT_Object_Class_MessageQueue].object_list;
-            if (!rt_list_isempty(tlist)) _list_msgqueue(tlist);
-#endif
-#ifdef RT_USING_MEMHEAP
-            /* list memory heap in module */
-            tlist = &module->module_object[RT_Object_Class_MemHeap].object_list;
-            if (!rt_list_isempty(tlist)) _list_memheap(tlist);
-#endif
-#ifdef RT_USING_MEMPOOL
-            /* list memory pool in module */
-            tlist = &module->module_object[RT_Object_Class_MemPool].object_list;
-            if (!rt_list_isempty(tlist)) _list_mempool(tlist);
-#endif
-#ifdef RT_USING_DEVICE
-            /* list device in module */
-            tlist = &module->module_object[RT_Object_Class_Device].object_list;
-            if (!rt_list_isempty(tlist)) _list_device(tlist);
-#endif
-            /* list timer in module */
-            tlist = &module->module_object[RT_Object_Class_Timer].object_list;
-            if (!rt_list_isempty(tlist)) _list_timer(tlist);
-        }
-
-        if (module->nsym > 0)
-        {
-            rt_kprintf("symbol    address   \n");
-            rt_kprintf("-------- ----------\n");
-
-            /* list module export symbols */
-            for (i = 0; i < module->nsym; i++)
-            {
-                rt_kprintf("%s 0x%x\n",
-                           module->symtab[i].name, module->symtab[i].addr);
-            }
-        }
-    }
-
-    return 0;
-}
-FINSH_FUNCTION_EXPORT(list_mod_detail, list module objects in system)
 #endif
 
 long list(void)

+ 1 - 1
components/finsh/msh.c

@@ -336,7 +336,7 @@ int msh_exec(char *cmd, rt_size_t length)
     {
         return cmd_ret;
     }
-#ifdef RT_USING_MODULE
+#if defined(RT_USING_MODULE) && defined(RT_USING_DFS)
     if (msh_exec_module(cmd, length) == 0)
     {
         return 0;

+ 2 - 0
components/libc/compilers/newlib/libc.c

@@ -35,6 +35,8 @@
 #include <pthread.h>
 #endif
 
+int	_EXFUN(putenv,(char *__string));
+
 int libc_system_init(void)
 {
 #if defined(RT_USING_DFS) & defined(RT_USING_DFS_DEVFS)

+ 2 - 0
components/libc/compilers/newlib/stdio.c

@@ -31,6 +31,8 @@
 
 #define STDIO_DEVICE_NAME_MAX   32
 
+int	_EXFUN(fileno, (FILE *));
+
 static FILE* std_console = NULL;
 
 int libc_stdio_set_console(const char* device_name, int mode)

+ 6 - 29
components/libc/compilers/newlib/syscalls.c

@@ -7,7 +7,7 @@
 #include <dfs_posix.h>
 #endif
 
-#ifdef RT_USING_PTHREADS 
+#ifdef RT_USING_PTHREADS
 #include <pthread.h>
 #endif
 
@@ -126,7 +126,7 @@ _open_r(struct _reent *ptr, const char *file, int flags, int mode)
 #endif
 }
 
-_ssize_t 
+_ssize_t
 _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes)
 {
 #ifndef RT_USING_DFS
@@ -372,7 +372,7 @@ void *_calloc_r (struct _reent *ptr, size_t size, size_t len)
     return result;
 }
 
-void 
+void
 _free_r (struct _reent *ptr, void *addr)
 {
     rt_free (addr);
@@ -387,43 +387,20 @@ _exit (int status)
     module = rt_module_self();
     if (module != RT_NULL)
     {
-        struct rt_list_node *list;
-        struct rt_object *object;
-
-        rt_enter_critical();
-        
-        /* delete all threads in the module */
-        list = &module->module_object[RT_Object_Class_Thread].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_thread_detach((rt_thread_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_thread_delete((rt_thread_t)object);
-            }
-        }
-        /* delete main thread */
-        rt_thread_delete(module->module_thread);
-        rt_exit_critical();
+        rt_thread_suspend(rt_thread_self());
 
         /* re-schedule */
         rt_schedule();
     }
 #endif
-    
+
     rt_kprintf("thread:%s exit with %d\n", rt_thread_self()->name, status);
     RT_ASSERT(0);
 
     while (1);
 }
 
-void 
+void
 _system(const char *s)
 {
     /* not support this call */

+ 7 - 0
components/lwp/Kconfig

@@ -0,0 +1,7 @@
+config RT_USING_LWP
+    bool "Using light-weight process"
+    select RT_USING_DFS
+    depends on ARCH_ARM_CORTEX_M
+    default n
+    help
+        The lwP is a light weight process running in user mode.

+ 20 - 0
components/lwp/SConscript

@@ -0,0 +1,20 @@
+Import('rtconfig')
+from building import *
+
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = []
+
+support_arch  = {"arm": ["cortex-m3", "cortex-m4", "cortex-m7"]}
+platform_file = {'armcc': 'rvds.S', 'gcc': 'gcc.S', 'iar': 'iar.S'}
+
+if rtconfig.PLATFORM in platform_file.keys():	# support platforms
+    if rtconfig.ARCH in support_arch.keys() and rtconfig.CPU in support_arch[rtconfig.ARCH]:
+        # arch/arm/cortex-m7/lwp_gcc.S
+        asm_path = 'arch/' + rtconfig.ARCH + '/' + rtconfig.CPU + '/*_' + platform_file[rtconfig.PLATFORM]
+        src = Glob('*.c') + Glob(asm_path)
+        CPPPATH = [cwd]
+
+group = DefineGroup('lwP', src, depend = ['RT_USING_LWP'], CPPPATH = CPPPATH)
+
+Return('group')

+ 176 - 0
components/lwp/arch/arm/cortex-m3/lwp_gcc.S

@@ -0,0 +1,176 @@
+/*
+ * File      : lwp_gcc.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+.cpu cortex-m3
+.syntax unified
+.thumb
+.text
+
+/*
+ * void* lwp_get_sys_api(rt_uint32_t number);
+ */
+.global lwp_get_sys_api
+.global lwp_get_kernel_sp
+.global lwp_set_kernel_sp
+
+
+/*
+ * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+ */
+.global lwp_user_entry
+.type lwp_user_entry, % function
+lwp_user_entry:
+    PUSH    {R0 - R1}           /* push text&data addr. */
+
+    MOV     R0, SP              /* v1 = SP */
+    BL      lwp_set_kernel_sp   /* lwp_set_kernel_sp(v1) */
+
+    POP     {R0 - R1}           /* pop app address to R1. */
+
+    /* set CPU to user-thread mode. */
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       /* use PSP, user-thread mode. */
+    MSR     CONTROL, R2
+
+    /* set data address. */
+    MOV     R9, R1
+
+    /* run app, only Thumb-mode. */
+    ORR     R0, R0, #0x01
+    BX      R0
+
+/*
+ * void SVC_Handler(void);
+ */
+.global SVC_Handler
+.type SVC_Handler, % function
+SVC_Handler:
+
+    PUSH    {LR}
+
+    /* get user SP. */
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                    /* push app SP. */
+    MOV     R2, R1
+
+    STMFD   R2!, {R4 - R11}     /* push app R4-R11 to app stack , and R1 not change. */
+
+    /* get SVC number. */
+    LDR     R0, [R1, #24]       /* get the app LR. */
+    LDRB    R0, [R0, #-2]       /* get the SVC No. from instruction. */
+
+    /* get kernel system API */
+    BL      lwp_get_sys_api
+
+    /* if(api == NULL) return; */
+    CMP     R0, #0
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    /* push api */
+    PUSH    {R0}
+
+    /* get kernel SP to R0. */
+    BL lwp_get_kernel_sp
+
+    POP     {R2}            /* pop api to R2. */
+    POP     {R1}            /* pop app SP to R1. */
+
+    /* copy R1(app SP) to R0(server SP). */
+    LDMFD   R1,   {R4 - R11}        /* pop exception_stack_frame to r4 - r11 register */
+    STMFD   R0!,  {R4 - R11}        /* push exception_stack_frame to server SP. */
+
+    POP     {LR}
+    PUSH    {LR}
+
+    /* save app SP. */
+    PUSH    {R0 - R3}
+    SUB     R0, R1, #0x20       /* keep {R4 - R11} */
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    /* set to thread-privilege mode. */
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    /* call api. */
+    LDR     R3, = svc_exit
+    STR     R3, [R0, #20]       /* update LR */
+    STR     R2, [R0, #24]       /* update api to PC */
+    MSR     PSP, R0         /* update stack pointer */
+    POP     {LR}            /* 0xFFFFFFED */
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+/*
+* void svc_exit(void);
+*/
+.global svc_exit
+.type svc_exit, % function
+svc_exit:
+
+    /* get user SP. */
+    PUSH    {R0}                        /* push result to SP. */
+    BL      lwp_get_kernel_sp
+
+    LDMFD   R0!, {R4 - R11}             /* pop app {R4 - R11} */
+
+    ADD     R0, R0, #16                 /* skip R0-R3 */
+    LDMFD   R0!, {R12, LR}
+    LDMFD   R0!, {R1}                   /* pop PC to R1 */
+    LDMFD   R0!, {R2}                   /* pop PSR to R2 */
+
+    /* align to 2 words */
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                        /* push user-SP to SP */
+
+    /* save server SP. */
+    ADD     R0, SP, #0x08               /* [user-SP, result] */
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                        /* pop user-SP to R3 */
+    POP     {R0}                        /* restore API result. */
+
+    MSR     APSR, R2                    /* restore PSR */
+    MSR     PSP, R3                     /* restore app stack pointer */
+
+    /* restore to PSP & thread-unprivilege mode. */
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    /* return to lwp. */
+    ORR     R1, R1, #0x01               /* only Thumb-mode. */
+    BX      R1                          /* return to user app. */

+ 176 - 0
components/lwp/arch/arm/cortex-m3/lwp_iar.S

@@ -0,0 +1,176 @@
+;/*
+; * File      : lwp_iar.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; *
+; *  This program is free software; you can redistribute it and/or modify
+; *  it under the terms of the GNU General Public License as published by
+; *  the Free Software Foundation; either version 2 of the License, or
+; *  (at your option) any later version.
+; *
+; *  This program is distributed in the hope that it will be useful,
+; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; *  GNU General Public License for more details.
+; *
+; *  You should have received a copy of the GNU General Public License along
+; *  with this program; if not, write to the Free Software Foundation, Inc.,
+; *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; */
+
+    SECTION    .text:CODE(2)
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+;/*
+; * void* lwp_get_sys_api(rt_uint32_t number);
+; */
+    IMPORT lwp_get_sys_api
+    IMPORT lwp_get_kernel_sp
+    IMPORT lwp_set_kernel_sp
+
+;/*
+; * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+; */
+    EXPORT  lwp_user_entry
+lwp_user_entry:
+
+    PUSH    {R0-R1}             ; push text&data addr.
+
+    MOV     R0, SP              ; v1 = SP
+    BL      lwp_set_kernel_sp   ; lwp_set_kernel_sp(v1)
+
+    POP     {R0-R1}             ; pop app address to R1.
+
+    ; set CPU to user-thread mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       ; use PSP, user-thread mode.
+    MSR     CONTROL, R2
+
+    ; set data address.
+    MOV     R9, R1
+
+    ; run app, only Thumb-mode.
+    ORR     R0, R0, #0x01
+    BX      R0
+
+;/*
+; * void SVC_Handler(void);
+; */
+    EXPORT SVC_Handler
+SVC_Handler:
+
+    PUSH    {LR}
+
+    ; get user SP.
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                        ; push app SP.
+    MOV     R2, R1
+
+    STMFD   R2!, {R4 - R11}              ; push app R4-R11 to app stack , and R1 not change.
+
+    ; get SVC number.
+    LDR     R0, [R1, #24]               ; get the app LR.
+    LDRB    R0, [R0, #-2]               ; get the SVC No. from instruction.
+
+    ; get kernel system API
+    BL      lwp_get_sys_api
+
+    ; if(api == NULL) return;
+    CMP     R0, #0         
+    ITTT    EQ
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    ; push api
+    PUSH    {R0}
+
+    ; get kernel SP to R0.
+    BL lwp_get_kernel_sp
+
+    POP     {R2}                        ; pop api to R2.
+    POP     {R1}                        ; pop app SP to R1.
+
+    ; copy R1(app SP) to R0(server SP).
+    LDMFD   R1,   {R4 - R11}     ; pop exception_stack_frame to r4 - r11 register
+    STMFD   R0!,  {R4 - R11}     ; push exception_stack_frame to server SP.
+
+    POP     {LR}
+    PUSH    {LR}
+
+    ; save app SP.
+    PUSH    {R0 - R3}
+    SUB     R0, R1, #0x20               ; keep {R4 - R11}
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    ; set to thread-privilege mode.
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    ; call api.
+    LDR     R3, =svc_exit
+    STR     R3, [R0, #20]       ; update LR
+    STR     R2, [R0, #24]       ; update api to PC
+    MSR     PSP, R0             ; update stack pointer
+    POP     {LR}                ; 0xFFFFFFED
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+;/*
+; * void svc_exit(void);
+; */
+    EXPORT svc_exit
+svc_exit:
+
+    ; get user SP.
+    PUSH    {R0}                    ; push result to SP.
+    BL      lwp_get_kernel_sp
+
+    LDMFD   R0!, {R4 - R11}         ; pop app {R4 - R11}
+
+    ADD     R0, R0, #16             ; skip R0-R3
+    LDMFD   R0!, {R12, LR}          ;
+    LDMFD   R0!, {R1}               ; pop PC to R1
+    LDMFD   R0!, {R2}               ; pop PSR to R2
+
+    ; align to 2 words
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                    ; push user-SP to SP
+
+    ; save server SP.
+    ADD     R0, SP, #0x08           ; [user-SP, result]
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                    ; pop user-SP to R3
+    POP     {R0}                    ; restore API result.
+
+    MSR     APSR, R2                ; restore PSR
+    MSR     PSP, R3                 ; restore app stack pointer
+
+    ; restore to PSP & thread-unprivilege mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    ; return to lwp.
+    ORR     R1, R1, #0x01           ; only Thumb-mode.
+    BX      R1                      ; return to user app.
+
+    END

+ 184 - 0
components/lwp/arch/arm/cortex-m3/lwp_rvds.S

@@ -0,0 +1,184 @@
+;/*
+; * File      : lwp_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; *
+; *  This program is free software; you can redistribute it and/or modify
+; *  it under the terms of the GNU General Public License as published by
+; *  the Free Software Foundation; either version 2 of the License, or
+; *  (at your option) any later version.
+; *
+; *  This program is distributed in the hope that it will be useful,
+; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; *  GNU General Public License for more details.
+; *
+; *  You should have received a copy of the GNU General Public License along
+; *  with this program; if not, write to the Free Software Foundation, Inc.,
+; *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; */
+
+    AREA |.text|, CODE, READONLY, ALIGN=2
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+;/*
+; * void* lwp_get_sys_api(rt_uint32_t number);
+; */
+    IMPORT lwp_get_sys_api
+    IMPORT lwp_get_kernel_sp
+    IMPORT lwp_set_kernel_sp
+
+;/*
+; * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+; */
+lwp_user_entry    PROC
+    EXPORT  lwp_user_entry
+
+    PUSH    {R0-R1}             ; push text&data addr.
+
+    MOV     R0, SP              ; v1 = SP
+    BL      lwp_set_kernel_sp   ; lwp_set_kernel_sp(v1)
+
+    POP     {R0-R1}             ; pop app address to R1.
+
+    ; set CPU to user-thread mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       ; use PSP, user-thread mode.
+    MSR     CONTROL, R2
+
+    ; set data address.
+    MOV     R9, R1
+
+    ; run app, only Thumb-mode.
+    ORR     R0, R0, #0x01
+    BX      R0
+
+    ; never reach here!
+    ENDP
+
+;/*
+; * void SVC_Handler(void);
+; */
+SVC_Handler    PROC
+    EXPORT SVC_Handler
+
+    PUSH    {LR}
+
+    ; get user SP.
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                        ; push app SP.
+    MOV     R2, R1
+
+    STMFD   R2!, {R4 - R11}              ; push app R4-R11 to app stack , and R1 not change.
+
+    ; get SVC number.
+    LDR     R0, [R1, #24]               ; get the app LR.
+    LDRB    R0, [R0, #-2]               ; get the SVC No. from instruction.
+
+    ; get kernel system API
+    BL      lwp_get_sys_api
+
+    ; if(api == NULL) return;
+    CMP     R0, #0
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    ; push api
+    PUSH    {R0}
+
+    ; get kernel SP to R0.
+    BL lwp_get_kernel_sp
+
+    POP     {R2}                        ; pop api to R2.
+    POP     {R1}                        ; pop app SP to R1.
+
+    ; copy R1(app SP) to R0(server SP).
+    LDMFD   R1,   {R4 - R11}     ; pop exception_stack_frame to r4 - r11 register
+    STMFD   R0!,  {R4 - R11}     ; push exception_stack_frame to server SP.
+
+    POP     {LR}
+    PUSH    {LR}
+
+    ; save app SP.
+    PUSH    {R0 - R3}
+    SUB     R0, R1, #0x20               ; keep {R4 - R11}
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    ; set to thread-privilege mode.
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    ; call api.
+    LDR     R3, =svc_exit
+    STR     R3, [R0, #20]       ; update LR
+    STR     R2, [R0, #24]       ; update api to PC
+    MSR     PSP, R0             ; update stack pointer
+    POP     {LR}                ; 0xFFFFFFED
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+    ENDP
+
+;/*
+; * void svc_exit(void);
+; */
+svc_exit     PROC
+    EXPORT svc_exit
+
+    ; get user SP.
+    PUSH    {R0}                    ; push result to SP.
+    BL      lwp_get_kernel_sp
+
+    LDMFD   R0!, {R4 - R11}         ; pop app {R4 - R11}
+
+    ADD     R0, R0, #16             ; skip R0-R3
+    LDMFD   R0!, {R12, LR}          ;
+    LDMFD   R0!, {R1}               ; pop PC to R1
+    LDMFD   R0!, {R2}               ; pop PSR to R2
+
+    ; align to 2 words
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                    ; push user-SP to SP
+
+    ; save server SP.
+    ADD     R0, SP, #0x08           ; [user-SP, result]
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                    ; pop user-SP to R3
+    POP     {R0}                    ; restore API result.
+
+    MSR     APSR, R2                ; restore PSR
+    MSR     PSP, R3                 ; restore app stack pointer
+
+    ; restore to PSP & thread-unprivilege mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    ; return to lwp.
+    ORR     R1, R1, #0x01           ; only Thumb-mode.
+    BX      R1                      ; return to user app.
+
+    ENDP
+
+    ALIGN
+
+    END

+ 210 - 0
components/lwp/arch/arm/cortex-m4/lwp_gcc.S

@@ -0,0 +1,210 @@
+/*
+ * File      : lwp_gcc.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+.cpu cortex-m4
+.syntax unified
+.thumb
+.text
+
+/*
+ * void* lwp_get_sys_api(rt_uint32_t number);
+ */
+.global lwp_get_sys_api
+.global lwp_get_kernel_sp
+.global lwp_set_kernel_sp
+
+
+/*
+ * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+ */
+.global lwp_user_entry
+.type lwp_user_entry, % function
+lwp_user_entry:
+    PUSH    {R0 - R1}           /* push text&data addr. */
+
+    MOV     R0, SP              /* v1 = SP */
+    BL      lwp_set_kernel_sp   /* lwp_set_kernel_sp(v1) */
+
+    POP     {R0 - R1}           /* pop app address to R1. */
+
+    /* set CPU to user-thread mode. */
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       /* use PSP, user-thread mode. */
+    MSR     CONTROL, R2
+
+    /* set data address. */
+    MOV     R9, R1
+
+    /* run app, only Thumb-mode. */
+    ORR     R0, R0, #0x01
+    BX      R0
+
+/*
+ * void SVC_Handler(void);
+ */
+.global SVC_Handler
+.type SVC_Handler, % function
+SVC_Handler:
+
+    PUSH    {LR}
+
+    /* get user SP. */
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                    /* push app SP. */
+    MOV     R2, R1
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    TST       LR, #0x10
+    VSTMDBEQ  R2!, {D8 - D15}
+#endif
+
+    STMFD   R2!, {R4 - R11}     /* push app R4-R11 to app stack , and R1 not change. */
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    MOV     R4, #0x00                   /* flag = 0 */
+    TST     LR, #0x10                   /* if(!EXC_RETURN[4]) */
+    MOVEQ   R4, #0x01                   /* flag = 1 */
+    STMFD   R2!, {R4}                   /* push flag */
+#endif
+
+    /* get SVC number. */
+    LDR     R0, [R1, #24]       /* get the app LR. */
+    LDRB    R0, [R0, #-2]       /* get the SVC No. from instruction. */
+
+    /* get kernel system API */
+    BL      lwp_get_sys_api
+
+    /* if(api == NULL) return; */
+    CMP     R0, #0
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    /* push api */
+    PUSH    {R0}
+
+    /* get kernel SP to R0. */
+    BL lwp_get_kernel_sp
+
+    POP     {R2}            /* pop api to R2. */
+    POP     {R1}            /* pop app SP to R1. */
+
+    /* copy R1(app SP) to R0(server SP). */
+    LDMFD   R1,   {R4 - R11}        /* pop exception_stack_frame to r4 - r11 register */
+    STMFD   R0!,  {R4 - R11}        /* push exception_stack_frame to server SP. */
+
+    POP     {LR}
+    PUSH    {LR}
+
+    /* save app SP. */
+    PUSH    {R0 - R3}
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    TST     LR, #0x10
+    SUBEQ   R0, R1, #0x64       /* keep {R4 - R11}, {D8-D15}, FLAG */
+    SUBNE   R0, R1, #0x24       /* keep {R4 - R11}, FLAG */
+#else
+    SUB     R0, R1, #0x20       /* keep {R4 - R11} */
+#endif
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    /* set to thread-privilege mode. */
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    /* call api. */
+    LDR     R3, = svc_exit
+    STR     R3, [R0, #20]       /* update LR */
+    STR     R2, [R0, #24]       /* update api to PC */
+    MSR     PSP, R0         /* update stack pointer */
+    POP     {LR}            /* 0xFFFFFFED */
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+/*
+* void svc_exit(void);
+*/
+.global svc_exit
+.type svc_exit, % function
+svc_exit:
+
+    /* get user SP. */
+    PUSH    {R0}                        /* push result to SP. */
+    BL      lwp_get_kernel_sp
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    LDMFD   R0!, {R3}                   /* pop flag */
+#endif
+
+    LDMFD   R0!, {R4 - R11}             /* pop app {R4 - R11} */
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    CMP     R3,  #0                     /* if(flag_r3 != 0) */
+    VLDMIANE  R0!, {D8 - D15}           /* pop FPU register s16~s31 */
+#endif
+
+    ADD     R0, R0, #16                 /* skip R0-R3 */
+    LDMFD   R0!, {R12, LR}
+    LDMFD   R0!, {R1}                   /* pop PC to R1 */
+    LDMFD   R0!, {R2}                   /* pop PSR to R2 */
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    CMP     R3,  #0                     /* if(flag_r3 != 0) */
+    VLDMIANE  R0!, {D0 - D7}            /* pop FPU register s16~s31 */
+    LDMIANE   R0!, {R3}
+    VMSRNE    FPSCR,  R3
+#endif
+
+    /* align to 2 words */
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                        /* push user-SP to SP */
+
+    /* save server SP. */
+    ADD     R0, SP, #0x08               /* [user-SP, result] */
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                        /* pop user-SP to R3 */
+    POP     {R0}                        /* restore API result. */
+
+    MSR     APSR, R2                    /* restore PSR */
+    MSR     PSP, R3                     /* restore app stack pointer */
+
+    /* restore to PSP & thread-unprivilege mode. */
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    /* return to lwp. */
+    ORR     R1, R1, #0x01               /* only Thumb-mode. */
+    BX      R1                          /* return to user app. */

+ 215 - 0
components/lwp/arch/arm/cortex-m4/lwp_iar.S

@@ -0,0 +1,215 @@
+;/*
+; * File      : lwp_iar.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; *
+; *  This program is free software; you can redistribute it and/or modify
+; *  it under the terms of the GNU General Public License as published by
+; *  the Free Software Foundation; either version 2 of the License, or
+; *  (at your option) any later version.
+; *
+; *  This program is distributed in the hope that it will be useful,
+; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; *  GNU General Public License for more details.
+; *
+; *  You should have received a copy of the GNU General Public License along
+; *  with this program; if not, write to the Free Software Foundation, Inc.,
+; *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; */
+
+    SECTION    .text:CODE(2)
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+;/*
+; * void* lwp_get_sys_api(rt_uint32_t number);
+; */
+    IMPORT lwp_get_sys_api
+    IMPORT lwp_get_kernel_sp
+    IMPORT lwp_set_kernel_sp
+
+;/*
+; * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+; */
+    EXPORT  lwp_user_entry
+lwp_user_entry:
+
+    PUSH    {R0-R1}             ; push text&data addr.
+
+    MOV     R0, SP              ; v1 = SP
+    BL      lwp_set_kernel_sp   ; lwp_set_kernel_sp(v1)
+
+    POP     {R0-R1}             ; pop app address to R1.
+
+    ; set CPU to user-thread mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       ; use PSP, user-thread mode.
+    MSR     CONTROL, R2
+
+    ; set data address.
+    MOV     R9, R1
+
+    ; run app, only Thumb-mode.
+    ORR     R0, R0, #0x01
+    BX      R0
+
+;/*
+; * void SVC_Handler(void);
+; */
+    EXPORT SVC_Handler
+SVC_Handler:
+
+    PUSH    {LR}
+
+    ; get user SP.
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                        ; push app SP.
+    MOV     R2, R1
+
+#if defined ( __ARMVFP__ )
+    TST       LR, #0x10
+    IT        EQ
+    VSTMDBEQ    R2!, {D8 - D15}
+#endif
+
+    STMFD   R2!, {R4 - R11}              ; push app R4-R11 to app stack , and R1 not change.
+
+#if defined ( __ARMVFP__ )
+    MOV     R4, #0x00               ; flag = 0
+    TST     LR, #0x10               ; if(!EXC_RETURN[4])
+    IT      EQ
+    MOVEQ   R4, #0x01               ; flag = 1
+    STMFD   R2!, {R4}               ; push flag
+#endif
+
+    ; get SVC number.
+    LDR     R0, [R1, #24]               ; get the app LR.
+    LDRB    R0, [R0, #-2]               ; get the SVC No. from instruction.
+
+    ; get kernel system API
+    BL      lwp_get_sys_api
+
+    ; if(api == NULL) return;
+    CMP     R0, #0         
+    ITTT    EQ
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    ; push api
+    PUSH    {R0}
+
+    ; get kernel SP to R0.
+    BL lwp_get_kernel_sp
+
+    POP     {R2}                        ; pop api to R2.
+    POP     {R1}                        ; pop app SP to R1.
+
+    ; copy R1(app SP) to R0(server SP).
+    LDMFD   R1,   {R4 - R11}     ; pop exception_stack_frame to r4 - r11 register
+    STMFD   R0!,  {R4 - R11}     ; push exception_stack_frame to server SP.
+
+    POP     {LR}
+    PUSH    {LR}
+
+    ; save app SP.
+    PUSH    {R0 - R3}
+#if defined ( __ARMVFP__ )
+    TST     LR, #0x10
+    ITE     EQ
+    SUBEQ   R0, R1, #0x64               ; keep {R4 - R11}, {D8-D15}, FLAG
+    SUBNE   R0, R1, #0x24               ; keep {R4 - R11}, FLAG
+#else
+    SUB     R0, R1, #0x20               ; keep {R4 - R11}
+#endif
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    ; set to thread-privilege mode.
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    ; call api.
+    LDR     R3, =svc_exit
+    STR     R3, [R0, #20]       ; update LR
+    STR     R2, [R0, #24]       ; update api to PC
+    MSR     PSP, R0             ; update stack pointer
+    POP     {LR}                ; 0xFFFFFFED
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+;/*
+; * void svc_exit(void);
+; */
+    EXPORT svc_exit
+svc_exit:
+
+    ; get user SP.
+    PUSH    {R0}                    ; push result to SP.
+    BL      lwp_get_kernel_sp
+
+#if defined ( __ARMVFP__ )
+    LDMFD   R0!, {R3}               ; pop flag
+#endif
+
+    LDMFD   R0!, {R4 - R11}         ; pop app {R4 - R11}
+
+#if defined ( __ARMVFP__ )
+    CMP     R3,  #0                 ; if(flag_r3 != 0)
+    IT      NE
+    VLDMIANE  R0!, {D8 - D15}       ; pop FPU register s16~s31
+#endif
+
+    ADD     R0, R0, #16             ; skip R0-R3
+    LDMFD   R0!, {R12, LR}          ;
+    LDMFD   R0!, {R1}               ; pop PC to R1
+    LDMFD   R0!, {R2}               ; pop PSR to R2
+
+#if defined ( __ARMVFP__ )
+    CMP     R3,  #0                 ; if(flag_r3 != 0)
+    ITTT      NE
+    VLDMIANE  R0!, {D0 - D7}       ; pop FPU register s16~s31
+    LDMIANE   R0!, {R3}
+    VMSRNE    FPSCR,  R3
+#endif
+
+    ; align to 2 words
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                    ; push user-SP to SP
+
+    ; save server SP.
+    ADD     R0, SP, #0x08           ; [user-SP, result]
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                    ; pop user-SP to R3
+    POP     {R0}                    ; restore API result.
+
+    MSR     APSR, R2                ; restore PSR
+    MSR     PSP, R3                 ; restore app stack pointer
+
+    ; restore to PSP & thread-unprivilege mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    ; return to lwp.
+    ORR     R1, R1, #0x01           ; only Thumb-mode.
+    BX      R1                      ; return to user app.
+
+    END

+ 219 - 0
components/lwp/arch/arm/cortex-m4/lwp_rvds.S

@@ -0,0 +1,219 @@
+;/*
+; * File      : lwp_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; *
+; *  This program is free software; you can redistribute it and/or modify
+; *  it under the terms of the GNU General Public License as published by
+; *  the Free Software Foundation; either version 2 of the License, or
+; *  (at your option) any later version.
+; *
+; *  This program is distributed in the hope that it will be useful,
+; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; *  GNU General Public License for more details.
+; *
+; *  You should have received a copy of the GNU General Public License along
+; *  with this program; if not, write to the Free Software Foundation, Inc.,
+; *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; */
+
+    AREA |.text|, CODE, READONLY, ALIGN=2
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+;/*
+; * void* lwp_get_sys_api(rt_uint32_t number);
+; */
+    IMPORT lwp_get_sys_api
+    IMPORT lwp_get_kernel_sp
+    IMPORT lwp_set_kernel_sp
+
+;/*
+; * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+; */
+lwp_user_entry    PROC
+    EXPORT  lwp_user_entry
+
+    PUSH    {R0-R1}             ; push text&data addr.
+
+    MOV     R0, SP              ; v1 = SP
+    BL      lwp_set_kernel_sp   ; lwp_set_kernel_sp(v1)
+
+    POP     {R0-R1}             ; pop app address to R1.
+
+    ; set CPU to user-thread mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       ; use PSP, user-thread mode.
+    MSR     CONTROL, R2
+
+    ; set data address.
+    MOV     R9, R1
+
+    ; run app, only Thumb-mode.
+    ORR     R0, R0, #0x01
+    BX      R0
+
+    ; never reach here!
+    ENDP
+
+;/*
+; * void SVC_Handler(void);
+; */
+SVC_Handler    PROC
+    EXPORT SVC_Handler
+
+    PUSH    {LR}
+
+    ; get user SP.
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                        ; push app SP.
+    MOV     R2, R1
+
+    IF      {FPU} != "SoftVFP"
+    TST       LR, #0x10
+    VSTMFDEQ  R2!, {D8 - D15}
+    ENDIF
+
+    STMFD   R2!, {R4 - R11}              ; push app R4-R11 to app stack , and R1 not change.
+
+    IF      {FPU} != "SoftVFP"
+    MOV     R4, #0x00               ; flag = 0
+    TST     LR, #0x10               ; if(!EXC_RETURN[4])
+    MOVEQ   R4, #0x01               ; flag = 1
+    STMFD   R2!, {R4}               ; push flag
+    ENDIF
+
+    ; get SVC number.
+    LDR     R0, [R1, #24]               ; get the app LR.
+    LDRB    R0, [R0, #-2]               ; get the SVC No. from instruction.
+
+    ; get kernel system API
+    BL      lwp_get_sys_api
+
+    ; if(api == NULL) return;
+    CMP     R0, #0
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    ; push api
+    PUSH    {R0}
+
+    ; get kernel SP to R0.
+    BL lwp_get_kernel_sp
+
+    POP     {R2}                        ; pop api to R2.
+    POP     {R1}                        ; pop app SP to R1.
+
+    ; copy R1(app SP) to R0(server SP).
+    LDMFD   R1,   {R4 - R11}     ; pop exception_stack_frame to r4 - r11 register
+    STMFD   R0!,  {R4 - R11}     ; push exception_stack_frame to server SP.
+
+    POP     {LR}
+    PUSH    {LR}
+
+    ; save app SP.
+    PUSH    {R0 - R3}
+    IF      {FPU} != "SoftVFP"
+    TST     LR, #0x10
+    SUBEQ   R0, R1, #0x64               ; keep {R4 - R11}, {D8-D15}, FLAG
+    SUBNE   R0, R1, #0x24               ; keep {R4 - R11}, FLAG
+    ELSE
+    SUB     R0, R1, #0x20               ; keep {R4 - R11}
+    ENDIF
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    ; set to thread-privilege mode.
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    ; call api.
+    LDR     R3, =svc_exit
+    STR     R3, [R0, #20]       ; update LR
+    STR     R2, [R0, #24]       ; update api to PC
+    MSR     PSP, R0             ; update stack pointer
+    POP     {LR}                ; 0xFFFFFFED
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+    ENDP
+
+;/*
+; * void svc_exit(void);
+; */
+svc_exit     PROC
+    EXPORT svc_exit
+
+    ; get user SP.
+    PUSH    {R0}                    ; push result to SP.
+    BL      lwp_get_kernel_sp
+
+    IF      {FPU} != "SoftVFP"
+    LDMFD   R0!, {R3}               ; pop flag
+    ENDIF
+
+    LDMFD   R0!, {R4 - R11}         ; pop app {R4 - R11}
+
+    IF      {FPU} != "SoftVFP"
+    CMP     R3,  #0                 ; if(flag_r3 != 0)
+    VLDMFDNE  R0!, {D8 - D15}       ; pop FPU register s16~s31
+    ENDIF
+
+    ADD     R0, R0, #16             ; skip R0-R3
+    LDMFD   R0!, {R12, LR}          ;
+    LDMFD   R0!, {R1}               ; pop PC to R1
+    LDMFD   R0!, {R2}               ; pop PSR to R2
+
+    IF      {FPU} != "SoftVFP"
+    CMP     R3,  #0                 ; if(flag_r3 != 0)
+    VLDMFDNE  R0!, {D0 - D7}       ; pop FPU register s16~s31
+    LDMFDNE   R0!, {R3}
+    VMSRNE    FPSCR,  R3
+
+    ENDIF
+
+    ; align to 2 words
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                    ; push user-SP to SP
+
+    ; save server SP.
+    ADD     R0, SP, #0x08           ; [user-SP, result]
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                    ; pop user-SP to R3
+    POP     {R0}                    ; restore API result.
+
+    MSR     APSR, R2                ; restore PSR
+    MSR     PSP, R3                 ; restore app stack pointer
+
+    ; restore to PSP & thread-unprivilege mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    ; return to lwp.
+    ORR     R1, R1, #0x01           ; only Thumb-mode.
+    BX      R1                      ; return to user app.
+
+    ENDP
+
+    ALIGN
+
+    END

+ 210 - 0
components/lwp/arch/arm/cortex-m7/lwp_gcc.S

@@ -0,0 +1,210 @@
+/*
+ * File      : lwp_gcc.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+.cpu cortex-m4
+.syntax unified
+.thumb
+.text
+
+/*
+ * void* lwp_get_sys_api(rt_uint32_t number);
+ */
+.global lwp_get_sys_api
+.global lwp_get_kernel_sp
+.global lwp_set_kernel_sp
+
+
+/*
+ * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+ */
+.global lwp_user_entry
+.type lwp_user_entry, % function
+lwp_user_entry:
+    PUSH    {R0 - R1}           /* push text&data addr. */
+
+    MOV     R0, SP              /* v1 = SP */
+    BL      lwp_set_kernel_sp   /* lwp_set_kernel_sp(v1) */
+
+    POP     {R0 - R1}           /* pop app address to R1. */
+
+    /* set CPU to user-thread mode. */
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       /* use PSP, user-thread mode. */
+    MSR     CONTROL, R2
+
+    /* set data address. */
+    MOV     R9, R1
+
+    /* run app, only Thumb-mode. */
+    ORR     R0, R0, #0x01
+    BX      R0
+
+/*
+ * void SVC_Handler(void);
+ */
+.global SVC_Handler
+.type SVC_Handler, % function
+SVC_Handler:
+
+    PUSH    {LR}
+
+    /* get user SP. */
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                    /* push app SP. */
+    MOV     R2, R1
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    TST       LR, #0x10
+    VSTMDBEQ  R2!, {D8 - D15}
+#endif
+
+    STMFD   R2!, {R4 - R11}     /* push app R4-R11 to app stack , and R1 not change. */
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    MOV     R4, #0x00                   /* flag = 0 */
+    TST     LR, #0x10                   /* if(!EXC_RETURN[4]) */
+    MOVEQ   R4, #0x01                   /* flag = 1 */
+    STMFD   R2!, {R4}                   /* push flag */
+#endif
+
+    /* get SVC number. */
+    LDR     R0, [R1, #24]       /* get the app LR. */
+    LDRB    R0, [R0, #-2]       /* get the SVC No. from instruction. */
+
+    /* get kernel system API */
+    BL      lwp_get_sys_api
+
+    /* if(api == NULL) return; */
+    CMP     R0, #0
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    /* push api */
+    PUSH    {R0}
+
+    /* get kernel SP to R0. */
+    BL lwp_get_kernel_sp
+
+    POP     {R2}            /* pop api to R2. */
+    POP     {R1}            /* pop app SP to R1. */
+
+    /* copy R1(app SP) to R0(server SP). */
+    LDMFD   R1,   {R4 - R11}        /* pop exception_stack_frame to r4 - r11 register */
+    STMFD   R0!,  {R4 - R11}        /* push exception_stack_frame to server SP. */
+
+    POP     {LR}
+    PUSH    {LR}
+
+    /* save app SP. */
+    PUSH    {R0 - R3}
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    TST     LR, #0x10
+    SUBEQ   R0, R1, #0x64       /* keep {R4 - R11}, {D8-D15}, FLAG */
+    SUBNE   R0, R1, #0x24       /* keep {R4 - R11}, FLAG */
+#else
+    SUB     R0, R1, #0x20       /* keep {R4 - R11} */
+#endif
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    /* set to thread-privilege mode. */
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    /* call api. */
+    LDR     R3, = svc_exit
+    STR     R3, [R0, #20]       /* update LR */
+    STR     R2, [R0, #24]       /* update api to PC */
+    MSR     PSP, R0         /* update stack pointer */
+    POP     {LR}            /* 0xFFFFFFED */
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+/*
+* void svc_exit(void);
+*/
+.global svc_exit
+.type svc_exit, % function
+svc_exit:
+
+    /* get user SP. */
+    PUSH    {R0}                        /* push result to SP. */
+    BL      lwp_get_kernel_sp
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    LDMFD   R0!, {R3}                   /* pop flag */
+#endif
+
+    LDMFD   R0!, {R4 - R11}             /* pop app {R4 - R11} */
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    CMP     R3,  #0                     /* if(flag_r3 != 0) */
+    VLDMIANE  R0!, {D8 - D15}           /* pop FPU register s16~s31 */
+#endif
+
+    ADD     R0, R0, #16                 /* skip R0-R3 */
+    LDMFD   R0!, {R12, LR}
+    LDMFD   R0!, {R1}                   /* pop PC to R1 */
+    LDMFD   R0!, {R2}                   /* pop PSR to R2 */
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+    CMP     R3,  #0                     /* if(flag_r3 != 0) */
+    VLDMIANE  R0!, {D0 - D7}            /* pop FPU register s16~s31 */
+    LDMIANE   R0!, {R3}
+    VMSRNE    FPSCR,  R3
+#endif
+
+    /* align to 2 words */
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                        /* push user-SP to SP */
+
+    /* save server SP. */
+    ADD     R0, SP, #0x08               /* [user-SP, result] */
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                        /* pop user-SP to R3 */
+    POP     {R0}                        /* restore API result. */
+
+    MSR     APSR, R2                    /* restore PSR */
+    MSR     PSP, R3                     /* restore app stack pointer */
+
+    /* restore to PSP & thread-unprivilege mode. */
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    /* return to lwp. */
+    ORR     R1, R1, #0x01               /* only Thumb-mode. */
+    BX      R1                          /* return to user app. */

+ 215 - 0
components/lwp/arch/arm/cortex-m7/lwp_iar.S

@@ -0,0 +1,215 @@
+;/*
+; * File      : lwp_iar.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; *
+; *  This program is free software; you can redistribute it and/or modify
+; *  it under the terms of the GNU General Public License as published by
+; *  the Free Software Foundation; either version 2 of the License, or
+; *  (at your option) any later version.
+; *
+; *  This program is distributed in the hope that it will be useful,
+; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; *  GNU General Public License for more details.
+; *
+; *  You should have received a copy of the GNU General Public License along
+; *  with this program; if not, write to the Free Software Foundation, Inc.,
+; *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; */
+
+    SECTION    .text:CODE(2)
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+;/*
+; * void* lwp_get_sys_api(rt_uint32_t number);
+; */
+    IMPORT lwp_get_sys_api
+    IMPORT lwp_get_kernel_sp
+    IMPORT lwp_set_kernel_sp
+
+;/*
+; * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+; */
+    EXPORT  lwp_user_entry
+lwp_user_entry:
+
+    PUSH    {R0-R1}             ; push text&data addr.
+
+    MOV     R0, SP              ; v1 = SP
+    BL      lwp_set_kernel_sp   ; lwp_set_kernel_sp(v1)
+
+    POP     {R0-R1}             ; pop app address to R1.
+
+    ; set CPU to user-thread mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       ; use PSP, user-thread mode.
+    MSR     CONTROL, R2
+
+    ; set data address.
+    MOV     R9, R1
+
+    ; run app, only Thumb-mode.
+    ORR     R0, R0, #0x01
+    BX      R0
+
+;/*
+; * void SVC_Handler(void);
+; */
+    EXPORT SVC_Handler
+SVC_Handler:
+
+    PUSH    {LR}
+
+    ; get user SP.
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                        ; push app SP.
+    MOV     R2, R1
+
+#if defined ( __ARMVFP__ )
+    TST       LR, #0x10
+    IT        EQ
+    VSTMDBEQ    R2!, {D8 - D15}
+#endif
+
+    STMFD   R2!, {R4 - R11}              ; push app R4-R11 to app stack , and R1 not change.
+
+#if defined ( __ARMVFP__ )
+    MOV     R4, #0x00               ; flag = 0
+    TST     LR, #0x10               ; if(!EXC_RETURN[4])
+    IT      EQ
+    MOVEQ   R4, #0x01               ; flag = 1
+    STMFD   R2!, {R4}               ; push flag
+#endif
+
+    ; get SVC number.
+    LDR     R0, [R1, #24]               ; get the app LR.
+    LDRB    R0, [R0, #-2]               ; get the SVC No. from instruction.
+
+    ; get kernel system API
+    BL      lwp_get_sys_api
+
+    ; if(api == NULL) return;
+    CMP     R0, #0         
+    ITTT    EQ
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    ; push api
+    PUSH    {R0}
+
+    ; get kernel SP to R0.
+    BL lwp_get_kernel_sp
+
+    POP     {R2}                        ; pop api to R2.
+    POP     {R1}                        ; pop app SP to R1.
+
+    ; copy R1(app SP) to R0(server SP).
+    LDMFD   R1,   {R4 - R11}     ; pop exception_stack_frame to r4 - r11 register
+    STMFD   R0!,  {R4 - R11}     ; push exception_stack_frame to server SP.
+
+    POP     {LR}
+    PUSH    {LR}
+
+    ; save app SP.
+    PUSH    {R0 - R3}
+#if defined ( __ARMVFP__ )
+    TST     LR, #0x10
+    ITE     EQ
+    SUBEQ   R0, R1, #0x64               ; keep {R4 - R11}, {D8-D15}, FLAG
+    SUBNE   R0, R1, #0x24               ; keep {R4 - R11}, FLAG
+#else
+    SUB     R0, R1, #0x20               ; keep {R4 - R11}
+#endif
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    ; set to thread-privilege mode.
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    ; call api.
+    LDR     R3, =svc_exit
+    STR     R3, [R0, #20]       ; update LR
+    STR     R2, [R0, #24]       ; update api to PC
+    MSR     PSP, R0             ; update stack pointer
+    POP     {LR}                ; 0xFFFFFFED
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+;/*
+; * void svc_exit(void);
+; */
+    EXPORT svc_exit
+svc_exit:
+
+    ; get user SP.
+    PUSH    {R0}                    ; push result to SP.
+    BL      lwp_get_kernel_sp
+
+#if defined ( __ARMVFP__ )
+    LDMFD   R0!, {R3}               ; pop flag
+#endif
+
+    LDMFD   R0!, {R4 - R11}         ; pop app {R4 - R11}
+
+#if defined ( __ARMVFP__ )
+    CMP     R3,  #0                 ; if(flag_r3 != 0)
+    IT      NE
+    VLDMIANE  R0!, {D8 - D15}       ; pop FPU register s16~s31
+#endif
+
+    ADD     R0, R0, #16             ; skip R0-R3
+    LDMFD   R0!, {R12, LR}          ;
+    LDMFD   R0!, {R1}               ; pop PC to R1
+    LDMFD   R0!, {R2}               ; pop PSR to R2
+
+#if defined ( __ARMVFP__ )
+    CMP     R3,  #0                 ; if(flag_r3 != 0)
+    ITTT      NE
+    VLDMIANE  R0!, {D0 - D7}       ; pop FPU register s16~s31
+    LDMIANE   R0!, {R3}
+    VMSRNE    FPSCR,  R3
+#endif
+
+    ; align to 2 words
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                    ; push user-SP to SP
+
+    ; save server SP.
+    ADD     R0, SP, #0x08           ; [user-SP, result]
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                    ; pop user-SP to R3
+    POP     {R0}                    ; restore API result.
+
+    MSR     APSR, R2                ; restore PSR
+    MSR     PSP, R3                 ; restore app stack pointer
+
+    ; restore to PSP & thread-unprivilege mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    ; return to lwp.
+    ORR     R1, R1, #0x01           ; only Thumb-mode.
+    BX      R1                      ; return to user app.
+
+    END

+ 219 - 0
components/lwp/arch/arm/cortex-m7/lwp_rvds.S

@@ -0,0 +1,219 @@
+;/*
+; * File      : lwp_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; *
+; *  This program is free software; you can redistribute it and/or modify
+; *  it under the terms of the GNU General Public License as published by
+; *  the Free Software Foundation; either version 2 of the License, or
+; *  (at your option) any later version.
+; *
+; *  This program is distributed in the hope that it will be useful,
+; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; *  GNU General Public License for more details.
+; *
+; *  You should have received a copy of the GNU General Public License along
+; *  with this program; if not, write to the Free Software Foundation, Inc.,
+; *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; */
+
+    AREA |.text|, CODE, READONLY, ALIGN=2
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+;/*
+; * void* lwp_get_sys_api(rt_uint32_t number);
+; */
+    IMPORT lwp_get_sys_api
+    IMPORT lwp_get_kernel_sp
+    IMPORT lwp_set_kernel_sp
+
+;/*
+; * void lwp_user_entry(u32 R0_text_addr, u32 R1_data_addr);
+; */
+lwp_user_entry    PROC
+    EXPORT  lwp_user_entry
+
+    PUSH    {R0-R1}             ; push text&data addr.
+
+    MOV     R0, SP              ; v1 = SP
+    BL      lwp_set_kernel_sp   ; lwp_set_kernel_sp(v1)
+
+    POP     {R0-R1}             ; pop app address to R1.
+
+    ; set CPU to user-thread mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03       ; use PSP, user-thread mode.
+    MSR     CONTROL, R2
+
+    ; set data address.
+    MOV     R9, R1
+
+    ; run app, only Thumb-mode.
+    ORR     R0, R0, #0x01
+    BX      R0
+
+    ; never reach here!
+    ENDP
+
+;/*
+; * void SVC_Handler(void);
+; */
+SVC_Handler    PROC
+    EXPORT SVC_Handler
+
+    PUSH    {LR}
+
+    ; get user SP.
+    TST     LR, #0x4
+    ITE     EQ
+    MRSEQ   R1, MSP
+    MRSNE   R1, PSP
+
+    PUSH    {R1}                        ; push app SP.
+    MOV     R2, R1
+
+    IF      {FPU} != "SoftVFP"
+    TST       LR, #0x10
+    VSTMFDEQ  R2!, {D8 - D15}
+    ENDIF
+
+    STMFD   R2!, {R4 - R11}              ; push app R4-R11 to app stack , and R1 not change.
+
+    IF      {FPU} != "SoftVFP"
+    MOV     R4, #0x00               ; flag = 0
+    TST     LR, #0x10               ; if(!EXC_RETURN[4])
+    MOVEQ   R4, #0x01               ; flag = 1
+    STMFD   R2!, {R4}               ; push flag
+    ENDIF
+
+    ; get SVC number.
+    LDR     R0, [R1, #24]               ; get the app LR.
+    LDRB    R0, [R0, #-2]               ; get the SVC No. from instruction.
+
+    ; get kernel system API
+    BL      lwp_get_sys_api
+
+    ; if(api == NULL) return;
+    CMP     R0, #0
+    POPEQ   {R1}
+    POPEQ   {LR}
+    BXEQ    LR
+
+    ; push api
+    PUSH    {R0}
+
+    ; get kernel SP to R0.
+    BL lwp_get_kernel_sp
+
+    POP     {R2}                        ; pop api to R2.
+    POP     {R1}                        ; pop app SP to R1.
+
+    ; copy R1(app SP) to R0(server SP).
+    LDMFD   R1,   {R4 - R11}     ; pop exception_stack_frame to r4 - r11 register
+    STMFD   R0!,  {R4 - R11}     ; push exception_stack_frame to server SP.
+
+    POP     {LR}
+    PUSH    {LR}
+
+    ; save app SP.
+    PUSH    {R0 - R3}
+    IF      {FPU} != "SoftVFP"
+    TST     LR, #0x10
+    SUBEQ   R0, R1, #0x64               ; keep {R4 - R11}, {D8-D15}, FLAG
+    SUBNE   R0, R1, #0x24               ; keep {R4 - R11}, FLAG
+    ELSE
+    SUB     R0, R1, #0x20               ; keep {R4 - R11}
+    ENDIF
+    BL      lwp_set_kernel_sp
+    POP     {R0 - R3}
+
+    ; set to thread-privilege mode.
+    MRS     R3, CONTROL
+    BIC     R3, R3, #0x01
+    ORR     R3, R3, #0x02
+    MSR     CONTROL, R3
+
+    ; call api.
+    LDR     R3, =svc_exit
+    STR     R3, [R0, #20]       ; update LR
+    STR     R2, [R0, #24]       ; update api to PC
+    MSR     PSP, R0             ; update stack pointer
+    POP     {LR}                ; 0xFFFFFFED
+
+    ORR     LR, LR, #0x10
+
+    BX      LR
+
+    ENDP
+
+;/*
+; * void svc_exit(void);
+; */
+svc_exit     PROC
+    EXPORT svc_exit
+
+    ; get user SP.
+    PUSH    {R0}                    ; push result to SP.
+    BL      lwp_get_kernel_sp
+
+    IF      {FPU} != "SoftVFP"
+    LDMFD   R0!, {R3}               ; pop flag
+    ENDIF
+
+    LDMFD   R0!, {R4 - R11}         ; pop app {R4 - R11}
+
+    IF      {FPU} != "SoftVFP"
+    CMP     R3,  #0                 ; if(flag_r3 != 0)
+    VLDMFDNE  R0!, {D8 - D15}       ; pop FPU register s16~s31
+    ENDIF
+
+    ADD     R0, R0, #16             ; skip R0-R3
+    LDMFD   R0!, {R12, LR}          ;
+    LDMFD   R0!, {R1}               ; pop PC to R1
+    LDMFD   R0!, {R2}               ; pop PSR to R2
+
+    IF      {FPU} != "SoftVFP"
+    CMP     R3,  #0                 ; if(flag_r3 != 0)
+    VLDMFDNE  R0!, {D0 - D7}       ; pop FPU register s16~s31
+    LDMFDNE   R0!, {R3}
+    VMSRNE    FPSCR,  R3
+
+    ENDIF
+
+    ; align to 2 words
+    ADD     R0, R0, #0x07
+    BIC     R0, R0, #0x07
+    PUSH    {R0}                    ; push user-SP to SP
+
+    ; save server SP.
+    ADD     R0, SP, #0x08           ; [user-SP, result]
+    PUSH    {R1 - R2, LR}
+    BL      lwp_set_kernel_sp
+    POP     {R1 - R2, LR}
+
+    POP     {R3}                    ; pop user-SP to R3
+    POP     {R0}                    ; restore API result.
+
+    MSR     APSR, R2                ; restore PSR
+    MSR     PSP, R3                 ; restore app stack pointer
+
+    ; restore to PSP & thread-unprivilege mode.
+    MRS     R2, CONTROL
+    ORR     R2, R2, #0x03
+    MSR     CONTROL, R2
+
+    ; return to lwp.
+    ORR     R1, R1, #0x01           ; only Thumb-mode.
+    BX      R1                      ; return to user app.
+
+    ENDP
+
+    ALIGN
+
+    END

+ 364 - 0
components/lwp/lwp.c

@@ -0,0 +1,364 @@
+/*
+ * File      : clock.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <dfs_posix.h>
+
+#ifdef RT_USING_FINSH
+    #include <finsh.h>
+#endif
+
+#ifndef RT_USING_DFS
+    #error  "lwp need file system(RT_USING_DFS)"
+#endif
+
+#include "lwp.h"
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME    "[LWP]"
+#define DBG_COLOR
+#define DBG_LEVEL           DBG_LOG
+#include <rtdbg.h>
+
+extern rt_thread_t rt_current_thread;
+extern void lwp_user_entry(const void *text, void *data);
+
+/**
+ * RT-Thread light-weight process
+ */
+void lwp_set_kernel_sp(uint32_t *sp)
+{
+    struct rt_lwp *user_data;
+    user_data = (struct rt_lwp *)rt_current_thread->user_data;
+    user_data->kernel_sp = sp;
+}
+
+uint32_t *lwp_get_kernel_sp(void)
+{
+    struct rt_lwp *user_data;
+    user_data = (struct rt_lwp *)rt_current_thread->user_data;
+
+    return user_data->kernel_sp;
+}
+
+static int lwp_load(const char *filename, struct rt_lwp *lwp, uint8_t *load_addr, size_t addr_size)
+{
+    int fd;
+    uint8_t *ptr;
+    int result = RT_EOK;
+    int nbytes;
+    struct lwp_header header;
+    struct lwp_chunk  chunk;
+
+    /* check file name */
+    RT_ASSERT(filename != RT_NULL);
+    /* check lwp control block */
+    RT_ASSERT(lwp != RT_NULL);
+
+    memset(lwp, 0x00, sizeof(struct rt_lwp));
+
+    if (load_addr != RT_NULL)
+    {
+        lwp->lwp_type = LWP_TYPE_FIX_ADDR;
+        ptr = load_addr;
+    }
+    else
+    {
+        lwp->lwp_type = LWP_TYPE_DYN_ADDR;
+        ptr = RT_NULL;
+    }
+
+    /* open lwp */
+    fd = open(filename, 0, O_RDONLY);
+    if (fd < 0)
+    {
+        dbg_log(DBG_ERROR, "open file:%s failed!\n", filename);
+        result = -RT_ENOSYS;
+        goto _exit;
+    }
+
+    /* read lwp header */
+    nbytes = read(fd, &header, sizeof(struct lwp_header));
+    if (nbytes != sizeof(struct lwp_header))
+    {
+        dbg_log(DBG_ERROR, "read lwp header return error size: %d!\n", nbytes);
+        result = -RT_EIO;
+        goto _exit;
+    }
+
+    /* check file header */
+    if (header.magic != LWP_MAGIC)
+    {
+        dbg_log(DBG_ERROR, "erro header magic number: 0x%02X\n", header.magic);
+        result = -RT_EINVAL;
+        goto _exit;
+    }
+
+    /* read text chunk info */
+    nbytes = read(fd, &chunk, sizeof(struct lwp_chunk));
+    if (nbytes != sizeof(struct lwp_chunk))
+    {
+        dbg_log(DBG_ERROR, "read text chunk info failed!\n");
+        result = -RT_EIO;
+        goto _exit;
+    }
+
+    dbg_log(DBG_LOG, "chunk name: %s, total len %d, data %d, need space %d!\n",
+            "text", /*chunk.name*/ chunk.total_len, chunk.data_len, chunk.data_len_space);
+
+    /* load text */
+    {
+        lwp->text_size = RT_ALIGN(chunk.data_len_space, 4);
+        if (load_addr)
+            lwp->text_entry = ptr;
+        else
+        {
+#ifdef RT_USING_CACHE
+            lwp->text_entry = (rt_uint8_t *)rt_malloc_align(lwp->text_size, RT_CPU_CACHE_LINE_SZ);
+#else
+            lwp->text_entry = (rt_uint8_t *)rt_malloc(lwp->text_size);
+#endif
+
+            if (lwp->text_entry == RT_NULL)
+            {
+                dbg_log(DBG_ERROR, "alloc text memory faild!\n");
+                result = -RT_ENOMEM;
+                goto _exit;
+            }
+            else
+            {
+                dbg_log(DBG_LOG, "lwp text malloc : %p, size: %d!\n", lwp->text_entry, lwp->text_size);
+            }
+        }
+        dbg_log(DBG_INFO, "load text %d  => (0x%08x, 0x%08x)\n", lwp->text_size, (uint32_t)lwp->text_entry, (uint32_t)lwp->text_entry + lwp->text_size);
+
+        nbytes = read(fd, lwp->text_entry, chunk.data_len);
+        if (nbytes != chunk.data_len)
+        {
+            dbg_log(DBG_ERROR, "read text region from file failed!\n");
+            result = -RT_EIO;
+            goto _exit;
+        }
+#ifdef RT_USING_CACHE
+        else
+        {
+            rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, lwp->text_entry, lwp->text_size);
+            rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, lwp->text_entry, lwp->text_size);
+        }
+#endif
+
+        if (ptr != RT_NULL) ptr += nbytes;
+
+        /* skip text hole */
+        if ((chunk.total_len - sizeof(struct lwp_chunk) - chunk.data_len))
+        {
+            dbg_log(DBG_LOG, "skip text hole %d!\n", (chunk.total_len - sizeof(struct lwp_chunk) - chunk.data_len));
+            lseek(fd, (chunk.total_len - sizeof(struct lwp_chunk) - chunk.data_len), SEEK_CUR);
+        }
+    }
+
+    /* load data */
+    nbytes = read(fd, &chunk, sizeof(struct lwp_chunk));
+    if (nbytes != sizeof(struct lwp_chunk))
+    {
+        dbg_log(DBG_ERROR, "read data chunk info failed!\n");
+        result = -RT_EIO;
+        goto _exit;
+    }
+
+    dbg_log(DBG_LOG, "chunk name: %s, total len %d, data %d, need space %d!\n",
+            chunk.name, chunk.total_len, chunk.data_len, chunk.data_len_space);
+
+    {
+        lwp->data_size = RT_ALIGN(chunk.data_len_space, 4);
+        if (load_addr)
+            lwp->data = ptr;
+        else
+        {
+            lwp->data = rt_malloc(lwp->data_size);
+            if (lwp->data == RT_NULL)
+            {
+                dbg_log(DBG_ERROR, "alloc data memory faild!\n");
+                result = -RT_ENOMEM;
+                goto _exit;
+            }
+            else
+            {
+                dbg_log(DBG_LOG, "lwp data malloc : %p, size: %d!\n", lwp->data, lwp->data_size);
+                rt_memset(lwp->data, 0, lwp->data_size);
+            }
+        }
+
+        dbg_log(DBG_INFO, "load data %d => (0x%08x, 0x%08x)\n", lwp->data_size, (uint32_t)lwp->data, (uint32_t)lwp->data + lwp->data_size);
+        nbytes = read(fd, lwp->data, chunk.data_len);
+        if (nbytes != chunk.data_len)
+        {
+            dbg_log(DBG_ERROR, "read data region from file failed!\n");
+            result = -RT_ERROR;
+            goto _exit;
+        }
+    }
+
+_exit:
+    if (fd >= 0)
+        close(fd);
+
+    if (result != RT_EOK)
+    {
+        if (lwp->lwp_type == LWP_TYPE_DYN_ADDR)
+        {
+            dbg_log(DBG_ERROR, "lwp dynamic load faild, %d\n", result);
+            if (lwp->text_entry)
+            {
+                dbg_log(DBG_LOG, "lwp text free: %p\n", lwp->text_entry);
+#ifdef RT_USING_CACHE
+                rt_free_align(lwp->text_entry);
+#else
+                rt_free(lwp->text_entry);
+#endif
+            }
+            if (lwp->data)
+            {
+                dbg_log(DBG_LOG, "lwp data free: %p\n", lwp->data);
+                rt_free(lwp->data);
+            }
+        }
+    }
+
+    return result;
+}
+
+static void lwp_cleanup(struct rt_thread *tid)
+{
+    struct rt_lwp *lwp;
+
+    dbg_log(DBG_INFO, "thread: %s, stack_addr: %08X\n", tid->name, tid->stack_addr);
+
+    lwp = (struct rt_lwp *)tid->user_data;
+
+    if (lwp->lwp_type == LWP_TYPE_DYN_ADDR)
+    {
+        dbg_log(DBG_INFO, "dynamic lwp\n");
+        if (lwp->text_entry)
+        {
+            dbg_log(DBG_LOG, "lwp text free: %p\n", lwp->text_entry);
+#ifdef RT_USING_CACHE
+            rt_free_align(lwp->text_entry);
+#else
+            rt_free(lwp->text_entry);
+#endif
+        }
+        if (lwp->data)
+        {
+            dbg_log(DBG_LOG, "lwp data free: %p\n", lwp->data);
+            rt_free(lwp->data);
+        }
+    }
+
+    dbg_log(DBG_LOG, "lwp free memory pages\n");
+    rt_lwp_mem_deinit(lwp);
+
+    dbg_log(DBG_LOG, "lwp free: %p\n", lwp);
+    rt_free(lwp);
+
+    /* TODO: cleanup fd table */
+}
+
+static void lwp_thread(void *parameter)
+{
+    volatile uint32_t tmp;
+    rt_thread_t tid;
+    struct rt_lwp *lwp;
+
+    rt_kprintf("%08x %08x\n", &tmp, tmp);
+
+    lwp = (struct rt_lwp *)parameter;
+    rt_lwp_mem_init(lwp);
+    tid = rt_thread_self();
+    tid->user_data = (rt_uint32_t)lwp;
+    tid->cleanup = lwp_cleanup;
+
+    lwp_user_entry(lwp->text_entry, lwp->data);
+}
+
+struct rt_lwp *rt_lwp_self(void)
+{
+    return (struct rt_lwp *)rt_thread_self()->user_data;
+}
+
+int exec(char *filename)
+{
+    struct rt_lwp *lwp;
+    int result;
+
+    if (filename == RT_NULL)
+        return -RT_ERROR;
+
+    lwp = (struct rt_lwp *)rt_malloc(sizeof(struct rt_lwp));
+    if (lwp == RT_NULL)
+    {
+        dbg_log(DBG_ERROR, "lwp struct out of memory!\n");
+        return -RT_ENOMEM;
+    }
+    dbg_log(DBG_INFO, "lwp malloc : %p, size: %d!\n", lwp, sizeof(struct rt_lwp));
+
+    rt_memset(lwp, 0, sizeof(*lwp));
+    result = lwp_load(filename, lwp, RT_NULL, 0);
+    if (result == RT_EOK)
+    {
+        rt_thread_t tid;
+
+        tid = rt_thread_create("user", lwp_thread, (void *)lwp,
+                               1024 * 4, 2, 200);
+        if (tid != RT_NULL)
+        {
+            dbg_log(DBG_LOG, "lwp kernel => (0x%08x, 0x%08x)\n", (rt_uint32_t)tid->stack_addr, (rt_uint32_t)tid->stack_addr + tid->stack_size);
+            rt_thread_startup(tid);
+            return RT_EOK;
+        }
+        else
+        {
+#ifdef RT_USING_CACHE
+            rt_free_align(lwp->text_entry);
+#else
+            rt_free(lwp->text_entry);
+#endif
+            rt_free(lwp->data);
+        }
+    }
+
+    rt_free(lwp);
+
+    return -RT_ERROR;
+}
+FINSH_FUNCTION_EXPORT(exec, loader a user app &run);
+
+int _exec(int argc, char **argv)
+{
+    if (argc != 2)
+        return -RT_ERROR;
+
+    return exec(argv[1]);
+}
+MSH_CMD_EXPORT_ALIAS(_exec, exec, loader a user app &run);

+ 83 - 0
components/lwp/lwp.h

@@ -0,0 +1,83 @@
+/*
+ * File      : lwp.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef __LWP_H__
+#define __LWP_H__
+
+#define LWP_MAGIC           0x5A
+
+#define LWP_TYPE_FIX_ADDR   0x01
+#define LWP_TYPE_DYN_ADDR   0x02
+
+#define LWP_ARG_MAX         8
+
+#include <stdint.h>
+#include <rtthread.h>
+#include <dfs.h>
+#include <lwp_memheap.h>
+
+struct rt_lwp
+{
+    uint8_t lwp_type;
+    uint8_t heap_cnt;
+    uint8_t reserv[2];
+
+    rt_list_t hlist;                                    /**< headp list */
+
+    uint8_t *text_entry;
+    uint32_t text_size;
+
+    uint8_t *data;
+    uint32_t data_size;
+
+    uint32_t *kernel_sp;                                /**< kernel stack point */
+    struct dfs_fdtable fdt;
+};
+
+struct lwp_header
+{
+    uint8_t magic;
+    uint8_t compress_encrypt_algo;
+    uint16_t reserved;
+
+    uint32_t crc32;
+};
+
+struct lwp_chunk
+{
+    uint32_t total_len;
+
+    char name[4];
+    uint32_t data_len;
+    uint32_t data_len_space;
+};
+
+extern struct rt_lwp *rt_lwp_self(void);
+
+extern void rt_lwp_mem_init(struct rt_lwp *lwp);
+extern void rt_lwp_mem_deinit(struct rt_lwp *lwp);
+extern void *rt_lwp_mem_malloc(rt_uint32_t size);
+extern void rt_lwp_mem_free(void *addr);
+extern void *rt_lwp_mem_realloc(void *rmem, rt_size_t newsize);
+
+#endif

+ 232 - 0
components/lwp/lwp_mem.c

@@ -0,0 +1,232 @@
+/*
+ * File      : lwp_mem.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-03-24     Tanek        the first version
+ */
+
+#include <stdio.h>
+#include <rtthread.h>
+#include <lwp.h>
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME    "[LWPMEM]"
+#define DBG_COLOR
+#define DBG_LEVEL           DBG_LOG
+#include <rtdbg.h>
+
+// todo: remove repleat code
+#define RT_MEMHEAP_SIZE         RT_ALIGN(sizeof(struct rt_lwp_memheap_item), RT_ALIGN_SIZE)
+#define MEMITEM_SIZE(item)      ((rt_uint32_t)item->next - (rt_uint32_t)item - RT_MEMHEAP_SIZE)
+
+#ifndef LWP_MEM_PAGE_SIZE
+    #define LWP_MEM_PAGE_SIZE       (4 * 1024)
+#endif
+
+#ifndef LWP_MEM_MAX_PAGE_COUNT
+    #define LWP_MEM_MAX_PAGE_COUNT  (256 * 4)
+#endif
+
+static void *rt_lwp_malloc_page(struct rt_lwp *lwp, rt_size_t npages)
+{
+    void *chunk;
+    char name[6];
+    struct rt_lwp_memheap *lwp_heap;
+    rt_size_t page_cnt;
+
+    RT_ASSERT(lwp != RT_NULL);
+
+    page_cnt = lwp->heap_cnt + npages;
+    if (page_cnt > LWP_MEM_MAX_PAGE_COUNT)
+    {
+        dbg_log(DBG_ERROR, "alloc new page failed, lwp memory size out of limited: %d\n", page_cnt);
+        return RT_NULL;
+    }
+
+    lwp_heap = rt_malloc(sizeof(struct rt_lwp_memheap));
+    if (lwp_heap == RT_NULL)
+    {
+        dbg_log(DBG_ERROR, "alloc new page head failed, out of memory : %d\n", page_cnt);
+        return RT_NULL;
+    }
+
+    chunk = rt_malloc(npages * LWP_MEM_PAGE_SIZE);
+    if (chunk == RT_NULL)
+    {
+        dbg_log(DBG_ERROR, "alloc new page buffer failed, out of memory : %d\n", page_cnt);
+        rt_free(lwp_heap);
+        return RT_NULL;
+    }
+
+    dbg_log(DBG_LOG, "lwp alloc page: %d\n", npages);
+
+    sprintf(name, "lwp%02x", lwp->heap_cnt);
+    rt_lwp_memheap_init(lwp_heap, name, chunk, npages * LWP_MEM_PAGE_SIZE);
+
+    rt_list_insert_before(&lwp->hlist, &lwp_heap->mlist);
+
+    lwp->heap_cnt += npages;
+
+    return chunk;
+}
+
+static void rt_lwp_free_page(struct rt_lwp *lwp, struct rt_lwp_memheap *lwp_heap)
+{
+    rt_size_t npages;
+
+    RT_ASSERT(lwp != RT_NULL);
+    RT_ASSERT(lwp_heap != RT_NULL);
+    RT_ASSERT(lwp_heap->start_addr != RT_NULL);
+
+    npages = lwp_heap->pool_size / LWP_MEM_PAGE_SIZE;
+    lwp->heap_cnt -= npages;
+
+    dbg_log(DBG_LOG, "lwp free page: %d\n", npages);
+
+    rt_list_remove(&lwp_heap->mlist);
+
+    rt_free(lwp_heap->start_addr);
+    rt_free(lwp_heap);
+}
+
+void rt_lwp_mem_init(struct rt_lwp *lwp)
+{
+    RT_ASSERT(lwp != RT_NULL);
+    rt_list_init(&lwp->hlist);
+}
+
+void rt_lwp_mem_deinit(struct rt_lwp *lwp)
+{
+    struct rt_list_node *node;
+    
+    RT_ASSERT(lwp != RT_NULL);
+
+    for (node  = lwp->hlist.next; node != &(lwp->hlist); node = node->next)
+    {
+        struct rt_lwp_memheap *lwp_heap;
+        lwp_heap = rt_list_entry(node, struct rt_lwp_memheap, mlist);
+        
+        RT_ASSERT(lwp_heap != RT_NULL);
+
+        rt_lwp_free_page(lwp, lwp_heap);
+    }
+}
+
+void *rt_lwp_mem_malloc(rt_uint32_t size)
+{
+    struct rt_lwp *lwp;
+    struct rt_list_node *node;
+    void *addr = RT_NULL;
+    rt_uint32_t npages;
+
+    if (size == 0)
+        return RT_NULL;
+
+    lwp = rt_lwp_self();
+    RT_ASSERT(lwp != RT_NULL);
+
+    for (node  = lwp->hlist.next; node != &(lwp->hlist); node = node->next)
+    {
+        struct rt_lwp_memheap *lwp_heap;
+        lwp_heap = rt_list_entry(node, struct rt_lwp_memheap, mlist);
+
+        addr = rt_lwp_memheap_alloc(lwp_heap, size);
+        if (addr != RT_NULL)
+        {
+            dbg_log(DBG_LOG, "lwp alloc 0x%x/%d\n", addr, size);
+            return addr;
+        }
+    }
+
+    npages = (size + rt_lwp_memheap_unavailable_size_get() + LWP_MEM_PAGE_SIZE) / LWP_MEM_PAGE_SIZE;
+    if (RT_NULL != rt_lwp_malloc_page(lwp, npages))
+        return rt_lwp_mem_malloc(size);
+    else
+        return RT_NULL;
+}
+
+void rt_lwp_mem_free(void *addr)
+{
+    struct rt_lwp_memheap_item *header_ptr;
+    struct rt_lwp_memheap *lwp_heap;
+
+    if (addr == RT_NULL)
+        return ;
+
+    /* get memory item */
+    header_ptr = (struct rt_lwp_memheap_item *)((rt_uint8_t *)addr - RT_MEMHEAP_SIZE);
+    RT_ASSERT(header_ptr);
+    
+    lwp_heap = header_ptr->pool_ptr;
+    RT_ASSERT(lwp_heap);
+
+    dbg_log(DBG_LOG, "lwp free 0x%x\n", addr);
+    rt_lwp_memheap_free((void *)addr);
+
+    if (rt_lwp_memheap_is_empty(lwp_heap))
+    {
+        rt_lwp_free_page(rt_lwp_self(), lwp_heap);
+    }
+}
+
+void *rt_lwp_mem_realloc(void *rmem, rt_size_t newsize)
+{
+    void *new_ptr;
+    struct rt_lwp_memheap_item *header_ptr;
+
+    if (rmem == RT_NULL)
+        return rt_lwp_mem_malloc(newsize);
+
+    if (newsize == 0)
+    {
+        rt_lwp_mem_free(rmem);
+        return RT_NULL;
+    }
+
+    /* get old memory item */
+    header_ptr = (struct rt_lwp_memheap_item *)
+                 ((rt_uint8_t *)rmem - RT_MEMHEAP_SIZE);
+
+    new_ptr = rt_lwp_memheap_realloc(header_ptr->pool_ptr, rmem, newsize);
+    if (new_ptr == RT_NULL)
+    {
+        /* allocate memory block from other memheap */
+        new_ptr = rt_lwp_mem_malloc(newsize);
+        if (new_ptr != RT_NULL && rmem != RT_NULL)
+        {
+            rt_size_t oldsize;
+
+            /* get the size of old memory block */
+            oldsize = MEMITEM_SIZE(header_ptr);
+            if (newsize > oldsize)
+                rt_memcpy(new_ptr, rmem, oldsize);
+            else
+                rt_memcpy(new_ptr, rmem, newsize);
+
+            dbg_log(DBG_LOG, "lwp realloc with memcpy 0x%x -> 0x%x/%d\n", rmem, new_ptr, newsize);
+            rt_lwp_mem_free(rmem);
+
+        }
+    }
+
+    dbg_log(DBG_LOG, "lwp realloc in same address 0x%x/%d\n", rmem, newsize);
+
+    return new_ptr;
+}

+ 34 - 0
components/lwp/lwp_mem.h

@@ -0,0 +1,34 @@
+/*
+ * File      : lwp_mem.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef __LWP_MEM_H__
+#define __LWP_MEM_H__
+
+extern void rt_lwp_mem_init(struct rt_lwp *lwp);
+extern void rt_lwp_mem_deinit(struct rt_lwp *lwp);
+
+extern void *rt_lwp_mem_malloc(rt_uint32_t size);
+extern void rt_lwp_mem_free(void *addr);
+extern void *rt_lwp_mem_realloc(void *rmem, rt_size_t newsize);
+
+#endif

+ 590 - 0
components/lwp/lwp_memheap.c

@@ -0,0 +1,590 @@
+/*
+ * File      : lwp_memheap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-04-10     Bernard      first implementation
+ * 2012-10-16     Bernard      add the mutex lock for heap object.
+ * 2012-12-29     Bernard      memheap can be used as system heap.
+ *                             change mutex lock to semaphore lock.
+ * 2013-04-10     Bernard      add rt_lwp_memheap_realloc function.
+ * 2013-05-24     Bernard      fix the rt_lwp_memheap_realloc issue.
+ * 2013-07-11     Grissiom     fix the memory block splitting issue.
+ * 2013-07-15     Grissiom     optimize rt_lwp_memheap_realloc
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <lwp.h>
+
+/* 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_lwp_memheap_item), RT_ALIGN_SIZE)
+#define MEMITEM_SIZE(item)      ((rt_uint32_t)item->next - (rt_uint32_t)item - RT_MEMHEAP_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_lwp_memheap_init(struct rt_lwp_memheap *memheap,
+                         const char        *name,
+                         void              *start_addr,
+                         rt_uint32_t        size)
+{
+    struct rt_lwp_memheap_item *item;
+
+    RT_ASSERT(memheap != RT_NULL);
+
+    /* initialize pool object */
+    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);
+    memheap->max_used_size  = memheap->pool_size - memheap->available_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_lwp_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_lwp_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_lwp_memheap_item *)start_addr;
+    item->prev      = (struct rt_lwp_memheap_item *)start_addr;
+    /* not in free list */
+    item->next_free = item->prev_free = RT_NULL;
+
+    /* initialize semaphore lock */
+    rt_sem_init(&(memheap->lock), name, 1, RT_IPC_FLAG_FIFO);
+
+    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
+                 ("memory heap: start addr 0x%08x, size %d, free list header 0x%08x\n",
+                  start_addr, size, &(memheap->free_header)));
+
+    return RT_EOK;
+}
+
+void *rt_lwp_memheap_alloc(struct rt_lwp_memheap *heap, rt_uint32_t size)
+{
+    rt_err_t result;
+    rt_uint32_t free_size;
+    struct rt_lwp_memheap_item *header_ptr;
+
+    RT_ASSERT(heap != 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 on heap:%8.*s",
+                                    size, RT_NAME_MAX, heap->parent.name));
+
+    if (size < heap->available_size)
+    {
+        /* search on free list */
+        free_size = 0;
+
+        /* lock memheap */
+        result = rt_sem_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 = heap->free_list->next_free;
+        while (header_ptr != heap->free_list && free_size < size)
+        {
+            /* get current freed memory block size */
+            free_size = MEMITEM_SIZE(header_ptr);
+            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_lwp_memheap_item *new_ptr;
+
+                /* split the block. */
+                new_ptr = (struct rt_lwp_memheap_item *)
+                          (((rt_uint8_t *)header_ptr) + size + RT_MEMHEAP_SIZE);
+
+                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
+                             ("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]\n",
+                              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 = heap;
+
+                /* 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 = 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: next_free 0x%08x, prev_free 0x%08x\n",
+                                                new_ptr->next_free,
+                                                new_ptr->prev_free));
+
+                /* decrement the available byte count.  */
+                heap->available_size = heap->available_size -
+                                       size -
+                                       RT_MEMHEAP_SIZE;
+                if (heap->pool_size - heap->available_size > heap->max_used_size)
+                    heap->max_used_size = heap->pool_size - heap->available_size;
+            }
+            else
+            {
+                /* decrement the entire free size from the available bytes count. */
+                heap->available_size = heap->available_size - free_size;
+                if (heap->pool_size - heap->available_size > heap->max_used_size)
+                    heap->max_used_size = heap->pool_size - heap->available_size;
+
+                /* remove header_ptr from free list */
+                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
+                             ("one block: block[0x%08x], next_free 0x%08x, prev_free 0x%08x\n",
+                              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;
+
+            /* release lock */
+            rt_sem_release(&(heap->lock));
+
+            /* Return a memory address to the caller.  */
+            RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
+                         ("alloc mem: memory[0x%08x], heap[0x%08x], size: %d\n",
+                          (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE),
+                          header_ptr,
+                          size));
+
+            return (void *)((rt_uint8_t *)header_ptr + RT_MEMHEAP_SIZE);
+        }
+
+        /* release lock */
+        rt_sem_release(&(heap->lock));
+    }
+
+    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("allocate memory: failed\n"));
+
+    /* Return the completion status.  */
+    return RT_NULL;
+}
+
+void *rt_lwp_memheap_realloc(struct rt_lwp_memheap *heap, void *ptr, rt_size_t newsize)
+{
+    rt_err_t result;
+    rt_size_t oldsize;
+    struct rt_lwp_memheap_item *header_ptr;
+    struct rt_lwp_memheap_item *new_ptr;
+
+    if (newsize == 0)
+    {
+        rt_lwp_memheap_free(ptr);
+
+        return RT_NULL;
+    }
+    /* align allocated size */
+    newsize = RT_ALIGN(newsize, RT_ALIGN_SIZE);
+    if (newsize < RT_MEMHEAP_MINIALLOC)
+        newsize = RT_MEMHEAP_MINIALLOC;
+
+    if (ptr == RT_NULL)
+    {
+        return rt_lwp_memheap_alloc(heap, newsize);
+    }
+
+    /* get memory block header and get the size of memory block */
+    header_ptr = (struct rt_lwp_memheap_item *)
+                 ((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);
+    oldsize = MEMITEM_SIZE(header_ptr);
+    /* re-allocate memory */
+    if (newsize > oldsize)
+    {
+        void *new_ptr;
+        struct rt_lwp_memheap_item *next_ptr;
+
+        /* lock memheap */
+        result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
+        if (result != RT_EOK)
+        {
+            rt_set_errno(result);
+            return RT_NULL;
+        }
+
+        next_ptr = header_ptr->next;
+
+        /* header_ptr should not be the tail */
+        RT_ASSERT(next_ptr > header_ptr);
+
+        /* check whether the following free space is enough to expand */
+        if (!RT_MEMHEAP_IS_USED(next_ptr))
+        {
+            rt_int32_t nextsize;
+
+            nextsize = MEMITEM_SIZE(next_ptr);
+            RT_ASSERT(next_ptr > 0);
+
+            /* Here is the ASCII art of the situation that we can make use of
+             * the next free node without alloc/memcpy, |*| is the control
+             * block:
+             *
+             *      oldsize           free node
+             * |*|-----------|*|----------------------|*|
+             *         newsize          >= minialloc
+             * |*|----------------|*|-----------------|*|
+             */
+            if (nextsize + oldsize > newsize + RT_MEMHEAP_MINIALLOC)
+            {
+                /* decrement the entire free size from the available bytes count. */
+                heap->available_size = heap->available_size - (newsize - oldsize);
+                if (heap->pool_size - heap->available_size > heap->max_used_size)
+                    heap->max_used_size = heap->pool_size - heap->available_size;
+
+                /* remove next_ptr from free list */
+                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
+                             ("remove block: block[0x%08x], next_free 0x%08x, prev_free 0x%08x",
+                              next_ptr,
+                              next_ptr->next_free,
+                              next_ptr->prev_free));
+
+                next_ptr->next_free->prev_free = next_ptr->prev_free;
+                next_ptr->prev_free->next_free = next_ptr->next_free;
+                next_ptr->next->prev = next_ptr->prev;
+                next_ptr->prev->next = next_ptr->next;
+
+                /* build a new one on the right place */
+                next_ptr = (struct rt_lwp_memheap_item *)((char *)ptr + newsize);
+
+                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
+                             ("new free block: block[0x%08x] nextm[0x%08x] prevm[0x%08x]",
+                              next_ptr,
+                              next_ptr->next,
+                              next_ptr->prev));
+
+                /* mark the new block as a memory block and freed. */
+                next_ptr->magic = RT_MEMHEAP_MAGIC;
+
+                /* put the pool pointer into the new block. */
+                next_ptr->pool_ptr = heap;
+
+                next_ptr->prev          = header_ptr;
+                next_ptr->next          = header_ptr->next;
+                header_ptr->next->prev = next_ptr;
+                header_ptr->next       = next_ptr;
+
+                /* insert next_ptr to free list */
+                next_ptr->next_free = heap->free_list->next_free;
+                next_ptr->prev_free = heap->free_list;
+                heap->free_list->next_free->prev_free = next_ptr;
+                heap->free_list->next_free            = next_ptr;
+                RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("new ptr: next_free 0x%08x, prev_free 0x%08x",
+                                                next_ptr->next_free,
+                                                next_ptr->prev_free));
+
+                /* release lock */
+                rt_sem_release(&(heap->lock));
+
+                return ptr;
+            }
+        }
+
+        /* release lock */
+        rt_sem_release(&(heap->lock));
+
+        /* re-allocate a memory block */
+        new_ptr = (void *)rt_lwp_memheap_alloc(heap, newsize);
+        if (new_ptr != RT_NULL)
+        {
+            rt_memcpy(new_ptr, ptr, oldsize < newsize ? oldsize : newsize);
+            rt_lwp_memheap_free(ptr);
+        }
+
+        return new_ptr;
+    }
+
+    /* don't split when there is less than one node space left */
+    if (newsize + RT_MEMHEAP_SIZE + RT_MEMHEAP_MINIALLOC >= oldsize)
+        return ptr;
+
+    /* lock memheap */
+    result = rt_sem_take(&(heap->lock), RT_WAITING_FOREVER);
+    if (result != RT_EOK)
+    {
+        rt_set_errno(result);
+
+        return RT_NULL;
+    }
+
+    /* split the block. */
+    new_ptr = (struct rt_lwp_memheap_item *)
+              (((rt_uint8_t *)header_ptr) + newsize + RT_MEMHEAP_SIZE);
+
+    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
+                 ("split: block[0x%08x] nextm[0x%08x] prevm[0x%08x] to new[0x%08x]\n",
+                  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 = heap;
+
+    /* 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;
+
+    /* determine if the block can be merged with the next neighbor. */
+    if (!RT_MEMHEAP_IS_USED(new_ptr->next))
+    {
+        struct rt_lwp_memheap_item *free_ptr;
+
+        /* merge block with next neighbor. */
+        free_ptr = new_ptr->next;
+        heap->available_size = heap->available_size - MEMITEM_SIZE(free_ptr);
+
+        RT_DEBUG_LOG(RT_DEBUG_MEMHEAP,
+                     ("merge: right node 0x%08x, next_free 0x%08x, prev_free 0x%08x\n",
+                      header_ptr, header_ptr->next_free, header_ptr->prev_free));
+
+        free_ptr->next->prev = new_ptr;
+        new_ptr->next   = free_ptr->next;
+
+        /* remove free ptr from free list */
+        free_ptr->next_free->prev_free = free_ptr->prev_free;
+        free_ptr->prev_free->next_free = free_ptr->next_free;
+    }
+
+    /* insert the split block to free list */
+    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 free ptr: next_free 0x%08x, prev_free 0x%08x\n",
+                                    new_ptr->next_free,
+                                    new_ptr->prev_free));
+
+    /* increment the available byte count.  */
+    heap->available_size = heap->available_size + MEMITEM_SIZE(new_ptr);
+
+    /* release lock */
+    rt_sem_release(&(heap->lock));
+
+    /* return the old memory block */
+    return ptr;
+}
+
+void rt_lwp_memheap_free(void *ptr)
+{
+    rt_err_t result;
+    struct rt_lwp_memheap *heap;
+    struct rt_lwp_memheap_item *header_ptr, *new_ptr;
+    rt_uint32_t insert_header;
+
+    /* NULL check */
+    if (ptr == RT_NULL) return;
+
+    /* set initial status as OK */
+    insert_header = 1;
+    new_ptr       = RT_NULL;
+    header_ptr    = (struct rt_lwp_memheap_item *)
+                    ((rt_uint8_t *)ptr - RT_MEMHEAP_SIZE);
+
+    RT_DEBUG_LOG(RT_DEBUG_MEMHEAP, ("free memory: memory[0x%08x], block[0x%08x]\n",
+                                    ptr, header_ptr));
+
+    /* check magic */
+    RT_ASSERT((header_ptr->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
+    RT_ASSERT(header_ptr->magic & RT_MEMHEAP_USED);
+    /* check whether this block of memory has been over-written. */
+    RT_ASSERT((header_ptr->next->magic & RT_MEMHEAP_MASK) == RT_MEMHEAP_MAGIC);
+
+    /* get pool ptr */
+    heap = header_ptr->pool_ptr;
+
+    /* lock memheap */
+    result = rt_sem_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. */
+    heap->available_size = heap->available_size + MEMITEM_SIZE(header_ptr);
+
+    /* 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\n",
+                                        header_ptr->prev));
+
+        /* adjust the available number of bytes. */
+        heap->available_size = heap->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;
+        /* don't insert header to free list */
+        insert_header = 0;
+    }
+
+    /* 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. */
+        heap->available_size = heap->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, next_free 0x%08x, prev_free 0x%08x\n",
+                      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 = 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: next_free 0x%08x, prev_free 0x%08x\n",
+                      header_ptr->next_free, header_ptr->prev_free));
+    }
+
+    /* release lock */
+    rt_sem_release(&(heap->lock));
+}
+
+rt_bool_t rt_lwp_memheap_is_empty(struct rt_lwp_memheap *memheap)
+{
+    RT_ASSERT(memheap != RT_NULL);
+
+    return (memheap->available_size + 2 * sizeof(struct rt_lwp_memheap_item)) == memheap->pool_size;
+}
+
+rt_bool_t rt_lwp_memheap_unavailable_size_get(void)
+{
+    return 2 * RT_MEMHEAP_SIZE + 3;
+}

+ 74 - 0
components/lwp/lwp_memheap.h

@@ -0,0 +1,74 @@
+/*
+ * File      : lwp_memheap.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef __LWP_MEMHEAP_H__
+#define __LWP_MEMHEAP_H__
+
+#include <stdint.h>
+#include <rtthread.h>
+
+/**
+ * memory item on the heap
+ */
+struct rt_lwp_memheap_item
+{
+    rt_uint32_t                 magic;                  /**< magic number for memheap */
+    struct rt_lwp_memheap      *pool_ptr;               /**< point of pool */
+
+    struct rt_lwp_memheap_item *next;                   /**< next memheap item */
+    struct rt_lwp_memheap_item *prev;                   /**< prev memheap item */
+
+    struct rt_lwp_memheap_item *next_free;              /**< next free memheap item */
+    struct rt_lwp_memheap_item *prev_free;              /**< prev free memheap item */
+};
+
+/**
+ * Base structure of memory heap object
+ */
+struct rt_lwp_memheap
+{
+    struct rt_object        parent;                     /**< inherit from rt_object */
+
+    void                   *start_addr;                 /**< pool start address and size */
+
+    rt_uint32_t             pool_size;                  /**< pool size */
+    rt_uint32_t             available_size;             /**< available size */
+    rt_uint32_t             max_used_size;              /**< maximum allocated size */
+
+    struct rt_lwp_memheap_item *block_list;             /**< used block list */
+    struct rt_lwp_memheap_item *free_list;              /**< free block list */
+    struct rt_lwp_memheap_item  free_header;            /**< free block list header */
+
+    struct rt_semaphore     lock;                       /**< semaphore lock */
+
+    rt_list_t mlist;
+};
+
+extern rt_err_t rt_lwp_memheap_init(struct rt_lwp_memheap *memheap, const char *name, void *start_addr, rt_uint32_t size);
+extern void *rt_lwp_memheap_alloc(struct rt_lwp_memheap *heap, rt_uint32_t size);
+extern void rt_lwp_memheap_free(void *ptr);
+extern void *rt_lwp_memheap_realloc(struct rt_lwp_memheap *heap, void *ptr, rt_size_t newsize);
+extern rt_bool_t rt_lwp_memheap_is_empty(struct rt_lwp_memheap *memheap);
+extern rt_bool_t rt_lwp_memheap_unavailable_size_get(void);
+
+#endif

+ 242 - 0
components/lwp/lwp_syscall.c

@@ -0,0 +1,242 @@
+/*
+ * File      : lwp_syscall.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+/* RT-Thread System call */
+#include <lwp.h>
+#include <lwp_mem.h>
+#include <lwp_syscall.h>
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME    "[LWP_CALL]"
+#define DBG_COLOR
+#define DBG_LEVEL           DBG_WARNING
+#include <rtdbg.h>
+
+/* thread/process */
+void sys_exit(int value)
+{
+    /* TODO: handle the return_value */
+
+    dbg_log(DBG_LOG, "enter sys_exit\n");
+
+    rt_thread_delete(rt_thread_self());
+
+    rt_schedule();
+
+    return;
+}
+
+/* syscall: "read" ret: "ssize_t" args: "int" "void *" "size_t" */
+ssize_t sys_read(int fd, void *buf, size_t nbyte)
+{
+    return read(fd, buf, nbyte);
+}
+
+/* syscall: "write" ret: "ssize_t" args: "int" "const void *" "size_t" */
+ssize_t sys_write(int fd, const void *buf, size_t nbyte)
+{
+    return write(fd, buf, nbyte);
+}
+
+/* syscall: "lseek" ret: "off_t" args: "int" "off_t" "int" */
+off_t sys_lseek(int fd, off_t offset, int whence)
+{
+    return lseek(fd, offset, whence);
+}
+
+/* syscall: "open" ret: "int" args: "const char *" "int" "..." */
+int sys_open(const char *name, int mode, ...)
+{
+    return open(name, mode, 0);
+}
+
+/* syscall: "close" ret: "int" args: "int" */
+int sys_close(int fd)
+{
+    return close(fd);
+}
+
+/* syscall: "ioctl" ret: "int" args: "int" "u_long" "..." */
+int sys_ioctl(int fd, unsigned long cmd, void* data)
+{
+    return ioctl(fd, cmd, data);
+}
+
+/* syscall: "nanosleep" ret: "int" args: "const struct timespec *" "struct timespec *" */
+int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
+{
+    rt_tick_t tick;
+
+    dbg_log(DBG_LOG, "sys_nanosleep\n");
+
+    tick = rqtp->tv_sec * RT_TICK_PER_SECOND + (rqtp->tv_nsec * RT_TICK_PER_SECOND)/ 1000000000;
+    rt_thread_delay(tick);
+
+    if (rmtp)
+    {
+        tick = rt_tick_get() - tick;
+        /* get the passed time */
+        rmtp->tv_sec = tick/RT_TICK_PER_SECOND;
+        rmtp->tv_nsec = (tick%RT_TICK_PER_SECOND) * (1000000000/RT_TICK_PER_SECOND);
+    }
+
+    return 0;
+}
+
+/* syscall: "getpriority" ret: "int" args: "int" "id_t" */
+int sys_getpriority(int which, id_t who)
+{
+    if (which == PRIO_PROCESS)
+    {
+        rt_thread_t tid;
+
+        tid = rt_thread_self();
+        if (who == (id_t)tid || who == 0xff)
+        {
+            return tid->current_priority;
+        }
+    }
+
+    return 0xff;
+}
+
+/* syscall: "setpriority" ret: "int" args: "int" "id_t" "int" */
+int sys_setpriority(int which, id_t who, int prio)
+{
+    if (which == PRIO_PROCESS)
+    {
+        rt_thread_t tid;
+
+        tid = rt_thread_self();
+        if ((who == (id_t)tid || who == 0xff) && (prio >= 0 && prio < RT_THREAD_PRIORITY_MAX))
+        {
+            rt_thread_control(tid, RT_THREAD_CTRL_CHANGE_PRIORITY, &prio);
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+/* syscall: "gettimeofday" ret: "int" args: "struct timeval *" "struct timezone *" */
+int sys_gettimeofday(struct timeval *tp, struct timezone *tzp)
+{
+    if (tp)
+    {
+        tp->tv_sec = rt_tick_get() / RT_TICK_PER_SECOND;
+        tp->tv_usec = (rt_tick_get() % RT_TICK_PER_SECOND) * (1000000 / RT_TICK_PER_SECOND);
+    }
+
+    return 0;
+}
+
+/* syscall: "settimeofday" ret: "int" args: "const struct timeval *" "const struct timezone *" */
+int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp)
+{
+    return 0;
+}
+
+/* syscall: "msgget" ret: "int" args: "key_t" "int" */
+int sys_msgget(key_t key, int msgflg)
+{
+    return -1;
+}
+
+/* syscall: "msgsnd" ret: "int" args: "int" "const void *" "size_t" "int" */
+int sys_msgsend(int msqid, const void *msgp, size_t msgsz, int msgflg)
+{
+    return -1;
+}
+
+/* syscall: "msgrcv" ret: "int" args: "int" "void *" "size_t" "long" "int" */
+int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
+{
+    return -1;
+}
+
+/* syscall: "sys_log" ret: "int" args: "const char*" "size" */
+int sys_log(const char* log, int size)
+{
+    rt_device_t console = rt_console_get_device();
+
+    if (console) rt_device_write(console, -1, log, size);
+
+    return 0;
+}
+
+void *sys_malloc(size_t size)
+{
+    return rt_lwp_mem_malloc(size);
+}
+
+void sys_free(void *addr)
+{
+    rt_lwp_mem_free(addr);
+}
+
+void *sys_realloc(void *rmem, size_t newsize)
+{
+    return rt_lwp_mem_realloc(rmem, newsize);
+}
+
+const static void* func_table[] =
+{
+    (void *)sys_exit,           // 0x01
+    (void *)sys_read,           // 0x02
+    (void *)sys_write,          // 0x03
+    (void *)sys_lseek,          // 0x04
+    (void *)sys_open,           // 0x05
+    (void *)sys_close,          // 0x06
+    (void *)sys_ioctl,          // 0x07
+
+    (void *)sys_nanosleep,      // 0x08
+
+    (void *)sys_getpriority,    // 0x09
+    (void *)sys_setpriority,    // 0x0a
+
+    (void *)sys_gettimeofday,   // 0x0b
+    (void *)sys_settimeofday,   // 0x0c
+        
+    (void *)sys_malloc,         // 0x0d
+    (void *)sys_free,           // 0x0e
+};
+
+const void *lwp_get_sys_api(rt_uint32_t number)
+{
+    const void *func = RT_NULL;
+
+    if (number == 0xff)
+    {
+        func = (void *)sys_log;
+    }
+    else
+    {
+        number -= 1;
+        if (number < sizeof(func_table)/sizeof(func_table[0]))
+        {
+            func = func_table[number];
+        }
+    }
+
+    return func;
+}

+ 78 - 0
components/lwp/lwp_syscall.h

@@ -0,0 +1,78 @@
+/*
+ * File      : lwp_syscall.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-18     Bernard      the first version
+ * 2006-04-25     Bernard      add rt_hw_context_switch_interrupt declaration
+ * 2006-09-24     Bernard      add rt_hw_context_switch_to declaration
+ * 2012-12-29     Bernard      add rt_hw_exception_install declaration
+ * 2017-10-17     Hichard      add some micros
+ */
+
+#ifndef __LWP_SYSCALL_H__
+#define __LWP_SYSCALL_H__
+
+#include <stdint.h>
+#include <rtthread.h>
+#include <dfs_posix.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+typedef long suseconds_t;       /* microseconds (signed) */
+typedef long key_t;             /* IPC key (for Sys V IPC) */
+typedef uint32_t id_t;          /* may contain pid, uid or gid */
+
+/*
+ * Process priority specifications to get/setpriority.
+ */
+#define	PRIO_MIN	    (-20)
+#define	PRIO_MAX	    20
+
+#define	PRIO_PROCESS	0       /* only support lwp process */
+#define	PRIO_PGRP	    1
+#define	PRIO_USER	    2
+
+#define TIMEVAL_TO_TIMESPEC(tv, ts) {                   \
+    (ts)->tv_sec = (tv)->tv_sec;                        \
+    (ts)->tv_nsec = (tv)->tv_usec * 1000;               \
+}
+#define TIMESPEC_TO_TIMEVAL(tv, ts) {                   \
+    (tv)->tv_sec = (ts)->tv_sec;                        \
+    (tv)->tv_usec = (ts)->tv_nsec / 1000;               \
+}
+
+void sys_exit(int value);
+ssize_t sys_read(int fd, void *buf, size_t nbyte);
+ssize_t sys_write(int fd, const void *buf, size_t nbyte);
+off_t sys_lseek(int fd, off_t offset, int whence);
+int sys_open(const char *name, int mode, ...);
+int sys_close(int fd);
+int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
+int sys_getpriority(int which, id_t who);
+int sys_setpriority(int which, id_t who, int prio);
+int sys_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp);
+int sys_msgget(key_t key, int msgflg);
+int sys_msgsend(int msqid, const void *msgp, size_t msgsz, int msgflg);
+int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
+
+int sys_log(const char* log, int size);
+
+#endif

+ 16 - 0
components/utilities/logtrace/log_file.c

@@ -112,6 +112,18 @@ static rt_err_t fdevice_control(rt_device_t dev, int cmd, void *arg)
     return RT_EOK;
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops log_trace_ops = 
+{
+    RT_NULL,
+    fdevice_open,
+    fdevice_close,
+    RT_NULL,
+    fdevice_write,
+    fdevice_control
+};
+#endif
+
 void log_trace_file_init(const char *filename)
 {
     rt_device_t device;
@@ -123,11 +135,15 @@ void log_trace_file_init(const char *filename)
 
         _file_device.parent.type  = RT_Device_Class_Char;
 
+#ifdef RT_USING_DEVICE_OPS
+        _file_device.parent.ops     = &log_trace_ops;
+#else
         _file_device.parent.init    = RT_NULL;
         _file_device.parent.open    = fdevice_open;
         _file_device.parent.close   = fdevice_close;
         _file_device.parent.write   = fdevice_write;
         _file_device.parent.control = fdevice_control;
+#endif
 
         rt_device_register(&_file_device.parent, "logfile", O_RDWR);
     }

+ 16 - 0
components/utilities/logtrace/log_trace.c

@@ -383,17 +383,33 @@ static rt_err_t _log_control(rt_device_t dev, int cmd, void *arg)
     return rt_device_control(_traceout_device, cmd, arg);
 }
 
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops log_device_ops = 
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    _log_write,
+    _log_control
+};
+#endif
+
 int log_trace_init(void)
 {
     rt_memset(&_log_device, 0x00, sizeof(_log_device));
 
     _log_device.type = RT_Device_Class_Char;
+#ifdef RT_USING_DEVICE_OPS
+    _log_device.ops     = &log_device_ops;
+#else
     _log_device.init    = RT_NULL;
     _log_device.open    = RT_NULL;
     _log_device.close   = RT_NULL;
     _log_device.read    = RT_NULL;
     _log_device.write   = _log_write;
     _log_device.control = _log_control;
+#endif
 
     /* no indication and complete callback */
     _log_device.rx_indicate = RT_NULL;

+ 17 - 2
include/rtdef.h

@@ -848,6 +848,17 @@ enum rt_device_class_type
 #define RT_DEVICE_CTRL_RTC_SET_ALARM    0x13            /**< set alarm */
 
 typedef struct rt_device *rt_device_t;
+struct rt_device_ops
+{
+    /* 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, int cmd, void *args);
+};
+
 /**
  * Device structure
  */
@@ -866,6 +877,9 @@ struct rt_device
     rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
     rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);
 
+#ifdef RT_USING_DEVICE_OPS
+    const struct rt_device_ops *ops;
+#else
     /* common device interface */
     rt_err_t  (*init)   (rt_device_t dev);
     rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
@@ -873,6 +887,7 @@ struct rt_device
     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, int cmd, void *args);
+#endif
 
 #if defined(RT_USING_POSIX)
     const struct dfs_file_ops *fops;
@@ -1030,8 +1045,8 @@ struct rt_module
 
     rt_uint32_t                  user_data;             /**< arch data in the module */
 
-    /* object in this module, module object is the last basic object type */
-    struct rt_object_information module_object[RT_Object_Class_Unknown];
+    void (*module_init)(void);
+    void (*module_cleanup)(void);
 };
 typedef struct rt_module *rt_module_t;
 

+ 4 - 0
src/Kconfig

@@ -192,6 +192,10 @@ menu "Kernel Device Object"
         bool "Using device object"
         default y
 
+    config RT_USING_DEVICE_OPS
+        bool "Using ops for each device object"
+        default n
+
     config RT_USING_INTERRUPT_INFO
         bool "Enable additional interrupt trace information"
         default n

+ 33 - 15
src/device.c

@@ -32,12 +32,28 @@
 
 #ifdef RT_USING_DEVICE
 
+#ifdef RT_USING_DEVICE_OPS
+#define device_init     (dev->ops->init)
+#define device_open     (dev->ops->open)
+#define device_close    (dev->ops->close)
+#define device_read     (dev->ops->read)
+#define device_write    (dev->ops->write)
+#define device_control  (dev->ops->control)
+#else
+#define device_init     (dev->init)
+#define device_open     (dev->open)
+#define device_close    (dev->close)
+#define device_read     (dev->read)
+#define device_write    (dev->write)
+#define device_control  (dev->control)
+#endif
+
 /**
  * This function registers a device driver with specified name.
  *
  * @param dev the pointer of device driver structure
  * @param name the device driver's name
- * @param flags the flag of device
+ * @param flags the capabilities flag of device
  *
  * @return the error code, RT_EOK on initialization successfully.
  */
@@ -154,6 +170,8 @@ rt_device_t rt_device_create(int type, int attach_size)
     rt_device_t device;
 
     size = RT_ALIGN(sizeof(struct rt_device), RT_ALIGN_SIZE);
+    attach_size = RT_ALIGN(attach_size, RT_ALIGN_SIZE);
+    /* use the totoal size */
     size += attach_size;
 
     device = (rt_device_t)rt_malloc(size);
@@ -197,11 +215,11 @@ rt_err_t rt_device_init(rt_device_t dev)
     RT_ASSERT(dev != RT_NULL);
 
     /* get device init handler */
-    if (dev->init != RT_NULL)
+    if (device_init != RT_NULL)
     {
         if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
         {
-            result = dev->init(dev);
+            result = device_init(dev);
             if (result != RT_EOK)
             {
                 rt_kprintf("To initialize device:%s failed. The error code is %d\n",
@@ -234,9 +252,9 @@ rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag)
     /* if device is not initialized, initialize it. */
     if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
     {
-        if (dev->init != RT_NULL)
+        if (device_init != RT_NULL)
         {
-            result = dev->init(dev);
+            result = device_init(dev);
             if (result != RT_EOK)
             {
                 rt_kprintf("To initialize device:%s failed. The error code is %d\n",
@@ -257,9 +275,9 @@ rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag)
     }
 
     /* call device open interface */
-    if (dev->open != RT_NULL)
+    if (device_open != RT_NULL)
     {
-        result = dev->open(dev, oflag);
+        result = device_open(dev, oflag);
     }
     else
     {
@@ -304,9 +322,9 @@ rt_err_t rt_device_close(rt_device_t dev)
         return RT_EOK;
 
     /* call device close interface */
-    if (dev->close != RT_NULL)
+    if (device_close != RT_NULL)
     {
-        result = dev->close(dev);
+        result = device_close(dev);
     }
 
     /* set open flag */
@@ -343,9 +361,9 @@ rt_size_t rt_device_read(rt_device_t dev,
     }
 
     /* call device read interface */
-    if (dev->read != RT_NULL)
+    if (device_read != RT_NULL)
     {
-        return dev->read(dev, pos, buffer, size);
+        return device_read(dev, pos, buffer, size);
     }
 
     /* set error code */
@@ -381,9 +399,9 @@ rt_size_t rt_device_write(rt_device_t dev,
     }
 
     /* call device write interface */
-    if (dev->write != RT_NULL)
+    if (device_write != RT_NULL)
     {
-        return dev->write(dev, pos, buffer, size);
+        return device_write(dev, pos, buffer, size);
     }
 
     /* set error code */
@@ -407,9 +425,9 @@ rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg)
     RT_ASSERT(dev != RT_NULL);
 
     /* call device write interface */
-    if (dev->control != RT_NULL)
+    if (device_control != RT_NULL)
     {
-        return dev->control(dev, cmd, arg);
+        return device_control(dev, cmd, arg);
     }
 
     return -RT_ENOSYS;

+ 2 - 26
src/idle.c

@@ -164,35 +164,11 @@ void rt_thread_idle_excute(void)
         rt_hw_interrupt_enable(lock);
 
 #ifdef RT_USING_HEAP
-#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)
-        /* the thread belongs to an application module */
-        if (thread->flags & RT_OBJECT_FLAG_MODULE)
-            rt_module_free((rt_module_t)thread->module_id, thread->stack_addr);
-        else
-#endif
-            /* release thread's stack */
-            RT_KERNEL_FREE(thread->stack_addr);
+        /* release thread's stack */
+        RT_KERNEL_FREE(thread->stack_addr);
         /* delete thread object */
         rt_object_delete((rt_object_t)thread);
 #endif
-
-#ifdef RT_USING_MODULE
-        if (module != RT_NULL)
-        {
-            extern rt_err_t rt_module_destroy(rt_module_t module);
-
-            /* if sub thread list and main thread are all empty */
-            if ((module->module_thread == RT_NULL) &&
-                rt_list_isempty(&module->module_object[RT_Object_Class_Thread].object_list))
-            {
-                module->nref --;
-            }
-
-            /* destroy module */
-            if (module->nref == 0)
-                rt_module_destroy(module);
-        }
-#endif
     }
 }
 

+ 4 - 18
src/ipc.c

@@ -1380,15 +1380,8 @@ rt_err_t rt_mb_delete(rt_mailbox_t mb)
     /* also resume all mailbox private suspended thread */
     rt_ipc_list_resume_all(&(mb->suspend_sender_thread));
 
-#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)
-    /* the mb object belongs to an application module */
-    if (mb->parent.parent.flag & RT_OBJECT_FLAG_MODULE)
-        rt_module_free(mb->parent.parent.module_id, mb->msg_pool);
-    else
-#endif
-
-        /* free mailbox pool */
-        RT_KERNEL_FREE(mb->msg_pool);
+    /* free mailbox pool */
+    RT_KERNEL_FREE(mb->msg_pool);
 
     /* delete mailbox object */
     rt_object_delete(&(mb->parent.parent));
@@ -1900,15 +1893,8 @@ rt_err_t rt_mq_delete(rt_mq_t mq)
     /* resume all suspended thread */
     rt_ipc_list_resume_all(&(mq->parent.suspend_thread));
 
-#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)
-    /* the mq object belongs to an application module */
-    if (mq->parent.parent.flag & RT_OBJECT_FLAG_MODULE)
-        rt_module_free(mq->parent.parent.module_id, mq->msg_pool);
-    else
-#endif
-
-        /* free message queue pool */
-        RT_KERNEL_FREE(mq->msg_pool);
+    /* free message queue pool */
+    RT_KERNEL_FREE(mq->msg_pool);
 
     /* delete message queue object */
     rt_object_delete(&(mq->parent.parent));

+ 2 - 9
src/mempool.c

@@ -292,15 +292,8 @@ rt_err_t rt_mp_delete(rt_mp_t mp)
         rt_hw_interrupt_enable(temp);
     }
 
-#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)
-    /* the mp object belongs to an application module */
-    if (mp->parent.flag & RT_OBJECT_FLAG_MODULE)
-        rt_module_free(mp->parent.module_id, mp->start_address);
-    else
-#endif
-
-        /* release allocated room */
-        rt_free(mp->start_address);
+    /* release allocated room */
+    rt_free(mp->start_address);
 
     /* detach object */
     rt_object_delete(&(mp->parent));

+ 2 - 773
src/module.c

@@ -65,30 +65,6 @@
 #define RT_USING_MODULE_PRIO (RT_THREAD_PRIORITY_MAX - 2)
 #endif
 
-#ifdef RT_USING_SLAB
-#define PAGE_COUNT_MAX    256
-
-/* module memory allocator */
-struct rt_mem_head
-{
-    rt_size_t size;                /* size of memory block */
-    struct rt_mem_head *next;      /* next valid memory block */
-};
-
-struct rt_page_info
-{
-    rt_uint32_t *page_ptr;
-    rt_uint32_t npage;
-};
-
-static void *rt_module_malloc_page(rt_size_t npages);
-static void rt_module_free_page(rt_module_t module,
-                                void       *page_ptr,
-                                rt_size_t   npages);
-
-static struct rt_semaphore mod_sem;
-#endif
-
 static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL;
 static struct rt_module_symtab *_rt_module_symtab_end   = RT_NULL;
 
@@ -120,10 +96,6 @@ int rt_system_module_init(void)
     _rt_module_symtab_end   = __section_end("RTMSymTab");
 #endif
 
-#ifdef RT_USING_SLAB
-    /* initialize heap semaphore */
-    rt_sem_init(&mod_sem, "module", 1, RT_IPC_FLAG_FIFO);
-#endif
     return 0;
 }
 INIT_COMPONENT_EXPORT(rt_system_module_init);
@@ -138,7 +110,7 @@ void list_symbol(void)
          index != _rt_module_symtab_end;
          index ++)
     {
-        rt_kprintf("%s\n", index->name);
+        rt_kprintf("%s => 0x%08x\n", index->name, index->addr);
     }
 
     return ;
@@ -295,80 +267,6 @@ static int rt_module_arm_relocate(struct rt_module *module,
     return 0;
 }
 
-void rt_module_init_object_container(struct rt_module *module)
-{
-    RT_ASSERT(module != RT_NULL);
-
-    /* clear all of object information */
-    rt_memset(&module->module_object[0], 0x0, sizeof(module->module_object));
-
-    /* initialize object container - thread */
-    rt_list_init(&(module->module_object[RT_Object_Class_Thread].object_list));
-    module->module_object[RT_Object_Class_Thread].object_size = sizeof(struct rt_thread);
-    module->module_object[RT_Object_Class_Thread].type = RT_Object_Class_Thread;
-
-#ifdef RT_USING_SEMAPHORE
-    /* initialize object container - semaphore */
-    rt_list_init(&(module->module_object[RT_Object_Class_Semaphore].object_list));
-    module->module_object[RT_Object_Class_Semaphore].object_size = sizeof(struct rt_semaphore);
-    module->module_object[RT_Object_Class_Semaphore].type = RT_Object_Class_Semaphore;
-#endif
-
-#ifdef RT_USING_MUTEX
-    /* initialize object container - mutex */
-    rt_list_init(&(module->module_object[RT_Object_Class_Mutex].object_list));
-    module->module_object[RT_Object_Class_Mutex].object_size = sizeof(struct rt_mutex);
-    module->module_object[RT_Object_Class_Mutex].type = RT_Object_Class_Mutex;
-#endif
-
-#ifdef RT_USING_EVENT
-    /* initialize object container - event */
-    rt_list_init(&(module->module_object[RT_Object_Class_Event].object_list));
-    module->module_object[RT_Object_Class_Event].object_size = sizeof(struct rt_event);
-    module->module_object[RT_Object_Class_Event].type = RT_Object_Class_Event;
-#endif
-
-#ifdef RT_USING_MAILBOX
-    /* initialize object container - mailbox */
-    rt_list_init(&(module->module_object[RT_Object_Class_MailBox].object_list));
-    module->module_object[RT_Object_Class_MailBox].object_size = sizeof(struct rt_mailbox);
-    module->module_object[RT_Object_Class_MailBox].type = RT_Object_Class_MailBox;
-#endif
-
-#ifdef RT_USING_MESSAGEQUEUE
-    /* initialize object container - message queue */
-    rt_list_init(&(module->module_object[RT_Object_Class_MessageQueue].object_list));
-    module->module_object[RT_Object_Class_MessageQueue].object_size = sizeof(struct rt_messagequeue);
-    module->module_object[RT_Object_Class_MessageQueue].type = RT_Object_Class_MessageQueue;
-#endif
-
-#ifdef RT_USING_MEMHEAP
-    /* initialize object container - memory heap */
-    rt_list_init(&(module->module_object[RT_Object_Class_MemHeap].object_list));
-    module->module_object[RT_Object_Class_MemHeap].object_size = sizeof(struct rt_memheap);
-    module->module_object[RT_Object_Class_MemHeap].type = RT_Object_Class_MemHeap;
-#endif
-
-#ifdef RT_USING_MEMPOOL
-    /* initialize object container - memory pool */
-    rt_list_init(&(module->module_object[RT_Object_Class_MemPool].object_list));
-    module->module_object[RT_Object_Class_MemPool].object_size = sizeof(struct rt_mempool);
-    module->module_object[RT_Object_Class_MemPool].type = RT_Object_Class_MemPool;
-#endif
-
-#ifdef RT_USING_DEVICE
-    /* initialize object container - device */
-    rt_list_init(&(module->module_object[RT_Object_Class_Device].object_list));
-    module->module_object[RT_Object_Class_Device].object_size = sizeof(struct rt_device);
-    module->module_object[RT_Object_Class_Device].type = RT_Object_Class_Device;
-#endif
-
-    /* initialize object container - timer */
-    rt_list_init(&(module->module_object[RT_Object_Class_Timer].object_list));
-    module->module_object[RT_Object_Class_Timer].object_size = sizeof(struct rt_timer);
-    module->module_object[RT_Object_Class_Timer].type = RT_Object_Class_Timer;
-}
-
 #ifdef RT_USING_HOOK
 static void (*rt_module_load_hook)(rt_module_t module);
 static void (*rt_module_unload_hook)(rt_module_t module);
@@ -1016,9 +914,6 @@ rt_module_t rt_module_do_main(const char *name,
     if (module == RT_NULL)
         return RT_NULL;
 
-    /* init module object container */
-    rt_module_init_object_container(module);
-
     if (line_size && cmd_line)
     {
         /* set module argument */
@@ -1042,16 +937,6 @@ rt_module_t rt_module_do_main(const char *name,
 
     if (elf_module->e_entry != 0)
     {
-#ifdef RT_USING_SLAB
-        /* init module memory allocator */
-        module->mem_list = RT_NULL;
-
-        /* create page array */
-        module->page_array =
-            (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
-        module->page_cnt = 0;
-#endif
-
         /* create module thread */
         module->module_thread = rt_thread_create(name,
                                                  module_main_entry, module,
@@ -1291,8 +1176,6 @@ FINSH_FUNCTION_EXPORT_ALIAS(rt_module_open, exec, exec module from a file);
 rt_err_t rt_module_destroy(rt_module_t module)
 {
     int i;
-    struct rt_object *object;
-    struct rt_list_node *list;
 
     RT_DEBUG_NOT_IN_INTERRUPT;
 
@@ -1306,147 +1189,6 @@ rt_err_t rt_module_destroy(rt_module_t module)
     /* module has entry point */
     if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
     {
-#ifdef RT_USING_SEMAPHORE
-        /* delete semaphores */
-        list = &module->module_object[RT_Object_Class_Semaphore].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_sem_detach((rt_sem_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_sem_delete((rt_sem_t)object);
-            }
-        }
-#endif
-
-#ifdef RT_USING_MUTEX
-        /* delete mutexs*/
-        list = &module->module_object[RT_Object_Class_Mutex].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_mutex_detach((rt_mutex_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_mutex_delete((rt_mutex_t)object);
-            }
-        }
-#endif
-
-#ifdef RT_USING_EVENT
-        /* delete mailboxs */
-        list = &module->module_object[RT_Object_Class_Event].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_event_detach((rt_event_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_event_delete((rt_event_t)object);
-            }
-        }
-#endif
-
-#ifdef RT_USING_MAILBOX
-        /* delete mailboxs */
-        list = &module->module_object[RT_Object_Class_MailBox].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_mb_detach((rt_mailbox_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_mb_delete((rt_mailbox_t)object);
-            }
-        }
-#endif
-
-#ifdef RT_USING_MESSAGEQUEUE
-        /* delete msgqueues */
-        list = &module->module_object[RT_Object_Class_MessageQueue].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_mq_detach((rt_mq_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_mq_delete((rt_mq_t)object);
-            }
-        }
-#endif
-
-#ifdef RT_USING_MEMPOOL
-        /* delete mempools */
-        list = &module->module_object[RT_Object_Class_MemPool].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_mp_detach((rt_mp_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_mp_delete((rt_mp_t)object);
-            }
-        }
-#endif
-
-#ifdef RT_USING_DEVICE
-        /* delete devices */
-        list = &module->module_object[RT_Object_Class_Device].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            rt_device_unregister((rt_device_t)object);
-        }
-#endif
-
-        /* delete timers */
-        list = &module->module_object[RT_Object_Class_Timer].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_timer_detach((rt_timer_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_timer_delete((rt_timer_t)object);
-            }
-        }
-
         /* delete command line */
         if (module->module_cmd_line != RT_NULL)
         {
@@ -1454,20 +1196,6 @@ rt_err_t rt_module_destroy(rt_module_t module)
         }
     }
 
-#ifdef RT_USING_SLAB
-    if (module->page_cnt > 0)
-    {
-        struct rt_page_info *page = (struct rt_page_info *)module->page_array;
-
-        rt_kprintf("Module: warning - memory still hasn't been free finished\n");
-
-        while (module->page_cnt != 0)
-        {
-            rt_module_free_page(module, page[0].page_ptr, page[0].npage);
-        }
-    }
-#endif
-
     /* release module space memory */
     rt_free(module->module_space);
 
@@ -1479,11 +1207,6 @@ rt_err_t rt_module_destroy(rt_module_t module)
     if (module->symtab != RT_NULL)
         rt_free(module->symtab);
 
-#ifdef RT_USING_SLAB
-    if (module->page_array != RT_NULL)
-        rt_free(module->page_array);
-#endif
-
     /* delete module object */
     rt_object_delete((rt_object_t)module);
 
@@ -1499,10 +1222,6 @@ rt_err_t rt_module_destroy(rt_module_t module)
  */
 rt_err_t rt_module_unload(rt_module_t module)
 {
-    struct rt_object *object;
-    struct rt_list_node *list;
-	rt_bool_t mdelete = RT_TRUE;
-
     RT_DEBUG_NOT_IN_INTERRUPT;
 
     /* check parameter */
@@ -1510,34 +1229,7 @@ rt_err_t rt_module_unload(rt_module_t module)
         return -RT_ERROR;
 
     rt_enter_critical();
-    if (!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
-    {
-    	/* delete module in main thread destroy */
-		mdelete = RT_FALSE;
-    
-        /* delete all sub-threads */
-        list = &module->module_object[RT_Object_Class_Thread].object_list;
-        while (list->next != list)
-        {
-            object = rt_list_entry(list->next, struct rt_object, list);
-            if (rt_object_is_systemobject(object) == RT_TRUE)
-            {
-                /* detach static object */
-                rt_thread_detach((rt_thread_t)object);
-            }
-            else
-            {
-                /* delete dynamic object */
-                rt_thread_delete((rt_thread_t)object);
-            }
-        }
-
-        /* delete the main thread of module */
-        if (module->module_thread != RT_NULL)
-        {
-            rt_thread_delete(module->module_thread);
-        }
-    }
+    /* invoke module cleanup */
     rt_exit_critical();
 
 #ifdef RT_USING_HOOK
@@ -1547,11 +1239,6 @@ rt_err_t rt_module_unload(rt_module_t module)
     }
 #endif
 
-	if (mdelete == RT_TRUE)
-	{
-		rt_module_destroy(module);
-	}
-
     return RT_EOK;
 }
 
@@ -1598,462 +1285,4 @@ rt_module_t rt_module_find(const char *name)
 }
 RTM_EXPORT(rt_module_find);
 
-#ifdef RT_USING_SLAB
-/*
- * This function will allocate the numbers page with specified size
- * in page memory.
- *
- * @param size the size of memory to be allocated.
- * @note this function is used for RT-Thread Application Module
- */
-static void *rt_module_malloc_page(rt_size_t npages)
-{
-    void *chunk;
-    struct rt_page_info *page;
-    rt_module_t self_module;
-
-    self_module = rt_module_self();
-    RT_ASSERT(self_module != RT_NULL);
-
-    chunk = rt_page_alloc(npages);
-    if (chunk == RT_NULL)
-        return RT_NULL;
-
-    page = (struct rt_page_info *)self_module->page_array;
-    page[self_module->page_cnt].page_ptr = chunk;
-    page[self_module->page_cnt].npage    = npages;
-    self_module->page_cnt ++;
-
-    RT_ASSERT(self_module->page_cnt <= PAGE_COUNT_MAX);
-    RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc_page 0x%x %d\n",
-                                   chunk, npages));
-
-    return chunk;
-}
-
-/*
- * This function will release the previously allocated memory page
- * by rt_malloc_page.
- *
- * @param page_ptr the page address to be released.
- * @param npages the number of page shall be released.
- *
- * @note this function is used for RT-Thread Application Module
- */
-static void rt_module_free_page(rt_module_t module,
-                                void       *page_ptr,
-                                rt_size_t   npages)
-{
-    int i, index;
-    struct rt_page_info *page;
-    rt_module_t self_module;
-
-    self_module = rt_module_self();
-    RT_ASSERT(self_module != RT_NULL);
-
-    RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_free_page 0x%x %d\n",
-                                   page_ptr, npages));
-    rt_page_free(page_ptr, npages);
-
-    page = (struct rt_page_info *)module->page_array;
-
-    for (i = 0; i < module->page_cnt; i ++)
-    {
-        if (page[i].page_ptr == page_ptr)
-        {
-            if (page[i].npage == npages + 1)
-            {
-                page[i].page_ptr +=
-                    npages * RT_MM_PAGE_SIZE / sizeof(rt_uint32_t);
-                page[i].npage    -= npages;
-            }
-            else if (page[i].npage == npages)
-            {
-                for (index = i; index < module->page_cnt - 1; index ++)
-                {
-                    page[index].page_ptr = page[index + 1].page_ptr;
-                    page[index].npage    = page[index + 1].npage;
-                }
-                page[module->page_cnt - 1].page_ptr = RT_NULL;
-                page[module->page_cnt - 1].npage    = 0;
-
-                module->page_cnt --;
-            }
-            else
-                RT_ASSERT(RT_FALSE);
-            self_module->page_cnt --;
-
-            return;
-        }
-    }
-
-    /* should not get here */
-    RT_ASSERT(RT_FALSE);
-}
-
-/**
- * rt_module_malloc - allocate memory block in free list
- */
-void *rt_module_malloc(rt_size_t size)
-{
-    struct rt_mem_head *b, *n, *up;
-    struct rt_mem_head **prev;
-    rt_uint32_t npage;
-    rt_size_t nunits;
-    rt_module_t self_module;
-
-    self_module = rt_module_self();
-    RT_ASSERT(self_module != RT_NULL);
-
-    RT_DEBUG_NOT_IN_INTERRUPT;
-
-    nunits = (size + sizeof(struct rt_mem_head) - 1) /
-             sizeof(struct rt_mem_head)
-             + 1;
-
-    RT_ASSERT(size != 0);
-    RT_ASSERT(nunits != 0);
-
-    rt_sem_take(&mod_sem, RT_WAITING_FOREVER);
-
-    for (prev = (struct rt_mem_head **)&self_module->mem_list;
-         (b = *prev) != RT_NULL;
-         prev = &(b->next))
-    {
-        if (b->size > nunits)
-        {
-            /* split memory */
-            n       = b + nunits;
-            n->next = b->next;
-            n->size = b->size - nunits;
-            b->size = nunits;
-            *prev   = n;
-
-            RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc 0x%x, %d\n",
-                                           b + 1, size));
-            rt_sem_release(&mod_sem);
-
-            return (void *)(b + 1);
-        }
-
-        if (b->size == nunits)
-        {
-            /* this node fit, remove this node */
-            *prev = b->next;
-
-            RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_malloc 0x%x, %d\n",
-                                           b + 1, size));
-
-            rt_sem_release(&mod_sem);
-
-            return (void *)(b + 1);
-        }
-    }
-
-    /* allocate pages from system heap */
-    npage = (size + sizeof(struct rt_mem_head) + RT_MM_PAGE_SIZE - 1) /
-            RT_MM_PAGE_SIZE;
-    if ((up = (struct rt_mem_head *)rt_module_malloc_page(npage)) == RT_NULL)
-        return RT_NULL;
-
-    up->size = npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head);
-
-    for (prev = (struct rt_mem_head **)&self_module->mem_list;
-         (b = *prev) != RT_NULL;
-         prev = &(b->next))
-    {
-        if (b > up + up->size)
-            break;
-    }
-
-    up->next = b;
-    *prev    = up;
-
-    rt_sem_release(&mod_sem);
-
-    return rt_module_malloc(size);
-}
-
-/**
- * rt_module_free - free memory block in free list
- */
-void rt_module_free(rt_module_t module, void *addr)
-{
-    struct rt_mem_head *b, *n, *r;
-    struct rt_mem_head **prev;
-
-    RT_DEBUG_NOT_IN_INTERRUPT;
-
-    RT_ASSERT(addr);
-    RT_ASSERT((((rt_uint32_t)addr) & (sizeof(struct rt_mem_head) - 1)) == 0);
-
-    RT_DEBUG_LOG(RT_DEBUG_MODULE, ("rt_module_free 0x%x\n", addr));
-
-    rt_sem_take(&mod_sem, RT_WAITING_FOREVER);
-
-    n = (struct rt_mem_head *)addr - 1;
-    prev = (struct rt_mem_head **)&module->mem_list;
-
-    while ((b = *prev) != RT_NULL)
-    {
-        RT_ASSERT(b->size > 0);
-        RT_ASSERT(b > n || b + b->size <= n);
-
-        if (b + b->size == n && ((rt_uint32_t)n % RT_MM_PAGE_SIZE != 0))
-        {
-            if (b + (b->size + n->size) == b->next)
-            {
-                b->size += b->next->size + n->size;
-                b->next = b->next->next;
-            }
-            else
-                b->size += n->size;
-
-            if ((rt_uint32_t)b % RT_MM_PAGE_SIZE == 0)
-            {
-                int npage =
-                    b->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE;
-                if (npage > 0)
-                {
-                    if ((b->size * sizeof(struct rt_page_info) % RT_MM_PAGE_SIZE) != 0)
-                    {
-                        rt_size_t nunits = npage *
-                                           RT_MM_PAGE_SIZE /
-                                           sizeof(struct rt_mem_head);
-                        /* split memory */
-                        r       = b + nunits;
-                        r->next = b->next;
-                        r->size = b->size - nunits;
-                        *prev   = r;
-                    }
-                    else
-                    {
-                        *prev = b->next;
-                    }
-
-                    rt_module_free_page(module, b, npage);
-                }
-            }
-
-            /* unlock */
-            rt_sem_release(&mod_sem);
-
-            return;
-        }
-
-        if (b == n + n->size)
-        {
-            n->size = b->size + n->size;
-            n->next = b->next;
-
-            if ((rt_uint32_t)n % RT_MM_PAGE_SIZE == 0)
-            {
-                int npage =
-                    n->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE;
-                if (npage > 0)
-                {
-                    if ((n->size * sizeof(struct rt_page_info) % RT_MM_PAGE_SIZE) != 0)
-                    {
-                        rt_size_t nunits = npage *
-                                           RT_MM_PAGE_SIZE /
-                                           sizeof(struct rt_mem_head);
-                        /* split memory */
-                        r       = n + nunits;
-                        r->next = n->next;
-                        r->size = n->size - nunits;
-                        *prev   = r;
-                    }
-                    else
-                        *prev = n->next;
-
-                    rt_module_free_page(module, n, npage);
-                }
-            }
-            else
-            {
-                *prev = n;
-            }
-
-            /* unlock */
-            rt_sem_release(&mod_sem);
-
-            return;
-        }
-        if (b > n + n->size)
-            break;
-
-        prev = &(b->next);
-    }
-
-    if ((rt_uint32_t)n % RT_MM_PAGE_SIZE == 0)
-    {
-        int npage = n->size * sizeof(struct rt_page_info) / RT_MM_PAGE_SIZE;
-        if (npage > 0)
-        {
-            rt_module_free_page(module, n, npage);
-            if (n->size % RT_MM_PAGE_SIZE != 0)
-            {
-                rt_size_t nunits =
-                    npage * RT_MM_PAGE_SIZE / sizeof(struct rt_mem_head);
-                /* split memory */
-                r       = n + nunits;
-                r->next = b;
-                r->size = n->size - nunits;
-                *prev   = r;
-            }
-            else
-            {
-                *prev = b;
-            }
-        }
-    }
-    else
-    {
-        n->next = b;
-        *prev   = n;
-    }
-
-    /* unlock */
-    rt_sem_release(&mod_sem);
-}
-
-/**
- * rt_module_realloc - realloc memory block in free list
- */
-void *rt_module_realloc(void *ptr, rt_size_t size)
-{
-    struct rt_mem_head *b, *p, *prev, *tmpp;
-    rt_size_t nunits;
-    rt_module_t self_module;
-
-    self_module = rt_module_self();
-    RT_ASSERT(self_module != RT_NULL);
-
-    RT_DEBUG_NOT_IN_INTERRUPT;
-
-    if (!ptr)
-        return rt_module_malloc(size);
-    if (size == 0)
-    {
-        rt_module_free(self_module, ptr);
-
-        return RT_NULL;
-    }
-
-    nunits = (size + sizeof(struct rt_mem_head) - 1) /
-             sizeof(struct rt_mem_head)
-             + 1;
-    b = (struct rt_mem_head *)ptr - 1;
-
-    if (nunits <= b->size)
-    {
-        /* new size is smaller or equal then before */
-        if (nunits == b->size)
-            return ptr;
-        else
-        {
-            p       = b + nunits;
-            p->size = b->size - nunits;
-            b->size = nunits;
-            rt_module_free(self_module, (void *)(p + 1));
-
-            return (void *)(b + 1);
-        }
-    }
-    else
-    {
-        /* more space then required */
-        prev = (struct rt_mem_head *)self_module->mem_list;
-        for (p = prev->next;
-             p != (b->size + b) && p != RT_NULL;
-             prev = p, p = p->next)
-        {
-            break;
-        }
-
-        /* available block after ap in freelist */
-        if (p != RT_NULL &&
-            (p->size >= (nunits - (b->size))) &&
-            p == (b + b->size))
-        {
-            /* perfect match */
-            if (p->size == (nunits - (b->size)))
-            {
-                b->size    = nunits;
-                prev->next = p->next;
-            }
-            else  /* more space then required, split block */
-            {
-                /* pointer to old header */
-                tmpp = p;
-                p    = b + nunits;
-
-                /* restoring old pointer */
-                p->next = tmpp->next;
-
-                /* new size for p */
-                p->size    = tmpp->size + b->size - nunits;
-                b->size    = nunits;
-                prev->next = p;
-            }
-            self_module->mem_list = (void *)prev;
-
-            return (void *)(b + 1);
-        }
-        else /* allocate new memory and copy old data */
-        {
-            if ((p = rt_module_malloc(size)) == RT_NULL)
-                return RT_NULL;
-            rt_memmove(p, (b + 1), ((b->size) * sizeof(struct rt_mem_head)));
-            rt_module_free(self_module, (void *)(b + 1));
-
-            return (void *)(p);
-        }
-    }
-}
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-
-void list_memlist(const char *name)
-{
-    rt_module_t module;
-    struct rt_mem_head **prev;
-    struct rt_mem_head *b;
-
-    module = rt_module_find(name);
-    if (module == RT_NULL)
-        return;
-
-    for (prev = (struct rt_mem_head **)&module->mem_list;
-         (b = *prev) != RT_NULL;
-         prev = &(b->next))
-    {
-        rt_kprintf("0x%x--%d\n", b, b->size * sizeof(struct rt_mem_head));
-    }
-}
-FINSH_FUNCTION_EXPORT(list_memlist, list module free memory information)
-
-void list_mempage(const char *name)
-{
-    rt_module_t module;
-    struct rt_page_info *page;
-    int i;
-
-    module = rt_module_find(name);
-    if (module == RT_NULL)
-        return;
-
-    page = (struct rt_page_info *)module->page_array;
-
-    for (i = 0; i < module->page_cnt; i ++)
-    {
-        rt_kprintf("0x%x--%d\n", page[i].page_ptr, page[i].npage);
-    }
-}
-FINSH_FUNCTION_EXPORT(list_mempage, list module using memory page information)
-#endif /* RT_USING_FINSH */
-
-#endif /* RT_USING_SLAB */
-
 #endif

+ 2 - 82
src/object.c

@@ -252,15 +252,9 @@ void rt_object_init(struct rt_object         *object,
     register rt_base_t temp;
     struct rt_object_information *information;
 
-#ifdef RT_USING_MODULE
-    /* get module object information */
-    information = (rt_module_self() != RT_NULL) ?
-                  &rt_module_self()->module_object[type] : rt_object_get_information(type);
-#else
     /* get object information */
     information = rt_object_get_information(type);
     RT_ASSERT(information != RT_NULL);
-#endif
 
     /* initialize object's parameters */
 
@@ -324,18 +318,9 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
 
     RT_DEBUG_NOT_IN_INTERRUPT;
 
-#ifdef RT_USING_MODULE
-    /*
-     * get module object information,
-     * module object should be managed by kernel object container
-     */
-    information = (rt_module_self() != RT_NULL && (type != RT_Object_Class_Module)) ?
-                  &rt_module_self()->module_object[type] : rt_object_get_information(type);
-#else
     /* get object information */
     information = rt_object_get_information(type);
     RT_ASSERT(information != RT_NULL);
-#endif
 
     object = (struct rt_object *)RT_KERNEL_MALLOC(information->object_size);
     if (object == RT_NULL)
@@ -402,14 +387,8 @@ void rt_object_delete(rt_object_t object)
     /* unlock interrupt */
     rt_hw_interrupt_enable(temp);
 
-#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB)
-    if (object->flag & RT_OBJECT_FLAG_MODULE)
-        rt_module_free((rt_module_t)object->module_id, object);
-    else
-#endif
-
-        /* free the memory of object */
-        RT_KERNEL_FREE(object);
+    /* free the memory of object */
+    RT_KERNEL_FREE(object);
 }
 #endif
 
@@ -458,65 +437,6 @@ rt_object_t rt_object_find(const char *name, rt_uint8_t type)
     /* which is invoke in interrupt status */
     RT_DEBUG_NOT_IN_INTERRUPT;
 
-#ifdef RT_USING_MODULE
-    /* check whether to find a object inside a module. */
-    {
-        const char *name_ptr;
-        int module_name_length;
-
-        name_ptr = name;
-        while ((*name_ptr != '\0') && (*name_ptr != '/'))
-            name_ptr ++;
-
-        if (*name_ptr == '/')
-        {
-            struct rt_module *module = RT_NULL;
-
-            /* get the name length of module */
-            module_name_length = name_ptr - name;
-
-            /* enter critical */
-            rt_enter_critical();
-
-            /* find module */
-            information = rt_object_get_information(RT_Object_Class_Module);
-            RT_ASSERT(information != RT_NULL);
-
-            for (node = information->object_list.next;
-                    node != &(information->object_list);
-                    node  = node->next)
-            {
-                object = rt_list_entry(node, struct rt_object, list);
-                if ((rt_strncmp(object->name, name, module_name_length) == 0) &&
-                        (module_name_length == RT_NAME_MAX || object->name[module_name_length] == '\0'))
-                {
-                    /* get module */
-                    module = (struct rt_module *)object;
-                    break;
-                }
-            }
-            rt_exit_critical();
-
-            /* there is no this module inside the system */
-            if (module == RT_NULL) return RT_NULL;
-
-            /* get the object pool of module */
-            information = &(module->module_object[type]);
-
-            /* get object name */
-            while ((*name_ptr == '/') && (*name_ptr != '\0')) name_ptr ++;
-            if (*name_ptr == '\0')
-            {
-                if (type == RT_Object_Class_Module) return object;
-                return RT_NULL;
-            }
-
-            /* point to the object name */
-            name = name_ptr;
-        }
-    }
-#endif
-
     /* enter critical */
     rt_enter_critical();
 

+ 0 - 19
src/slab.c

@@ -496,11 +496,6 @@ void *rt_malloc(rt_size_t size)
     if (size == 0)
         return RT_NULL;
 
-#ifdef RT_USING_MODULE
-    if (rt_module_self() != RT_NULL)
-        return rt_module_malloc(size);
-#endif
-
     /*
      * Handle large allocations directly.  There should not be very many of
      * these so performance is not a big issue.
@@ -705,11 +700,6 @@ void *rt_realloc(void *ptr, rt_size_t size)
         return RT_NULL;
     }
 
-#ifdef RT_USING_MODULE
-    if (rt_module_self() != RT_NULL)
-        return rt_module_realloc(ptr, size);
-#endif
-
     /*
      * Get the original allocation's zone.  If the new request winds up
      * using the same chunk size we do not have to do anything.
@@ -800,15 +790,6 @@ void rt_free(void *ptr)
 
     RT_OBJECT_HOOK_CALL(rt_free_hook, (ptr));
 
-#ifdef RT_USING_MODULE
-    if (rt_module_self() != RT_NULL)
-    {
-        rt_module_free(rt_module_self(), ptr);
-
-        return;
-    }
-#endif
-
     /* get memory usage */
 #if RT_DEBUG_SLAB
     {