ソースを参照

add bsp: simluator for linux

prife 12 年 前
コミット
212b71205b

+ 12 - 0
bsp/simlinux/SConscript

@@ -0,0 +1,12 @@
+from building import *
+
+cwd  = GetCurrentDir()
+objs = []
+list = os.listdir(cwd)
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')

+ 91 - 0
bsp/simlinux/SConstruct

@@ -0,0 +1,91 @@
+import os
+import sys
+import rtconfig
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
+
+if os.getenv('RTT_RTGUI'):
+    RTT_RTGUI = os.getenv('RTT_RTGUI')
+else:
+    # set the rtgui root directory by hand
+    # empty string means use the RTGUI in svn
+    # RTT_RTGUI = os.path.normpath(r'F:\Project\git\rt-gui\components\rtgui')
+    RTT_RTGUI =''
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+
+env = Environment()
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+if rtconfig.PLATFORM == 'cl':
+    TARGET = 'rtthread-win32.' + rtconfig.TARGET_EXT
+
+    libs = Split('''
+    winmm
+    gdi32
+    winspool
+    comdlg32
+    advapi32
+    shell32
+    ole32
+    oleaut32
+    uuid
+    odbc32
+    odbccp32
+    ''')
+    definitions = Split('''
+    WIN32
+    _DEBUG
+    _CONSOLE
+    MSVC
+    _TIME_T_DEFINED
+    ''')
+    env.Append(CCFLAGS=rtconfig.CFLAGS)
+    env.Append(LINKFLAGS=rtconfig.LFLAGS)
+    env['LIBS']=libs
+    env['CPPDEFINES']=definitions
+else:
+    TARGET = 'rtthread'
+    env.Append(CCFLAGS=rtconfig.CFLAGS)
+    env.Append(LINKFLAGS=rtconfig.LFLAGS)
+
+
+# prepare building environment
+
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False, remove_components=['rtgui'])
+if GetDepend('RT_USING_RTGUI'):
+    sdl_lib = ['SDL', 'SDLmain']
+    sdl_lib_path = [os.path.abspath('SDL/lib/x86')]
+    sdl_include_path = [os.path.abspath('SDL/include')]
+    env.Append(LIBS=sdl_lib)
+    env.Append(LIBPATH=sdl_lib_path)
+    env.Append(CPPPATH=sdl_include_path)
+
+    if RTT_RTGUI:
+        objs += SConscript(os.path.join(RTT_RTGUI, 'SConscript'),
+						   variant_dir='build/components/rtgui',
+						   duplicate=0)
+        objs = objs + SConscript(RTT_RTGUI+'/../../demo/examples/SConscript', 
+				variant_dir='build/examples/gui', duplicate=0)
+    else:
+        objs += SConscript(os.path.join(RTT_ROOT + '/components/rtgui', 'SConscript'),
+						   variant_dir='build/components/rtgui',
+						   duplicate=0)
+        objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', 
+				variant_dir='build/examples/gui', duplicate=0)
+
+if GetDepend('RT_USING_TC'):
+    objs = objs + SConscript(RTT_ROOT + '/examples/kernel/SConscript', variant_dir = 'build/tc/kernel', duplicate=0)
+
+# build program 
+program = env.Program(TARGET, objs)
+
+# end building
+EndBuilding(TARGET, program)

+ 9 - 0
bsp/simlinux/applications/SConscript

@@ -0,0 +1,9 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src	= Glob('*.c')
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 146 - 0
bsp/simlinux/applications/application.c

@@ -0,0 +1,146 @@
+/*
+ * File      : application.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      the first version
+ */
+
+#include <rtthread.h>
+#include <stdio.h>
+#include <board.h>
+
+#include <components.h>
+
+void rt_init_thread_entry(void *parameter)
+{
+#ifdef RT_USING_LWIP
+    pcap_netif_hw_init();
+#endif
+
+    /* initialization RT-Thread Components */
+    rt_components_init();
+
+    rt_platform_init();
+
+    /* File system Initialization */
+#ifdef RT_USING_DFS
+    {
+#ifdef RT_USING_DFS_WINSHAREDIR
+        {
+            extern rt_err_t rt_win_sharedir_init(const char *name);
+            extern int dfs_win32_init(void);
+
+            rt_win_sharedir_init("wdd");
+            dfs_win32_init();
+
+            if (dfs_mount("wdd", "/", "wdir", 0, 0) == 0)
+                rt_kprintf("win32 share directory initialized!\n");
+            else
+                rt_kprintf("win32 share directory initialized failed!\n");
+        }
+#endif
+
+#ifdef RT_USING_DFS_ELMFAT
+        /* mount sd card fatfs as root directory */
+        if (dfs_mount("sd0", "/disk/sd", "elm", 0, 0) == 0)
+            rt_kprintf("fatfs initialized!\n");
+        else
+            rt_kprintf("fatfs initialization failed!\n");
+#endif
+
+#ifdef RT_USING_DFS_UFFS
+        /* mount uffs as the nand flash file system */
+        if (dfs_mount("nand0", "/disk/nand", "uffs", 0, 0) == 0)
+            rt_kprintf("uffs initialized!\n");
+        else
+            rt_kprintf("uffs initialization failed!\n");
+#endif
+
+#ifdef RT_USING_DFS_JFFS2
+        /* mount jffs2 as the nor flash file system */
+        if (dfs_mount("nor", "/disk/nor", "jffs2", 0, 0) == 0)
+            rt_kprintf("jffs2 initialized!\n");
+        else
+            rt_kprintf("jffs2 initialization failed!\n");
+#endif
+
+    }
+#endif
+
+#if 0
+    {
+        extern void application_init(void);
+        rt_thread_delay(RT_TICK_PER_SECOND);
+        application_init();
+    }
+#endif
+
+#if defined(RT_USING_RTGUI)
+    rt_thread_delay(3000);
+    snake_main();
+#endif
+}
+
+static void rt_test_thread_entry(void *parameter)
+{
+    int i;
+    for (i = 0; i < 10; i++)
+    {
+        rt_kprintf("hello, world\n");
+        rt_thread_delay(RT_TICK_PER_SECOND);
+    }
+}
+
+static void rt_high_thread_entry(void *parameter)
+{
+    int i;
+    for (i = 0; i < 3; i++)
+    {
+        rt_kprintf("high thread <%d> \n", i);
+        rt_thread_delay(2*RT_TICK_PER_SECOND);
+    }
+}
+
+int rt_application_init()
+{
+    rt_thread_t tid;
+
+#if 0
+    tid = rt_thread_create("init",
+                           rt_init_thread_entry, RT_NULL,
+                           2048, RT_THREAD_PRIORITY_MAX / 3, 20);
+
+    if (tid != RT_NULL)
+        rt_thread_startup(tid);
+    tid = rt_thread_create("test",
+                           rt_test_thread_entry, RT_NULL,
+                           2048, RT_THREAD_PRIORITY_MAX * 3 / 4, 20);
+    if (tid != RT_NULL)
+        rt_thread_startup(tid);
+
+#endif
+
+    tid = rt_thread_create("test1",
+                           rt_high_thread_entry, RT_NULL,
+                           2048, RT_THREAD_PRIORITY_MAX / 2, 20);
+    if (tid != RT_NULL)
+        rt_thread_startup(tid);
+
+    tid = rt_thread_create("test2",
+                           rt_test_thread_entry, RT_NULL,
+                           2048, RT_THREAD_PRIORITY_MAX / 2, 20);
+    if (tid != RT_NULL)
+        rt_thread_startup(tid);
+
+    return 0;
+}
+
+
+/*@}*/

+ 29 - 0
bsp/simlinux/applications/platform.c

@@ -0,0 +1,29 @@
+#include <rtthread.h>
+#include "board.h"
+
+void rt_platform_init(void)
+{
+#ifdef RT_USING_DFS
+    /* initialize sd card */
+    rt_hw_sdcard_init();
+
+#if defined(RT_USING_MTD_NAND)
+    rt_hw_mtd_nand_init();
+#endif
+
+#if defined(RT_USING_MTD_NOR)
+    sst25vfxx_mtd_init("nor", 0, RT_UINT32_MAX);
+#endif
+
+#endif /* RT_USING_DFS */
+
+#ifdef RT_USING_RTGUI
+    /* start sdl thread to simulate an LCD */
+    rt_hw_sdl_start();
+#endif /* RT_USING_RTGUI */
+
+#ifdef _WIN32
+    rt_thread_idle_sethook(rt_hw_win32_low_cpu);
+#endif
+}
+

+ 92 - 0
bsp/simlinux/applications/startup.c

