/* 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;
}
Exemplo n.º 2
0
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;
}