/* call routine */ int fn_call(void *pvHandle, unsigned long ulNetxAddress, unsigned long ulParameterR0, lua_State *L, int iLuaCallbackTag, void *pvCallbackUserData) { command_context_t *cmd_ctx; int iOocdResult; int iResult; wxString strCmd; target_t *target; bool fIsRunning; enum target_state state; /* cast the handle to the command context */ cmd_ctx = (command_context_t*)pvHandle; // expect failure iResult = 1; // set R0 parameter strCmd.Printf(wxT("reg r0 0x%08X"), ulParameterR0); iOocdResult = command_run_line(cmd_ctx, strCmd.ToAscii()); if( iOocdResult!=ERROR_OK ) { wxLogError(wxT("config failed!")); } else { // resume <ulNetxAddress> strCmd.Printf(wxT("resume 0x%08X"), ulNetxAddress); iOocdResult = command_run_line(cmd_ctx, strCmd.ToAscii()); if( iOocdResult!=ERROR_OK ) { wxLogError(wxT("config failed!")); } else { // grab messages here // TODO: redirect outputhandler, then grab messages, restore default output handler on halt // wait for halt target = get_current_target(cmd_ctx); do { wxMilliSleep(100); target->type->poll(target); state = target->state; if( state==TARGET_HALTED ) { wxLogMessage(wxT("call finished!")); iResult = 0; } else { // execute callback fIsRunning = callback(L, iLuaCallbackTag, 0, pvCallbackUserData); if( fIsRunning!=true ) { // operation was canceled, halt the target wxLogMessage(wxT("Call canceled, stopping target...")); target = get_current_target(cmd_ctx); iOocdResult = target->type->halt(target); if( iOocdResult!=ERROR_OK && iOocdResult!=ERROR_TARGET_ALREADY_HALTED ) { wxLogError(wxT("Failed to halt target!")); } break; } else { target_call_timer_callbacks(); } } } while( state!=TARGET_HALTED ); // usb cmd delay wxMilliSleep(1); } } return iResult; }
int server_loop(struct command_context *command_context) { struct service *service; bool poll_ok = true; /* used in select() */ fd_set read_fds; int fd_max; /* used in accept() */ int retval; #ifndef _WIN32 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) LOG_ERROR("couldn't set SIGPIPE to SIG_IGN"); #endif while (!shutdown_openocd) { /* monitor sockets for activity */ fd_max = 0; FD_ZERO(&read_fds); /* add service and connection fds to read_fds */ for (service = services; service; service = service->next) { if (service->fd != -1) { /* listen for new connections */ FD_SET(service->fd, &read_fds); if (service->fd > fd_max) fd_max = service->fd; } if (service->connections) { struct connection *c; for (c = service->connections; c; c = c->next) { /* check for activity on the connection */ FD_SET(c->fd, &read_fds); if (c->fd > fd_max) fd_max = c->fd; } } } struct timeval tv; tv.tv_sec = 0; if (poll_ok) { /* we're just polling this iteration, this is faster on embedded * hosts */ tv.tv_usec = 0; retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); } else { /* Every 100ms */ tv.tv_usec = 100000; /* Only while we're sleeping we'll let others run */ openocd_sleep_prelude(); kept_alive(); retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); openocd_sleep_postlude(); } if (retval == -1) { #ifdef _WIN32 errno = WSAGetLastError(); if (errno == WSAEINTR) FD_ZERO(&read_fds); else { LOG_ERROR("error during select: %s", strerror(errno)); exit(-1); } #else if (errno == EINTR) FD_ZERO(&read_fds); else { LOG_ERROR("error during select: %s", strerror(errno)); exit(-1); } #endif } if (retval == 0) { /* We only execute these callbacks when there was nothing to do or we timed *out */ target_call_timer_callbacks(); process_jim_events(command_context); FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */ /* We timed out/there was nothing to do, timeout rather than poll next time **/ poll_ok = false; } else { /* There was something to do, next time we'll just poll */ poll_ok = true; } /* This is a simple back-off algorithm where we immediately * re-poll if we did something this time around. * * This greatly improves performance of DCC. */ poll_ok = poll_ok || target_got_message(); for (service = services; service; service = service->next) { /* handle new connections on listeners */ if ((service->fd != -1) && (FD_ISSET(service->fd, &read_fds))) { if (service->max_connections > 0) add_connection(service, command_context); else { if (service->type == CONNECTION_TCP) { struct sockaddr_in sin; socklen_t address_size = sizeof(sin); int tmp_fd; tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size); close_socket(tmp_fd); } LOG_INFO( "rejected '%s' connection, no more connections allowed", service->name); } } /* handle activity on connections */ if (service->connections) { struct connection *c; for (c = service->connections; c; ) { if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending) { retval = service->input(c); if (retval != ERROR_OK) { struct connection *next = c->next; if (service->type == CONNECTION_PIPE) { /* if connection uses a pipe then *shutdown openocd on error */ shutdown_openocd = 1; } remove_connection(service, c); LOG_INFO("dropped '%s' connection", service->name); c = next; continue; } } c = c->next; } } } #ifdef _WIN32 MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) shutdown_openocd = 1; } #endif } return ERROR_OK; }
static int romloader_openocd_connect(command_context_t **pptCmdCtx) { int iResult; command_context_t *cmd_ctx; target_t *target; wxString strCmd; wxString strMsg; size_t sizCfgCnt; size_t sizCfgMax; int iInitCnt; cmd_ctx = command_init(); /* register subsystem commands */ log_register_commands(cmd_ctx); jtag_register_commands(cmd_ctx); interpreter_register_commands(cmd_ctx); xsvf_register_commands(cmd_ctx); target_register_commands(cmd_ctx); /* init the log functions */ iResult = log_init(cmd_ctx); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to init log level: %d"), iResult); wxLogError(strMsg); } else { command_set_output_handler(cmd_ctx, romloader_openocd_default_output_handler, NULL); log_set_output_handler(romloader_openocd_log_printf, romloader_openocd_short_log_printf); cmd_ctx->mode = COMMAND_CONFIG; // set config sizCfgCnt = 0; sizCfgMax = astrInitCfg.GetCount(); while( sizCfgCnt<sizCfgMax ) { strCmd = astrInitCfg.Item(sizCfgCnt); wxLogMessage(wxT("command: ") + strCmd); iResult = command_run_line(cmd_ctx, strCmd.ToAscii()); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to set config: %d"), iResult); wxLogError(strMsg); strMsg = wxT("error line was: '") + strCmd + wxT("'"); wxLogError(strMsg); break; } ++sizCfgCnt; } if( iResult==ERROR_OK ) { cmd_ctx->mode = COMMAND_EXEC; iResult = jtag_init(cmd_ctx); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to init jtag: %d"), iResult); wxLogError(strMsg); } else { iResult = target_init(cmd_ctx); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to init jtag: %d"), iResult); wxLogError(strMsg); } else { wxMilliSleep(500); /* wait for target reset */ iInitCnt = 10; do { target_call_timer_callbacks(); wxMilliSleep(100); } while( --iInitCnt>0 ); target = get_current_target(cmd_ctx); if( target->state!=TARGET_HALTED ) { wxLogError(wxT("failed to halt the target")); iResult = ERROR_TARGET_NOT_HALTED; } else { // set config sizCfgCnt = 0; sizCfgMax = astrRunCfg.GetCount(); while( sizCfgCnt<sizCfgMax ) { strCmd = astrRunCfg.Item(sizCfgCnt); wxLogMessage(wxT("command: ") + strCmd); iResult = command_run_line(cmd_ctx, strCmd.ToAscii()); if( iResult!=ERROR_OK ) { strMsg.Printf(wxT("failed to run command: %d"), iResult); wxLogError(strMsg); strMsg = wxT("error line was: '") + strCmd + wxT("'"); wxLogError(strMsg); break; } ++sizCfgCnt; } if( iResult!=ERROR_OK ) { wxLogError(wxT("config failed!")); } } } } } } if( iResult!=ERROR_OK ) { // close connection romloader_openocd_close_instance(cmd_ctx); *pptCmdCtx = NULL; } else { // connection open, ok! *pptCmdCtx = cmd_ctx; } return iResult; }