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

📄 synth_intr.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 4 页
字号:
        request[SYNTH_REQUEST_TXLEN_OFFSET + 1]     = (txlen >>  8) & 0x0FF;        request[SYNTH_REQUEST_TXLEN_OFFSET + 2]     = (txlen >> 16) & 0x0FF;        request[SYNTH_REQUEST_TXLEN_OFFSET + 3]     = (txlen >> 24) & 0x0FF;        request[SYNTH_REQUEST_RXLEN_OFFSET + 0]     = (rxlen >>  0) & 0x0FF;        request[SYNTH_REQUEST_RXLEN_OFFSET + 1]     = (rxlen >>  8) & 0x0FF;        request[SYNTH_REQUEST_RXLEN_OFFSET + 2]     = (rxlen >> 16) & 0x0FF;        request[SYNTH_REQUEST_RXLEN_OFFSET + 3]     = ((rxlen >> 24) & 0x0FF) | (((int*)0 != result) ? 0x080 : 0);        // sizeof(synth_auxiliary_request) < PIPE_BUF (4096) so a single write should be atomic,        // subject only to incoming clock or SIGIO or child-related signals.        do {            rc = cyg_hal_sys_write(to_aux, (const void*) &request, SYNTH_REQUEST_LENGTH);        } while (-CYG_HAL_SYS_EINTR == rc);        // Is there any more data to be sent?        if (0 < txlen) {            int sent    = 0;            CYG_LOOP_INVARIANT(synth_auxiliary_running, "The auxiliary cannot just disappear");                    while (sent < txlen) {                rc = cyg_hal_sys_write(to_aux, (const void*) &(txdata[sent]), txlen - sent);                if (-CYG_HAL_SYS_EINTR == rc) {                    continue;                } else if (rc < 0) {                    diag_printf("Internal error: unexpected result %d when sending buffer to auxiliary.\n", rc);                    diag_printf("              : this application is exiting immediately.\n");                    cyg_hal_sys_exit(1);                } else {                    sent += rc;                }            }            CYG_ASSERT(sent <= txlen, "Amount of data sent should not exceed requested size");        }        // The auxiliary can now process this entire request. Is a reply expected?        if ((int*)0 != result) {            // The basic reply is also only a small number of bytes, so should be atomic.            do {                rc = cyg_hal_sys_read(from_aux, (void*) &reply, SYNTH_REPLY_LENGTH);            } while (-CYG_HAL_SYS_EINTR == rc);            if (rc <= 0) {                if (rc < 0) {                    diag_printf("Internal error: unexpected result %d when receiving data from auxiliary.\n", rc);                } else {                    diag_printf("Internal error: EOF detected on pipe from auxiliary.\n");                }                diag_printf("              : this application is exiting immediately.\n");                cyg_hal_sys_exit(1);            }            CYG_ASSERT(SYNTH_REPLY_LENGTH == rc, "The correct amount of data should have been read");            // Replies are packed in Tcl and assumed to be two 32-bit            // little-endian integers.            *result   = (reply[SYNTH_REPLY_RESULT_OFFSET + 3] << 24) |                (reply[SYNTH_REPLY_RESULT_OFFSET + 2] << 16) |                (reply[SYNTH_REPLY_RESULT_OFFSET + 1] <<  8) |                (reply[SYNTH_REPLY_RESULT_OFFSET + 0] <<  0);            reply_rxlen = (reply[SYNTH_REPLY_RXLEN_OFFSET + 3] << 24) |                (reply[SYNTH_REPLY_RXLEN_OFFSET + 2] << 16) |                (reply[SYNTH_REPLY_RXLEN_OFFSET + 1] <<  8) |                (reply[SYNTH_REPLY_RXLEN_OFFSET + 0] <<  0);                    CYG_ASSERT(reply_rxlen <= rxlen, "The auxiliary should not be sending more data than was requested.");                    if ((int*)0 != actual_rxlen) {                *actual_rxlen  = reply_rxlen;            }            if (reply_rxlen) {                int received = 0;                            while (received < reply_rxlen) {                    rc = cyg_hal_sys_read(from_aux, (void*) &(rxdata[received]), reply_rxlen - received);                    if (-CYG_HAL_SYS_EINTR == rc) {                        continue;                    } else if (rc <= 0) {                        if (rc < 0) {                            diag_printf("Internal error: unexpected result %d when receiving data from auxiliary.\n", rc);                        } else {                            diag_printf("Internal error: EOF detected on pipe from auxiliary.\n");                        }                        diag_printf("              : this application is exiting immediately.\n");                    } else {                        received += rc;                    }                }                CYG_ASSERT(received == reply_rxlen, "Amount received should be exact");            }        }    }    HAL_RESTORE_INTERRUPTS(old_isrstate);}// Instantiate a device. This takes arguments such as// devs/eth/synth/ecosynth, current, ethernet, eth0, and 200x100 If// the package and version are NULL strings then the device being// initialized is application-specific and does not belong to any// particular package.intsynth_auxiliary_instantiate(const char* pkg, const char* version, const char* devtype, const char* devinst, const char* devdata){    int         result = -1;    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 voidsynth_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 voidsynth_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);    }}// ----------------------------------------------------------------------------// Initializationvoidsynth_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_bogus    = (void (*)(int)) 0;    action.hal_handler  = &synth_alrm_sighandler;    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");    }    // 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-goingvoidsynth_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 + -