📄 synth_intr.c
字号:
// 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 + -