targets/zephyr/Makefile.zephyr: Use zephyr_getline module for line input.

The original implementation used shell facility, but it was designed for
a unix shell like input, and automatically tokenized it into
space-separated "words", with limit of 10 (i.e. 9 spaces per line). For
JavaScript input, it is quite easy to have more than 9 spaces per line,
and get error:

Too many parameters (max 10)

After consultation with upstream
(https://jira.zephyrproject.org/browse/ZEP-532) it was decided that the
best approach is to skip using shell facility and use Zephyr console
facility. That however requires some Zephyr-specific boilerplate code.
This code was implemented as reusable modules in
https://github.com/pfalcon/zephyr_console_helpers repository, to be
usable for other console-based projects too. zephyr_getline.h/c in this
commits are direct imports from this repository.

JerryScript-DCO-1.0-Signed-off-by: Paul Sokolovsky paul.sokolovsky@linaro.org
This commit is contained in:
Paul Sokolovsky
2016-08-11 17:22:12 +03:00
parent 27253112c2
commit 314e74f8ce
5 changed files with 106 additions and 136 deletions
+6 -13
View File
@@ -132,28 +132,21 @@ Test command line in a serial terminal.
You should see something similar to this:
```
Jerry Compilation May 26 2016 13:37:50
JerryScript build: Aug 12 2016 17:12:55
JerryScript API 1.0
Zephyr version 1.4.0
js>
```
Run the example javascript command test function
```
js> test
Script [var test=0; for (t=100; t<1000; t++) test+=t; print ('Hi JS World! '+test);]
js> var test=0; for (t=100; t<1000; t++) test+=t; print ('Hi JS World! '+test);
Hi JS World! 494550
```
Try more complex functions:
Try a more complex function:
```
js>function hello(t){t=t*10;return t}; print("result"+hello(10.5));
js> function hello(t) {t=t*10;return t}; print("result"+hello(10.5));
```
Help will provide a list of commands
```
> help
```
This program, is built in top of the Zephyr command line, so there is a limit of 10 spaces.
+1 -1
View File
@@ -19,4 +19,4 @@ endif
# Adding path for jerry script APIs
ZEPHYRINCLUDE += -I$(JERRY_INCLUDE)
obj-y += main-zephyr.o
obj-y += main-zephyr.o getline-zephyr.o
+58
View File
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2016 Linaro
*
* 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 <zephyr.h>
#include <uart.h>
#include <drivers/console/uart_console.h>
#include "getline-zephyr.h"
/* While app processes one input line, Zephyr will have another line
buffer to accumulate more console input. */
static struct uart_console_input line_bufs[2];
static struct nano_fifo free_queue;
static struct nano_fifo used_queue;
char *zephyr_getline(void)
{
static struct uart_console_input *cmd;
/* Recycle cmd buffer returned previous time */
if (cmd != NULL)
{
nano_fifo_put(&free_queue, cmd);
}
cmd = nano_fifo_get(&used_queue, TICKS_UNLIMITED);
return cmd->line;
}
void zephyr_getline_init(void)
{
int i;
nano_fifo_init(&used_queue);
nano_fifo_init(&free_queue);
for (i = 0; i < sizeof(line_bufs) / sizeof(*line_bufs); i++)
{
nano_fifo_put(&free_queue, &line_bufs[i]);
}
/* Zephyr UART handler takes an empty buffer from free_queue,
stores UART input in it until EOL, and then puts it into
used_queue. */
uart_register_input(&free_queue, &used_queue, NULL);
}
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2016 Linaro
*
* 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.
*/
void zephyr_getline_init(void);
char *zephyr_getline(void);
+23 -122
View File
@@ -20,120 +20,20 @@
#include <zephyr.h>
#include <misc/printk.h>
#include <misc/shell.h>
#include "getline-zephyr.h"
#include "jerry-api.h"
#if defined (CONFIG_STDOUT_CONSOLE)
#include <stdio.h>
#define PRINT printf
#else
#include <misc/printk.h>
#define PRINT printk
#endif
static char *source_buffer = NULL;
static unsigned char flags = 0;
static jerry_value_t print_function;
#define VERBOSE 0x01
/**
* Jerryscript simple test loop
*/
int jerryscript_test ()
static int shell_cmd_handler (char *source_buffer)
{
jerry_value_t ret_val;
const char script[] =
"var test=0; " \
"for (var t=100; t<1000; t++) test+=t; " \
"print ('Hi JS World! '+test);";
printf ("Script [%s]\n", script);
ret_val = jerry_eval ((jerry_char_t *) script,
strlen (script),
false);
return jerry_value_has_error_flag (ret_val) ? -1 : 0;
} /* jerryscript_test */
static int shell_cmd_verbose (int argc, char *argv[])
{
printf ("Enable verbose \n");
flags |= VERBOSE;
return 0;
} /* shell_cmd_verbose */
static int shell_cmd_syntax_help (int argc, char *argv[])
{
printf ("version jerryscript & zephyr versions\n");
return 0;
} /* shell_cmd_syntax_help */
static int shell_cmd_version (int argc, char *argv[])
{
uint32_t version = sys_kernel_version_get ();
printf ("Jerryscript API %d.%d\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION);
printk ("Zephyr version %d.%d.%d\n", SYS_KERNEL_VER_MAJOR (version),
SYS_KERNEL_VER_MINOR (version),
SYS_KERNEL_VER_PATCHLEVEL (version));
return 0;
} /* shell_cmd_version */
static int shell_cmd_test (int argc, char *argv[])
{
return jerryscript_test ();
} /* shell_cmd_test */
static int shell_cmd_handler (int argc, char *argv[])
{
if (argc <= 0)
{
return -1;
}
unsigned int size = 0;
for (int t = 0; t < argc; t++)
{
size += strlen (argv[t]) + 1;
}
source_buffer = (char *) malloc (size);
char *d = source_buffer;
unsigned int len;
for (int t = 0; t < argc; t++)
{
len = strlen (argv[t]);
memcpy (d, argv[t], len);
d += len;
*d = ' ';
d++;
}
* (d - 1) = '\0';
if (flags & VERBOSE)
{
printf ("[%s] %lu\n", source_buffer, strlen (source_buffer));
}
jerry_value_t ret_val;
ret_val = jerry_eval ((jerry_char_t *) source_buffer,
strlen (source_buffer),
false);
free (source_buffer);
if (jerry_value_has_error_flag (ret_val))
{
/* User-friendly error messages require at least "cp" JerryScript
@@ -159,21 +59,16 @@ static int shell_cmd_handler (int argc, char *argv[])
return 0;
} /* shell_cmd_handler */
#define SHELL_COMMAND(name,cmd) { name, cmd }
const struct shell_cmd commands[] =
{
SHELL_COMMAND ("syntax", shell_cmd_syntax_help),
SHELL_COMMAND ("version", shell_cmd_version),
SHELL_COMMAND ("test", shell_cmd_test),
SHELL_COMMAND ("verbose", shell_cmd_verbose),
SHELL_COMMAND (NULL, NULL)
};
void main (void)
{
printf ("Jerry Compilation " __DATE__ " " __TIME__ "\n");
uint32_t zephyr_ver = sys_kernel_version_get ();
printf ("JerryScript build: " __DATE__ " " __TIME__ "\n");
printf ("JerryScript API %d.%d\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION);
printf ("Zephyr version %d.%d.%d\n", (int)SYS_KERNEL_VER_MAJOR (zephyr_ver),
(int)SYS_KERNEL_VER_MINOR (zephyr_ver),
(int)SYS_KERNEL_VER_PATCHLEVEL (zephyr_ver));
zephyr_getline_init ();
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t global_obj_val = jerry_get_global_object ();
@@ -186,11 +81,17 @@ void main (void)
printf ("Error: could not look up print function, expression results won't be printed\n");
}
shell_register_app_cmd_handler (shell_cmd_handler);
shell_init ("js> ", commands);
/* Don't call jerry_cleanup() here, as shell_init() returns after setting
up background task to process shell input, and that task calls
shell_cmd_handler(), etc. as callbacks. This processing happens in
the infinite loop, so JerryScript doesn't need to be de-initialized. */
} /* main */
while (1)
{
char *s;
printf("js> ");
fflush(stdout);
s = zephyr_getline ();
if (*s)
{
shell_cmd_handler (s);
}
}
/* As we never retturn from REPL above, don't call jerry_cleanup() here. */
} /* main */