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 + -
显示快捷键?