[Debugger] Implementation of transport over serial connection (#2800)
JerryScript-DCO-1.0-Signed-off-by: Robert Sipka rsipka.uszeged@partner.samsung.com
This commit is contained in:
+5
-3
@@ -68,9 +68,11 @@ When using the extension-provided WebSocket transport layer, the
|
|||||||
debugger can be enabled by calling `jerryx_debugger_after_connect
|
debugger can be enabled by calling `jerryx_debugger_after_connect
|
||||||
(jerryx_debugger_tcp_create (debug_port) && jerryx_debugger_ws_create ())`
|
(jerryx_debugger_tcp_create (debug_port) && jerryx_debugger_ws_create ())`
|
||||||
after the `jerry_init ()` function. It initializes the debugger and
|
after the `jerry_init ()` function. It initializes the debugger and
|
||||||
blocks until a client connects. (Custom transport layers may be
|
blocks until a client connects.
|
||||||
implemented and initialized similarly. Currently, `jerryx_debugger_rp_create()` for
|
(Custom transport layers may be implemented and initialized similarly.
|
||||||
raw packet transport layer is also available.)
|
Currently, `jerryx_debugger_rp_create ()` for raw packet transport layer and
|
||||||
|
`jerryx_debugger_serial_create (const char* config)` for serial protocol
|
||||||
|
are also available.)
|
||||||
|
|
||||||
The resource name provided to `jerry_parse ()` is used by the client
|
The resource name provided to `jerry_parse ()` is used by the client
|
||||||
to identify the resource name of the source code. This resource name
|
to identify the resource name of the source code. This resource name
|
||||||
|
|||||||
@@ -193,6 +193,8 @@ jerry_cleanup (void)
|
|||||||
#ifdef JERRY_DEBUGGER
|
#ifdef JERRY_DEBUGGER
|
||||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||||
{
|
{
|
||||||
|
jerry_debugger_send_type (JERRY_DEBUGGER_CLOSE_CONNECTION);
|
||||||
|
|
||||||
jerry_debugger_transport_close ();
|
jerry_debugger_transport_close ();
|
||||||
}
|
}
|
||||||
#endif /* JERRY_DEBUGGER */
|
#endif /* JERRY_DEBUGGER */
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ typedef struct
|
|||||||
* The number of message types in the debugger should reflect the
|
* The number of message types in the debugger should reflect the
|
||||||
* debugger versioning.
|
* debugger versioning.
|
||||||
*/
|
*/
|
||||||
JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 32
|
JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 33
|
||||||
&& JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 21
|
&& JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 21
|
||||||
&& JERRY_DEBUGGER_VERSION == 8,
|
&& JERRY_DEBUGGER_VERSION == 9,
|
||||||
debugger_version_correlates_to_message_type_count);
|
debugger_version_correlates_to_message_type_count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ typedef enum
|
|||||||
JERRY_DEBUGGER_SCOPE_CHAIN_END = 29, /**< last output of scope chain */
|
JERRY_DEBUGGER_SCOPE_CHAIN_END = 29, /**< last output of scope chain */
|
||||||
JERRY_DEBUGGER_SCOPE_VARIABLES = 30, /**< scope variables */
|
JERRY_DEBUGGER_SCOPE_VARIABLES = 30, /**< scope variables */
|
||||||
JERRY_DEBUGGER_SCOPE_VARIABLES_END = 31, /**< last output of scope variables */
|
JERRY_DEBUGGER_SCOPE_VARIABLES_END = 31, /**< last output of scope variables */
|
||||||
|
JERRY_DEBUGGER_CLOSE_CONNECTION = 32, /**< close connection with the client */
|
||||||
JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */
|
JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */
|
||||||
|
|
||||||
/* Messages sent by the client to server. */
|
/* Messages sent by the client to server. */
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ extern "C"
|
|||||||
/**
|
/**
|
||||||
* JerryScript debugger protocol version.
|
* JerryScript debugger protocol version.
|
||||||
*/
|
*/
|
||||||
#define JERRY_DEBUGGER_VERSION (8)
|
#define JERRY_DEBUGGER_VERSION (9)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types for the client source wait and run method.
|
* Types for the client source wait and run method.
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ import logging
|
|||||||
import time
|
import time
|
||||||
import jerry_client_main
|
import jerry_client_main
|
||||||
|
|
||||||
|
from jerry_client_websocket import WebSocket
|
||||||
|
from jerry_client_rawpacket import RawPacket
|
||||||
|
from jerry_client_tcp import Socket
|
||||||
|
from jerry_client_serial import Serial
|
||||||
|
|
||||||
def write(string):
|
def write(string):
|
||||||
print(string, end='')
|
print(string, end='')
|
||||||
|
|
||||||
@@ -246,14 +251,40 @@ def src_check_args(args):
|
|||||||
print("Error: Non-negative integer number expected: %s" % (val_errno))
|
print("Error: Non-negative integer number expected: %s" % (val_errno))
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
# pylint: disable=too-many-branches,too-many-locals,too-many-statements
|
# pylint: disable=too-many-branches,too-many-locals,too-many-statements,redefined-variable-type
|
||||||
def main():
|
def main():
|
||||||
args = jerry_client_main.arguments_parse()
|
args = jerry_client_main.arguments_parse()
|
||||||
|
|
||||||
debugger = jerry_client_main.JerryDebugger(args.address, args.channel)
|
channel = None
|
||||||
|
protocol = None
|
||||||
|
|
||||||
|
if args.protocol == "tcp":
|
||||||
|
address = None
|
||||||
|
if ":" not in args.address:
|
||||||
|
address = (args.address, 5001) # use default port
|
||||||
|
else:
|
||||||
|
host, port = args.address.split(":")
|
||||||
|
address = (host, int(port))
|
||||||
|
|
||||||
|
protocol = Socket(address)
|
||||||
|
elif args.protocol == "serial":
|
||||||
|
protocol = Serial(args.serial_config)
|
||||||
|
else:
|
||||||
|
print("Unsupported transmission protocol")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
if args.channel == "websocket":
|
||||||
|
channel = WebSocket(protocol=protocol)
|
||||||
|
elif args.channel == "rawpacket":
|
||||||
|
channel = RawPacket(protocol=protocol)
|
||||||
|
else:
|
||||||
|
print("Unsupported communication channel")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
debugger = jerry_client_main.JerryDebugger(channel)
|
||||||
debugger.non_interactive = args.non_interactive
|
debugger.non_interactive = args.non_interactive
|
||||||
|
|
||||||
logging.debug("Connected to JerryScript on %d port", debugger.port)
|
logging.debug("Connected to JerryScript")
|
||||||
|
|
||||||
prompt = DebuggerPrompt(debugger)
|
prompt = DebuggerPrompt(debugger)
|
||||||
prompt.prompt = "(jerry-debugger) "
|
prompt.prompt = "(jerry-debugger) "
|
||||||
|
|||||||
@@ -21,12 +21,9 @@ import re
|
|||||||
import select
|
import select
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
from jerry_client_websocket import WebSocket
|
|
||||||
from jerry_client_rawpacket import RawPacket
|
|
||||||
from jerry_client_tcp import Socket
|
|
||||||
|
|
||||||
# Expected debugger protocol version.
|
# Expected debugger protocol version.
|
||||||
JERRY_DEBUGGER_VERSION = 8
|
JERRY_DEBUGGER_VERSION = 9
|
||||||
|
|
||||||
# Messages sent by the server to client.
|
# Messages sent by the server to client.
|
||||||
JERRY_DEBUGGER_CONFIGURATION = 1
|
JERRY_DEBUGGER_CONFIGURATION = 1
|
||||||
@@ -60,6 +57,7 @@ JERRY_DEBUGGER_SCOPE_CHAIN = 28
|
|||||||
JERRY_DEBUGGER_SCOPE_CHAIN_END = 29
|
JERRY_DEBUGGER_SCOPE_CHAIN_END = 29
|
||||||
JERRY_DEBUGGER_SCOPE_VARIABLES = 30
|
JERRY_DEBUGGER_SCOPE_VARIABLES = 30
|
||||||
JERRY_DEBUGGER_SCOPE_VARIABLES_END = 31
|
JERRY_DEBUGGER_SCOPE_VARIABLES_END = 31
|
||||||
|
JERRY_DEBUGGER_CLOSE_CONNECTION = 32
|
||||||
|
|
||||||
# Debugger option flags
|
# Debugger option flags
|
||||||
JERRY_DEBUGGER_LITTLE_ENDIAN = 0x1
|
JERRY_DEBUGGER_LITTLE_ENDIAN = 0x1
|
||||||
@@ -123,7 +121,7 @@ def arguments_parse():
|
|||||||
parser = argparse.ArgumentParser(description="JerryScript debugger client")
|
parser = argparse.ArgumentParser(description="JerryScript debugger client")
|
||||||
|
|
||||||
parser.add_argument("address", action="store", nargs="?", default="localhost:5001",
|
parser.add_argument("address", action="store", nargs="?", default="localhost:5001",
|
||||||
help="specify a unique network address for connection (default: %(default)s)")
|
help="specify a unique network address for tcp connection (default: %(default)s)")
|
||||||
parser.add_argument("-v", "--verbose", action="store_true", default=False,
|
parser.add_argument("-v", "--verbose", action="store_true", default=False,
|
||||||
help="increase verbosity (default: %(default)s)")
|
help="increase verbosity (default: %(default)s)")
|
||||||
parser.add_argument("--non-interactive", action="store_true", default=False,
|
parser.add_argument("--non-interactive", action="store_true", default=False,
|
||||||
@@ -138,6 +136,10 @@ def arguments_parse():
|
|||||||
help="specify a javascript source file to execute")
|
help="specify a javascript source file to execute")
|
||||||
parser.add_argument("--channel", choices=["websocket", "rawpacket"], default="websocket",
|
parser.add_argument("--channel", choices=["websocket", "rawpacket"], default="websocket",
|
||||||
help="specify the communication channel (default: %(default)s)")
|
help="specify the communication channel (default: %(default)s)")
|
||||||
|
parser.add_argument("--protocol", choices=["tcp", "serial"], default="tcp",
|
||||||
|
help="specify the transmission protocol over the communication channel (default: %(default)s)")
|
||||||
|
parser.add_argument("--serial-config", metavar="CONFIG_STRING", default="/dev/ttyUSB0,115200,8,N,1",
|
||||||
|
help="Configure parameters for serial port (default: %(default)s)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
@@ -266,17 +268,7 @@ class DebuggerAction(object):
|
|||||||
|
|
||||||
class JerryDebugger(object):
|
class JerryDebugger(object):
|
||||||
# pylint: disable=too-many-instance-attributes,too-many-statements,too-many-public-methods,no-self-use,redefined-variable-type
|
# pylint: disable=too-many-instance-attributes,too-many-statements,too-many-public-methods,no-self-use,redefined-variable-type
|
||||||
def __init__(self, address, channel):
|
def __init__(self, channel):
|
||||||
|
|
||||||
if ":" not in address:
|
|
||||||
self.host = address
|
|
||||||
self.port = 5001 # use default port
|
|
||||||
else:
|
|
||||||
self.host, self.port = address.split(":")
|
|
||||||
self.port = int(self.port)
|
|
||||||
|
|
||||||
print("Connecting to: %s:%s" % (self.host, self.port))
|
|
||||||
|
|
||||||
self.prompt = False
|
self.prompt = False
|
||||||
self.function_list = {}
|
self.function_list = {}
|
||||||
self.source = ''
|
self.source = ''
|
||||||
@@ -304,15 +296,7 @@ class JerryDebugger(object):
|
|||||||
self.non_interactive = False
|
self.non_interactive = False
|
||||||
self.current_out = b""
|
self.current_out = b""
|
||||||
self.current_log = b""
|
self.current_log = b""
|
||||||
self.channel = None
|
self.channel = channel
|
||||||
|
|
||||||
protocol = Socket()
|
|
||||||
if channel == "websocket":
|
|
||||||
self.channel = WebSocket(address=(self.host, self.port), protocol=protocol)
|
|
||||||
elif channel == "rawpacket":
|
|
||||||
self.channel = RawPacket(address=(self.host, self.port), protocol=protocol)
|
|
||||||
else:
|
|
||||||
raise Exception("Unsupported communication channel")
|
|
||||||
|
|
||||||
config_size = 8
|
config_size = 8
|
||||||
# The server will send the configuration message after connection established
|
# The server will send the configuration message after connection established
|
||||||
@@ -697,7 +681,6 @@ class JerryDebugger(object):
|
|||||||
# pylint: disable=too-many-branches,too-many-locals,too-many-statements,too-many-return-statements
|
# pylint: disable=too-many-branches,too-many-locals,too-many-statements,too-many-return-statements
|
||||||
def process_messages(self):
|
def process_messages(self):
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
data = self.channel.get_message(False)
|
data = self.channel.get_message(False)
|
||||||
if not self.non_interactive:
|
if not self.non_interactive:
|
||||||
@@ -846,6 +829,9 @@ class JerryDebugger(object):
|
|||||||
|
|
||||||
return DebuggerAction(DebuggerAction.TEXT, result)
|
return DebuggerAction(DebuggerAction.TEXT, result)
|
||||||
|
|
||||||
|
elif JERRY_DEBUGGER_CLOSE_CONNECTION:
|
||||||
|
return DebuggerAction(DebuggerAction.END, "")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception("Unknown message")
|
raise Exception("Unknown message")
|
||||||
|
|
||||||
|
|||||||
@@ -20,14 +20,13 @@ MAX_BUFFER_SIZE = 256
|
|||||||
|
|
||||||
class RawPacket(object):
|
class RawPacket(object):
|
||||||
""" Simplified transmission layer. """
|
""" Simplified transmission layer. """
|
||||||
def __init__(self, address, protocol):
|
def __init__(self, protocol):
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
self.data_buffer = b""
|
self.data_buffer = b""
|
||||||
self.address = address
|
|
||||||
|
|
||||||
def connect(self, config_size):
|
def connect(self, config_size):
|
||||||
""" Create connection. """
|
""" Create connection. """
|
||||||
self.protocol.connect(self.address)
|
self.protocol.connect()
|
||||||
self.data_buffer = b""
|
self.data_buffer = b""
|
||||||
|
|
||||||
# It will return with the Network configurations, which has the following struct:
|
# It will return with the Network configurations, which has the following struct:
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import select
|
||||||
|
import serial
|
||||||
|
|
||||||
|
class Serial(object):
|
||||||
|
""" Create a new socket using the given address family, socket type and protocol number. """
|
||||||
|
def __init__(self, serial_config):
|
||||||
|
config = serial_config.split(',')
|
||||||
|
config_size = len(config)
|
||||||
|
|
||||||
|
port = config[0] if config_size > 0 else "/dev/ttyUSB0"
|
||||||
|
baudrate = config[1] if config_size > 1 else 115200
|
||||||
|
bytesize = int(config[2]) if config_size > 2 else 8
|
||||||
|
parity = config[3] if config_size > 3 else 'N'
|
||||||
|
stopbits = int(config[4]) if config_size > 4 else 1
|
||||||
|
|
||||||
|
self.ser = serial.Serial(port=port, baudrate=baudrate, parity=parity,
|
||||||
|
stopbits=stopbits, bytesize=bytesize, timeout=1)
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
""" Connect to the server, write a 'c' to the serial port """
|
||||||
|
self.send_data('c')
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""" close the serial port. """
|
||||||
|
self.ser.close()
|
||||||
|
|
||||||
|
def receive_data(self, max_size=1024):
|
||||||
|
""" The maximum amount of data to be received at once is specified by max_size. """
|
||||||
|
return self.ser.read(max_size)
|
||||||
|
|
||||||
|
def send_data(self, data):
|
||||||
|
""" Write data to the serial port. """
|
||||||
|
return self.ser.write(data)
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
""" Monitor the file descriptor. """
|
||||||
|
result = select.select([self.ser.fileno()], [], [], 0)[0]
|
||||||
|
|
||||||
|
return self.ser.fileno() in result
|
||||||
@@ -17,17 +17,20 @@
|
|||||||
import socket
|
import socket
|
||||||
import select
|
import select
|
||||||
|
|
||||||
|
# pylint: disable=too-many-arguments,superfluous-parens
|
||||||
class Socket(object):
|
class Socket(object):
|
||||||
""" Create a new socket using the given address family, socket type and protocol number. """
|
""" Create a new socket using the given address family, socket type and protocol number. """
|
||||||
def __init__(self, socket_family=socket.AF_INET, socket_type=socket.SOCK_STREAM, proto=0, fileno=None):
|
def __init__(self, address, socket_family=socket.AF_INET, socket_type=socket.SOCK_STREAM, proto=0, fileno=None):
|
||||||
|
self.address = address
|
||||||
self.socket = socket.socket(socket_family, socket_type, proto, fileno)
|
self.socket = socket.socket(socket_family, socket_type, proto, fileno)
|
||||||
|
|
||||||
def connect(self, address):
|
def connect(self):
|
||||||
"""
|
"""
|
||||||
Connect to a remote socket at address (host, port).
|
Connect to a remote socket at address (host, port).
|
||||||
The format of address depends on the address family.
|
The format of address depends on the address family.
|
||||||
"""
|
"""
|
||||||
self.socket.connect(address)
|
print("Connecting to: %s:%s" % (self.address[0], self.address[1]))
|
||||||
|
self.socket.connect(self.address)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""" Mark the socket closed. """
|
"""" Mark the socket closed. """
|
||||||
|
|||||||
@@ -21,11 +21,10 @@ WEBSOCKET_BINARY_FRAME = 2
|
|||||||
WEBSOCKET_FIN_BIT = 0x80
|
WEBSOCKET_FIN_BIT = 0x80
|
||||||
|
|
||||||
class WebSocket(object):
|
class WebSocket(object):
|
||||||
def __init__(self, address, protocol):
|
def __init__(self, protocol):
|
||||||
|
|
||||||
self.data_buffer = b""
|
self.data_buffer = b""
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
self.address = address
|
|
||||||
|
|
||||||
def __handshake(self):
|
def __handshake(self):
|
||||||
""" Client Handshake Request. """
|
""" Client Handshake Request. """
|
||||||
@@ -55,7 +54,7 @@ class WebSocket(object):
|
|||||||
|
|
||||||
def connect(self, config_size):
|
def connect(self, config_size):
|
||||||
""" WebSockets connection. """
|
""" WebSockets connection. """
|
||||||
self.protocol.connect(self.address)
|
self.protocol.connect()
|
||||||
self.data_buffer = b""
|
self.data_buffer = b""
|
||||||
self.__handshake()
|
self.__handshake()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,409 @@
|
|||||||
|
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "jerryscript-debugger-transport.h"
|
||||||
|
#include "jerryscript-ext/debugger.h"
|
||||||
|
#include "jext-common.h"
|
||||||
|
|
||||||
|
#if defined JERRY_DEBUGGER && !defined WIN32
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Max size of configuration string */
|
||||||
|
#define CONFIG_SIZE (255)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of transport over serial connection.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
jerry_debugger_transport_header_t header; /**< transport header */
|
||||||
|
int fd; /**< file descriptor */
|
||||||
|
} jerryx_debugger_transport_serial_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure parameters for a serial port.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *device_id;
|
||||||
|
uint32_t baud_rate; /**< specify the rate at which bits are transmitted for the serial interface */
|
||||||
|
uint32_t data_bits; /**< specify the number of data bits to transmit over the serial interface */
|
||||||
|
char parity; /**< specify how you want to check parity bits in the data bits transmitted via the serial port */
|
||||||
|
uint32_t stop_bits; /**< specify the number of bits used to indicate the end of a byte. */
|
||||||
|
} jerryx_debugger_transport_serial_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correctly close a file descriptor.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
jerryx_debugger_serial_close_fd (int fd) /**< file descriptor to close */
|
||||||
|
{
|
||||||
|
if (close (fd) != 0)
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Error while closing the file descriptor: %d\n", errno);
|
||||||
|
}
|
||||||
|
} /* jerryx_debugger_serial_close_fd */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a file descriptor to blocking or non-blocking mode.
|
||||||
|
*
|
||||||
|
* @return true if everything is ok
|
||||||
|
* false if there was an error
|
||||||
|
**/
|
||||||
|
static bool
|
||||||
|
jerryx_debugger_serial_set_blocking (int fd, bool blocking)
|
||||||
|
{
|
||||||
|
/* Save the current flags */
|
||||||
|
int flags = fcntl (fd, F_GETFL, 0);
|
||||||
|
if (flags == -1)
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Error %d during get flags from file descriptor\n", errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blocking)
|
||||||
|
{
|
||||||
|
flags &= ~O_NONBLOCK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcntl (fd, F_SETFL, flags) == -1)
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Error %d during set flags from file descriptor\n", errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} /* jerryx_debugger_serial_set_blocking */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the file descriptor used by the serial communcation.
|
||||||
|
*
|
||||||
|
* @return true if everything is ok
|
||||||
|
* false if there was an error
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
jerryx_debugger_serial_configure_attributes (int fd, jerryx_debugger_transport_serial_config_t serial_config)
|
||||||
|
{
|
||||||
|
struct termios options;
|
||||||
|
memset (&options, 0, sizeof (options));
|
||||||
|
|
||||||
|
/* Get the parameters associated with the file descriptor */
|
||||||
|
if (tcgetattr (fd, &options) != 0)
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Error %d from tggetattr\n", errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the input and output baud rates */
|
||||||
|
cfsetispeed (&options, serial_config.baud_rate);
|
||||||
|
cfsetospeed (&options, serial_config.baud_rate);
|
||||||
|
|
||||||
|
/* Set the control modes */
|
||||||
|
options.c_cflag &= (uint32_t) ~CSIZE; // character size mask
|
||||||
|
options.c_cflag |= (CLOCAL | CREAD); // ignore modem control lines and enable the receiver
|
||||||
|
|
||||||
|
switch (serial_config.data_bits)
|
||||||
|
{
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
options.c_cflag |= CS5; // set character size mask to 5-bit chars
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
options.c_cflag |= CS6; // set character size mask to 6-bit chars
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 7:
|
||||||
|
{
|
||||||
|
options.c_cflag |= CS7; // set character size mask to 7-bit chars
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
options.c_cflag |= CS8; // set character size mask to 8-bit chars
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Unsupported data bits: %d\n", serial_config.data_bits);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (serial_config.parity)
|
||||||
|
{
|
||||||
|
case 'N':
|
||||||
|
{
|
||||||
|
options.c_cflag &= (unsigned int) ~(PARENB | PARODD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'O':
|
||||||
|
{
|
||||||
|
options.c_cflag |= PARENB;
|
||||||
|
options.c_cflag |= PARODD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'E':
|
||||||
|
{
|
||||||
|
options.c_cflag |= PARENB;
|
||||||
|
options.c_cflag |= PARODD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Unsupported parity: %c\n", serial_config.parity);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (serial_config.stop_bits)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
options.c_cflag &= (uint32_t) ~CSTOPB; // set 1 stop bits
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
options.c_cflag |= CSTOPB; // set 2 stop bits
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Unsupported stop bits: %d\n", serial_config.stop_bits);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the input modes */
|
||||||
|
options.c_iflag &= (uint32_t) ~IGNBRK; // disable break processing
|
||||||
|
options.c_iflag &= (uint32_t) ~(IXON | IXOFF | IXANY); // disable xon/xoff ctrl
|
||||||
|
|
||||||
|
/* Set the output modes: no remapping, no delays */
|
||||||
|
options.c_oflag = 0;
|
||||||
|
|
||||||
|
/* Set the local modes: no signaling chars, no echo, no canoncial processing */
|
||||||
|
options.c_lflag = 0;
|
||||||
|
|
||||||
|
/* Read returns when at least one byte of data is available. */
|
||||||
|
options.c_cc[VMIN] = 1; // read block
|
||||||
|
options.c_cc[VTIME] = 5; // 0.5 seconds read timeout
|
||||||
|
|
||||||
|
/* Set the parameters associated with the file descriptor */
|
||||||
|
if (tcsetattr (fd, TCSANOW, &options) != 0)
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Error %d from tcsetattr", errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flushes both data received but not read, and data written but not transmitted */
|
||||||
|
if (tcflush (fd, TCIOFLUSH) != 0)
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Error %d in tcflush() :%s\n", errno, strerror (errno));
|
||||||
|
jerryx_debugger_serial_close_fd (fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} /* jerryx_debugger_serial_configure_attributes */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close a serial connection.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
jerryx_debugger_serial_close (jerry_debugger_transport_header_t *header_p) /**< serial implementation */
|
||||||
|
{
|
||||||
|
JERRYX_ASSERT (!jerry_debugger_transport_is_connected ());
|
||||||
|
|
||||||
|
jerryx_debugger_transport_serial_t *serial_p = (jerryx_debugger_transport_serial_t *) header_p;
|
||||||
|
|
||||||
|
JERRYX_DEBUG_MSG ("Serial connection closed.\n");
|
||||||
|
|
||||||
|
jerryx_debugger_serial_close_fd (serial_p->fd);
|
||||||
|
|
||||||
|
jerry_heap_free ((void *) header_p, sizeof (jerryx_debugger_transport_serial_t));
|
||||||
|
} /* jerryx_debugger_serial_close */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data over a serial connection.
|
||||||
|
*
|
||||||
|
* @return true - if the data has been sent successfully
|
||||||
|
* false - otherwise
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
jerryx_debugger_serial_send (jerry_debugger_transport_header_t *header_p, /**< serial implementation */
|
||||||
|
uint8_t *message_p, /**< message to be sent */
|
||||||
|
size_t message_length) /**< message length in bytes */
|
||||||
|
{
|
||||||
|
JERRYX_ASSERT (jerry_debugger_transport_is_connected ());
|
||||||
|
|
||||||
|
jerryx_debugger_transport_serial_t *serial_p = (jerryx_debugger_transport_serial_t *) header_p;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ssize_t sent_bytes = write (serial_p->fd, message_p, message_length);
|
||||||
|
|
||||||
|
if (sent_bytes < 0)
|
||||||
|
{
|
||||||
|
if (errno == EWOULDBLOCK)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
JERRYX_ERROR_MSG ("Error: write to file descriptor: %d\n", errno);
|
||||||
|
jerry_debugger_transport_close ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
message_p += sent_bytes;
|
||||||
|
message_length -= (size_t) sent_bytes;
|
||||||
|
}
|
||||||
|
while (message_length > 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} /* jerryx_debugger_serial_send */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive data from a serial connection.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
jerryx_debugger_serial_receive (jerry_debugger_transport_header_t *header_p, /**< serial implementation */
|
||||||
|
jerry_debugger_transport_receive_context_t *receive_context_p) /**< receive context */
|
||||||
|
{
|
||||||
|
jerryx_debugger_transport_serial_t *serial_p = (jerryx_debugger_transport_serial_t *) header_p;
|
||||||
|
|
||||||
|
uint8_t *buffer_p = receive_context_p->buffer_p + receive_context_p->received_length;
|
||||||
|
size_t buffer_size = JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE - receive_context_p->received_length;
|
||||||
|
|
||||||
|
ssize_t length = read (serial_p->fd, buffer_p, buffer_size);
|
||||||
|
|
||||||
|
if (length <= 0)
|
||||||
|
{
|
||||||
|
if (errno != EWOULDBLOCK || length == 0)
|
||||||
|
{
|
||||||
|
jerry_debugger_transport_close ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
receive_context_p->received_length += (size_t) length;
|
||||||
|
|
||||||
|
if (receive_context_p->received_length > 0)
|
||||||
|
{
|
||||||
|
receive_context_p->message_p = receive_context_p->buffer_p;
|
||||||
|
receive_context_p->message_length = receive_context_p->received_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} /* jerryx_debugger_serial_receive */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a serial connection.
|
||||||
|
*
|
||||||
|
* @return true if successful,
|
||||||
|
* false otherwise
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
jerryx_debugger_serial_create (const char *config) /**< specify the configuration */
|
||||||
|
{
|
||||||
|
/* Parse the configuration string */
|
||||||
|
char tmp_config[CONFIG_SIZE];
|
||||||
|
strncpy (tmp_config, config, CONFIG_SIZE);
|
||||||
|
jerryx_debugger_transport_serial_config_t serial_config;
|
||||||
|
|
||||||
|
char *token = strtok (tmp_config, ",");
|
||||||
|
serial_config.device_id = token ? token : "/dev/ttyS0";
|
||||||
|
serial_config.baud_rate = (token = strtok (NULL, ",")) ? (uint32_t) strtoul (token, NULL, 10) : 115200;
|
||||||
|
serial_config.data_bits = (token = strtok (NULL, ",")) ? (uint32_t) strtoul (token, NULL, 10) : 8;
|
||||||
|
serial_config.parity = (token = strtok (NULL, ",")) ? token[0] : 'N';
|
||||||
|
serial_config.stop_bits = (token = strtok (NULL, ",")) ? (uint32_t) strtoul (token, NULL, 10) : 1;
|
||||||
|
|
||||||
|
int fd = open (serial_config.device_id, O_RDWR);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
JERRYX_ERROR_MSG ("Error %d opening %s: %s", errno, serial_config.device_id, strerror (errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!jerryx_debugger_serial_configure_attributes (fd, serial_config))
|
||||||
|
{
|
||||||
|
jerryx_debugger_serial_close_fd (fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JERRYX_DEBUG_MSG ("Waiting for client connection\n");
|
||||||
|
|
||||||
|
/* Client will sent a 'c' char to initiate the connection. */
|
||||||
|
uint8_t conn_char;
|
||||||
|
ssize_t t = read (fd, &conn_char, 1);
|
||||||
|
if (t != 1 || conn_char != 'c' || !jerryx_debugger_serial_set_blocking (fd, false))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JERRYX_DEBUG_MSG ("Client connected\n");
|
||||||
|
|
||||||
|
size_t size = sizeof (jerryx_debugger_transport_serial_t);
|
||||||
|
|
||||||
|
jerry_debugger_transport_header_t *header_p;
|
||||||
|
header_p = (jerry_debugger_transport_header_t *) jerry_heap_alloc (size);
|
||||||
|
|
||||||
|
if (!header_p)
|
||||||
|
{
|
||||||
|
jerryx_debugger_serial_close_fd (fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
header_p->close = jerryx_debugger_serial_close;
|
||||||
|
header_p->send = jerryx_debugger_serial_send;
|
||||||
|
header_p->receive = jerryx_debugger_serial_receive;
|
||||||
|
|
||||||
|
((jerryx_debugger_transport_serial_t *) header_p)->fd = fd;
|
||||||
|
|
||||||
|
jerry_debugger_transport_add (header_p,
|
||||||
|
0,
|
||||||
|
JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE,
|
||||||
|
0,
|
||||||
|
JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} /* jerryx_debugger_serial_create */
|
||||||
|
|
||||||
|
#else /* !JERRY_DEBUGGER || WIN32 */
|
||||||
|
/**
|
||||||
|
* Dummy function when debugger is disabled.
|
||||||
|
*
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
jerryx_debugger_serial_create (const char *config)
|
||||||
|
{
|
||||||
|
JERRYX_UNUSED (config);
|
||||||
|
return false;
|
||||||
|
} /* jerryx_debugger_serial_create */
|
||||||
|
|
||||||
|
#endif /* JERRY_DEBUGGER */
|
||||||
@@ -30,6 +30,7 @@ void jerryx_debugger_after_connect (bool success);
|
|||||||
* Message transmission interfaces.
|
* Message transmission interfaces.
|
||||||
*/
|
*/
|
||||||
bool jerryx_debugger_tcp_create (uint16_t port);
|
bool jerryx_debugger_tcp_create (uint16_t port);
|
||||||
|
bool jerryx_debugger_serial_create (const char *config);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Message encoding interfaces.
|
* Message encoding interfaces.
|
||||||
|
|||||||
+45
-7
@@ -318,6 +318,8 @@ typedef enum
|
|||||||
OPT_DEBUG_SERVER,
|
OPT_DEBUG_SERVER,
|
||||||
OPT_DEBUG_PORT,
|
OPT_DEBUG_PORT,
|
||||||
OPT_DEBUG_CHANNEL,
|
OPT_DEBUG_CHANNEL,
|
||||||
|
OPT_DEBUG_PROTOCOL,
|
||||||
|
OPT_DEBUG_SERIAL_CONFIG,
|
||||||
OPT_DEBUGGER_WAIT_SOURCE,
|
OPT_DEBUGGER_WAIT_SOURCE,
|
||||||
OPT_EXEC_SNAP,
|
OPT_EXEC_SNAP,
|
||||||
OPT_EXEC_SNAP_FUNC,
|
OPT_EXEC_SNAP_FUNC,
|
||||||
@@ -349,6 +351,10 @@ static const cli_opt_t main_opts[] =
|
|||||||
.help = "debug server port (default: 5001)"),
|
.help = "debug server port (default: 5001)"),
|
||||||
CLI_OPT_DEF (.id = OPT_DEBUG_CHANNEL, .longopt = "debug-channel", .meta = "[websocket|rawpacket]",
|
CLI_OPT_DEF (.id = OPT_DEBUG_CHANNEL, .longopt = "debug-channel", .meta = "[websocket|rawpacket]",
|
||||||
.help = "Specify the debugger transmission channel (default: websocket)"),
|
.help = "Specify the debugger transmission channel (default: websocket)"),
|
||||||
|
CLI_OPT_DEF (.id = OPT_DEBUG_PROTOCOL, .longopt = "debug-protocol", .meta = "PROTOCOL",
|
||||||
|
.help = "Specify the transmission protocol over the communication channel (tcp|serial, default: tcp)"),
|
||||||
|
CLI_OPT_DEF (.id = OPT_DEBUG_SERIAL_CONFIG, .longopt = "serial-config", .meta = "OPTIONS_STRING",
|
||||||
|
.help = "Configure parameters for serial port (default: /dev/ttyS0,115200,8,N,1)"),
|
||||||
CLI_OPT_DEF (.id = OPT_DEBUGGER_WAIT_SOURCE, .longopt = "debugger-wait-source",
|
CLI_OPT_DEF (.id = OPT_DEBUGGER_WAIT_SOURCE, .longopt = "debugger-wait-source",
|
||||||
.help = "wait for an executable source from the client"),
|
.help = "wait for an executable source from the client"),
|
||||||
CLI_OPT_DEF (.id = OPT_EXEC_SNAP, .longopt = "exec-snapshot", .meta = "FILE",
|
CLI_OPT_DEF (.id = OPT_EXEC_SNAP, .longopt = "exec-snapshot", .meta = "FILE",
|
||||||
@@ -422,21 +428,33 @@ context_alloc (size_t size,
|
|||||||
static void
|
static void
|
||||||
init_engine (jerry_init_flag_t flags, /**< initialized flags for the engine */
|
init_engine (jerry_init_flag_t flags, /**< initialized flags for the engine */
|
||||||
char *debug_channel, /**< enable the debugger init or not */
|
char *debug_channel, /**< enable the debugger init or not */
|
||||||
uint16_t debug_port) /**< the debugger port */
|
char *debug_protocol, /**< enable the debugger init or not */
|
||||||
|
uint16_t debug_port, /**< the debugger port for tcp protocol */
|
||||||
|
char *debug_serial_config) /**< configuration string for serial protocol */
|
||||||
{
|
{
|
||||||
jerry_init (flags);
|
jerry_init (flags);
|
||||||
if (strcmp (debug_channel, ""))
|
if (strcmp (debug_channel, ""))
|
||||||
{
|
{
|
||||||
bool tcp_created = jerryx_debugger_tcp_create (debug_port);
|
bool protocol = false;
|
||||||
|
|
||||||
|
if (!strcmp (debug_protocol, "tcp"))
|
||||||
|
{
|
||||||
|
protocol = jerryx_debugger_tcp_create (debug_port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (!strcmp (debug_protocol, "serial"));
|
||||||
|
protocol = jerryx_debugger_serial_create (debug_serial_config);
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp (debug_channel, "rawpacket"))
|
if (!strcmp (debug_channel, "rawpacket"))
|
||||||
{
|
{
|
||||||
jerryx_debugger_after_connect (tcp_created && jerryx_debugger_rp_create ());
|
jerryx_debugger_after_connect (protocol && jerryx_debugger_rp_create ());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert (!strcmp (debug_channel, "websocket"));
|
assert (!strcmp (debug_channel, "websocket"));
|
||||||
jerryx_debugger_after_connect (tcp_created && jerryx_debugger_ws_create ());
|
jerryx_debugger_after_connect (protocol && jerryx_debugger_ws_create ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,6 +482,8 @@ main (int argc,
|
|||||||
bool start_debug_server = false;
|
bool start_debug_server = false;
|
||||||
uint16_t debug_port = 5001;
|
uint16_t debug_port = 5001;
|
||||||
char *debug_channel = "websocket";
|
char *debug_channel = "websocket";
|
||||||
|
char *debug_protocol = "tcp";
|
||||||
|
char *debug_serial_config = "/dev/ttyS0,115200,8,N,1";
|
||||||
|
|
||||||
bool is_repl_mode = false;
|
bool is_repl_mode = false;
|
||||||
bool is_wait_mode = false;
|
bool is_wait_mode = false;
|
||||||
@@ -542,6 +562,24 @@ main (int argc,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OPT_DEBUG_PROTOCOL:
|
||||||
|
{
|
||||||
|
if (check_feature (JERRY_FEATURE_DEBUGGER, cli_state.arg))
|
||||||
|
{
|
||||||
|
debug_protocol = (char *) cli_consume_string (&cli_state);
|
||||||
|
check_usage (!strcmp (debug_protocol, "tcp") || !strcmp (debug_protocol, "serial"),
|
||||||
|
argv[0], "Error: invalid value for --debug-protocol: ", cli_state.arg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OPT_DEBUG_SERIAL_CONFIG:
|
||||||
|
{
|
||||||
|
if (check_feature (JERRY_FEATURE_DEBUGGER, cli_state.arg))
|
||||||
|
{
|
||||||
|
debug_serial_config = (char *) cli_consume_string (&cli_state);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OPT_DEBUGGER_WAIT_SOURCE:
|
case OPT_DEBUGGER_WAIT_SOURCE:
|
||||||
{
|
{
|
||||||
if (check_feature (JERRY_FEATURE_DEBUGGER, cli_state.arg))
|
if (check_feature (JERRY_FEATURE_DEBUGGER, cli_state.arg))
|
||||||
@@ -640,7 +678,7 @@ main (int argc,
|
|||||||
debug_channel = "";
|
debug_channel = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
init_engine (flags, debug_channel, debug_port);
|
init_engine (flags, debug_channel, debug_protocol, debug_port, debug_serial_config);
|
||||||
|
|
||||||
jerry_value_t ret_value = jerry_create_undefined ();
|
jerry_value_t ret_value = jerry_create_undefined ();
|
||||||
|
|
||||||
@@ -758,7 +796,7 @@ main (int argc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_engine (flags, debug_channel, debug_port);
|
init_engine (flags, debug_channel, debug_protocol, debug_port, debug_serial_config);
|
||||||
|
|
||||||
ret_value = jerry_create_undefined ();
|
ret_value = jerry_create_undefined ();
|
||||||
}
|
}
|
||||||
@@ -802,7 +840,7 @@ main (int argc,
|
|||||||
|
|
||||||
jerry_cleanup ();
|
jerry_cleanup ();
|
||||||
|
|
||||||
init_engine (flags, debug_channel, debug_port);
|
init_engine (flags, debug_channel, debug_protocol, debug_port, debug_serial_config);
|
||||||
|
|
||||||
ret_value = jerry_create_undefined ();
|
ret_value = jerry_create_undefined ();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user