syscall.c

来自「ecos实时嵌入式操作系统」· C语言 代码 · 共 652 行 · 第 1/2 页

C
652
字号
/*==========================================================================////      syscall.c////      Redboot syscall handling for GNUPro bsp support////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    msalter// Contributors: msalter// Date:         1999-02-20// Purpose:      Temporary support for gnupro bsp////####DESCRIPTIONEND####////=========================================================================*/#include <redboot.h>#include <cyg/hal/hal_intr.h>#include <cyg/hal/drv_api.h>#include <cyg/hal/hal_stub.h>#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS#define NEWLIB_EIO 5              /* I/O error */#define NEWLIB_ENOSYS 88          /* Syscall not supported *//* * Clients of this BSP will need to have access to BSP functions and * data structures. Because, the client and the BSP may not be linked * together, a structure of vectors is used to gain this access. A * pointer to this structure can be gotten via a syscall. This syscall * is made automatically from within the crt0.o file. */typedef struct {    int         version;        /* version number for future expansion */    const void **__ictrl_table;    void **__exc_table;    void *__dbg_vector;    void *__kill_vector;    void *__console_procs;    void *__debug_procs;    void (*__flush_dcache)(void *__p, int __nbytes);    void (*__flush_icache)(void *__p, int __nbytes);    void *__cpu_data;    void *__board_data;    void *__sysinfo;    int  (*__set_debug_comm)(int __comm_id);    int  (*__set_console_comm)(int __comm_id);    int  (*__set_serial_baud)(int __comm_id, int baud);    void *__dbg_data;    void (*__reset)(void);    int  __console_interrupt_flag;} __shared_t;static __shared_t __shared_data = { 2 };// this is used by newlib's mode_t so we should match it#ifdef __GNUC__#define _ST_INT32 __attribute__ ((__mode__ (__SI__)))#else#define _ST_INT32#endiftypedef unsigned int    newlib_mode_t _ST_INT32;typedef short           newlib_dev_t;typedef unsigned short  newlib_ino_t;typedef unsigned short  newlib_nlink_t;typedef long            newlib_off_t;typedef unsigned short  newlib_uid_t;typedef unsigned short  newlib_gid_t;typedef long            newlib_time_t;typedef long            newlib_long_t;struct newlib_stat {    newlib_dev_t     st_dev;    newlib_ino_t     st_ino;    newlib_mode_t    st_mode;    newlib_nlink_t   st_nlink;    newlib_uid_t     st_uid;    newlib_gid_t     st_gid;    newlib_dev_t     st_rdev;    newlib_off_t     st_size;    // We assume we've been compiled with the same flags as newlib here#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)    newlib_time_t    st_atime;    newlib_time_t    st_mtime;    newlib_time_t    st_ctime;#else    newlib_time_t    st_atime;    newlib_long_t    st_spare1;    newlib_time_t    st_mtime;    newlib_long_t    st_spare2;    newlib_time_t    st_ctime;    newlib_long_t    st_spare3;    newlib_long_t    st_blksize;    newlib_long_t    st_blocks;    newlib_long_t    st_spare4[2];#endif};#define NEWLIB_S_IFCHR 0020000 // character special filestatic inline char __getc(void){    char c;    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();        if (__chan)        c = CYGACC_COMM_IF_GETC(*__chan);    else {        __chan = CYGACC_CALL_IF_DEBUG_PROCS();        c = CYGACC_COMM_IF_GETC(*__chan);    }    return c;}static inline void __putc(char c){    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();    if (__chan)        CYGACC_COMM_IF_PUTC(*__chan, c);    else {        __chan = CYGACC_CALL_IF_DEBUG_PROCS();        CYGACC_COMM_IF_PUTC(*__chan, c);    }}static inline void __flush(void){    hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();    if (__chan == NULL)        __chan = CYGACC_CALL_IF_DEBUG_PROCS();    CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_FLUSH_OUTPUT);}// Timer supportstatic cyg_handle_t  sys_timer_handle;static cyg_interrupt sys_timer_interrupt;static cyg_uint64    sys_timer_ticks = 0;#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROFstatic unsigned int set_period = CYGNUM_HAL_RTC_PERIOD; // The defaulttypedef void *callback_func( char *pc, char *sp );static callback_func *timer_callback = 0;#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROFstatic voidsys_timer_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    // do nothing}static cyg_uint32sys_timer_isr(cyg_vector_t vector, cyg_addrword_t data){    ++sys_timer_ticks;#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF    HAL_CLOCK_RESET(CYGNUM_HAL_INTERRUPT_RTC, set_period);#else    HAL_CLOCK_RESET(CYGNUM_HAL_INTERRUPT_RTC, CYGNUM_HAL_RTC_PERIOD);#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_RTC);#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF    if ( timer_callback ) {        char *intrpc = (char *)0;        char *intrsp = (char *)0;        // There may be a number of ways to get the PC and (optional) SP        // information out of the HAL.  Hence this is conditioned.  In some        // configurations, a register-set pointer is available as        // (invisible) argument 3 to this ISR call.#ifdef HAL_GET_PROFILE_INFO        HAL_GET_PROFILE_INFO( intrpc, intrsp );#endif // HAL_GET_PROFILE_INFO available        CYGARC_HAL_SAVE_GP();        timer_callback( intrpc, intrsp );        CYGARC_HAL_RESTORE_GP();    }#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF    return CYG_ISR_HANDLED;}static void sys_timer_init(void){#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF    HAL_CLOCK_INITIALIZE(set_period);#else    HAL_CLOCK_INITIALIZE(CYGNUM_HAL_RTC_PERIOD);#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF        cyg_drv_interrupt_create(        CYGNUM_HAL_INTERRUPT_RTC,        0,                      // Priority - unused        (CYG_ADDRWORD)0,        // Data item passed to ISR & DSR        sys_timer_isr,          // ISR        sys_timer_dsr,          // DSR        &sys_timer_handle,      // handle to intr obj        &sys_timer_interrupt ); // space for int obj    cyg_drv_interrupt_attach(sys_timer_handle);    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_RTC);}//// read  -- read bytes from the serial port. Ignore fd, since//          we only have stdin.static intsys_read(int fd, char *buf, int nbytes){    int i = 0;    for (i = 0; i < nbytes; i++) {        *(buf + i) = __getc();        if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {            (*(buf + i + 1)) = 0;            break;        }    }    return (i);}//// write -- write bytes to the serial port. Ignore fd, since//          stdout and stderr are the same. Since we have no filesystem,//          open will only return an error.//static intsys_write(int fd, char *buf, int nbytes){#define WBUFSIZE  256    int  tosend;    tosend = nbytes;    while (tosend > 0) {        if (*buf == '\n')            __putc('\r');        __putc(*buf++);        tosend--;    }    __flush();    return (nbytes);}//// open -- open a file descriptor. We don't have a filesystem, so//         we return an error.//static intsys_open (const char *buf, int flags, int mode){    return (-NEWLIB_EIO);}//// close -- We don't need to do anything, but pretend we did.//static intsys_close(int fd){    return (0);}//// lseek --  Since a serial port is non-seekable, we return an error.//static intsys_lseek(int fd,  int offset, int whence){    return (-NEWLIB_EIO);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?