@@ -0,0 +1,92 @@
+/*
+ * File      : startup.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-09-03     prife        first implementation
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+
+/**
+ * @addtogroup win32
+ */
+
+/*@{*/
+
+extern int  rt_application_init(void);
+#ifdef RT_USING_FINSH
+extern void finsh_system_init(void);
+extern void finsh_set_device(const char *device);
+#endif
+
+extern rt_uint8_t *heap;
+/**
+ * This function will startup RT-Thread RTOS.
+ */
+void rtthread_startup(void)
+{
+    /* init board */
+    rt_hw_board_init();
+
+    /* show version */
+    rt_show_version();
+
+    /* init tick */
+    rt_system_tick_init();
+
+    /* init kernel object */
+    rt_system_object_init();
+
+    /* init timer system */
+    rt_system_timer_init();
+
+#ifdef RT_USING_HEAP
+    /* init memory system */
+    rt_system_heap_init((void *)heap, (void *)&heap[RT_HEAP_SIZE - 1]);
+#endif
+
+    /* init scheduler system */
+    rt_system_scheduler_init();
+
+    /* init all device */
+#ifdef RT_USING_DEVICE
+    rt_device_init_all();
+#endif
+    /* init application */
+    rt_application_init();
+
+    /* init timer thread */
+    rt_system_timer_thread_init();
+
+    /* init idle thread */
+    rt_thread_idle_init();
+
+    /* start scheduler */
+    rt_system_scheduler_start();
+
+    /* never reach here */
+    return ;
+}
+
+int main(void)
+{
+    /* disable interrupt first */
+    rt_hw_interrupt_disable();
+
+    /* startup RT-Thread RTOS */
+    rtthread_startup();
+
+    return 0;
+}
+
+/*@}*/

+ 22 - 0
bsp/simlinux/drivers/SConscript

@@ -0,0 +1,22 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+
+# remove no need file.
+if GetDepend('RT_USING_RTGUI') == False:
+    SrcRemove(src, 'sdl_fb.c')
+if GetDepend('RT_USING_DFS') == False or GetDepend('RT_USING_DFS_ELMFAT') == False:
+    SrcRemove(src, 'sd_sim.c')
+if GetDepend('RT_USING_DFS') == False or GetDepend('RT_USING_MTD_NAND') == False:
+    SrcRemove(src, 'nanddrv_file.c')
+if GetDepend('RT_USING_DFS') == False or GetDepend('RT_USING_MTD_NOR') == False:
+    SrcRemove(src, 'sst25vfxx_mtd_sim.c')
+if GetDepend('RT_USING_SERIAL') == False:
+    SrcRemove(src, 'usart_sim.c')
+
+CPPPATH = [cwd]
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 91 - 0
bsp/simlinux/drivers/board.c

@@ -0,0 +1,91 @@
+/*
+ * File      : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009 RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-01-05     Bernard      first implementation
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "board.h"
+#include <stdlib.h>
+
+/**
+ * @addtogroup simulator on win32
+ */
+rt_uint8_t *heap;
+
+rt_uint8_t *rt_hw_sram_init(void)
+{
+    rt_uint8_t *heap;
+    heap = malloc(RT_HEAP_SIZE);
+    if (heap == RT_NULL)
+    {
+        rt_kprintf("there is no memory in pc.");
+#ifdef _WIN32
+        _exit(1);
+#else
+		exit(1);
+#endif
+    }
+    return heap;
+}
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+void rt_hw_win32_low_cpu(void)
+{
+#ifdef _WIN32
+	/* in windows */
+    Sleep(1000);
+#else
+	/* in linux */
+	sleep(1);
+#endif
+}
+
+#if defined(RT_USING_FINSH)
+
+#ifndef _CRT_TERMINATE_DEFINED
+#define _CRT_TERMINATE_DEFINED
+_CRTIMP __declspec(noreturn) void __cdecl exit(__in int _Code);
+_CRTIMP __declspec(noreturn) void __cdecl _exit(__in int _Code);
+_CRTIMP void __cdecl abort(void);
+#endif
+
+#include <finsh.h>
+void rt_hw_exit(void)
+{
+    rt_kprintf("RT-Thread, bye\n");
+    exit(0);
+}
+FINSH_FUNCTION_EXPORT_ALIAS(rt_hw_exit, exit, exit rt - thread);
+#endif /* RT_USING_FINSH */
+
+/**
+ * This function will initial win32
+ */
+void rt_hw_board_init()
+{
+    /* init system memory */
+    heap = rt_hw_sram_init();
+
+#if defined(RT_USING_USART)
+    rt_hw_usart_init();
+#endif
+
+#if defined(RT_USING_CONSOLE)
+    rt_hw_serial_init();
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif
+}
+/*@}*/

+ 33 - 0
bsp/simlinux/drivers/board.h

@@ -0,0 +1,33 @@
+/*
+ * File      : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-09-22     Bernard      add board.h to this bsp
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+void rt_hw_board_init(void);
+rt_uint8_t *rt_hw_sram_init(void);
+
+/* SD Card init function */
+void rt_hw_sdcard_init(void);
+
+int rt_hw_mtd_nand_init(void);
+int sst25vfxx_mtd_init(const char *, unsigned int , unsigned int);
+void pcap_netif_hw_init(void);
+void rt_platform_init(void);
+void rt_hw_usart_init(void);
+void rt_hw_serial_init(void);
+void rt_hw_sdl_start(void);
+void rt_hw_win32_low_cpu(void);
+
+void rt_hw_exit(void);
+#endif

+ 399 - 0
bsp/simlinux/drivers/nanddrv_file.c

