⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 synth_intr.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
// particular package.
int
synth_auxiliary_instantiate(const char* pkg, const char* version, const char* devtype, const char* devinst, const char* devdata)
{
    int           result = -1;
    unsigned char buf[512 + 1];
    const char*   str;
    int           index;

    CYG_ASSERT((const char*)0 != devtype, "Device instantiations must specify a valid device type");
    CYG_ASSERT((((const char*)0 != pkg) && ((const char*)0 != version)) || \
               (((const char*)0 == pkg) && ((const char*)0 == version)), "If a package is specified then the version must be supplied as well");
    
    index = 0;
    str = pkg;
    if ((const char*)0 == str) {
        str = "";
    }
    while ( (index < 512) && ('\0' != *str) ) {
        buf[index++] = *str++;
    }
    if (index < 512) buf[index++] = '\0';
    str = version;
    if ((const char*)0 == str) {
        str = "";
    }
    while ((index < 512) && ('\0' != *str) ) {
        buf[index++] = *str++;
    }
    if (index < 512) buf[index++] = '\0';
    for (str = devtype; (index < 512) && ('\0' != *str); ) {
        buf[index++] = *str++;
    }
    if (index < 512) buf[index++] = '\0';
    if ((const char*)0 != devinst) {
        for (str = devinst; (index < 512) && ('\0' != *str); ) {
            buf[index++] = *str++;
        }
    }
    if (index < 512) buf[index++] = '\0';
    if ((const char*)0 != devdata) {
        for (str = devdata; (index < 512) && ('\0' != *str); ) {
            buf[index++] = *str++;
        }
    }
    if (index < 512) {
        buf[index++] = '\0';
    } else {
        diag_printf("Internal error: buffer overflow constructing instantiate request for auxiliary.\n");
        diag_printf("              : this application is exiting immediately.\n");
        cyg_hal_sys_exit(1);
    }

    if (synth_auxiliary_running) {
        synth_auxiliary_xchgmsg(SYNTH_DEV_AUXILIARY, SYNTH_AUXREQ_INSTANTIATE, 0, 0,
                                buf, index,
                                &result, 
                                (unsigned char*) 0, (int *) 0, 0);
    }
    return result;
}

// ----------------------------------------------------------------------------
// SIGPIPE and SIGCHLD are special, related to the auxiliary process.
//
// A SIGPIPE can only happen when the application is writing to the
// auxiliary, which only happens inside synth_auxiliary_xchgmsg() (this
// assumes that no other code is writing down a pipe, e.g. to interact
// with a process other than the standard I/O auxiliary). Either the
// auxiliary has explicitly closed the pipe, which it is not supposed
// to do, or more likely it has exited. Either way, there is little
// point in continuing - unless we already know that the system is
// shutting down.
static void
synth_pipe_sighandler(int sig)
{
    CYG_ASSERT(CYG_HAL_SYS_SIGPIPE == sig, "The right signal handler should be invoked");
    if (synth_auxiliary_running) {
        synth_auxiliary_running   = false;
        diag_printf("Internal error: communication with the I/O auxiliary has been lost.\n");
        diag_printf("              : this application is exiting immediately.\n");
        cyg_hal_sys_exit(1);
    }
}

// Similarly it is assumed that there will be no child processes other than
// the auxiliary. Therefore a SIGCHLD indicates that the auxiliary has
// terminated unexpectedly. This is bad: normal termination involves
// the application exiting and the auxiliary terminating in response,
// not the other way around.
//
// As a special case, if it is known that the auxiliary is not currently
// usable then the signal is ignored. This copes with the situation where
// the auxiliary has just been fork()'d but has failed to initialize, or
// alternatively where the whole system is in the process of shutting down
// cleanly and it happens that the auxiliary got there first.
static void
synth_chld_sighandler(int sig)
{
    CYG_ASSERT(CYG_HAL_SYS_SIGCHLD == sig, "The right signal handler should be invoked");
    if (synth_auxiliary_running) {
        synth_auxiliary_running   = false;
        diag_printf("Internal error: the I/O auxiliary has terminated unexpectedly.\n");
        diag_printf("              : this application is exiting immediately.\n");
        cyg_hal_sys_exit(1);
    }
}

