Skip to content

Commit 3ec5b47

Browse files
jimmy-huanggrgustaf
authored andcommitted
[debugger] Added debugger support for Zephyr
Created shim layer for building against the POSIX network stack on Zephyr which enables the debugger to run on the frdm_k64f board with TCP IPV4 on port 5001. Signed-off-by: Jimmy Huang <jimmy.huang@intel.com>
1 parent 0f1ca54 commit 3ec5b47

14 files changed

+250
-60
lines changed

Makefile

+18-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ OS := $(shell uname)
1010

1111
BOARD ?= arduino_101
1212

13+
SCRIPT_SIZE ?= 8192
1314
RAM ?= 64
1415
ROM ?= 144
1516
V ?= 0
@@ -37,9 +38,11 @@ $(error ZJS_BASE not defined. You need to source zjs-env.sh)
3738
endif
3839

3940
ifeq ($(DEBUGGER), on)
40-
ifneq ($(BOARD), linux)
41-
$(error Debugger only runs on linux, set BOARD=linux)
41+
ifneq (,$(filter $(MAKECMDGOALS), linux arduino_101))
42+
$(error Debugger only runs on linux and arduino_101)
4243
endif
44+
# debugger requires unminimized JS which will require much a larger script size
45+
SCRIPT_SIZE = 16384
4346
ifneq ($(SNAPSHOT), on)
4447
$(warning Debugger on, disabling snapshot)
4548
SNAPSHOT=off
@@ -120,6 +123,8 @@ else
120123
SNAPSHOT ?= on
121124
endif
122125

126+
ZJS_FLAGS += -DMAX_SCRIPT_SIZE=$(SCRIPT_SIZE)
127+
123128
ifeq ($(FUNC_NAME), on)
124129
ZJS_FLAGS += -DZJS_FIND_FUNC_NAME
125130
endif
@@ -130,6 +135,11 @@ else
130135
FORCED := $(FORCE),zjs_common.json
131136
endif
132137

138+
ifeq ($(DEBUGGER), on)
139+
# debugger will require networking support
140+
FORCED := $(FORCED),zjs_debugger.json
141+
endif
142+
133143
# Settings for ashell builds
134144
ifneq (,$(filter $(MAKECMDGOALS),ide ashell))
135145
ASHELL=zjs_ashell_$(ASHELL_TYPE).json
@@ -308,6 +318,7 @@ analyze: $(JS)
308318
-DBLE_ADDR=$(BLE_ADDR) \
309319
-DBOARD=$(BOARD) \
310320
-DCB_STATS=$(CB_STATS) \
321+
-DDEBUGGER=$(DEBUGGER) \
311322
-DJERRY_BASE=$(JERRY_BASE) \
312323
-DJERRY_OUTPUT=$(JERRY_OUTPUT) \
313324
-DJERRY_PROFILE=$(OUT)/$(BOARD)/jerry_feature.profile \
@@ -389,10 +400,14 @@ else
389400
@echo Creating C string from JS application...
390401
ifeq ($(BOARD), linux)
391402
@./scripts/convert.py $(JS) $(OUT)/include/zjs_script_gen.h
403+
else
404+
ifeq ($(DEBUGGER), on)
405+
@./scripts/convert.py --full $(OUT)/$(JS_TMP) $(OUT)/include/zjs_script_gen.h
392406
else
393407
@./scripts/convert.py $(OUT)/$(JS_TMP) $(OUT)/include/zjs_script_gen.h
394408
endif
395409
endif
410+
endif
396411

397412
# Run QEMU target
398413
.PHONY: qemu
@@ -466,6 +481,7 @@ linux: generate
466481
-DDEBUGGER=$(DEBUGGER) \
467482
-DV=$(V) \
468483
-DVARIANT=$(VARIANT) \
484+
-DZJS_FLAGS="$(ZJS_FLAGS)" \
469485
-H. && \
470486
make -C $(OUT)/linux;
471487

README.md

+40-7
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,48 @@ breakpoints such as `b main` and `run` to start debugging as usual with gdb.
282282
##### Debugging JavaScript code
283283
JerryScript has a built-in remote debugger which allows debugging JavaScript
284284
programs. At the moment only a Websocket-based implementation is provided by
285-
JerryScript which transmits messages over TCP/IP networks. This implementation
286-
requires a socket API which currently only work when running on Linux. The
287-
socket API is not yet supported with NewLib when building with Zephyr natively.
285+
JerryScript which transmits messages over TCP/IP networks, but it currently
286+
only supports ethernet, so you'll need to run it on a board that has ethernet
287+
support, for example, the FRDM-K64F or Linux.
288288