@@ -0,0 +1,399 @@
+#include <rtdevice.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NAND_SIM  "nand.bin"
+#if 1
+#define OOB_SIZE        64
+#define PAGE_DATA_SIZE  2048
+#define PAGE_SIZE       (2048 + 64)
+#define PAGE_PER_BLOCK  64
+#define BLOCK_SIZE      (PAGE_SIZE * PAGE_PER_BLOCK)
+#define BLOCK_NUM       512
+// #define BLOCK_NUM        2048
+#else
+#define OOB_SIZE        16
+#define PAGE_SIZE       (512 + OOB_SIZE)
+#define PAGE_PER_BLOCK  32
+#define BLOCK_SIZE      (PAGE_SIZE * PAGE_PER_BLOCK)
+#define BLOCK_NUM       512
+#endif
+
+#define ECC_SIZE       ((PAGE_DATA_SIZE) * 3 / 256)
+
+static unsigned char block_data[BLOCK_SIZE];
+static struct rt_mtd_nand_device _nanddrv_file_device;
+static FILE *file = NULL;
+
+static rt_uint8_t CountBitsInByte(rt_uint8_t byte)
+{
+    rt_uint8_t count = 0;
+
+    while (byte > 0)
+    {
+        if (byte & 1)
+        {
+            count++;
+        }
+        byte >>= 1;
+    }
+
+    return count;
+}
+
+static void Compute256(const rt_uint8_t *data, rt_uint8_t *code)
+{
+    rt_uint32_t i;
+    rt_uint8_t columnSum = 0;
+    rt_uint8_t evenLineCode = 0;
+    rt_uint8_t oddLineCode = 0;
+    rt_uint8_t evenColumnCode = 0;
+    rt_uint8_t oddColumnCode = 0;
+
+    // Xor all bytes together to get the column sum;
+    // At the same time, calculate the even and odd line codes
+    for (i = 0; i < 256; i++)
+    {
+        columnSum ^= data[i];
+
+        // If the xor sum of the byte is 0, then this byte has no incidence on
+        // the computed code; so check if the sum is 1.
+        if ((CountBitsInByte(data[i]) & 1) == 1)
+        {
+            // Parity groups are formed by forcing a particular index bit to 0
+            // (even) or 1 (odd).
+            // Example on one byte:
+            //
+            // bits (dec)  7   6   5   4   3   2   1   0
+            //      (bin) 111 110 101 100 011 010 001 000
+            //                            '---'---'---'----------.
+            //                                                   |
+            // groups P4' ooooooooooooooo eeeeeeeeeeeeeee P4     |
+            //        P2' ooooooo eeeeeee ooooooo eeeeeee P2     |
+            //        P1' ooo eee ooo eee ooo eee ooo eee P1     |
+            //                                                   |
+            // We can see that:                                  |
+            //  - P4  -> bit 2 of index is 0 --------------------'
+            //  - P4' -> bit 2 of index is 1.
+            //  - P2  -> bit 1 of index if 0.
+            //  - etc...
+            // We deduce that a bit position has an impact on all even Px if
+            // the log2(x)nth bit of its index is 0
+            //     ex: log2(4) = 2, bit2 of the index must be 0 (-> 0 1 2 3)
+            // and on all odd Px' if the log2(x)nth bit of its index is 1
+            //     ex: log2(2) = 1, bit1 of the index must be 1 (-> 0 1 4 5)
+            //
+            // As such, we calculate all the possible Px and Px' values at the
+            // same time in two variables, evenLineCode and oddLineCode, such as
+            //     evenLineCode bits: P128  P64  P32  P16  P8  P4  P2  P1
+            //     oddLineCode  bits: P128' P64' P32' P16' P8' P4' P2' P1'
+            //
+            evenLineCode ^= (255 - i);
+            oddLineCode ^= i;
+        }
+    }
+
+    // At this point, we have the line parities, and the column sum. First, We
+    // must caculate the parity group values on the column sum.
+    for (i = 0; i < 8; i++)
+    {
+        if (columnSum & 1)
+        {
+            evenColumnCode ^= (7 - i);
+            oddColumnCode ^= i;
+        }
+        columnSum >>= 1;
+    }
+
+    // Now, we must interleave the parity values, to obtain the following layout:
+    // Code[0] = Line1
+    // Code[1] = Line2
+    // Code[2] = Column
+    // Line = Px' Px P(x-1)- P(x-1) ...
+    // Column = P4' P4 P2' P2 P1' P1 PadBit PadBit
+    code[0] = 0;
+    code[1] = 0;
+    code[2] = 0;
+
+    for (i = 0; i < 4; i++)
+    {
+        code[0] <<= 2;
+        code[1] <<= 2;
+        code[2] <<= 2;
+
+        // Line 1
+        if ((oddLineCode & 0x80) != 0)
+        {
+            code[0] |= 2;
+        }
+
+        if ((evenLineCode & 0x80) != 0)
+        {
+            code[0] |= 1;
+        }
+
+        // Line 2
+        if ((oddLineCode & 0x08) != 0)
+        {
+            code[1] |= 2;
+        }
+
+        if ((evenLineCode & 0x08) != 0)
+        {
+            code[1] |= 1;
+        }
+
+        // Column
+        if ((oddColumnCode & 0x04) != 0)
+        {
+            code[2] |= 2;
+        }
+
+        if ((evenColumnCode & 0x04) != 0)
+        {
+            code[2] |= 1;
+        }
+
+        oddLineCode <<= 1;
+        evenLineCode <<= 1;
+        oddColumnCode <<= 1;
+        evenColumnCode <<= 1;
+    }
+
+    // Invert codes (linux compatibility)
+    code[0] = (~(rt_uint32_t)code[0]);
+    code[1] = (~(rt_uint32_t)code[1]);
+    code[2] = (~(rt_uint32_t)code[2]);
+}
+
+void ecc_hamming_compute256x(const rt_uint8_t *pucData, rt_uint32_t dwSize, rt_uint8_t *puCode)
+{
+    while (dwSize > 0)
+    {
+        Compute256(pucData, puCode) ;
+
+        pucData += 256;
+        puCode += 3;
+        dwSize -= 256;
+    }
+}
+
+/* read chip id */
+static rt_uint32_t nanddrv_file_read_id(struct rt_mtd_nand_device *device)
+{
+    return 0x00;
+}
+
+/* read/write/move page */
+static rt_err_t nanddrv_file_read_page(struct rt_mtd_nand_device *device,
+                                       rt_off_t page,
+                                       rt_uint8_t *data, rt_uint32_t data_len,
+                                       rt_uint8_t *spare, rt_uint32_t spare_len)
+{
+    rt_uint32_t offset;
+    rt_uint8_t oob_ecc [ECC_SIZE];
+    rt_uint8_t ecc [ECC_SIZE];
+
+    page = page + device->block_start * device->pages_per_block;
+
+    if (page / device->pages_per_block > device->block_end)
+    {
+        return -RT_EIO;
+    }
+
+    /* write page */
+    offset = page * PAGE_SIZE;
+    if (data != NULL && data_len != 0)
+    {
+        fseek(file, offset, SEEK_SET);
+        fread(data, data_len, 1, file);
+        if (data_len == PAGE_DATA_SIZE)
+        {
+            /* read ecc size */
+            fread(oob_ecc, ECC_SIZE, 1, file);
+
+            /* verify ECC */
+            ecc_hamming_compute256x(data, PAGE_DATA_SIZE, &ecc[0]);
+            if (memcmp(&oob_ecc[0], &ecc[0], ECC_SIZE) != 0)
+                return -RT_MTD_EECC;
+        }
+    }
+
+    if (spare != NULL && spare_len)
+    {
+        offset = page * PAGE_SIZE + PAGE_DATA_SIZE;
+        fseek(file, offset, SEEK_SET);
+        fread(spare, spare_len, 1, file);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t nanddrv_file_write_page(struct rt_mtd_nand_device *device,
+                                        rt_off_t page,
+                                        const rt_uint8_t *data, rt_uint32_t data_len,
+                                        const rt_uint8_t *oob, rt_uint32_t spare_len)
+{
+    rt_uint32_t offset;
+    rt_uint8_t ecc[ECC_SIZE];
+
+    page = page + device->block_start * device->pages_per_block;
+    if (page / device->pages_per_block > device->block_end)
+    {
+        return -RT_EIO;
+    }
+
+    /* write page */
+    offset = page * PAGE_SIZE;
+    if (data != RT_NULL && data_len != 0)
+    {
+        fseek(file, offset, SEEK_SET);
+        fwrite(data, data_len, 1, file);
+
+        if (data_len == PAGE_DATA_SIZE)
+        {
+            /*write the ecc information */
+            ecc_hamming_compute256x(data, PAGE_DATA_SIZE, ecc);
+
+            fwrite(ecc, ECC_SIZE, 1, file);
+        }
+    }
+
+    if (oob != RT_NULL && spare_len != 0)
+    {
+        offset = page * PAGE_SIZE + PAGE_DATA_SIZE + ECC_SIZE;
+        fseek(file, offset, SEEK_SET);
+        fwrite(&oob[ECC_SIZE], spare_len-ECC_SIZE, 1, file);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t nanddrv_file_move_page(struct rt_mtd_nand_device *device, rt_off_t from, rt_off_t to)
+{
+    rt_uint32_t offset;
+    rt_uint8_t  page_buffer[PAGE_DATA_SIZE];
+    rt_uint8_t  oob_buffer[OOB_SIZE];
+
+    from = from + device->block_start * device->pages_per_block;
+    to = to + device->block_start * device->pages_per_block;
+
+    if (from / device->pages_per_block > device->block_end ||
+            to / device->pages_per_block > device->block_end)
+    {
+        return -RT_EIO;
+    }
+
+    if (device->plane_num > 1)
+    {
+        rt_uint32_t mask;
+        rt_uint16_t from_block, to_block;
+
+        from_block = (rt_uint16_t)(from / PAGE_PER_BLOCK);
+        to_block = (rt_uint16_t)(to / PAGE_PER_BLOCK);
+        mask = device->plane_num - 1;
+
+        if ((from_block & mask) != (to_block & mask))
+        {
+            rt_kprintf("invalid page copy on the block. from [%d] --> to[%d]\n", from_block, to_block);
+            return -RT_EIO;
+        }
+    }
+
+    /* read page */
+    offset = from * PAGE_SIZE;
+    fseek(file, offset, SEEK_SET);
+    fread(page_buffer, sizeof(page_buffer), 1, file);
+    fread(oob_buffer, sizeof(oob_buffer), 1, file);
+
+    /* write page */
+    offset = to * PAGE_SIZE;
+    fseek(file, offset, SEEK_SET);
+    fwrite(page_buffer, sizeof(page_buffer), 1, file);
+    fwrite(oob_buffer, sizeof(oob_buffer), 1, file);
+
+    return RT_EOK;
+}
+
+/* erase block */
+static rt_err_t nanddrv_file_erase_block(struct rt_mtd_nand_device *device, rt_uint32_t block)
+{
+    if (block > BLOCK_NUM) return -RT_EIO;
+
+    /* add the start blocks */
+    block = block + device->block_start;
+
+    fseek(file, block * BLOCK_SIZE, SEEK_SET);
+    fwrite(block_data, sizeof(block_data), 1, file);
+
+    return RT_EOK;
+}
+
+const static struct rt_mtd_nand_driver_ops _ops =
+{
+    nanddrv_file_read_id,
+    nanddrv_file_read_page,
+    nanddrv_file_write_page,
+    nanddrv_file_move_page,
+    nanddrv_file_erase_block,
+    RT_NULL,
+    RT_NULL,
+};
+
+void nand_eraseall(void);
+
+void rt_hw_mtd_nand_init(void)
+{
+    rt_uint16_t ecc_size;
+    rt_uint32_t size;
+
+    memset(block_data, 0xff, sizeof(block_data));
+    /* open file */
+    file = fopen(NAND_SIM, "rb+");
+    if (file == NULL)
+    {
+        file = fopen(NAND_SIM, "wb+");
+    }
+    fseek(file, 0, SEEK_END);
+    size = ftell(file);
+
+    fseek(file, 0, SEEK_SET);
+    if (size < BLOCK_NUM * BLOCK_SIZE)
+    {
+        rt_uint32_t index;
+        fseek(file, 0, SEEK_SET);
+        for (index = 0; index < BLOCK_NUM; index ++)
+        {
+            fwrite(block_data, sizeof(block_data), 1, file);
+        }
+    }
+    fseek(file, 0, SEEK_SET);
+
+    ecc_size = (PAGE_DATA_SIZE) * 3 / 256;
+    _nanddrv_file_device.plane_num = 2;
+    _nanddrv_file_device.oob_size = OOB_SIZE;
+    _nanddrv_file_device.oob_free = OOB_SIZE - ecc_size;
+    _nanddrv_file_device.page_size = PAGE_DATA_SIZE;
+    _nanddrv_file_device.pages_per_block = PAGE_PER_BLOCK;
+    _nanddrv_file_device.block_start = 0;
+    _nanddrv_file_device.block_end = BLOCK_NUM / 2;
+    _nanddrv_file_device.block_total = _nanddrv_file_device.block_end - _nanddrv_file_device.block_start;
+    _nanddrv_file_device.ops = &_ops;
+
+    rt_mtd_nand_register_device("nand0", &_nanddrv_file_device);
+}
+
+#if defined(RT_USING_FINSH)
+#include <finsh.h>
+void nand_eraseall()
+{
+    int index;
+    for (index = 0; index < _nanddrv_file_device.block_total; index ++)
+    {
+        nanddrv_file_erase_block(&_nanddrv_file_device, index);
+    }
+}
+FINSH_FUNCTION_EXPORT(nand_eraseall, erase all of block in the nand flash);
+
+#endif //RT_USING_FINSH

+ 193 - 0
bsp/simlinux/drivers/sd_sim.c

@@ -0,0 +1,193 @@
+#include <rtthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dfs_def.h>
+
+// #define SD_TRACE     rt_kprintf
+#define SD_TRACE(...)
+
+//#define SDCARD_SIM  "F:\\Project\\tools\\SDCARD"
+#define SDCARD_SIM  "sd.bin"
+#define SDCARD_SIZE (16*1024*1024)  //16M
+
+struct sdcard_device
+{
+    struct rt_device parent;
+    FILE *file;
+};
+static struct sdcard_device _sdcard;
+
+#define SDCARD_DEVICE(device)       (( struct sdcard_device*)(device))
+
+static rt_mutex_t lock;
+
+/* RT-Thread device interface */
+
+static rt_err_t rt_sdcard_init(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t rt_sdcard_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+/* position: block page address, not bytes address
+ * buffer:
+ * size  : how many blocks
+ */
+static rt_size_t rt_sdcard_read(rt_device_t device, rt_off_t position, void *buffer, rt_size_t size)
+{
+    struct sdcard_device *sd;
+    int result = 0;
+
+    SD_TRACE("sd read: pos %d, size %d\n", position, size);
+
+    rt_mutex_take(lock, RT_WAITING_FOREVER);
+    sd = SDCARD_DEVICE(device);
+    fseek(sd->file, position * SECTOR_SIZE, SEEK_SET);
+
+    result = fread(buffer, size * SECTOR_SIZE, 1, sd->file);
+    if (result < 0)
+        goto _err;
+
+    rt_mutex_release(lock);
+    return size;
+
+_err:
+    SD_TRACE("sd read errors!\n");
+    rt_mutex_release(lock);
+    return 0;
+}
+
+/* position: block page address, not bytes address
+ * buffer:
+ * size  : how many blocks
+ */
+static rt_size_t rt_sdcard_write(rt_device_t device, rt_off_t position, const void *buffer, rt_size_t size)
+{
+    struct sdcard_device *sd;
+    int result = 0;
+
+    SD_TRACE("sst write: pos %d, size %d\n", position, size);
+
+    rt_mutex_take(lock, RT_WAITING_FOREVER);
+    sd = SDCARD_DEVICE(device);
+    fseek(sd->file, position * SECTOR_SIZE, SEEK_SET);
+
+    result = fwrite(buffer, size * SECTOR_SIZE, 1, sd->file);
+    if (result < 0)
+        goto _err;
+
+    rt_mutex_release(lock);
+    return size;
+
+_err:
+    SD_TRACE("sd write errors!\n");
+    rt_mutex_release(lock);
+    return 0;
+}
+
+static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+    struct sdcard_device *sd;
+    unsigned int size;
+
+    RT_ASSERT(dev != RT_NULL);
+
+    sd = SDCARD_DEVICE(dev);
+
+    if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
+    {
+        struct rt_device_blk_geometry *geometry;
+
+        geometry = (struct rt_device_blk_geometry *)args;
+        if (geometry == RT_NULL) return -RT_ERROR;
+
+        geometry->bytes_per_sector = SECTOR_SIZE;
+        geometry->block_size = SECTOR_SIZE;
+
+        fseek(sd->file, 0, SEEK_END);
+        size = ftell(sd->file);
+
+        geometry->sector_count = size / SECTOR_SIZE;
+    }
+    return RT_EOK;
+}
+
+
+rt_err_t rt_hw_sdcard_init(const char *spi_device_name)
+{
+    int size;
+    struct sdcard_device *sd;
+    struct rt_device *device;
+
+    sd = &_sdcard;
+    device = &(sd->parent);
+
+    lock = rt_mutex_create("lock", RT_IPC_FLAG_FIFO);
+
+    /* open sd card file, if not exist, then create it  */
+    sd->file = fopen(SDCARD_SIM, "rb+");
+    if (sd->file == NULL)
+    {
+        /* create a file to simulate sd card */
+        sd->file = fopen(SDCARD_SIM, "wb+");
+
+        fseek(sd->file, 0, SEEK_END);
+        size = ftell(sd->file);
+
+        fseek(sd->file, 0, SEEK_SET);
+        if (size < SDCARD_SIZE)
+        {
+            int i;
+            unsigned char *ptr;
+
+            ptr = (unsigned char *) malloc(1024 * 1024);
+            if (ptr == NULL)
+            {
+                SD_TRACE("malloc error, no memory!\n");
+                return RT_ERROR;
+            }
+            memset(ptr, 0x0, 1024 * 1024);
+
+            fseek(sd->file, 0, SEEK_SET);
+
+            for (i = 0; i < (SDCARD_SIZE / (1024 * 1024)); i++)
+                fwrite(ptr, 1024 * 1024, 1, sd->file);
+
+            free(ptr);
+        }
+    }
+    fseek(sd->file, 0, SEEK_SET);
+
+    device->type  = RT_Device_Class_Block;
+    device->init = rt_sdcard_init;
+    device->open = rt_sdcard_open;
+    device->close = rt_sdcard_close;
+    device->read = rt_sdcard_read;
+    device->write = rt_sdcard_write;
+    device->control = rt_sdcard_control;
+    device->user_data = NULL;
+
+    rt_device_register(device, "sd0",
+                       RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+    return RT_EOK;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+void eraseall(void)
+{
+    printf("had not implemented yet!\n");
+}
+FINSH_FUNCTION_EXPORT(eraseall, erase all block in SPI flash);
+#endif

+ 304 - 0
bsp/simlinux/drivers/sdl_fb.c

@@ -0,0 +1,304 @@
+#include <rtthread.h>
+
+#include <sdl.h>
+#include <rtdevice.h>
+#include <rtgui/driver.h>
+
+#define SDL_SCREEN_WIDTH    800
+#define SDL_SCREEN_HEIGHT   480
+
+struct sdlfb_device
+{
+    struct rt_device parent;
+
+    SDL_Surface *screen;
+    rt_uint16_t width;
+    rt_uint16_t height;
+};
+struct sdlfb_device _device;
+
+/* common device interface */
+static rt_err_t  sdlfb_init(rt_device_t dev)
+{
+    return RT_EOK;
+}
+static rt_err_t  sdlfb_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+static rt_err_t  sdlfb_close(rt_device_t dev)
+{
+    SDL_Quit();
+    return RT_EOK;
+}
+
+static rt_mutex_t sdllock;
+static rt_err_t  sdlfb_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+    struct sdlfb_device *device;
+
+    rt_mutex_take(sdllock, RT_WAITING_FOREVER);
+    device = (struct sdlfb_device *)dev;
+    RT_ASSERT(device != RT_NULL);
+    RT_ASSERT(device->screen != RT_NULL);
+
+    switch (cmd)
+    {
+    case RTGRAPHIC_CTRL_GET_INFO:
+    {
+        struct rt_device_graphic_info *info;
+
+        info = (struct rt_device_graphic_info *) args;
+        info->bits_per_pixel = 16;
+        info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565P;
+        info->framebuffer = device->screen->pixels;
+        info->width = device->screen->w;
+        info->height = device->screen->h;
+    }
+    break;
+    case RTGRAPHIC_CTRL_RECT_UPDATE:
+    {
+        struct rt_device_rect_info *rect;
+        rect = (struct rt_device_rect_info *)args;
+
+        /* SDL_UpdateRect(_device.screen, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); */
+        SDL_UpdateRect(_device.screen, 0, 0, device->width, device->height);
+    }
+    break;
+    case RTGRAPHIC_CTRL_SET_MODE:
+    {
+#if 0
+        struct rt_device_rect_info *rect;
+
+        rect = (struct rt_device_rect_info *)args;
+        if ((_device.width == rect->width) && (_device.height == rect->height)) return -RT_ERROR;
+
+        _device.width = rect->width;
+        _device.height = rect->height;
+
+        if (_device.screen != RT_NULL)
+        {
+            SDL_FreeSurface(_device.screen);
+
+            /* re-create screen surface */
+            _device.screen = SDL_SetVideoMode(_device.width, _device.height, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
+            if (_device.screen == NULL)
+            {
+                fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
+                exit(1);
+            }
+
+            SDL_WM_SetCaption("RT-Thread/GUI Simulator", NULL);
+        }
+#endif
+    }
+    break;
+    }
+    rt_mutex_release(sdllock);
+    return RT_EOK;
+}
+
+static void sdlfb_hw_init(void)
+{
+    /* set video driver for VC++ debug */
+    //_putenv("SDL_VIDEODRIVER=windib");
+
+    //if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) < 0)
+    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
+    {
+        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
+        exit(1);
+    }
+
+    _device.parent.init = sdlfb_init;
+    _device.parent.open = sdlfb_open;
+    _device.parent.close = sdlfb_close;
+    _device.parent.read = RT_NULL;
+    _device.parent.write = RT_NULL;
+    _device.parent.control = sdlfb_control;
+
+    _device.width  = SDL_SCREEN_WIDTH;
+    _device.height = SDL_SCREEN_HEIGHT;
+    _device.screen = SDL_SetVideoMode(_device.width, _device.height, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
+    if (_device.screen == NULL)
+    {
+        fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
+        exit(1);
+    }
+
+    SDL_WM_SetCaption("RT-Thread/GUI Simulator", NULL);
+    rt_device_register(RT_DEVICE(&_device), "sdl", RT_DEVICE_FLAG_RDWR);
+
+    sdllock = rt_mutex_create("fb", RT_IPC_FLAG_FIFO);
+}
+
+#include  <windows.h>
+#include  <mmsystem.h>
+#include  <stdio.h>
+#include <sdl.h>
+#include <rtgui/event.h>
+#include <rtgui/kbddef.h>
+#include <rtgui/rtgui_server.h>
+#include <rtgui/rtgui_system.h>
+
+static DWORD WINAPI sdl_loop(LPVOID lpParam)
+{
+    int quit = 0;
+    SDL_Event event;
+    int button_state = 0;
+
+    rt_device_t device;
+    sdlfb_hw_init();
+
+    device = rt_device_find("sdl");
+    rtgui_graphic_set_device(device);
+
+    /* handle SDL event */
+    while (!quit)
+    {
+        SDL_WaitEvent(&event);
+
+        switch (event.type)
+        {
+        case SDL_MOUSEMOTION:
+#if  0
+        {
+            struct rtgui_event_mouse emouse;
+            emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
+            emouse.parent.sender = RT_NULL;
+            emouse.wid = RT_NULL;
+
+            emouse.x = ((SDL_MouseMotionEvent *)&event)->x;
+            emouse.y = ((SDL_MouseMotionEvent *)&event)->y;
+
+            /* init mouse button */
+            emouse.button = button_state;
+
+            /* send event to server */
+            rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
+        }
+#endif
+        break;
+
+        case SDL_MOUSEBUTTONDOWN:
+        case SDL_MOUSEBUTTONUP:
+        {
+            struct rtgui_event_mouse emouse;
+            SDL_MouseButtonEvent *mb;
+
+            emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
+            emouse.parent.sender = RT_NULL;
+            emouse.wid = RT_NULL;
+
+            mb = (SDL_MouseButtonEvent *)&event;
+
+            emouse.x = mb->x;
+            emouse.y = mb->y;
+
+            /* init mouse button */
+            emouse.button = 0;
+
+            /* set emouse button */
+            if (mb->button & (1 << (SDL_BUTTON_LEFT - 1)))
+            {
+                emouse.button |= RTGUI_MOUSE_BUTTON_LEFT;
+            }
+            else if (mb->button & (1 << (SDL_BUTTON_RIGHT - 1)))
+            {
+                emouse.button |= RTGUI_MOUSE_BUTTON_RIGHT;
+            }
+            else if (mb->button & (1 << (SDL_BUTTON_MIDDLE - 1)))
+            {
+                emouse.button |= RTGUI_MOUSE_BUTTON_MIDDLE;
+            }
+
+            if (mb->type == SDL_MOUSEBUTTONDOWN)
+            {
+                emouse.button |= RTGUI_MOUSE_BUTTON_DOWN;
+                button_state = emouse.button;
+            }
+            else
+            {
+                emouse.button |= RTGUI_MOUSE_BUTTON_UP;
+                button_state = 0;
+            }
+
+
+            /* send event to server */
+            rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
+        }
+        break;
+
+        case SDL_KEYUP:
+        {
+            struct rtgui_event_kbd ekbd;
+            ekbd.parent.type    = RTGUI_EVENT_KBD;
+            ekbd.parent.sender  = RT_NULL;
+            ekbd.type = RTGUI_KEYUP;
+            ekbd.wid = RT_NULL;
+            ekbd.mod = event.key.keysym.mod;
+            ekbd.key = event.key.keysym.sym;
+
+            /* FIXME: unicode */
+            ekbd.unicode = 0;
+
+            /* send event to server */
+            rtgui_server_post_event(&ekbd.parent, sizeof(struct rtgui_event_kbd));
+        }
+        break;
+
+        case SDL_KEYDOWN:
+        {
+            struct rtgui_event_kbd ekbd;
+            ekbd.parent.type    = RTGUI_EVENT_KBD;
+            ekbd.parent.sender  = RT_NULL;
+            ekbd.type = RTGUI_KEYDOWN;
+            ekbd.wid = RT_NULL;
+            ekbd.mod = event.key.keysym.mod;
+            ekbd.key = event.key.keysym.sym;
+
+            /* FIXME: unicode */
+            ekbd.unicode = 0;
+
+            /* send event to server */
+            rtgui_server_post_event(&ekbd.parent, sizeof(struct rtgui_event_kbd));
+        }
+        break;
+
+        case SDL_QUIT:
+            SDL_Quit();
+            quit = 1;
+            break;
+
+        default:
+            break;
+        }
+
+        if (quit)
+            break;
+    }
+    //exit(0);
+    return 0;
+}
+
+/* start sdl thread */
+void rt_hw_sdl_start(void)
+{
+    HANDLE thread;
+    DWORD  thread_id;
+
+    /* create thread that loop sdl event */
+    thread = CreateThread(NULL,
+                          0,
+                          (LPTHREAD_START_ROUTINE)sdl_loop,
+                          0,
+                          CREATE_SUSPENDED,
+                          &thread_id);
+    if (thread == NULL)
+    {
+        //Display Error Message
+
+        return;
+    }
+    ResumeThread(thread);
+}

+ 176 - 0
bsp/simlinux/drivers/serial.c

@@ -0,0 +1,176 @@
+/*
+******************************************************************************
+* By   : parai
+* email:parai@foxmail.com
+* virtual serial driver
+******************************************************************************
+*/
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#define _DEBUG_SERIAL 0
+#include "serial.h"
+#include <stdio.h>
+struct rt_device serial_device;
+//extern struct serial_int_rx serial_rx;
+struct serial_int_rx serial_rx;
+
+#if 0
+static FILE *fp = RT_NULL;
+#endif
+
+/*@{*/
+
+/* RT-Thread Device Interface */
+/**
+ * This function initializes serial
+ */
+static rt_err_t rt_serial_init(rt_device_t dev)
+{
+    if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
+    {
+        if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+        {
+            rt_memset(serial_rx.rx_buffer, 0,
+                      sizeof(serial_rx.rx_buffer));
+            serial_rx.read_index = 0;
+            serial_rx.save_index = 0;
+        }
+
+        dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
+    }
+    return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+#if _DEBUG_SERIAL==1
+    printf("in rt_serial_open()\n");
+#endif
+    return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+#if _DEBUG_SERIAL==1
+    printf("in rt_serial_close()\n");
+#endif
+    return RT_EOK;
+}
+static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    rt_uint8_t *ptr;
+    rt_err_t err_code;
+
+    ptr = buffer;
+    err_code = RT_EOK;
+
+    if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+    {
+        /* interrupt mode Rx */
+        while (size)
+        {
+            rt_base_t level;
+
+            /* disable interrupt */
+            level = rt_hw_interrupt_disable();
+
+            if (serial_rx.read_index != serial_rx.save_index)
+            {
+                /* read a character */
+                *ptr++ = serial_rx.rx_buffer[serial_rx.read_index];
+                size--;
+
+                /* move to next position */
+                serial_rx.read_index ++;
+                if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
+                    serial_rx.read_index = 0;
+            }
+            else
+            {
+                /* set error code */
+                err_code = -RT_EEMPTY;
+
+                /* enable interrupt */
+                rt_hw_interrupt_enable(level);
+                break;
+            }
+
+            /* enable interrupt */
+            rt_hw_interrupt_enable(level);
+        }
+    }
+
+
+    /* set error code */
+    rt_set_errno(err_code);
+    return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+}
+
+static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+#if _DEBUG_SERIAL==1
+    printf("in rt_serial_write()\n");
+#endif
+#if 0
+    if (fp == NULL)
+        fp = fopen("log.txt", "wb+");
+
+    if (fp != NULL)
+        fwrite(buffer, size, 1, fp);
+#endif
+
+    printf("%s", (char *)buffer);
+    return size;
+}
+
+static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+    RT_ASSERT(dev != RT_NULL);
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_SUSPEND:
+        /* suspend device */
+        dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
+        break;
+
+    case RT_DEVICE_CTRL_RESUME:
+        /* resume device */
+        dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
+        break;
+    }
+
+    return RT_EOK;
+}
+
+/*
+ * serial register
+ */
+static rt_err_t rt_hw_serial_register(rt_device_t device, const char *name, rt_uint32_t flag)
+{
+    RT_ASSERT(device != RT_NULL);
+#if _DEBUG_SERIAL==1
+    printf("in rt_serial_register()\n");
+#endif
+    device->type        = RT_Device_Class_Char;
+    device->rx_indicate = RT_NULL;
+    device->tx_complete = RT_NULL;
+    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;
+    device->user_data       = RT_NULL;
+
+    /* register a character device */
+    return rt_device_register(device, name, (rt_uint16_t)(RT_DEVICE_FLAG_RDWR | flag));
+}
+
+rt_err_t rt_hw_serial_init(void)
+{
+    return rt_hw_serial_register(&serial_device, RT_CONSOLE_DEVICE_NAME,
+                                 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
+}

+ 22 - 0
bsp/simlinux/drivers/serial.h

@@ -0,0 +1,22 @@
+/*
+*********************************************************************************************************
+*                                       MC9S12DP256/DG128 Specific code
+*                                          BANKED MEMORY MODEL
+*
+* File : rthw.c
+* By   : parai
+* email:parai@foxmail.com
+*******************************************************************************************************/
+
+#ifndef __RT_HW_SERIAL_H__
+#define __RT_HW_SERIAL_H__
+
+#define SERIAL_RX_BUFFER_SIZE 80
+struct serial_int_rx
+{
+    rt_uint8_t  rx_buffer[SERIAL_RX_BUFFER_SIZE];
+    rt_uint32_t read_index, save_index;
+};
+
+rt_err_t rt_hw_serial_init(void);
+#endif

+ 24 - 0
bsp/simlinux/drivers/sst25vfxx_mtd.h

@@ -0,0 +1,24 @@
+/*
+ * File      : sst25vfxx_mtd.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-12-16     aozima       the first version
+ * 2012-02-01     mbbill       MTD driver version
+ */
+
+#ifndef SST25VFXX_MTD_H
+#define SST25VFXX_MTD_H
+
+#include <rtthread.h>
+#include <drivers/spi.h>
+
+rt_err_t sst25vfxx_mtd_init(const char *spi_device_name, rt_uint32_t block_start, rt_uint32_t block_end);
+
+#endif

+ 227 - 0
bsp/simlinux/drivers/sst25vfxx_mtd_sim.c

@@ -0,0 +1,227 @@
+/*
+ * File      : rtdef.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-10-21     prife        the first version
+ */
+
+#include <rtdevice.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "sst25vfxx_mtd.h"
+
+#ifdef RT_USING_MTD_NOR
+#define NOR_SIM "nor.bin"
+/* JEDEC Manufacturer¡¯s ID */
+#define MF_ID           (0xBF)
+/* JEDEC Device ID : Memory Type */
+#define MT_ID           (0x25)
+/* JEDEC Device ID: Memory Capacity */
+#define MC_ID_SST25VF016               (0x41)
+#define MC_ID_SST25VF032               (0x4A)
+#define MC_ID_SST25VF064               (0x4B)
+
+#define BLOCK_SIZE   (64*1024)
+
+
+#define SST25_MTD(device)       ((struct sst25_mtd*)(device))
+struct sst25_mtd
+{
+    struct rt_mtd_nor_device parent;
+    FILE *file;
+};
+static struct sst25_mtd _sst25_mtd;
+
+static struct rt_mutex flash_lock;
+
+/* RT-Thread MTD device interface */
+static rt_uint32_t sst25vfxx_read_id(struct rt_mtd_nor_device *device)
+{
+    rt_uint8_t id_recv[3] = {MF_ID, MT_ID, MC_ID_SST25VF016};
+
+    return (id_recv[0] << 16) | (id_recv[1] << 8) | id_recv[2];
+}
+
+static int sst25vfxx_read(struct rt_mtd_nor_device *device, rt_off_t position, rt_uint8_t *data, rt_size_t size)
+{
+    struct sst25_mtd *sst25;
+    int result;
+
+    sst25 = SST25_MTD(device);
+    RT_ASSERT(sst25 != RT_NULL);
+
+    rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
+
+    fseek(sst25->file, position, SEEK_SET);
+    result = fread(data, size, 1, sst25->file);
+    if (result < 0)
+        rt_kprintf("sst read error.\n");
+
+    rt_mutex_release(&flash_lock);
+    return size;
+}
+
+static int sst25vfxx_write(struct rt_mtd_nor_device *device, rt_off_t position,
+                           const rt_uint8_t *data, rt_size_t size)
+{
+    struct sst25_mtd *sst25;
+    int result;
+
+    sst25 = SST25_MTD(device);
+    RT_ASSERT(sst25 != RT_NULL);
+
+    rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
+
+    fseek(sst25->file, position, SEEK_SET);
+    result = fwrite(data, size, 1, sst25->file);
+    if (result < 0)
+        rt_kprintf("sst write error.\n");
+
+    rt_mutex_release(&flash_lock);
+    return size;
+}
+
+static char block_buffer[BLOCK_SIZE];
+static rt_err_t sst25vfxx_erase_block(struct rt_mtd_nor_device *device, rt_off_t offset, rt_uint32_t length)
+{
+    struct sst25_mtd *sst25;
+    int result;
+
+    sst25 = SST25_MTD(device);
+
+    RT_ASSERT(sst25 != RT_NULL);
+
+    rt_mutex_take(&flash_lock, RT_WAITING_FOREVER);
+
+    memset(block_buffer, 0xFF, BLOCK_SIZE);
+    fseek(sst25->file, offset, SEEK_SET);
+
+    result = fwrite(block_buffer, BLOCK_SIZE, 1, sst25->file);
+    if (result < 0)
+        rt_kprintf("sst write error.\n");
+
+    rt_mutex_release(&flash_lock);
+    return RT_EOK;
+}
+
+const static struct rt_mtd_nor_driver_ops sst25vfxx_mtd_ops =
+{
+    sst25vfxx_read_id,
+    sst25vfxx_read,
+    sst25vfxx_write,
+    sst25vfxx_erase_block,
+};
+static rt_err_t sst25vfxx_hw_init(struct sst25_mtd *mtd)
+{
+    mtd = mtd;
+    return RT_EOK;
+}
+
+/**
+ * SST25vfxx API
+ */
+rt_err_t sst25vfxx_mtd_init(const char *nor_name,
+                            rt_uint32_t block_start,
+                            rt_uint32_t block_end)
+{
+    rt_uint32_t id, total_block;
+    struct sst25_mtd *sst25;
+    struct rt_mtd_nor_device *mtd;
+
+
+    sst25 = &_sst25_mtd;
+    mtd = &(sst25->parent);
+
+    /* set page size and block size */
+    mtd->block_size = 64 * 1024; /* 64kByte */
+    mtd->ops = &sst25vfxx_mtd_ops;
+
+    /* initialize mutex */
+    if (rt_mutex_init(&flash_lock, nor_name, RT_IPC_FLAG_FIFO) != RT_EOK)
+    {
+        rt_kprintf("init sd lock mutex failed\n");
+    }
+
+    /* initialize flash */
+    id = sst25vfxx_read_id(mtd);
+    switch (id & 0xff)
+    {
+    case MC_ID_SST25VF016:
+        total_block = (16 * 1024 * 1024 / 8) / mtd->block_size;
+        break;
+    case MC_ID_SST25VF032:
+        total_block = (32 * 1024 * 1024 / 8) / mtd->block_size;
+        break;
+    case MC_ID_SST25VF064:
+        total_block = (64 * 1024 * 1024 / 8) / mtd->block_size;
+        break;
+    default:
+        rt_kprintf("SST25 detection error, id: %x\n", id);
+        return -RT_ERROR;
+    }
+
+    if ((block_end == RT_UINT32_MAX) || (block_end == 0))
+    {
+        block_end = total_block;
+    }
+    else if (block_end > total_block)
+    {
+        rt_kprintf("SST25 total block: %d, out of block\n", total_block);
+        return -RT_ERROR;
+    }
+
+    mtd->block_start = block_start;
+    mtd->block_end   = block_end;
+
+    /* open nor file, if not exist, then create it  */
+    sst25->file = fopen(NOR_SIM, "rb+");
+    if (sst25->file == NULL)
+    {
+        rt_uint32_t i;
+        /* create a file to simulate nor */
+        sst25->file = fopen(NOR_SIM, "wb+");
+
+        memset(block_buffer, 0xFF, sizeof(block_buffer));
+        for (i = 0; i < total_block; i++)
+        {
+            fseek(sst25->file, i * BLOCK_SIZE, SEEK_SET);
+            fwrite(block_buffer, BLOCK_SIZE, 1, sst25->file);
+        }
+    }
+
+    fseek(sst25->file, 0, SEEK_SET);
+
+    /* initialize hardware */
+    sst25vfxx_hw_init(&_sst25_mtd);
+
+    /* register MTD device */
+    rt_mtd_nor_register_device("nor", mtd);
+
+    return RT_EOK;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+void nor_erase(void)
+{
+    rt_uint32_t index;
+    struct rt_mtd_nor_device *mtd;
+
+    mtd = RT_MTD_NOR_DEVICE(&_sst25_mtd);
+    for (index = mtd->block_start; index < mtd->block_end; index ++)
+    {
+        sst25vfxx_erase_block(mtd, index * mtd->block_size, BLOCK_SIZE);
+    }
+}
+FINSH_FUNCTION_EXPORT(nor_erase, erase all block in SPI flash);
+#endif
+
+#endif

+ 138 - 0
bsp/simlinux/drivers/usart_sim.c

@@ -0,0 +1,138 @@
+#include  <rthw.h>
+#include  <rtthread.h>
+
+#ifdef _WIN32
+#include  <windows.h>
+#include  <mmsystem.h>
+#endif
+
+#include  <stdio.h>
+#include  <conio.h>
+
+#include "serial.h"
+
+struct serial_int_rx serial_rx;
+extern struct rt_device serial_device;
+
+/*
+ * Handler for OSKey Thread
+ */
+static HANDLE       OSKey_Thread;
+static DWORD        OSKey_ThreadID;
+
+static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam);
+void rt_hw_usart_init(void)
+{
+
+    /*
+     * create serial thread that receive key input from keyboard
+     */
+
+    OSKey_Thread = CreateThread(NULL,
+                                0,
+                                (LPTHREAD_START_ROUTINE)ThreadforKeyGet,
+                                0,
+                                CREATE_SUSPENDED,
+                                &OSKey_ThreadID);
+    if (OSKey_Thread == NULL)
+    {
+        //Display Error Message
+
+        return;
+    }
+    SetThreadPriority(OSKey_Thread,
+                      THREAD_PRIORITY_NORMAL);
+    SetThreadPriorityBoost(OSKey_Thread,
+                           TRUE);
+    SetThreadAffinityMask(OSKey_Thread,
+                          0x01);
+    /*
+     * Start OS get key Thread
+     */
+    ResumeThread(OSKey_Thread);
+
+}
+
+/*
+ * 方向键(←): 0xe04b
+ * 方向键(↑): 0xe048
+ * 方向键(→): 0xe04d
+ * 方向键(↓): 0xe050
+ */
+static int savekey(unsigned char key)
+{
+    /* save on rx buffer */
+    {
+        rt_base_t level;
+
+        /* disable interrupt */
+        //暂时关闭中断,因为要操作uart数据结构
+        level = rt_hw_interrupt_disable();
+
+        /* save character */
+        serial_rx.rx_buffer[serial_rx.save_index] = key;
+        serial_rx.save_index ++;
+        //下面的代码检查save_index是否已经到到缓冲区尾部,如果是则回转到头部,称为一个环形缓冲区
+        if (serial_rx.save_index >= SERIAL_RX_BUFFER_SIZE)
+            serial_rx.save_index = 0;
+
+        //这种情况表示反转后的save_index追上了read_index,则增大read_index,丢弃一个旧的数据
+        /* if the next position is read index, discard this 'read char' */
+        if (serial_rx.save_index == serial_rx.read_index)
+        {
+            serial_rx.read_index ++;
+            if (serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE)
+                serial_rx.read_index = 0;
+        }
+
+        /* enable interrupt */
+        //uart数据结构已经操作完成,重新使能中断
+        rt_hw_interrupt_enable(level);
+    }
+
+    /* invoke callback */
+    if (serial_device.rx_indicate != RT_NULL)
+    {
+        rt_size_t rx_length;
+
+        /* get rx length */
+        rx_length = serial_rx.read_index > serial_rx.save_index ?
+                    SERIAL_RX_BUFFER_SIZE - serial_rx.read_index + serial_rx.save_index :
+                    serial_rx.save_index - serial_rx.read_index;
+
+        serial_device.rx_indicate(&serial_device, rx_length);
+    }
+    return 0;
+}
+static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam)
+{
+    unsigned char key;
+
+    (void)lpParam;              //prevent compiler warnings
+
+    for (;;)
+    {
+        key = getch();
+        if (key == 0xE0)
+        {
+            key = getch();
+
+            if (key == 0x48) //up key , 0x1b 0x5b 0x41
+            {
+                savekey(0x1b);
+                savekey(0x5b);
+                savekey(0x41);
+            }
+            else if (key == 0x50)//0x1b 0x5b 0x42
+            {
+                savekey(0x1b);
+                savekey(0x5b);
+                savekey(0x42);
+            }
+
+            continue;
+        }
+
+        savekey(key);
+    }
+} /*** ThreadforKeyGet ***/

+ 228 - 0
bsp/simlinux/rtconfig.h

@@ -0,0 +1,228 @@
+/* RT-Thread config file */
+#ifndef __RTTHREAD_CFG_H__
+#define __RTTHREAD_CFG_H__
+
+#define RT_HEAP_SIZE   (1024*1024*2)
+
+#if  defined(_MSC_VER)
+/* SECTION: port for visual studio */
+#undef RT_USING_NEWLIB
+#undef RT_USING_MINILIBC
+#define NORESOURCE  //RT_VESRION in winuser.h
+#define _CRT_ERRNO_DEFINED  //errno macro redefinition
+
+/* disable some warning in MSC */
+#pragma warning(disable:4273)	/* to ignore: warning C4273: inconsistent dll linkage */
+#pragma warning(disable:4312)   /* to ignore: warning C4312: 'type cast' : conversion from 'rt_uint32_t' to 'rt_uint32_t *' */
+#pragma warning(disable:4311)   /* to ignore: warning C4311: 'type cast' : pointer truncation from 'short *__w64 ' to 'long' */
+#pragma warning(disable:4996)   /* to ignore: warning C4996: The POSIX name for this item is deprecated. */
+#pragma warning(disable:4267)   /* to ignore: warning C4267: conversion from 'size_t' to 'rt_size_t', possible loss of data */
+#pragma warning(disable:4244)   /* to ignore: warning C4244: '=' : conversion from '__w64 int' to 'rt_size_t', possible loss of data */
+
+#elif defined(__GNUC__)
+#define RT_USING_NOLIBC
+#endif
+
+/* SECTION: basic kernel options */
+/* RT_NAME_MAX*/
+#define RT_NAME_MAX	8
+
+/* RT_ALIGN_SIZE*/
+#define RT_ALIGN_SIZE	4
+
+/* PRIORITY_MAX */
+#define RT_THREAD_PRIORITY_MAX  32	
+
+/* Tick per Second */
+#define RT_TICK_PER_SECOND	2
+
+/* SECTION: RT_DEBUG */
+/* Thread Debug */
+#define RT_DEBUG
+//#define RT_DEBUG_SCHEDULER   1
+#define RT_THREAD_DEBUG
+
+#define RT_USING_OVERFLOW_CHECK
+
+/* Using Hook */
+#define RT_USING_HOOK
+
+/* Using Software Timer */
+/* #define RT_USING_TIMER_SOFT */
+#define RT_TIMER_THREAD_PRIO		4
+#define RT_TIMER_THREAD_STACK_SIZE	512
+#define RT_TIMER_TICK_PER_SECOND	10
+
+/* SECTION: IPC */
+/* Using Semaphore*/
+#define RT_USING_SEMAPHORE
+
+/* Using Mutex */
+#define RT_USING_MUTEX
+
+/* Using Event */
+#define RT_USING_EVENT
+
+/* Using MailBox */
+#define RT_USING_MAILBOX
+
+/* Using Message Queue */
+#define RT_USING_MESSAGEQUEUE
+
+/* SECTION: Memory Management */
+/* Using Memory Pool Management*/
+/* #define RT_USING_MEMPOOL */
+
+/* Using Dynamic Heap Management */
+#define RT_USING_HEAP
+
+/* Using Small MM */
+#define RT_USING_SMALL_MEM
+/* #define RT_TINY_SIZE */
+
+/* SECTION: Device System */
+/* Using Device System */
+#define RT_USING_DEVICE
+/* #define RT_USING_UART1 */
+
+/* SECTION: Console options */
+#define RT_USING_CONSOLE
+/* the buffer size of console*/
+#define RT_CONSOLEBUF_SIZE	128
+#define RT_CONSOLE_DEVICE_NAME	"sci0"
+
+/* SECTION: component options */
+#define RT_USING_COMPONENTS_INIT
+
+/* SECTION: MTD interface options */
+/* using mtd nand flash */
+/* #define RT_USING_MTD_NAND */
+/* using mtd nor flash */
+/* #define RT_USING_MTD_NOR */
+
+/* SECTION: finsh, a C-Express shell */
+/* #define RT_USING_FINSH */
+/* Using symbol table */
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+
+/* SECTION: device file system */
+/* #define RT_USING_DFS */
+#define DFS_FILESYSTEM_TYPES_MAX  8
+
+/* DFS: ELM FATFS options */
+#define RT_USING_DFS_ELMFAT
+#define RT_DFS_ELM_WORD_ACCESS
+/* Reentrancy (thread safe) of the FatFs module.  */
+#define RT_DFS_ELM_REENTRANT
+/* Number of volumes (logical drives) to be used. */
+#define RT_DFS_ELM_DRIVES			2
+/* #define RT_DFS_ELM_USE_LFN			1 */
+#define RT_DFS_ELM_MAX_LFN			255
+/* Maximum sector size to be handled. */
+#define RT_DFS_ELM_MAX_SECTOR_SIZE  512
+
+/* DFS: network file system options */
+/* #define RT_USING_DFS_NFS */
+
+/* DFS: UFFS nand file system options */
+#define RT_USING_DFS_UFFS
+/* configuration for uffs, more to see dfs_uffs.h and uffs_config.h */
+#define RT_CONFIG_UFFS_ECC_MODE  UFFS_ECC_HW_AUTO
+/* enable this ,you need provide a mark_badblock/check_block function */
+/* #define RT_UFFS_USE_CHECK_MARK_FUNCITON */
+
+/* DFS: JFFS2 nor flash file system options */
+#define RT_USING_DFS_JFFS2
+
+/* DFS: windows share directory mounted to rt-thread/dfs  */
+/* only used in bsp/simulator */
+#define RT_USING_DFS_WINSHAREDIR
+
+/* the max number of mounted file system */
+#define DFS_FILESYSTEMS_MAX			4
+/* the max number of opened files 		*/
+#define DFS_FD_MAX					4
+
+/* SECTION: lwip, a lightweight TCP/IP protocol stack */
+/* #define RT_USING_LWIP */
+/* LwIP uses RT-Thread Memory Management */
+#define RT_LWIP_USING_RT_MEM
+/* Enable ICMP protocol*/
+#define RT_LWIP_ICMP
+/* Enable UDP protocol*/
+#define RT_LWIP_UDP
+/* Enable TCP protocol*/
+#define RT_LWIP_TCP
+/* Enable DNS */
+#define RT_LWIP_DNS
+
+/* the number of simultaneously active TCP connections*/
+#define RT_LWIP_TCP_PCB_NUM	5
+
+/* Using DHCP */
+/* #define RT_LWIP_DHCP */
+
+/* ip address of target*/
+#define RT_LWIP_IPADDR0	192
+#define RT_LWIP_IPADDR1	168
+#define RT_LWIP_IPADDR2	126
+#define RT_LWIP_IPADDR3	30
+
+/* gateway address of target*/
+#define RT_LWIP_GWADDR0	192
+#define RT_LWIP_GWADDR1	168
+#define RT_LWIP_GWADDR2	126
+#define RT_LWIP_GWADDR3	1
+
+/* mask address of target*/
+#define RT_LWIP_MSKADDR0	255
+#define RT_LWIP_MSKADDR1	255
+#define RT_LWIP_MSKADDR2	255
+#define RT_LWIP_MSKADDR3	0
+
+/* tcp thread options */
+#define RT_LWIP_TCPTHREAD_PRIORITY		12
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE		10
+#define RT_LWIP_TCPTHREAD_STACKSIZE		1024
+
+/* Ethernet if thread options */
+#define RT_LWIP_ETHTHREAD_PRIORITY		15
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE		10
+#define RT_LWIP_ETHTHREAD_STACKSIZE		512
+
+/* TCP sender buffer space */
+#define RT_LWIP_TCP_SND_BUF	8192
+/* TCP receive window. */
+#define RT_LWIP_TCP_WND		8192
+
+/* SECTION: RT-Thread/GUI */
+/* #define RT_USING_RTGUI */
+
+/* name length of RTGUI object */
+#define RTGUI_NAME_MAX		12
+/* support 16 weight font */
+#define RTGUI_USING_FONT16
+/* support Chinese font */
+#define RTGUI_USING_FONTHZ
+/* use DFS as file interface */
+#define RTGUI_USING_DFS_FILERW
+/* use font file as Chinese font */
+/* #define RTGUI_USING_HZ_FILE */
+/* use Chinese bitmap font */
+#define RTGUI_USING_HZ_BMP
+/* use small size in RTGUI */
+#define RTGUI_USING_SMALL_SIZE
+/* use mouse cursor */
+/* #define RTGUI_USING_MOUSE_CURSOR */
+/* default font size in RTGUI */
+#define RTGUI_DEFAULT_FONT_SIZE	16
+
+/* image support */
+#define RTGUI_IMAGE_XPM
+#define RTGUI_IMAGE_BMP
+/* #define RTGUI_IMAGE_JPEG */
+/* #define RTGUI_IMAGE_PNG */
+#define RTGUI_USING_NOTEBOOK_IMAGE
+
+#endif

+ 80 - 0
bsp/simlinux/rtconfig.py

@@ -0,0 +1,80 @@
+# toolchains options
+ARCH='sim'
+#CPU='win32' 
+#CPU='posix'
+CPU='posix'
+CROSS_TOOL='gcc' #msvc # gcc
+
+# lcd panel options
+# 'FMT0371','ILI932X', 'SSD1289'
+# RT_USING_LCD_TYPE = 'SSD1289'
+
+# cross_tool provides the cross compiler
+# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
+if  CROSS_TOOL == 'gcc':
+	PLATFORM 	= 'gcc'
+	EXEC_PATH 	= '/usr/bin/gcc'
+
+if  CROSS_TOOL == 'msvc':
+	PLATFORM 	= 'cl'
+	EXEC_PATH = ''
+
+BUILD = 'debug'
+#BUILD = ''
+
+if PLATFORM == 'gcc':
+    # toolchains
+    PREFIX = ''
+    CC = PREFIX + 'gcc'
+    AS = PREFIX + 'gcc'
+    AR = PREFIX + 'ar'
+    LINK = PREFIX + 'gcc'
+    TARGET_EXT = 'axf'
+    SIZE = PREFIX + 'size'
+    OBJDUMP = PREFIX + 'objdump'
+    OBJCPY = PREFIX + 'objcopy'
+
+    DEVICE = ' -ffunction-sections -fdata-sections'
+    CFLAGS = DEVICE + ' -I/usr/include -w -D_REENTRANT'
+    AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
+    #LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-linux.map,-cref,-u,Reset_Handler -T stm32_rom.ld'
+    #LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-linux.map -lpthread'
+    LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-linux.map -pthread'
+
+    CPATH = ''
+    LPATH = ''
+
+    if BUILD == 'debug':
+        CFLAGS += ' -g -O0 -gdwarf-2'
+        AFLAGS += ' -gdwarf-2'
+    else:
+        CFLAGS += ' -O2'
+
+    POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
+
+elif PLATFORM == 'cl':
+    # toolchains
+    PREFIX = ''
+    TARGET_EXT = 'exe'
+    AS = PREFIX + 'cl'
+    CC = PREFIX + 'cl'
+    AR = PREFIX + 'cl'
+    LINK = PREFIX + 'cl'
+    AFLAGS = ''
+    CFLAGS = ''
+    LFLAGS = ''
+
+    if BUILD == 'debug':
+        CFLAGS += ' /MTd'
+        LFLAGS += ' /DEBUG'
+    else:
+        CFLAGS += ' /MT'
+        LFLAGS += ''
+
+    CFLAGS += ' /ZI /Od /W 3 /WL '
+    LFLAGS += ' /SUBSYSTEM:CONSOLE /MACHINE:X86 '
+
+    CPATH = ''
+    LPATH = ''
+
+    POST_ACTION = ''