// ----------------------------------------------------------------------------
// Initialization

void
synth_hardware_init(void)
{
    struct cyg_hal_sys_sigaction action;
    struct cyg_hal_sys_sigset_t  blocked;
    int i;

    // Set up a sigprocmask to block all signals except the ones we
    // particularly want to handle. However do not block the tty
    // signals - the ability to ctrl-C a program is important.
    CYG_HAL_SYS_SIGFILLSET(&blocked);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGILL);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGBUS);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGFPE);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGSEGV);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGPIPE);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGCHLD);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGALRM);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGIO);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGHUP);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGINT);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGQUIT);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGTERM);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGCONT);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGSTOP);
    CYG_HAL_SYS_SIGDELSET(&blocked, CYG_HAL_SYS_SIGTSTP);
        
    if (0 != cyg_hal_sys_sigprocmask(CYG_HAL_SYS_SIG_SETMASK, &blocked, (cyg_hal_sys_sigset_t*) 0)) {
        CYG_FAIL("Failed to initialize sigprocmask");
    }

    // Now set up the VSR and ISR statics
    synth_VSR = &synth_default_vsr;
    for (i = 0; i < CYGNUM_HAL_ISR_COUNT; i++) {
        synth_isr_handlers[i].isr       = &synth_default_isr;
        synth_isr_handlers[i].data      = (CYG_ADDRWORD) 0;
        synth_isr_handlers[i].obj       = (CYG_ADDRESS) 0;
        synth_isr_handlers[i].pri       = CYGNUM_HAL_ISR_COUNT;
    }

    // Install signal handlers for SIGIO and SIGALRM, the two signals
    // that may cause the VSR to run. SA_NODEFER is important: it
    // means that the current signal will not be blocked while the
    // signal handler is running. Combined with a mask of 0, it means
    // that the sigprocmask does not change when a signal handler is
    // invoked, giving eCos the flexibility to switch to other threads
    // instead of having the signal handler return immediately.
    action.hal_mask     = 0;
    action.hal_flags    = CYG_HAL_SYS_SA_NODEFER;
    action.hal_handler  = &synth_alrm_sighandler;
    action.hal_restorer = (void (*)(void)) 0;
#ifdef CYG_HAL_SYS_SIGACTION_ADJUST
    CYG_HAL_SYS_SIGACTION_ADJUST(CYG_HAL_SYS_SIGALRM, &action);