289289
To enable the remote debugger for a particular JS application:
290290
```bash
291+
make BOARD=frdm_k64f DEBUGGER=on JS=xxx.js
292+
```
293+
294+
When you flash and run the JS application, it will start in debugging mode,
295+
running on 192.168.1.101:5001, and you will see the following on serial output:
296+
297+
```bash
298+
Debugger mode: connect using jerry-client-ws.py
299+
300+
Waiting for client connection
301+
```
302+
you might need to add a route on your PC to connect to the network if you
303+
are connecting the board directly to your PC:
304+
305+
```bash
306+
ip route add 192.168.1/24 dev eno1
307+
```
308+
309+
Then you can use the jerryscript command line or html client to connect to the
310+
debugger to debug your JS application:
311+
312+
python jerryscript/jerry-debugger/jerry-client-ws.py --display 10 192.168.1.1
313+
314+
In the client, type 'help' to get a list of debugger commands, such as
315+
adding breakpoints, stepping through JS sources, etc.
316+
317+
Alternatively, we've created a client that integrates with Chome DevTools,
318+
which lets you use the Chrome's built-in debugger to connect and you can
319+
use it to set breakpoints and step through source from all within the browser.
320+
Please see installation instructions on how to set it up from
321+
[here](https://github.com/jerryscript-project/jerryscript-debugger-ts)
322+
323+
##### Debugging JavaScript code on Linux:
324+
325+
To enable the remote debugger on Linux:
326+
```bash
291327
make BOARD=linux DEBUGGER=on
292328
outdir/linux/release/jslinux app.js --debugger
293329
```
@@ -296,12 +332,9 @@ It will then be run on debugger mode waiting for client connection, you can then
296332
in another terminal, you can connect to it by running the python client in
297333
JerryScript:
298334
```bash
299-
jerry-debugger/jerry-client-ws.py
335+
python jerryscript/jerry-debugger/jerry-client-ws.py --display 10 localhost
300336
```
301337

302-
In the client, type 'help' to get a list of debugger commands, such as
303-
adding breakpoints, stepping through JS sources, etc.
304-
305338
#### Additional details
306339

307340
See below for a few more tips, such as increasing the space available for your

cmake/jerry.cmake

+17-5
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,32 @@ include(ExternalProject)
44

55
# Additional build flags to work around JerryScript warnings
66
set(jerry_cflags " \
7-
-Wall \
8-
-Werror \
97
-Wno-conversion \
108
-Wno-implicit-function-declaration \
119
-Wno-old-style-declaration \
12-
-Wno-undef"
10+
-Wno-pedantic \
11+
-Wno-shadow \
12+
-Wno-sign-compare \
13+
-Wno-sign-conversion \
14+
-Wno-undef \
15+
-Wno-unused-parameter \
16+
-Wno-unused-variable"
1317
)
1418

1519
zephyr_get_include_directories_for_lang_as_string(C includes)
1620
zephyr_get_system_include_directories_for_lang_as_string(C system_includes)
1721
zephyr_get_compile_definitions_for_lang_as_string(C definitions)
1822
zephyr_get_compile_options_for_lang_as_string(C options)
1923

24+
# include the shim layer that ports the network API to build on Zephyr
25+
if("${DEBUGGER}" STREQUAL "on")
26+
set(net_includes
27+
"-I${CMAKE_SOURCE_DIR}/src/jerry-port"
28+
)
29+
endif()
30+
2031
set(external_project_cflags
21-
"${includes} ${definitions} ${options} ${system_includes}${jerry_cflags}"
32+
"${includes} ${definitions} ${options} ${system_includes} ${jerry_cflags} ${net_includes}"
2233
)
2334

2435
if("${SNAPSHOT}" STREQUAL "on")
@@ -33,10 +44,11 @@ set(CMAKE_ARGS
3344
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
3445
-DCMAKE_C_COMPILER_WORKS=TRUE
3546
-DCMAKE_SYSTEM_NAME=Zephyr
36-
-DENABLE_ALL_IN_ONE=${ALL_IN_ONE}
47+
-DENABLE_ALL_IN_ONE=OFF
3748
-DENABLE_LTO=OFF
3849
-DEXTERNAL_COMPILE_FLAGS=${external_project_cflags}
3950
-DFEATURE_ERROR_MESSAGES=ON
51+
-DFEATURE_DEBUGGER=${DEBUGGER}
4052
-DFEATURE_INIT_FINI=ON
4153
-DFEATURE_PROFILE=${JERRY_PROFILE}
4254
-DFEATURE_SNAPSHOT_EXEC=OFF

cmake/zjs.cmake

+29-16
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,35 @@ target_compile_options(app PRIVATE
5656
-Wno-implicit-function-declaration
5757
)
5858

59-
target_include_directories(app PRIVATE ./src)
60-
target_include_directories(app PRIVATE ${ZEPHYR_BASE}/drivers)
61-
target_include_directories(app PRIVATE ${JERRY_BASE}/jerry-core/include)
62-
target_include_directories(app PRIVATE ${JERRY_BASE}/jerry-core/jrt)
63-
target_include_directories(app PRIVATE ${JERRY_BASE}/jerry-ext/include)
64-
target_include_directories(app PRIVATE ${CMAKE_BINARY_DIR}/../include)
65-
66-
target_sources(app PRIVATE src/main.c)
67-
target_sources(app PRIVATE src/zjs_callbacks.c)
68-
target_sources(app PRIVATE src/zjs_common.c)
69-
target_sources(app PRIVATE src/zjs_error.c)
70-
target_sources(app PRIVATE src/zjs_modules.c)
71-
target_sources(app PRIVATE src/zjs_script.c)
72-
target_sources(app PRIVATE src/zjs_timers.c)
73-
target_sources(app PRIVATE src/zjs_util.c)
74-
target_sources(app PRIVATE src/jerry-port/zjs_jerry_port.c)
59+
set(APP_INCLUDES
60+
./src
61+
${ZEPHYR_BASE}/drivers
62+
${JERRY_BASE}/jerry-core/include
63+
${JERRY_BASE}/jerry-core/jrt
64+
${JERRY_BASE}/jerry-ext/include
65+
${CMAKE_BINARY_DIR}/../include
66+
)
67+
68+
set(APP_SRC
69+
src/main.c
70+
src/zjs_callbacks.c
71+
src/zjs_common.c
72+
src/zjs_error.c
73+
src/zjs_modules.c
74+
src/zjs_script.c
75+
src/zjs_timers.c
76+
src/zjs_util.c
77+
src/jerry-port/zjs_jerry_port.c
78+
)
79+
80+
if("${DEBUGGER}" STREQUAL "on")
81+
add_definitions(-DJERRY_DEBUGGER)
82+
add_definitions(-DZJS_DEBUGGER)
83+
endif()
84+
85+
target_include_directories(app PRIVATE ${APP_INCLUDES})
86+
87+
target_sources(app PRIVATE ${APP_SRC})
7588

7689
target_link_libraries(app jerry-core jerry-ext)
7790

cmake/zjs_linux.cmake

+13-6
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,8 @@ set(APP_COMPILE_OPTIONS
7777
-std=gnu99
7878
)
7979

80-
if(CB_STATS)
81-
add_definitions(-DCB_STATS=${CB_STATS})
82-
endif()
83-
84-
if(DEBUGGER)
85-
add_definitions(-DZJS_DEBUGGER=${ZJS_DEBUGGER})
80+
if("${CB_STATS}" STREQUAL "on")
81+
add_definitions(-DZJS_PRINT_CALLBACK_STATS)
8682
endif()
8783

8884
if("${VARIANT}" STREQUAL "debug")
@@ -141,6 +137,17 @@ if(NOT APPLE)
141137

142138
# these flags are needed to get rid of warnings in iotivity-constrained
143139
list(APPEND APP_COMPILE_OPTIONS -Wno-pointer-sign)
140+
141+
if("${DEBUGGER}" STREQUAL "on")
142+
list(APPEND APP_INCLUDES
143+
${JERRY_BASE}/jerry-core/debugger
144+
${JERRY_BASE}/jerry-core/ecma/base
145+
${JERRY_BASE}/jerry-core/jmem
146+
${JERRY_BASE}/jerry-core/lit
147+
)
148+
add_definitions(-DJERRY_DEBUGGER)
149+
add_definitions(-DZJS_DEBUGGER)
150+
endif()
144151
endif()
145152

146153
# build libjerry as a static library

scripts/convert.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,18 @@
2020

2121
def main():
2222
args = parse_args()
23-
minified_result = uglifyjs(args.input)
23+
minified_result = None
24+
if not args.full:
25+
minified_result = uglifyjs(args.input)
26+
if minified_result == None:
27+
# full JS or couldn't uglify the JS,
28+
# return content of the file as is
29+
fp = open(str(args.input), "r")
30+
content = fp.read()
31+
fp.close()
32+
minified_result = Uglify(content, False)
2433
write_minified(args.output, minified_result)
2534

26-
2735
def write_minified(output_path, minified_result):
2836
"""Write the minified output, escaping things as necessary
2937
@@ -61,6 +69,7 @@ def uglifyjs(input_path):
6169
:param input_path: A pathlib.Path() object of the input file.
6270
:returns: An Uglify() object
6371
"""
72+
6473
filename = str(input_path)
6574
# NOTE(jlvillal): The docs say that '-nc' is the same as '--no-copyright'
6675
# but in testing it is not.
@@ -73,8 +82,8 @@ def uglifyjs(input_path):
7382
try:
7483
result = subprocess.call(cmd_line, stdout=subprocess.DEVNULL)
7584
except FileNotFoundError:
76-
# We don't have uglifyjs, so return the contents of the file
77-
return Uglify(input_path.read_text(), False)
85+
# We don't have uglifyjs
86+
return None
7887

7988
if result == 0:
8089
# We have newer uglifyjs
@@ -96,6 +105,8 @@ def parse_args():
96105
"a C string format."))
97106
parser.add_argument("input", metavar='INPUT_FILE')
98107
parser.add_argument("output", metavar='OUTPUT_FILE')
108+
parser.add_argument("-f", "--full", help="Skip minimizing JS for debugging",
109+
action="store_true")
99110
args = parser.parse_args()
100111
# Make all paths absolute and expand any "~/" usage.
101112
for arg_name in ('input', 'output'):

