syscall.c

来自「eCos操作系统源码」· C语言 代码 · 共 656 行 · 第 1/2 页

C
656
字号
#define TICKS_PER_SEC  (1000000000ULL / NS_PER_TICK)// This needs to match newlib HZ which is normally 60.#define HZ (60ULL)#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROFstatic unsigned int set_freq   = TICKS_PER_SEC; // The default#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROFstatic intsys_times(unsigned long *p){    static int inited = 0;    if (!inited) {        inited = 1;        sys_timer_init();    }    /* target clock runs at CLOCKS_PER_SEC. Convert to HZ */    if (p)#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF        *p = (sys_timer_ticks * HZ) / (cyg_uint64)set_freq;#else        *p = (sys_timer_ticks * HZ) / TICKS_PER_SEC;#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF    return 0;}#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROFstatic void sys_profile_call_back( char *func, char **previous_call_back ){    if ( previous_call_back )        *previous_call_back = (char *)timer_callback;    timer_callback = (callback_func *)func;    // Ensure the timer is started    (void)sys_times( (unsigned long *)0 );} static void sys_profile_frequency( int freq, int *previous_freq ){// Requested HZ:// 0         => tell me the current value (no change, IMPLEMENTED HERE)// - 1       => tell me the slowest (no change)// - 2       => tell me the default (no change, IMPLEMENTED HERE)// -nnn      => tell me what you would choose for nnn (no change)// MIN_INT   => tell me the fastest (no change)//        // 1         => tell me the slowest (sets the clock)// MAX_INT   => tell me the fastest (sets the clock)    // Ensure the timer is started    (void)sys_times( (unsigned long *)0 );    if ( -2 == freq )        freq = TICKS_PER_SEC; // default value    else if ( 0 == freq )        freq = set_freq; // collect current value    else {        int do_set_freq = (freq > 0);        unsigned int period = CYGNUM_HAL_RTC_PERIOD;        if ( 0 == (freq ^ -freq) ) // Then it's MIN_INT in local size            freq++; // just so that it will negate correctly        // Then set the timer to that fast - or pass on the enquiry#ifdef HAL_CLOCK_REINITIALIZE        // Give the HAL enough info to do the division sum relative to        // the default setup, in period and TICKS_PER_SEC.        HAL_CLOCK_REINITIALIZE( freq, period, TICKS_PER_SEC );#else        freq = TICKS_PER_SEC; // the only choice#endif        if ( do_set_freq ) { // update the global variables            unsigned int orig = set_freq;            set_freq = freq;            set_period = period;            // We must "correct" sys_timer_ticks for the new scale factor.            sys_timer_ticks = sys_timer_ticks * set_freq / orig;        }    }    if ( previous_freq ) // Return the current value (new value)        *previous_freq = freq;}void sys_profile_reset( void ){    timer_callback = NULL;// Want to preserve the frequency between runs, for clever GDB users!//    sys_profile_frequency( TICKS_PER_SEC, NULL );}#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF////  Generic syscall handler.////  Returns 0 if syscall number is not handled by this//  module, 1 otherwise. This allows applications to//  extend the syscall handler by using exception chaining.//CYG_ADDRWORD__do_syscall(CYG_ADDRWORD func,                 // syscall function number             CYG_ADDRWORD arg1, CYG_ADDRWORD arg2,      // up to four args.             CYG_ADDRWORD arg3, CYG_ADDRWORD arg4,             CYG_ADDRWORD *retval, CYG_ADDRWORD *sig)   // syscall return value{    int err = 0;    *sig = 0;    switch (func) {      case SYS_open:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_open( const char *name, int flags,                                                 int mode, int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_open((const char *)arg1, (int)arg2, (int)arg3,					   (int *)sig);	  else#endif	      err = sys_open((const char *)arg1, (int)arg2, (int)arg3);          break;      }      case SYS_read:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_read( int fd, void *buf, size_t count,                                                int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_read((int)arg1, (void *)arg2, (size_t)arg3,					   (int *)sig);	  else#endif	      err = sys_read((int)arg1, (char *)arg2, (int)arg3);          break;      }      case SYS_write:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_write( int fd, const void *buf,                                                 size_t count, int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_write((int)arg1, (const void *)arg2,					    (size_t)arg3, (int *)sig);	  else#endif	      err = sys_write((int)arg1, (char *)arg2, (int)arg3);          break;      }      case SYS_close:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_close( int fd, int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_close((int)arg1, (int *)sig);	  else#endif	      err = sys_close((int)arg1);          break;      }      case SYS_lseek:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_lseek( int fd, long offset,                                                 int whence, int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_lseek((int)arg1, (long)arg2, (int)arg3,					    (int *)sig);	  else#endif	      err = sys_lseek((int)arg1, (int)arg2, (int)arg3);          break;      }      case SYS_stat:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_stat( const char *pathname,                                                void *statbuf, int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_stat((const char *)arg1, (void *)arg2,					   (int *)sig);	  else#endif	      err = -NEWLIB_ENOSYS;          break;      }      case SYS_fstat:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_fstat( int fd, void *statbuf,                                                 int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_fstat((int)arg1, (void *)arg2,					    (int *)sig);	  else#endif	  {	      struct newlib_stat *st = (struct newlib_stat *)arg2;	      st->st_mode = NEWLIB_S_IFCHR;	      st->st_blksize = 4096;	      err = 0;	  }          break;      }      case SYS_rename:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_rename( const char *oldpath,                                                  const char *newpath,                                                  int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_rename((const char *)arg1, (const char *)arg2,					     (int *)sig);	  else#endif	      err = -NEWLIB_ENOSYS;          break;      }      case SYS_unlink:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_unlink( const char *pathname,                                                  int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_unlink((const char *)arg1, (int *)sig);	  else#endif	      err = -NEWLIB_ENOSYS;          break;      }      case SYS_isatty:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_isatty( int fd, int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_isatty((int)arg1, (int *)sig);	  else#endif	      err = 1;          break;      }      case SYS_system:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_system( const char *command,                                                  int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_system((const char *)arg1, (int *)sig);	  else#endif	      err = -1;          break;      }      case SYS_gettimeofday:      {#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol          __externC int cyg_hal_gdbfileio_gettimeofday( void *tv, void *tz,                                                        int *sig );	  if (gdb_active)	      err = cyg_hal_gdbfileio_gettimeofday((void *)arg1, (void *)arg2,						   (int *)sig);	  else#endif	      err = 0;          break;      }      case SYS_utime:        // FIXME. Some libglosses depend on this behavior.        err = sys_times((unsigned long *)arg1);        break;      case SYS_times:        err = sys_times((unsigned long *)arg1);        break;      case SYS_meminfo:        err = 1;        *(unsigned long *)arg1 = (unsigned long)(ram_end-ram_start);        *(unsigned long *)arg2 = (unsigned long)ram_end;        break;#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF    case SYS_timer_call_back:        sys_profile_call_back( (char *)arg1, (char **)arg2 );        break;    case SYS_timer_frequency:        sys_profile_frequency( (int)arg1, (unsigned int *)arg2 );        break;    case SYS_timer_reset:        sys_profile_reset();        break;#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF      case __GET_SHARED:        *(__shared_t **)arg1 = &__shared_data;        break;      case SYS_exit:	*sig = -1;    // signal exit	err = arg1;	if (gdb_active) {#ifdef CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP	    __send_exit_status((int)arg1);#else	    *sig = SIGTRAP;	    err = func;#endif // CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP	}	break;      default:        return 0;    }        *retval = err;    return 1;}#endif

⌨️ 快捷键说明

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