#endif    
    if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGALRM, &action, (struct cyg_hal_sys_sigaction*) 0)) {
        CYG_FAIL("Failed to install signal handler for SIGALRM");
    }
    action.hal_handler  = &synth_io_sighandler;
    if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGIO, &action, (struct cyg_hal_sys_sigaction*) 0)) {
        CYG_FAIL("Failed to install signal handler for SIGIO");
    }

    // Install handlers for the various exceptions. For now these also
    // operate with unchanged sigprocmasks, allowing nested
    // exceptions. It is not clear that this is entirely a good idea,
    // but in practice these exceptions will usually be handled by gdb
    // anyway.
    action.hal_handler  = &synth_exception_sighandler;
    if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGILL,  &action, (struct cyg_hal_sys_sigaction*) 0)) {
        CYG_FAIL("Failed to install signal handler for SIGILL");
    }
    if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGBUS,  &action, (struct cyg_hal_sys_sigaction*) 0)) {
        CYG_FAIL("Failed to install signal handler for SIGBUS");
    }
    if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGFPE,  &action, (struct cyg_hal_sys_sigaction*) 0)) {
        CYG_FAIL("Failed to install signal handler for SIGFPE");
    }
    if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGSEGV,  &action, (struct cyg_hal_sys_sigaction*) 0)) {
        CYG_FAIL("Failed to install signal handler for SIGSEGV");
    }

    // Also cope with SIGCHLD and SIGPIPE. SIGCHLD indicates that the
    // auxiliary has terminated, which is a bad thing. SIGPIPE
    // indicates that a write to the auxiliary has terminated, but
    // the error condition was caught at a different stage.
    action.hal_handler = &synth_pipe_sighandler;
    if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGPIPE,  &action, (struct cyg_hal_sys_sigaction*) 0)) {
        CYG_FAIL("Failed to install signal handler for SIGPIPE");
    }
    action.hal_handler = &synth_chld_sighandler;
    action.hal_flags  |= CYG_HAL_SYS_SA_NOCLDSTOP | CYG_HAL_SYS_SA_NOCLDWAIT;
    if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGCHLD,  &action, (struct cyg_hal_sys_sigaction*) 0)) {
        CYG_FAIL("Failed to install signal handler for SIGCHLD");
    }

    // Determine the processor's bogomips rating. This adds some
    // start-up overhead to all applications, even if HAL_DELAY_US()
    // is not used. However doing it on demand in the first call
    // to HAL_DELAY_US() would risk running out of file descriptors.
    {
        int     fd;
        char    buf[4096];      // much larger than current /proc/cpuinfo, but still small enough for synthetic target stacks
        int     read;
        int     i;

        fd  = cyg_hal_sys_open("/proc/cpuinfo", CYG_HAL_SYS_O_RDONLY, 0);
        if (fd < 0) {
            CYG_FAIL("Failed to open /proc/cpuinfo, needed for BogoMips rating");
        }
        read    = cyg_hal_sys_read(fd, buf, 4096);
        cyg_hal_sys_close(fd);

        for (i = 0; i < read; i++) {
            if ((buf[i  ] == 'b') && (buf[i+1] == 'o') && (buf[i+2] == 'g') && (buf[i+3] == 'o') &&
                (buf[i+4] == 'm') && (buf[i+5] == 'i') && (buf[i+6] == 'p') && (buf[i+7] == 's')) {

                for ( i += 8; (i < read) && ((buf[i] < '1') || (buf[i] > '9')); i++) {
                    ;
                }
                // Only bother with the integer part of the rating
                for ( ; (i < read) && (buf[i] >= '0') && (buf[i] <= '9'); i++) {
                    hal_bogomips = (10 * hal_bogomips) + (buf[i] - '0');
                }
                break;
            }
        }
        if (0 == hal_bogomips) {
            CYG_FAIL("Failed to find bogomips entry in /proc/cpuinfo");
        }
    }
    
    // Start up the auxiliary process.
    synth_start_auxiliary();
    
    // All done. At this stage interrupts are still disabled, no ISRs
    // have been installed, and the clock is not yet ticking.
    // Exceptions can come in and will be processed normally. SIGIO
    // and SIGALRM could come in, but nothing has yet been done
    // to make that happen.
}

// Second-stage hardware init. This is called after all C++ static
// constructors have been run, which should mean that all device
// drivers have been initialized and will have performed appropriate
// interactions with the I/O auxiliary. There should now be a
// message exchange with the auxiliary to let it know that there will
// not be any more devices, allowing it to remove unwanted frames,
// run the user's mainrc.tcl script, and so on. Also this is the
// time that the various toplevels get mapped on to the display.
//
// This request blocks until the auxiliary is ready. The return value
// indicates whether or not any errors occurred on the auxiliary side,
// and that those errors have not been suppressed using --keep-going

void
synth_hardware_init2(void)
{
    if (synth_auxiliary_running) {
        int result;
        synth_auxiliary_xchgmsg(SYNTH_DEV_AUXILIARY, SYNTH_AUXREQ_CONSTRUCTORS_DONE,
                               0, 0, (const unsigned char*) 0, 0,
                               &result,
                               (unsigned char*) 0, (int*) 0, 0);
        if ( !result ) {
            cyg_hal_sys_exit(1);
        }
    }
}

⌨️ 快捷键说明

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