scripts/trlite

+8
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ if [ "$RUN" == "all" -o "$RUN" == "2" ]; then
332332
write_modules_test $TMPFILE $MODULES $SENSORS
333333
try_command "k64f net" make $VERBOSE JS=$TMPFILE ROM=256 BOARD=frdm_k64f
334334

335+
# debugger test
336+
MODULES=(buffer)
337+
write_modules_test $TMPFILE $MODULE
338+
try_command "k64f debugger" make $VERBOSE JS=$TMPFILE ROM=256 BOARD=frdm_k64f DEBUGGER=on
339+
335340
# OCF test
336341
echo "var ocf = require('ocf');" > $TMPFILE
337342
echo "var client = ocf.client;" >> $TMPFILE
@@ -450,6 +455,9 @@ if [ "$RUN" == "all" -o "$RUN" == "3" ]; then
450455
# linux build tests
451456
try_command "linux" make $VERBOSE BOARD=linux
452457

458+
# linux debugger tests
459+
try_command "linux debuger" make $VERBOSE BOARD=linux DEBUGGER=on
460+
453461
# linux unit tests
454462
try_command "unit tests" ./outdir/linux/release/jslinux --unittest
455463

src/jerry-port/arpa/inet.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) 2018, Intel Corporation.
2+
3+
// Zephyr network stack port
4+
// JerryScript debugger includes <arpa/inet.h> but Zephyr has different headers
5+
6+
#include <sys/fcntl.h>
7+
#include <net/socket.h>
8+
9+
#define SOL_SOCKET (1)
10+
#define SO_REUSEADDR (201)
11+
12+
#define setsockopt(sd, level, optname, optval, optlen) 0
13+
14+
char addr_str[NET_IPV4_ADDR_LEN];
15+
16+
#define socket(domain, type, protocol) socket(domain, type, IPPROTO_TCP)
17+
18+
inline char *inet_ntoa (struct in_addr addr) {
19+
return net_addr_ntop(AF_INET, &addr, addr_str, sizeof(addr_str));
20+
}

0 commit comments

Comments
 (0)