diff options
| author | Bernard Xiong <[email protected]> | 2015-09-30 16:26:40 +0800 |
|---|---|---|
| committer | Bernard Xiong <[email protected]> | 2015-09-30 16:26:40 +0800 |
| commit | 7e45f059dce0a7751beef09e5ac122a83d731c5b (patch) | |
| tree | f12f0189df20a8541c175b144400e795483413b6 /bsp/simulator/drivers | |
| parent | 4ab8ea53c220f64263207ef40ff33cb5e52bceb3 (diff) | |
[BSP] Update simualtor bsp for Win32/MSVC
Diffstat (limited to 'bsp/simulator/drivers')
| -rwxr-xr-x | bsp/simulator/drivers/board.c | 13 | ||||
| -rw-r--r-- | bsp/simulator/drivers/module_win32.c | 184 | ||||
| -rwxr-xr-x | bsp/simulator/drivers/serial.c | 218 | ||||
| -rw-r--r-- | bsp/simulator/drivers/serial.h | 32 | ||||
| -rw-r--r--[-rwxr-xr-x] | bsp/simulator/drivers/uart_console.c (renamed from bsp/simulator/drivers/usart_sim.c) | 179 | ||||
| -rw-r--r-- | bsp/simulator/drivers/uart_console.h | 6 |
6 files changed, 312 insertions, 320 deletions
diff --git a/bsp/simulator/drivers/board.c b/bsp/simulator/drivers/board.c index dcb8d9a049..4e498395c9 100755 --- a/bsp/simulator/drivers/board.c +++ b/bsp/simulator/drivers/board.c @@ -14,9 +14,12 @@ #include <rthw.h> #include <rtthread.h> -#include "board.h" + #include <stdlib.h> +#include "board.h" +#include "uart_console.h" + /** * @addtogroup simulator on win32 */ @@ -93,9 +96,11 @@ void rt_hw_board_init() /* init system memory */ heap = rt_hw_sram_init(); -//#if defined(RT_USING_USART) - rt_hw_usart_init(); -//#endif + uart_console_init(); + +#ifdef _WIN32 + rt_thread_idle_sethook(rt_hw_win32_low_cpu); +#endif #if defined(RT_USING_CONSOLE) rt_console_set_device(RT_CONSOLE_DEVICE_NAME); diff --git a/bsp/simulator/drivers/module_win32.c b/bsp/simulator/drivers/module_win32.c index 3f0a273746..95cb301037 100644 --- a/bsp/simulator/drivers/module_win32.c +++ b/bsp/simulator/drivers/module_win32.c @@ -130,6 +130,7 @@ void rt_module_unload_sethook(void (*hook)(rt_module_t module)) */ int rt_system_module_init(void) { + return 0; } /** @@ -148,6 +149,7 @@ rt_module_t rt_module_self(void) /* return current module */ return (rt_module_t)tid->module_id; } +RTM_EXPORT(rt_module_self); /** * This function will find the specified module. @@ -191,6 +193,7 @@ rt_module_t rt_module_find(const char *name) /* not found */ return RT_NULL; } +RTM_EXPORT(rt_module_find); #ifdef RT_USING_DFS #include <windows.h> @@ -237,10 +240,10 @@ rt_module_t rt_module_open(const char *path) struct dfs_filesystem *fs; appentry_t fptr; HINSTANCE hinstlib; - int len; - char * winpath; - rt_module_t module; - char * name; + rt_module_t module; + + char * winpath = RT_NULL; + char * name = RT_NULL; RT_DEBUG_NOT_IN_INTERRUPT; @@ -256,10 +259,10 @@ rt_module_t rt_module_open(const char *path) } /* change path */ - len = strlen(path+1); + // len = strlen(path+1); if ((winpath = dfs_win32_dirdup((char *)path)) == RT_NULL) { - rt_kprintf("out of memory, exit", path); + rt_kprintf("out of memory, exit"); return RT_NULL; } @@ -282,10 +285,8 @@ rt_module_t rt_module_open(const char *path) name = _module_name(path); /* allocate module */ - module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, - name); - if (!module) - return RT_NULL; + module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, name); + if (!module) return RT_NULL; module->nref = 0; module->module_entry = fptr; @@ -298,31 +299,21 @@ rt_module_t rt_module_open(const char *path) if (module->module_entry != 0) { - rt_uint32_t *stack_size; - rt_uint8_t *priority; - #ifdef RT_USING_SLAB /* init module memory allocator */ module->mem_list = RT_NULL; /* create page array */ - module->page_array = + module->page_array = (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info)); module->page_cnt = 0; #endif - /* get the main thread stack size */ - module->stack_size = 2048; - module->thread_priority = RT_THREAD_PRIORITY_MAX - 2; - /* create module thread */ module->module_thread = rt_thread_create(name, - (void(*)(void *))module->module_entry, - RT_NULL, - module->stack_size, - module->thread_priority, - 10); + (void(*)(void *))module->module_entry, RT_NULL, + 2048, RT_THREAD_PRIORITY_MAX - 2, 10); RT_DEBUG_LOG(RT_DEBUG_MODULE, ("thread entry 0x%x\n", module->module_entry)); @@ -354,12 +345,157 @@ rt_module_t rt_module_open(const char *path) #if defined(RT_USING_FINSH) #include <finsh.h> - FINSH_FUNCTION_EXPORT_ALIAS(rt_module_open, exec, exec module from a file); #endif #endif +/** + * This function will do a excutable program with main function and parameters. + * + * @param path the full path of application module + * @param cmd_line the command line of program + * @param size the size of command line of program + * + * @return the module object + */ +rt_module_t rt_module_exec_cmd(const char *path, const char* cmd_line, int line_size) +{ + struct dfs_filesystem *fs; + appentry_t fptr; + HINSTANCE hinstlib; + rt_module_t module; + + char * winpath = RT_NULL; + char * name = RT_NULL; + char *full_path = RT_NULL; + + RT_DEBUG_NOT_IN_INTERRUPT; + + /* check parameters */ + RT_ASSERT(path != RT_NULL); + + if (*path != '/') + { + full_path = dfs_normalize_path(RT_NULL, path); + } + else + { + full_path = (const char*)path; + } + + /* app module should only in DFS_WIN32 */ + fs = dfs_filesystem_lookup(full_path); + if ((fs == RT_NULL) || (strcmp(fs->ops->name,"wdir") != 0)) + { + rt_kprintf("invalid path: %s\n", path); + goto __exit; + } + + /* change path */ + // len = strlen(full_path + 1); + if ((winpath = dfs_win32_dirdup((char *)full_path)) == RT_NULL) + { + rt_kprintf("out of memory, exit", path); + goto __exit; + } + + hinstlib = LoadLibrary(winpath); + if (hinstlib == NULL) + { + rt_kprintf("error: unable to open %s\n", winpath); + goto __exit; + } + + fptr = (appentry_t)GetProcAddress(hinstlib, "main"); + if (fptr == NULL) + { + rt_kprintf("error: unable to find function in %s\n", winpath); + FreeLibrary(hinstlib); + goto __exit; + } + + /* release winpath */ + rt_free(winpath); + + /* get the name of the module */ + name = _module_name(path); + + /* allocate module */ + module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, name); + if (!module) + { + goto __exit; + } + + module->nref = 0; + module->module_entry = fptr; + + /* init module object container */ + rt_module_init_object_container(module); + + /* increase module reference count */ + module->nref ++; + + if (module->module_entry != 0) + { + /* set module argument */ + module->module_cmd_line = (rt_uint8_t*)rt_malloc(line_size + 1); + rt_memcpy(module->module_cmd_line, cmd_line, line_size); + module->module_cmd_line[line_size] = '\0'; + module->module_cmd_size = line_size; + +#ifdef RT_USING_SLAB + /* init module memory allocator */ + module->mem_list = RT_NULL; + + /* create page array */ + module->page_array = + (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info)); + module->page_cnt = 0; +#endif + + /* create module thread */ + module->module_thread = + rt_thread_create(name, + (void(*)(void *))module->module_entry, RT_NULL, + 2048, RT_THREAD_PRIORITY_MAX - 2, 10); + + RT_DEBUG_LOG(RT_DEBUG_MODULE, ("thread entry 0x%x\n", + module->module_entry)); + + /* set module id */ + module->module_thread->module_id = (void *)module; + module->parent.flag = RT_MODULE_FLAG_WITHENTRY; + + /* startup module thread */ + rt_thread_startup(module->module_thread); + } + else + { + /* without entry point */ + module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY; + } + +#ifdef RT_USING_HOOK + if (rt_module_load_hook != RT_NULL) + { + rt_module_load_hook(module); + } +#endif + + rt_free(name); + return module; + +__exit: + if (full_path != path) rt_free(full_path); + if (name != RT_NULL) rt_free(full_path); + if (winpath != RT_NULL)rt_free(winpath); + + return RT_NULL; + /* FreeLibrary(hinstlib); */ +} + rt_err_t rt_module_destroy(rt_module_t module) { return 0; diff --git a/bsp/simulator/drivers/serial.c b/bsp/simulator/drivers/serial.c deleted file mode 100755 index 72cbad3baf..0000000000 --- a/bsp/simulator/drivers/serial.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * File : serial.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013 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-02-05 Bernard first version - * 2009-10-25 Bernard fix rt_serial_read bug when there is no data - * in the buffer. - * 2010-03-29 Bernard cleanup code. - * 2013-02-7 prife rewrite for simulator - */ - -#include <rthw.h> - -#include "serial.h" -#include <stdio.h> - -#if 0 -static FILE *fp = RT_NULL; -#endif - -/*@{*/ -int seial_save_byte(unsigned char ch, struct serial_device * serial) -{ - /* save on rx buffer */ - rt_base_t level; - struct rt_device * dev = RT_DEVICE(serial); - /* disable interrupt */ - //��ʱ�ر��жϣ���ΪҪ����uart���ݽṹ - level = rt_hw_interrupt_disable(); - - /* save character */ - serial->serial_rx.rx_buffer[serial->serial_rx.save_index] = ch; - serial->serial_rx.save_index ++; - //����Ĵ�����save_index�Ƿ��Ѿ�����������β������������ת��ͷ������Ϊһ�����λ����� - if (serial->serial_rx.save_index >= SERIAL_RX_BUFFER_SIZE) - serial->serial_rx.save_index = 0; - - //���������ʾ��ת���save_index����read_index��������read_index������һ���ɵ����� - /* if the next position is read index, discard this 'read char' */ - if (serial->serial_rx.save_index == serial->serial_rx.read_index) - { - serial->serial_rx.read_index ++; - if (serial->serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE) - serial->serial_rx.read_index = 0; - } - - /* enable interrupt */ - //uart���ݽṹ�Ѿ�������ɣ�����ʹ���ж� - rt_hw_interrupt_enable(level); - - /* invoke callback */ - if (dev->rx_indicate != RT_NULL) - { - rt_size_t rx_length; - - /* get rx length */ - rx_length = serial->serial_rx.read_index > serial->serial_rx.save_index ? - SERIAL_RX_BUFFER_SIZE - serial->serial_rx.read_index + serial->serial_rx.save_index : - serial->serial_rx.save_index - serial->serial_rx.read_index; - - dev->rx_indicate(dev, rx_length); - } - return 0; -} - -/* RT-Thread Device Interface */ -/** - * This function initializes serial - */ -static rt_err_t rt_serial_init(rt_device_t dev) -{ - struct serial_device * serial = SERIAL_DEVICE(dev); - if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) - { - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - rt_memset(serial->serial_rx.rx_buffer, 0, - sizeof(serial->serial_rx.rx_buffer)); - serial->serial_rx.read_index = 0; - serial->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) -{ - return RT_EOK; -} - -static rt_err_t rt_serial_close(rt_device_t dev) -{ - 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; - struct serial_device * serial = SERIAL_DEVICE(dev); - - 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->serial_rx.read_index != serial->serial_rx.save_index) - { - /* read a character */ - *ptr++ = serial->serial_rx.rx_buffer[serial->serial_rx.read_index]; - size--; - - /* move to next position */ - serial->serial_rx.read_index ++; - if (serial->serial_rx.read_index >= SERIAL_RX_BUFFER_SIZE) - serial->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) -{ - int level; -#if 0 - if (fp == NULL) - fp = fopen("log.txt", "wb+"); - - if (fp != NULL) - fwrite(buffer, size, 1, fp); -#endif - - level = rt_hw_interrupt_disable(); - fwrite(buffer, size, 1, stdout); - fflush(stdout); - rt_hw_interrupt_enable(level); - 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 - */ -rt_err_t rt_hw_serial_register(rt_device_t device, const char *name, rt_uint32_t flag) -{ - RT_ASSERT(device != RT_NULL); - 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(struct serial_device * serial, char * name) -{ - return rt_hw_serial_register(RT_DEVICE(serial), name, - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM); -} diff --git a/bsp/simulator/drivers/serial.h b/bsp/simulator/drivers/serial.h deleted file mode 100644 index 7c554c3f45..0000000000 --- a/bsp/simulator/drivers/serial.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -********************************************************************************************************* -* MC9S12DP256/DG128 Specific code -* BANKED MEMORY MODEL -* -* File : rthw.c -* By : parai -* email:[email protected] -*******************************************************************************************************/ - -#ifndef __RT_HW_SERIAL_H__ -#define __RT_HW_SERIAL_H__ - -#include <rtdevice.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; -}; - -struct serial_device -{ - struct rt_device dev; - struct serial_int_rx serial_rx; -}; - -#define SERIAL_DEVICE(dev) ((struct serial_device *)(dev)) - -int seial_save_byte(unsigned char ch, struct serial_device * serial); -rt_err_t rt_hw_serial_init(struct serial_device * serial, char * name); -#endif diff --git a/bsp/simulator/drivers/usart_sim.c b/bsp/simulator/drivers/uart_console.c index 6c8209dcc0..95a9cb11dd 100755..100644 --- a/bsp/simulator/drivers/usart_sim.c +++ b/bsp/simulator/drivers/uart_console.c @@ -1,34 +1,29 @@ -/* - * File : serial.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013 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 - * 2012-09-25 prife first implementation - * 2013-01-15 prife support linux - * 2013-02-6 prife rewrite to fit the new serial.c - */ -#include <rthw.h> -#include <rtthread.h> +#include <stdio.h> + +#include <rthw.h> +#include <rtdevice.h> +#include <rtthread.h> +#include <rtdevice.h> + +#include <cpu_port.h> + +/* uart driver */ +struct console_uart +{ + int rx_ready; + + struct rt_ringbuffer rb; + rt_uint8_t rx_buffer[256]; +} _console_uart; +static struct rt_serial_device _serial; + +#define SAVEKEY(key) do { char ch = key; rt_ringbuffer_put_force(&(_console_uart.rb), &ch, 1); } while (0) #ifdef _WIN32 #include <windows.h> #include <mmsystem.h> #include <conio.h> -#endif - -#include <stdio.h> -#include "serial.h" -struct serial_device serial1; - -#define SAVEKEY(key) seial_save_byte(key, &serial1) -#ifdef _WIN32 /* * Handler for OSKey Thread */ @@ -36,9 +31,8 @@ static HANDLE OSKey_Thread; static DWORD OSKey_ThreadID; static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam); -void rt_hw_usart_init(void) +void console_lowlevel_init(void) { - rt_hw_serial_init(&serial1, RT_CONSOLE_DEVICE_NAME); /* * create serial thread that receive key input from keyboard */ @@ -52,9 +46,9 @@ void rt_hw_usart_init(void) if (OSKey_Thread == NULL) { //Display Error Message - return; } + SetThreadPriority(OSKey_Thread, THREAD_PRIORITY_NORMAL); SetThreadPriorityBoost(OSKey_Thread, @@ -67,6 +61,7 @@ void rt_hw_usart_init(void) ResumeThread(OSKey_Thread); } +static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam) #else /* POSIX version */ #include <pthread.h> @@ -78,11 +73,11 @@ void rt_hw_usart_init(void) static void * ThreadforKeyGet(void * lpParam); static pthread_t OSKey_Thread; -void rt_hw_usart_init(void) + +void console_lowlevel_init(void) { int res; - rt_hw_serial_init(&serial1, RT_CONSOLE_DEVICE_NAME); res = pthread_create(&OSKey_Thread, NULL, &ThreadforKeyGet, NULL); if (res) { @@ -90,15 +85,10 @@ void rt_hw_usart_init(void) exit(EXIT_FAILURE); } } -#endif - -#ifdef _WIN32 -static DWORD WINAPI ThreadforKeyGet(LPVOID lpParam) -#else static struct termios oldt, newt; /*simulate windows' getch(), it works!!*/ -void set_stty(void) +static void set_stty(void) { /* get terminal input's attribute */ tcgetattr(STDIN_FILENO, &oldt); @@ -109,22 +99,21 @@ void set_stty(void) tcsetattr(STDIN_FILENO, TCSANOW, &newt); } -void restore_stty(void) +static void restore_stty(void) { /* recover terminal's attribute */ tcsetattr(STDIN_FILENO, TCSANOW, &oldt); } #define getch getchar - static void * ThreadforKeyGet(void * lpParam) #endif /* not _WIN32*/ { /* - * �����(��)�� 0xe04b - * �����(��)�� 0xe048 - * �����(��)�� 0xe04d - * �����(��)�� 0xe050 + * left key(��)�� 0xe04b + * up key(��)�� 0xe048 + * right key(��)�� 0xe04d + * down key(��)�� 0xe050 */ unsigned char key; @@ -135,7 +124,9 @@ static void * ThreadforKeyGet(void * lpParam) pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); set_stty(); #endif + (void)lpParam; //prevent compiler warnings + for (;;) { key = getch(); @@ -173,5 +164,109 @@ static void * ThreadforKeyGet(void * lpParam) } #endif SAVEKEY(key); + + /* Notfiy serial ISR */ + rt_hw_serial_isr(&_serial, RT_SERIAL_EVENT_RX_IND); } } /*** ThreadforKeyGet ***/ + +static rt_err_t console_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + /* no baudrate, nothing */ + + return RT_EOK; +} + +static rt_err_t console_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct console_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct console_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + uart->rx_ready = 0; + break; + case RT_DEVICE_CTRL_SET_INT: + uart->rx_ready = 1; + break; + } + + return RT_EOK; +} + +static int console_putc(struct rt_serial_device *serial, char c) +{ + int level; + struct console_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct console_uart *)serial->parent.user_data; + +#if 0 /* Enable it if you want to save the console log */ + { + static FILE* fp = NULL; + + if (fp == NULL) + fp = fopen("log.txt", "wb+"); + + if (fp != NULL) + fwrite(buffer, size, 1, fp); + } +#endif + + level = rt_hw_interrupt_disable(); + fwrite(&c, 1, 1, stdout); + fflush(stdout); + rt_hw_interrupt_enable(level); + return 1; +} + +static int console_getc(struct rt_serial_device *serial) +{ + char ch; + struct console_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct console_uart *)serial->parent.user_data; + + if (rt_ringbuffer_getchar(&(uart->rb), &ch)) return ch; + + return -1; +} + +static const struct rt_uart_ops console_uart_ops = +{ + console_configure, + console_control, + console_putc, + console_getc, +}; + +int uart_console_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + struct console_uart* uart; + struct rt_serial_device* serial; + + uart = &_console_uart; + serial = &_serial; + + uart->rx_ready = 0; + + serial->ops = &console_uart_ops; + serial->config = config; + /* initialize ring buffer */ + rt_ringbuffer_init(&uart->rb, uart->rx_buffer, sizeof(uart->rx_buffer)); + + /* register UART device */ + rt_hw_serial_register(serial, "console", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); + + console_lowlevel_init(); + + return 0; +} diff --git a/bsp/simulator/drivers/uart_console.h b/bsp/simulator/drivers/uart_console.h new file mode 100644 index 0000000000..149a7a21f8 --- /dev/null +++ b/bsp/simulator/drivers/uart_console.h @@ -0,0 +1,6 @@ +#ifndef UART_CONSOLE_H__ +#define UART_CONSOLE_H__ + +int uart_console_init(void); + +#endif |
