diff --git a/bsp/simlinux/SConscript b/bsp/simlinux/SConscript new file mode 100755 index 0000000000..0992612410 --- /dev/null +++ b/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') diff --git a/bsp/simlinux/SConstruct b/bsp/simlinux/SConstruct new file mode 100755 index 0000000000..4dd5342cc6 --- /dev/null +++ b/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) diff --git a/bsp/simlinux/applications/SConscript b/bsp/simlinux/applications/SConscript new file mode 100755 index 0000000000..4ccb177207 --- /dev/null +++ b/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') diff --git a/bsp/simlinux/applications/application.c b/bsp/simlinux/applications/application.c new file mode 100755 index 0000000000..c8ced1accb --- /dev/null +++ b/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 +#include +#include + +#include + +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; +} + + +/*@}*/ diff --git a/bsp/simlinux/applications/platform.c b/bsp/simlinux/applications/platform.c new file mode 100755 index 0000000000..3c7ffdb541 --- /dev/null +++ b/bsp/simlinux/applications/platform.c @@ -0,0 +1,29 @@ +#include +#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 +} + diff --git a/bsp/simlinux/applications/startup.c b/bsp/simlinux/applications/startup.c new file mode 100755 index 0000000000..2b21c69016 --- /dev/null +++ b/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 +#include + +#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; +} + +/*@}*/ diff --git a/bsp/simlinux/drivers/SConscript b/bsp/simlinux/drivers/SConscript new file mode 100755 index 0000000000..34b1a0bda7 --- /dev/null +++ b/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') diff --git a/bsp/simlinux/drivers/board.c b/bsp/simlinux/drivers/board.c new file mode 100755 index 0000000000..5506acb55d --- /dev/null +++ b/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 +#include +#include "board.h" +#include + +/** + * @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 +#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 +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 +} +/*@}*/ diff --git a/bsp/simlinux/drivers/board.h b/bsp/simlinux/drivers/board.h new file mode 100755 index 0000000000..7edb856505 --- /dev/null +++ b/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 diff --git a/bsp/simlinux/drivers/nanddrv_file.c b/bsp/simlinux/drivers/nanddrv_file.c new file mode 100755 index 0000000000..770751ac79 --- /dev/null +++ b/bsp/simlinux/drivers/nanddrv_file.c @@ -0,0 +1,399 @@ +#include +#include +#include +#include + +#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 +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 diff --git a/bsp/simlinux/drivers/sd_sim.c b/bsp/simlinux/drivers/sd_sim.c new file mode 100755 index 0000000000..7c9844bae3 --- /dev/null +++ b/bsp/simlinux/drivers/sd_sim.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include + +// #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 +void eraseall(void) +{ + printf("had not implemented yet!\n"); +} +FINSH_FUNCTION_EXPORT(eraseall, erase all block in SPI flash); +#endif diff --git a/bsp/simlinux/drivers/sdl_fb.c b/bsp/simlinux/drivers/sdl_fb.c new file mode 100755 index 0000000000..790797f2af --- /dev/null +++ b/bsp/simlinux/drivers/sdl_fb.c @@ -0,0 +1,304 @@ +#include + +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include + +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); +} diff --git a/bsp/simlinux/drivers/serial.c b/bsp/simlinux/drivers/serial.c new file mode 100755 index 0000000000..2bcdb15866 --- /dev/null +++ b/bsp/simlinux/drivers/serial.c @@ -0,0 +1,176 @@ +/* +****************************************************************************** +* By : parai +* email:parai@foxmail.com +* virtual serial driver +****************************************************************************** +*/ + +#include +#include + +#define _DEBUG_SERIAL 0 +#include "serial.h" +#include +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); +} diff --git a/bsp/simlinux/drivers/serial.h b/bsp/simlinux/drivers/serial.h new file mode 100755 index 0000000000..010631ab32 --- /dev/null +++ b/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 diff --git a/bsp/simlinux/drivers/sst25vfxx_mtd.h b/bsp/simlinux/drivers/sst25vfxx_mtd.h new file mode 100755 index 0000000000..cb0bb84129 --- /dev/null +++ b/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 +#include + +rt_err_t sst25vfxx_mtd_init(const char *spi_device_name, rt_uint32_t block_start, rt_uint32_t block_end); + +#endif diff --git a/bsp/simlinux/drivers/sst25vfxx_mtd_sim.c b/bsp/simlinux/drivers/sst25vfxx_mtd_sim.c new file mode 100755 index 0000000000..9271c1bb03 --- /dev/null +++ b/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 +#include +#include +#include +#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 +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 diff --git a/bsp/simlinux/drivers/usart_sim.c b/bsp/simlinux/drivers/usart_sim.c new file mode 100755 index 0000000000..6a2564786a --- /dev/null +++ b/bsp/simlinux/drivers/usart_sim.c @@ -0,0 +1,138 @@ +#include +#include + +#ifdef _WIN32 +#include +#include +#endif + +#include +#include + +#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 ***/ diff --git a/bsp/simlinux/rtconfig.h b/bsp/simlinux/rtconfig.h new file mode 100755 index 0000000000..ae213813ec --- /dev/null +++ b/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 diff --git a/bsp/simlinux/rtconfig.py b/bsp/simlinux/rtconfig.py new file mode 100755 index 0000000000..020649f329 --- /dev/null +++ b/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 = ''