* [U-Boot] [PATCH 0/2] ANSI terminal Bootmenu
@ 2012-05-27 16:38 Pali Rohár
2012-05-27 16:38 ` [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions Pali Rohár
` (3 more replies)
0 siblings, 4 replies; 37+ messages in thread
From: Pali Rohár @ 2012-05-27 16:38 UTC (permalink / raw)
To: u-boot
This patch series adds ANSI terminal Bootmenu command. It use generic menu
code for creating menu structures, but use own functions for drawing menu on
ANSI terminal. First patch modify generic menu code for using other functions
for printing and choosing menu entry, second patch is bootmenu command itself.
Pali Roh?r (2):
menu: Added support to use user defined functions
New command bootmenu: ANSI terminal Boot Menu support
board/ait/cam_enc_4xx/cam_enc_4xx.c | 5 +-
common/Makefile | 1 +
common/cmd_bootmenu.c | 446 +++++++++++++++++++++++++++++++++++
common/cmd_pxe.c | 3 +-
common/menu.c | 43 ++--
doc/README.bootmenu | 61 +++++
include/common.h | 20 ++
include/config_cmd_all.h | 1 +
include/menu.h | 6 +-
9 files changed, 566 insertions(+), 20 deletions(-)
create mode 100644 common/cmd_bootmenu.c
create mode 100644 doc/README.bootmenu
--
1.7.9.5
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions
2012-05-27 16:38 [U-Boot] [PATCH 0/2] ANSI terminal Bootmenu Pali Rohár
@ 2012-05-27 16:38 ` Pali Rohár
2012-06-03 9:59 ` Marek Vasut
2012-05-27 16:38 ` [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
` (2 subsequent siblings)
3 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2012-05-27 16:38 UTC (permalink / raw)
To: u-boot
* In menu_interactive_choice can be used user specified function
item_data_choice (instead hardcoded function which read input
from standard input)
* Added option to specify user data for menu
* menu_display_statusline will pass pointer to user data
(instead pointer to menu)
* This patch is needed for creating ANSI bootmenu
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
---
board/ait/cam_enc_4xx/cam_enc_4xx.c | 5 ++--
common/cmd_pxe.c | 3 ++-
| 43 +++++++++++++++++++++++------------
| 6 +++--
4 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c
index 32b28f9..5078b01 100644
--- a/board/ait/cam_enc_4xx/cam_enc_4xx.c
+++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c
@@ -561,7 +561,8 @@ static char *menu_handle(struct menu_display *display)
char *s;
char temp[6][200];
- m = menu_create(display->title, display->timeout, 1, ait_menu_print);
+ m = menu_create(display->title, display->timeout, 1, ait_menu_print,
+ NULL, NULL);
for (i = 0; display->menulist[i]; i++) {
sprintf(key, "%d", i + 1);
@@ -1097,7 +1098,7 @@ int menu_show(int bootdelay)
return MENU_EXIT;
}
-void menu_display_statusline(struct menu *m)
+void menu_display_statusline(void *data)
{
char *s1, *s2;
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index b3c1f67..346e275 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -1198,7 +1198,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/*
* Create a menu and add items for all the labels.
*/
- m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print);
+ m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
+ NULL, NULL);
if (!m)
return NULL;
--git a/common/menu.c b/common/menu.c
index aa16c9a..470eb9f 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -47,6 +47,8 @@ struct menu {
char *title;
int prompt;
void (*item_data_print)(void *);
+ char *(*item_data_choice)(void *);
+ void *data;
struct list_head items;
};
@@ -113,11 +115,11 @@ static inline void *menu_item_destroy(struct menu *m,
return NULL;
}
-void __menu_display_statusline(struct menu *m)
+void __menu_display_statusline(void *menu_data)
{
return;
}
-void menu_display_statusline(struct menu *m)
+void menu_display_statusline(void *menu_data)
__attribute__ ((weak, alias("__menu_display_statusline")));
/*
@@ -130,7 +132,7 @@ static inline void menu_display(struct menu *m)
puts(m->title);
putc('\n');
}
- menu_display_statusline(m);
+ menu_display_statusline(m->data);
menu_items_iter(m, menu_item_print, NULL);
}
@@ -230,20 +232,27 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)
menu_display(m);
- readret = readline_into_buffer("Enter choice: ", cbuf,
- m->timeout);
-
- if (readret >= 0) {
- choice_item = menu_item_by_key(m, cbuf);
-
- if (!choice_item) {
- printf("%s not found\n", cbuf);
- m->timeout = 0;
+ if (!m->item_data_choice) {
+ readret = readline_into_buffer("Enter choice: ", cbuf,
+ m->timeout);
+
+ if (readret >= 0) {
+ choice_item = menu_item_by_key(m, cbuf);
+ if (!choice_item)
+ printf("%s not found\n", cbuf);
+ } else {
+ puts("^C\n");
+ return -EINTR;
}
} else {
- puts("^C\n");
- return -EINTR;
+ char *key = m->item_data_choice(m->data);
+ if (!key)
+ return -EINTR;
+ choice_item = menu_item_by_key(m, key);
}
+
+ if (!choice_item)
+ m->timeout = 0;
}
*choice = choice_item->data;
@@ -380,7 +389,9 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data)
* insufficient memory available to create the menu.
*/
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *))
+ void (*item_data_print)(void *),
+ char *(*item_data_choice)(void *),
+ void *menu_data)
{
struct menu *m;
@@ -393,6 +404,8 @@ struct menu *menu_create(char *title, int timeout, int prompt,
m->prompt = prompt;
m->timeout = timeout;
m->item_data_print = item_data_print;
+ m->item_data_choice = item_data_choice;
+ m->data = menu_data;
if (title) {
m->title = strdup(title);
--git a/include/menu.h b/include/menu.h
index 7af5fdb..00e8975 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -21,12 +21,14 @@
struct menu;
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *));
+ void (*item_data_print)(void *),
+ char *(*item_data_choice)(void *),
+ void *menu_data);
int menu_default_set(struct menu *m, char *item_key);
int menu_get_choice(struct menu *m, void **choice);
int menu_item_add(struct menu *m, char *item_key, void *item_data);
int menu_destroy(struct menu *m);
-void menu_display_statusline(struct menu *m);
+void menu_display_statusline(void *menu_data);
#if defined(CONFIG_MENU_SHOW)
int menu_show(int bootdelay);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support
2012-05-27 16:38 [U-Boot] [PATCH 0/2] ANSI terminal Bootmenu Pali Rohár
2012-05-27 16:38 ` [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions Pali Rohár
@ 2012-05-27 16:38 ` Pali Rohár
2012-06-03 10:06 ` Marek Vasut
2012-11-01 11:39 ` [U-Boot] [PATCH v2 0/4] ANSI terminal Bootmenu Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 0/4] ANSI terminal Bootmenu Pali Rohár
3 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2012-05-27 16:38 UTC (permalink / raw)
To: u-boot
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
---
common/Makefile | 1 +
| 446 ++++++++++++++++++++++++++++++++++++++++++++++
| 61 +++++++
include/common.h | 20 +++
include/config_cmd_all.h | 1 +
5 files changed, 529 insertions(+)
create mode 100644 common/cmd_bootmenu.c
create mode 100644 doc/README.bootmenu
diff --git a/common/Makefile b/common/Makefile
index 6e23baa..b9d4a4a 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -69,6 +69,7 @@ COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o
COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
+COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
--git a/common/cmd_bootmenu.c b/common/cmd_bootmenu.c
new file mode 100644
index 0000000..935b60a
--- /dev/null
+++ b/common/cmd_bootmenu.c
@@ -0,0 +1,446 @@
+/*
+ * (C) Copyright 2011-2012 Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <menu.h>
+#include <hush.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <linux/string.h>
+
+struct bootmenu_entry {
+ int num; /* unique number 0..99 */
+ char key[3]; /* key idetifier of number */
+ char *title; /* title of entry */
+ char *command; /* hush command of entry */
+ struct bootmenu_data *menu; /* this bootmenu */
+ struct bootmenu_entry *next; /* next menu entry (num+1) */
+};
+
+struct bootmenu_data {
+ int delay; /* delay for autoboot */
+ int active; /* active menu entry */
+ int count; /* total count of menu entries */
+ struct bootmenu_entry *first; /* first menu entry */
+};
+
+static char *bootmenu_getoption(int n)
+{
+ char name[] = "bootmenu_\0\0";
+
+ if (n < 0 || n > 99)
+ return NULL;
+
+ sprintf(name+9, "%d", n);
+ return getenv(name);
+}
+
+static void bootmenu_print_entry(void *data)
+{
+ struct bootmenu_entry *entry = data;
+ int reverse = (entry->menu->active == entry->num);
+
+ printf(ANSI_CURSOR_POSITION, entry->num + 4, 1);
+
+ if (reverse)
+ puts(ANSI_COLOR_REVERSE);
+
+ puts(" ");
+ puts(entry->title);
+ puts(ANSI_CLEAR_LINE_TO_END);
+
+ if (reverse)
+ puts(ANSI_COLOR_RESET);
+}
+
+static char *bootmenu_choice_entry(void *data)
+{
+ struct bootmenu_data *menu = data;
+
+ int key = 0; /* 0 - NONE, 1 - UP, 2 - DOWN, 3 - SELECT */
+ int esc = 0;
+
+ while (1) {
+
+ if (menu->delay >= 0) {
+
+ if (menu->delay > 0) {
+ printf(ANSI_CURSOR_POSITION, menu->count+5, 1);
+ printf(" Hit any key to stop autoboot: %2d ",
+ menu->delay);
+ }
+
+ while (menu->delay > 0) {
+
+ int i;
+ for (i = 0; i < 100; ++i) {
+ if (tstc()) {
+ menu->delay = -1;
+ key = getc();
+
+ if (key == '\e') {
+ esc = 1;
+ key = 0;
+ } else if (key == '\r')
+ key = 3;
+ else
+ key = 0;
+
+ break;
+
+ }
+
+ WATCHDOG_RESET();
+ udelay(10000);
+
+ }
+
+ if (menu->delay < 0)
+ break;
+
+ --menu->delay;
+ printf("\b\b\b%2d ", menu->delay);
+
+ }
+
+ if (menu->delay == 0)
+ key = 3;
+
+ } else {
+
+ while (!tstc()) {
+ WATCHDOG_RESET();
+ udelay(10000);
+ }
+
+ key = getc();
+
+ if (esc == 0) {
+
+ if (key == '\e') {
+ esc = 1;
+ key = 0;
+ }
+
+ } else if (esc == 1) {
+
+ if (key == '[') {
+ esc = 2;
+ key = 0;
+ } else
+ esc = 0;
+
+ } else if (esc == 2 || esc == 3) {
+
+ if (esc == 2 && key == '1') {
+ esc = 3;
+ key = 0;
+ } else
+ esc = 0;
+
+ if (key == 'A')
+ key = 1;
+ else if (key == 'B')
+ key = 2;
+ else
+ key = 0;
+
+ }
+
+ if (key == '\r')
+ key = 3;
+
+ }
+
+ if (key == 1) {
+ if (menu->active > 0)
+ --menu->active;
+ return ""; /* invalid menu entry, regenerate menu */
+ } else if (key == 2) {
+ if (menu->active < menu->count-1)
+ ++menu->active;
+ return ""; /* invalid menu entry, regenerate menu */
+ } else if (key == 3) {
+ int i;
+ struct bootmenu_entry *iter = menu->first;
+ for (i = 0; i < menu->active; ++i)
+ iter = iter->next;
+ return iter->key;
+ }
+
+ }
+
+ /* never happends */
+ return NULL;
+}
+
+static struct bootmenu_data *bootmenu_create(int delay)
+{
+ int i = 0;
+ const char *option;
+ struct bootmenu_data *menu;
+ struct bootmenu_entry *iter = NULL;
+
+ menu = malloc(sizeof(struct bootmenu_data));
+ if (!menu)
+ return NULL;
+
+ menu->delay = delay;
+ menu->active = 0;
+ menu->first = NULL;
+
+ while ((option = bootmenu_getoption(i))) {
+
+ int len;
+ char *sep;
+ struct bootmenu_entry *entry;
+
+ sep = strchr(option, '=');
+ if (!sep)
+ break;
+
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ len = sep-option;
+ entry->title = malloc(len+1);
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->title, option, len);
+ entry->title[len] = 0;
+
+ len = strlen(sep+1);
+ entry->command = malloc(len+1);
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->command, sep+1, len);
+ entry->command[len] = 0;
+
+ sprintf(entry->key, "%d", i);
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+
+ if (i >= 100)
+ break;
+
+ }
+
+ /* Add U-Boot console entry at the end */
+ if (i < 100) {
+ struct bootmenu_entry *entry = malloc(
+ sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ entry->title = strdup("U-Boot console");
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+
+ entry->command = strdup("");
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+
+ }
+
+ menu->count = i;
+ return menu;
+
+cleanup:
+ iter = menu->first;
+ while (iter) {
+ struct bootmenu_entry *next = iter->next;
+ free(iter->title);
+ free(iter->command);
+ free(iter);
+ iter = next;
+ }
+ free(menu);
+ return NULL;
+}
+
+static void bootmenu_destroy(struct bootmenu_data *menu)
+{
+ struct bootmenu_entry *iter = menu->first;
+ while (iter) {
+ struct bootmenu_entry *next = iter->next;
+ free(iter->title);
+ free(iter->command);
+ free(iter);
+ iter = next;
+ }
+ free(menu);
+}
+
+static void bootmenu_show(int delay)
+{
+ int init = 0;
+ void *choice = NULL;
+ char *title = NULL;
+ char *command = NULL;
+ struct menu *menu;
+ struct bootmenu_data *bootmenu;
+ struct bootmenu_entry *iter;
+
+ /* If delay is 0 do not create menu, just run first entry */
+ if (delay == 0) {
+ char *option, *sep;
+ option = bootmenu_getoption(0);
+ if (!option)
+ return;
+ sep = strchr(option, '=');
+ if (!sep)
+ return;
+ run_command(sep+1, 0);
+ return;
+ }
+
+ bootmenu = bootmenu_create(delay);
+ if (!bootmenu)
+ return;
+
+ menu = menu_create(NULL, bootmenu->delay, (bootmenu->delay >= 0),
+ bootmenu_print_entry, bootmenu_choice_entry, bootmenu);
+ if (!menu)
+ return;
+
+ for (iter = bootmenu->first; iter; iter = iter->next)
+ if (!menu_item_add(menu, iter->key, iter))
+ goto cleanup;
+
+ /* Default menu entry is always first */
+ menu_default_set(menu, "0");
+
+ puts(ANSI_CURSOR_HIDE);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+
+ init = 1;
+
+ if (menu_get_choice(menu, &choice)) {
+ iter = choice;
+ title = strdup(iter->title);
+ command = strdup(iter->command);
+ }
+
+cleanup:
+ menu_destroy(menu);
+ bootmenu_destroy(bootmenu);
+
+ if (init) {
+ puts(ANSI_CURSOR_SHOW);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ }
+
+ if (title && command) {
+ printf("Starting entry '%s'\n", title);
+ free(title);
+ run_command(command, 0);
+ free(command);
+ }
+}
+
+void menu_display_statusline(void *data)
+{
+ struct bootmenu_data *menu = data;
+
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, 2, 1);
+ puts(" *** U-Boot BOOT MENU ***");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, 3, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
+ puts(" Press UP/DOWN to move, ENTER to select");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
+ puts(ANSI_CLEAR_LINE);
+}
+
+int menu_show(int bootdelay)
+{
+ bootmenu_show(bootdelay);
+ return -1; /* -1 - abort boot and run monitor code */
+}
+
+int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ char *delay_str = NULL;
+ int delay = 10;
+
+ if (argc >= 2)
+ delay_str = argv[1];
+
+ if (!delay_str)
+ delay_str = getenv("bootmenu_delay");
+
+ if (delay_str)
+ delay = (int)simple_strtol(delay_str, NULL, 10);
+
+ bootmenu_show(delay);
+ return 0;
+}
+
+U_BOOT_CMD(
+ bootmenu, 2, 1, do_bootmenu,
+ "ANSI terminal bootmenu",
+ "[delay]\n"
+ " - show ANSI terminal bootmenu with autoboot delay (default 10s)"
+);
--git a/doc/README.bootmenu b/doc/README.bootmenu
new file mode 100644
index 0000000..69ef93b
--- /dev/null
+++ b/doc/README.bootmenu
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2011-2012 Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+This is ANSI terminal BootMenu command. It is extension to generic menu,
+which provide output for ANSI terminals.
+
+Configuration is done via env variables bootmenu_delay and bootmenu_<num>:
+
+ bootmenu_delay=<delay>
+ bootmenu_<num>="<title>=<commands>"
+
+ (title and commands are separated by first char '=')
+
+ <delay> is delay in seconds of autobooting first entry
+ <num> is boot menu entry, starting from zero
+ <title> is text shown in boot screen
+ <commands> are commands which will be executed when menu entry is selected
+
+First argument of bootmenu command override bootmenu_delay env
+If env bootmenu_delay or bootmenu arg is not specified, delay is 10 seconds
+If delay is 0, no entry will be shown on screen and first will be called
+If delay is less then 0, no autoboot delay will be used
+Boot Menu will stop finding next menu entry if last was not defined
+Boot Menu always add menu entry "U-Boot console" at end of all entries
+
+Example using:
+
+ setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set first menu entry
+ setenv bootmenu_1 Boot 2. kernel=bootm 0x83000000 # Set second menu entry
+ setenv bootmenu_2 Reset board=reset # Set third menu entry
+ setenv bootmenu_3 U-Boot boot order=boot # Set fourth menu entry
+ setenv bootmenu_4 # Empty string is end of all bootmenu entries
+ bootmenu 20 # Run bootmenu with autoboot delay 20s
+
+
+To enable ANSI bootmenu comamnd add these definitions to board code:
+
+ #define CONFIG_BOOTDELAY 30
+ #define CONFIG_AUTOBOOT_KEYED
+ #define CONFIG_MENU
+ #define CONFIG_MENU_SHOW
+ #define CONFIG_CMD_BOOTMENU
diff --git a/include/common.h b/include/common.h
index 8564a65..59ecdb9 100644
--- a/include/common.h
+++ b/include/common.h
@@ -761,6 +761,26 @@ void clear_ctrlc (void); /* clear the Control-C condition */
int disable_ctrlc (int); /* 1 to disable, 0 to enable Control-C detect */
/*
+ * ANSI terminal
+ */
+
+#define ANSI_CURSOR_UP "\e[%dA"
+#define ANSI_CURSOR_DOWN "\e[%dB"
+#define ANSI_CURSOR_FORWARD "\e[%dC"
+#define ANSI_CURSOR_BACK "\e[%dD"
+#define ANSI_CURSOR_NEXTLINE "\e[%dE"
+#define ANSI_CURSOR_PREVIOUSLINE "\e[%dF"
+#define ANSI_CURSOR_COLUMN "\e[%dG"
+#define ANSI_CURSOR_POSITION "\e[%d;%dH"
+#define ANSI_CURSOR_SHOW "\e[?25h"
+#define ANSI_CURSOR_HIDE "\e[?25l"
+#define ANSI_CLEAR_CONSOLE "\e[2J"
+#define ANSI_CLEAR_LINE_TO_END "\e[0K"
+#define ANSI_CLEAR_LINE "\e[2K"
+#define ANSI_COLOR_RESET "\e[0m"
+#define ANSI_COLOR_REVERSE "\e[7m"
+
+/*
* STDIO based functions (can always be used)
*/
/* serial stuff */
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index 55f4f7a..d47a860 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -19,6 +19,7 @@
#define CONFIG_CMD_BEDBUG /* Include BedBug Debugger */
#define CONFIG_CMD_BMP /* BMP support */
#define CONFIG_CMD_BOOTD /* bootd */
+#define CONFIG_CMD_BOOTMENU /* ANSI terminal Boot Menu */
#define CONFIG_CMD_BOOTZ /* boot zImage */
#define CONFIG_CMD_BSP /* Board Specific functions */
#define CONFIG_CMD_CACHE /* icache, dcache */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions
2012-05-27 16:38 ` [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions Pali Rohár
@ 2012-06-03 9:59 ` Marek Vasut
2012-06-03 10:05 ` Pali Rohár
0 siblings, 1 reply; 37+ messages in thread
From: Marek Vasut @ 2012-06-03 9:59 UTC (permalink / raw)
To: u-boot
Dear Pali Roh?r,
Please CC proper custodians in order to get reviews next time.
[...]
> --- a/include/menu.h
> +++ b/include/menu.h
> @@ -21,12 +21,14 @@
> struct menu;
>
> struct menu *menu_create(char *title, int timeout, int prompt,
> - void (*item_data_print)(void *));
> + void (*item_data_print)(void *),
> + char *(*item_data_choice)(void *),
Where is this item_data_choice() used?
> + void *menu_data);
> int menu_default_set(struct menu *m, char *item_key);
> int menu_get_choice(struct menu *m, void **choice);
> int menu_item_add(struct menu *m, char *item_key, void *item_data);
> int menu_destroy(struct menu *m);
> -void menu_display_statusline(struct menu *m);
> +void menu_display_statusline(void *menu_data);
>
> #if defined(CONFIG_MENU_SHOW)
> int menu_show(int bootdelay);
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions
2012-06-03 9:59 ` Marek Vasut
@ 2012-06-03 10:05 ` Pali Rohár
2012-06-03 10:27 ` Marek Vasut
0 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2012-06-03 10:05 UTC (permalink / raw)
To: u-boot
On Sunday 03 June 2012 11:59:16 Marek Vasut wrote:
> > --- a/include/menu.h
> > +++ b/include/menu.h
> > @@ -21,12 +21,14 @@
> >
> > struct menu;
> >
> > struct menu *menu_create(char *title, int timeout, int
> > prompt,
> >
> > - void (*item_data_print)(void *));
> > + void (*item_data_print)(void *),
> > + char *(*item_data_choice)(void *),
>
> Where is this item_data_choice() used?
This is alternative function for menu entry choice. It is used in
function menu_interactive_choice. If item_data_choice is NULL
default code with readline_into_buffer is used.
ANSI bootmenu command (in next patch) is using its own function.
--
Pali Roh?r
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120603/890ac1d8/attachment.pgp>
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support
2012-05-27 16:38 ` [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
@ 2012-06-03 10:06 ` Marek Vasut
2012-06-03 16:22 ` Luka Perkov
0 siblings, 1 reply; 37+ messages in thread
From: Marek Vasut @ 2012-06-03 10:06 UTC (permalink / raw)
To: u-boot
Dear Pali Roh?r,
> Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
Try keeping the subject line short and add a patch description instead. Btw. Try
avoiding unicode characters in the patch. Also, is "Pali" your real name that
you have on your IDs etc. ?
> ---
> common/Makefile | 1 +
> common/cmd_bootmenu.c | 446
> ++++++++++++++++++++++++++++++++++++++++++++++ doc/README.bootmenu |
> 61 +++++++
> include/common.h | 20 +++
> include/config_cmd_all.h | 1 +
> 5 files changed, 529 insertions(+)
> create mode 100644 common/cmd_bootmenu.c
> create mode 100644 doc/README.bootmenu
>
> diff --git a/common/Makefile b/common/Makefile
> index 6e23baa..b9d4a4a 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -69,6 +69,7 @@ COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o
> COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
> COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
> COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
> +COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
> COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
> COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
> COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
> diff --git a/common/cmd_bootmenu.c b/common/cmd_bootmenu.c
> new file mode 100644
> index 0000000..935b60a
> --- /dev/null
> +++ b/common/cmd_bootmenu.c
> @@ -0,0 +1,446 @@
> +/*
> + * (C) Copyright 2011-2012 Pali Roh?r <pali.rohar@gmail.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <menu.h>
> +#include <hush.h>
> +#include <watchdog.h>
> +#include <malloc.h>
> +#include <linux/string.h>
> +
> +struct bootmenu_entry {
> + int num; /* unique number 0..99 */
> + char key[3]; /* key idetifier of number */
> + char *title; /* title of entry */
> + char *command; /* hush command of entry */
> + struct bootmenu_data *menu; /* this bootmenu */
> + struct bootmenu_entry *next; /* next menu entry (num+1) */
> +};
> +
> +struct bootmenu_data {
> + int delay; /* delay for autoboot */
> + int active; /* active menu entry */
> + int count; /* total count of menu entries */
> + struct bootmenu_entry *first; /* first menu entry */
> +};
> +
> +static char *bootmenu_getoption(int n)
> +{
> + char name[] = "bootmenu_\0\0";
> +
> + if (n < 0 || n > 99)
Why add this artificial limit?
> + return NULL;
> +
> + sprintf(name+9, "%d", n);
> + return getenv(name);
> +}
> +
> +static void bootmenu_print_entry(void *data)
> +{
> + struct bootmenu_entry *entry = data;
> + int reverse = (entry->menu->active == entry->num);
Why not just write it below into the condition?
> +
> + printf(ANSI_CURSOR_POSITION, entry->num + 4, 1);
What are all these artificial numbers here?
> +
> + if (reverse)
> + puts(ANSI_COLOR_REVERSE);
> +
> + puts(" ");
> + puts(entry->title);
> + puts(ANSI_CLEAR_LINE_TO_END);
> +
> + if (reverse)
> + puts(ANSI_COLOR_RESET);
> +}
> +
> +static char *bootmenu_choice_entry(void *data)
> +{
> + struct bootmenu_data *menu = data;
> +
> + int key = 0; /* 0 - NONE, 1 - UP, 2 - DOWN, 3 - SELECT */
> + int esc = 0;
Can't the spaghetti function below be split into multiple smaller ones? You know
the rule of the thumb, if the code spans multiple screens, something's seriously
wrong.
> + while (1) {
> +
> + if (menu->delay >= 0) {
> +
> + if (menu->delay > 0) {
> + printf(ANSI_CURSOR_POSITION, menu->count+5, 1);
> + printf(" Hit any key to stop autoboot: %2d ",
> + menu->delay);
> + }
> +
> + while (menu->delay > 0) {
> +
> + int i;
> + for (i = 0; i < 100; ++i) {
> + if (tstc()) {
if (!tstc())
continue;
... do your job
break;
You'll get one less level of indent and much more readable code.
> + menu->delay = -1;
> + key = getc();
> +
> + if (key == '\e') {
> + esc = 1;
> + key = 0;
> + } else if (key == '\r')
> + key = 3;
> + else
> + key = 0;
> +
> + break;
> +
> + }
> +
> + WATCHDOG_RESET();
> + udelay(10000);
mdelay() ?
> +
> + }
> +
> + if (menu->delay < 0)
> + break;
> +
> + --menu->delay;
Why do you use predecrement in the above statement? It's pointless here, simply
postdecrement it.
> + printf("\b\b\b%2d ", menu->delay);
> +
> + }
> +
> + if (menu->delay == 0)
> + key = 3;
> +
> + } else {
> +
> + while (!tstc()) {
> + WATCHDOG_RESET();
> + udelay(10000);
> + }
> +
> + key = getc();
> +
> + if (esc == 0) {
> +
> + if (key == '\e') {
> + esc = 1;
> + key = 0;
> + }
> +
> + } else if (esc == 1) {
> +
> + if (key == '[') {
> + esc = 2;
> + key = 0;
> + } else
> + esc = 0;
> +
> + } else if (esc == 2 || esc == 3) {
> +
> + if (esc == 2 && key == '1') {
> + esc = 3;
> + key = 0;
> + } else
> + esc = 0;
> +
> + if (key == 'A')
> + key = 1;
> + else if (key == 'B')
> + key = 2;
> + else
> + key = 0;
> +
> + }
> +
> + if (key == '\r')
> + key = 3;
> +
> + }
> +
> + if (key == 1) {
> + if (menu->active > 0)
> + --menu->active;
> + return ""; /* invalid menu entry, regenerate menu */
> + } else if (key == 2) {
> + if (menu->active < menu->count-1)
> + ++menu->active;
Let me guess ... they taught you at the compiler class that predecrement is
faster than postdecrement, right? Not so much on anything but intel ... and even
on intel, GCC does the decision about putting the instructions there properly to
create the fastest possible code anyway.
> + return ""; /* invalid menu entry, regenerate menu */
> + } else if (key == 3) {
> + int i;
> + struct bootmenu_entry *iter = menu->first;
> + for (i = 0; i < menu->active; ++i)
> + iter = iter->next;
> + return iter->key;
> + }
> +
> + }
> +
> + /* never happends */
Add debug() clause maybe ?
> + return NULL;
> +}
> +
> +static struct bootmenu_data *bootmenu_create(int delay)
> +{
> + int i = 0;
> + const char *option;
> + struct bootmenu_data *menu;
> + struct bootmenu_entry *iter = NULL;
> +
> + menu = malloc(sizeof(struct bootmenu_data));
> + if (!menu)
> + return NULL;
> +
> + menu->delay = delay;
> + menu->active = 0;
> + menu->first = NULL;
> +
> + while ((option = bootmenu_getoption(i))) {
> +
> + int len;
> + char *sep;
> + struct bootmenu_entry *entry;
> +
> + sep = strchr(option, '=');
> + if (!sep)
> + break;
> +
> + entry = malloc(sizeof(struct bootmenu_entry));
> + if (!entry)
> + goto cleanup;
> +
> + len = sep-option;
> + entry->title = malloc(len+1);
> + if (!entry->title) {
> + free(entry);
> + goto cleanup;
> + }
> + memcpy(entry->title, option, len);
> + entry->title[len] = 0;
> +
> + len = strlen(sep+1);
> + entry->command = malloc(len+1);
> + if (!entry->command) {
> + free(entry->title);
> + free(entry);
> + goto cleanup;
> + }
> + memcpy(entry->command, sep+1, len);
> + entry->command[len] = 0;
> +
> + sprintf(entry->key, "%d", i);
> +
> + entry->num = i;
> + entry->menu = menu;
> + entry->next = NULL;
> +
> + if (!iter)
> + menu->first = entry;
> + else
> + iter->next = entry;
> +
> + iter = entry;
> + ++i;
> +
> + if (i >= 100)
> + break;
> +
> + }
> +
> + /* Add U-Boot console entry at the end */
> + if (i < 100) {
> + struct bootmenu_entry *entry = malloc(
> + sizeof(struct bootmenu_entry));
> + if (!entry)
> + goto cleanup;
> +
> + entry->title = strdup("U-Boot console");
> + if (!entry->title) {
> + free(entry);
> + goto cleanup;
> + }
> +
> + entry->command = strdup("");
> + if (!entry->command) {
> + free(entry->title);
> + free(entry);
> + goto cleanup;
> + }
> +
> + entry->num = i;
> + entry->menu = menu;
> + entry->next = NULL;
> +
> + if (!iter)
> + menu->first = entry;
> + else
> + iter->next = entry;
> +
> + iter = entry;
> + ++i;
> +
> + }
> +
> + menu->count = i;
> + return menu;
> +
> +cleanup:
> + iter = menu->first;
> + while (iter) {
> + struct bootmenu_entry *next = iter->next;
> + free(iter->title);
> + free(iter->command);
> + free(iter);
> + iter = next;
> + }
> + free(menu);
> + return NULL;
> +}
> +
> +static void bootmenu_destroy(struct bootmenu_data *menu)
> +{
> + struct bootmenu_entry *iter = menu->first;
> + while (iter) {
> + struct bootmenu_entry *next = iter->next;
I don't like how you declare variables in the middle of code. It has sideeffects
and looking them up is really troublesome.
> + free(iter->title);
> + free(iter->command);
> + free(iter);
> + iter = next;
> + }
> + free(menu);
> +}
> +
> +static void bootmenu_show(int delay)
> +{
> + int init = 0;
> + void *choice = NULL;
> + char *title = NULL;
> + char *command = NULL;
> + struct menu *menu;
> + struct bootmenu_data *bootmenu;
> + struct bootmenu_entry *iter;
> +
> + /* If delay is 0 do not create menu, just run first entry */
> + if (delay == 0) {
> + char *option, *sep;
> + option = bootmenu_getoption(0);
> + if (!option)
> + return;
> + sep = strchr(option, '=');
> + if (!sep)
> + return;
> + run_command(sep+1, 0);
> + return;
> + }
> +
> + bootmenu = bootmenu_create(delay);
> + if (!bootmenu)
> + return;
> +
> + menu = menu_create(NULL, bootmenu->delay, (bootmenu->delay >= 0),
> + bootmenu_print_entry, bootmenu_choice_entry, bootmenu);
> + if (!menu)
> + return;
> +
> + for (iter = bootmenu->first; iter; iter = iter->next)
> + if (!menu_item_add(menu, iter->key, iter))
> + goto cleanup;
> +
> + /* Default menu entry is always first */
> + menu_default_set(menu, "0");
> +
> + puts(ANSI_CURSOR_HIDE);
> + puts(ANSI_CLEAR_CONSOLE);
> + printf(ANSI_CURSOR_POSITION, 1, 1);
> +
> + init = 1;
> +
> + if (menu_get_choice(menu, &choice)) {
> + iter = choice;
> + title = strdup(iter->title);
> + command = strdup(iter->command);
> + }
> +
> +cleanup:
> + menu_destroy(menu);
> + bootmenu_destroy(bootmenu);
> +
> + if (init) {
> + puts(ANSI_CURSOR_SHOW);
> + puts(ANSI_CLEAR_CONSOLE);
> + printf(ANSI_CURSOR_POSITION, 1, 1);
> + }
> +
> + if (title && command) {
> + printf("Starting entry '%s'\n", title);
> + free(title);
> + run_command(command, 0);
> + free(command);
> + }
> +}
> +
> +void menu_display_statusline(void *data)
> +{
> + struct bootmenu_data *menu = data;
> +
> + printf(ANSI_CURSOR_POSITION, 1, 1);
> + puts(ANSI_CLEAR_LINE);
> + printf(ANSI_CURSOR_POSITION, 2, 1);
> + puts(" *** U-Boot BOOT MENU ***");
> + puts(ANSI_CLEAR_LINE_TO_END);
> + printf(ANSI_CURSOR_POSITION, 3, 1);
> + puts(ANSI_CLEAR_LINE);
> +
> + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
> + puts(ANSI_CLEAR_LINE);
> + printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
> + puts(" Press UP/DOWN to move, ENTER to select");
> + puts(ANSI_CLEAR_LINE_TO_END);
> + printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
> + puts(ANSI_CLEAR_LINE);
> +}
> +
> +int menu_show(int bootdelay)
> +{
> + bootmenu_show(bootdelay);
> + return -1; /* -1 - abort boot and run monitor code */
> +}
> +
> +int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
> +{
> + char *delay_str = NULL;
> + int delay = 10;
> +
> + if (argc >= 2)
> + delay_str = argv[1];
> +
> + if (!delay_str)
> + delay_str = getenv("bootmenu_delay");
> +
> + if (delay_str)
> + delay = (int)simple_strtol(delay_str, NULL, 10);
> +
> + bootmenu_show(delay);
> + return 0;
> +}
> +
> +U_BOOT_CMD(
> + bootmenu, 2, 1, do_bootmenu,
> + "ANSI terminal bootmenu",
> + "[delay]\n"
> + " - show ANSI terminal bootmenu with autoboot delay (default 10s)"
> +);
> diff --git a/doc/README.bootmenu b/doc/README.bootmenu
> new file mode 100644
> index 0000000..69ef93b
> --- /dev/null
> +++ b/doc/README.bootmenu
> @@ -0,0 +1,61 @@
> +/*
> + * (C) Copyright 2011-2012 Pali Roh?r <pali.rohar@gmail.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +This is ANSI terminal BootMenu command. It is extension to generic menu,
> +which provide output for ANSI terminals.
> +
> +Configuration is done via env variables bootmenu_delay and bootmenu_<num>:
> +
> + bootmenu_delay=<delay>
> + bootmenu_<num>="<title>=<commands>"
> +
> + (title and commands are separated by first char '=')
> +
> + <delay> is delay in seconds of autobooting first entry
> + <num> is boot menu entry, starting from zero
> + <title> is text shown in boot screen
> + <commands> are commands which will be executed when menu entry is
> selected +
> +First argument of bootmenu command override bootmenu_delay env
> +If env bootmenu_delay or bootmenu arg is not specified, delay is 10
> seconds +If delay is 0, no entry will be shown on screen and first will be
> called +If delay is less then 0, no autoboot delay will be used
> +Boot Menu will stop finding next menu entry if last was not defined
> +Boot Menu always add menu entry "U-Boot console" at end of all entries
> +
> +Example using:
> +
> + setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set first menu
> entry + setenv bootmenu_1 Boot 2. kernel=bootm 0x83000000 # Set second
> menu entry + setenv bootmenu_2 Reset board=reset # Set
> third menu entry + setenv bootmenu_3 U-Boot boot order=boot #
> Set fourth menu entry + setenv bootmenu_4 # Empty string is end of all
> bootmenu entries + bootmenu 20 # Run bootmenu with autoboot delay
> 20s
> +
> +
> +To enable ANSI bootmenu comamnd add these definitions to board code:
> +
> + #define CONFIG_BOOTDELAY 30
> + #define CONFIG_AUTOBOOT_KEYED
> + #define CONFIG_MENU
> + #define CONFIG_MENU_SHOW
> + #define CONFIG_CMD_BOOTMENU
> diff --git a/include/common.h b/include/common.h
> index 8564a65..59ecdb9 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -761,6 +761,26 @@ void clear_ctrlc (void); /* clear the Control-C
> condition */ int disable_ctrlc (int); /* 1 to disable, 0 to enable
> Control-C detect */
>
> /*
> + * ANSI terminal
> + */
> +
> +#define ANSI_CURSOR_UP "\e[%dA"
> +#define ANSI_CURSOR_DOWN "\e[%dB"
> +#define ANSI_CURSOR_FORWARD "\e[%dC"
> +#define ANSI_CURSOR_BACK "\e[%dD"
> +#define ANSI_CURSOR_NEXTLINE "\e[%dE"
> +#define ANSI_CURSOR_PREVIOUSLINE "\e[%dF"
> +#define ANSI_CURSOR_COLUMN "\e[%dG"
> +#define ANSI_CURSOR_POSITION "\e[%d;%dH"
> +#define ANSI_CURSOR_SHOW "\e[?25h"
> +#define ANSI_CURSOR_HIDE "\e[?25l"
> +#define ANSI_CLEAR_CONSOLE "\e[2J"
> +#define ANSI_CLEAR_LINE_TO_END "\e[0K"
> +#define ANSI_CLEAR_LINE "\e[2K"
> +#define ANSI_COLOR_RESET "\e[0m"
> +#define ANSI_COLOR_REVERSE "\e[7m"
Isn't it possible to extend the normal bootmenu code with the ansi command
sequences and be done with it?
> +/*
> * STDIO based functions (can always be used)
> */
> /* serial stuff */
> diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
> index 55f4f7a..d47a860 100644
> --- a/include/config_cmd_all.h
> +++ b/include/config_cmd_all.h
> @@ -19,6 +19,7 @@
> #define CONFIG_CMD_BEDBUG /* Include BedBug Debugger */
> #define CONFIG_CMD_BMP /* BMP support */
> #define CONFIG_CMD_BOOTD /* bootd */
> +#define CONFIG_CMD_BOOTMENU /* ANSI terminal Boot Menu */
> #define CONFIG_CMD_BOOTZ /* boot zImage */
> #define CONFIG_CMD_BSP /* Board Specific functions */
> #define CONFIG_CMD_CACHE /* icache, dcache */
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions
2012-06-03 10:05 ` Pali Rohár
@ 2012-06-03 10:27 ` Marek Vasut
0 siblings, 0 replies; 37+ messages in thread
From: Marek Vasut @ 2012-06-03 10:27 UTC (permalink / raw)
To: u-boot
Dear Pali Roh?r,
> On Sunday 03 June 2012 11:59:16 Marek Vasut wrote:
> > > --- a/include/menu.h
> > > +++ b/include/menu.h
> > > @@ -21,12 +21,14 @@
> > >
> > > struct menu;
> > >
> > > struct menu *menu_create(char *title, int timeout, int
> > > prompt,
> > >
> > > - void (*item_data_print)(void *));
> > > + void (*item_data_print)(void *),
> > > + char *(*item_data_choice)(void *),
> >
> > Where is this item_data_choice() used?
>
> This is alternative function for menu entry choice. It is used in
> function menu_interactive_choice. If item_data_choice is NULL
> default code with readline_into_buffer is used.
>
> ANSI bootmenu command (in next patch) is using its own function.
Hm so why not make this ANSI stuff one plugin and the other bootmenu stuff
another plugin (which will be default). Then you won't have to check if anything
is null.
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support
2012-06-03 10:06 ` Marek Vasut
@ 2012-06-03 16:22 ` Luka Perkov
2012-06-03 18:27 ` Marek Vasut
0 siblings, 1 reply; 37+ messages in thread
From: Luka Perkov @ 2012-06-03 16:22 UTC (permalink / raw)
To: u-boot
Hi Marek,
On Sun, Jun 03, 2012 at 12:06:55PM +0200, Marek Vasut wrote:
> Dear Pali Roh?r,
>
> > Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
>
> Try keeping the subject line short and add a patch description instead. Btw. Try
> avoiding unicode characters in the patch. Also, is "Pali" your real name that
> you have on your IDs etc. ?
What kind of question is that :) ?
Like you can do anything if it's real or not...
Regards,
Luka
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support
2012-06-03 16:22 ` Luka Perkov
@ 2012-06-03 18:27 ` Marek Vasut
2012-06-03 21:20 ` Luka Perkov
0 siblings, 1 reply; 37+ messages in thread
From: Marek Vasut @ 2012-06-03 18:27 UTC (permalink / raw)
To: u-boot
Dear Luka Perkov,
> Hi Marek,
>
> On Sun, Jun 03, 2012 at 12:06:55PM +0200, Marek Vasut wrote:
> > Dear Pali Roh?r,
> >
> > > Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
> >
> > Try keeping the subject line short and add a patch description instead.
> > Btw. Try avoiding unicode characters in the patch. Also, is "Pali" your
> > real name that you have on your IDs etc. ?
>
> What kind of question is that :) ?
>
> Like you can do anything if it's real or not...
I can vote for the patch to not be merged obviously if it's of suspicious
origin. But before you loose your temper completely and flame me to death, read
on ...
Basically, I don't want to be the bitch that wards people off here, but we
better obey some kind of rules. See http://lwn.net/Articles/195643/ why such
possibly minor thing might be an issue. There was very long thread about it in
the LKML back in the day. Though it's not exactly the case here, Pavel, please
use the real name in your patches and especially in the SoB lines.
> Regards,
> Luka
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support
2012-06-03 18:27 ` Marek Vasut
@ 2012-06-03 21:20 ` Luka Perkov
0 siblings, 0 replies; 37+ messages in thread
From: Luka Perkov @ 2012-06-03 21:20 UTC (permalink / raw)
To: u-boot
Hi Marek,
On Sun, Jun 03, 2012 at 08:27:53PM +0200, Marek Vasut wrote:
> > > Try keeping the subject line short and add a patch description instead.
> > > Btw. Try avoiding unicode characters in the patch. Also, is "Pali" your
> > > real name that you have on your IDs etc. ?
> >
> > What kind of question is that :) ?
> >
> > Like you can do anything if it's real or not...
>
> I can vote for the patch to not be merged obviously if it's of suspicious
> origin.
Ah yes, I forgot that one.
> But before you loose your temper completely and flame me to death, read
> on ...
I'm not loosing my temper nor going to flame you ;) I was just supprised
with the question. And now I know why you have asked it.
> Basically, I don't want to be the bitch that wards people off here, but we
> better obey some kind of rules. See http://lwn.net/Articles/195643/ why such
> possibly minor thing might be an issue. There was very long thread about it in
> the LKML back in the day.
It was a good read. Thanks for pointing out that one.
Regards,
Luka
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v2 0/4] ANSI terminal Bootmenu
2012-05-27 16:38 [U-Boot] [PATCH 0/2] ANSI terminal Bootmenu Pali Rohár
2012-05-27 16:38 ` [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions Pali Rohár
2012-05-27 16:38 ` [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
@ 2012-11-01 11:39 ` Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 1/4] menu: Added support to use user defined functions Pali Rohár
` (3 more replies)
2013-02-01 15:07 ` [U-Boot] [PATCH v3 0/4] ANSI terminal Bootmenu Pali Rohár
3 siblings, 4 replies; 37+ messages in thread
From: Pali Rohár @ 2012-11-01 11:39 UTC (permalink / raw)
To: u-boot
This patch series adds ANSI terminal Bootmenu command. It use generic menu
code for creating menu structures, but use own functions for drawing menu on
ANSI terminal. First patch modify generic menu code for using other functions
for printing and choosing menu entry, second patch is bootmenu command itself.
Third and fourth patches are new in v2. Third adding new command clear which
clear ANSI terminal and fourth adding bootmenu support to Nokia RX-51 board.
Pali Roh?r (4):
menu: Added support to use user defined functions
New command bootmenu: ANSI terminal Boot Menu support
New command clear: Clear the ANSI terminal
RX-51: Add support for bootmenu
board/ait/cam_enc_4xx/cam_enc_4xx.c | 5 +-
common/Makefile | 2 +
common/cmd_bootmenu.c | 471 +++++++++++++++++++++++++++++++++++
common/cmd_clear.c | 43 ++++
common/cmd_pxe.c | 3 +-
common/menu.c | 43 ++--
doc/README.bootmenu | 61 +++++
include/ansi.h | 42 ++++
include/configs/nokia_rx51.h | 25 +-
include/menu.h | 6 +-
10 files changed, 678 insertions(+), 23 deletions(-)
create mode 100644 common/cmd_bootmenu.c
create mode 100644 common/cmd_clear.c
create mode 100644 doc/README.bootmenu
create mode 100644 include/ansi.h
--
1.7.10.4
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v2 1/4] menu: Added support to use user defined functions
2012-11-01 11:39 ` [U-Boot] [PATCH v2 0/4] ANSI terminal Bootmenu Pali Rohár
@ 2012-11-01 11:39 ` Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 2/4] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
` (2 subsequent siblings)
3 siblings, 0 replies; 37+ messages in thread
From: Pali Rohár @ 2012-11-01 11:39 UTC (permalink / raw)
To: u-boot
* In menu_interactive_choice can be used user specified function
item_data_choice (instead hardcoded function which read input
from standard input)
* Added option to specify user data for menu
* menu_display_statusline will pass pointer to user data
(instead pointer to menu)
* This patch is needed for creating ANSI bootmenu
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
---
Changes in v2:
- Rebased on next
board/ait/cam_enc_4xx/cam_enc_4xx.c | 5 ++--
common/cmd_pxe.c | 3 ++-
| 43 +++++++++++++++++++++++------------
| 6 +++--
4 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c
index 32b28f9..5078b01 100644
--- a/board/ait/cam_enc_4xx/cam_enc_4xx.c
+++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c
@@ -561,7 +561,8 @@ static char *menu_handle(struct menu_display *display)
char *s;
char temp[6][200];
- m = menu_create(display->title, display->timeout, 1, ait_menu_print);
+ m = menu_create(display->title, display->timeout, 1, ait_menu_print,
+ NULL, NULL);
for (i = 0; display->menulist[i]; i++) {
sprintf(key, "%d", i + 1);
@@ -1097,7 +1098,7 @@ int menu_show(int bootdelay)
return MENU_EXIT;
}
-void menu_display_statusline(struct menu *m)
+void menu_display_statusline(void *data)
{
char *s1, *s2;
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index ee75db9..2dbd49c 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -1280,7 +1280,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/*
* Create a menu and add items for all the labels.
*/
- m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print);
+ m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
+ NULL, NULL);
if (!m)
return NULL;
--git a/common/menu.c b/common/menu.c
index 6b2a2db..8b27c10 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -47,6 +47,8 @@ struct menu {
char *title;
int prompt;
void (*item_data_print)(void *);
+ char *(*item_data_choice)(void *);
+ void *data;
struct list_head items;
};
@@ -113,11 +115,11 @@ static inline void *menu_item_destroy(struct menu *m,
return NULL;
}
-void __menu_display_statusline(struct menu *m)
+void __menu_display_statusline(void *menu_data)
{
return;
}
-void menu_display_statusline(struct menu *m)
+void menu_display_statusline(void *menu_data)
__attribute__ ((weak, alias("__menu_display_statusline")));
/*
@@ -130,7 +132,7 @@ static inline void menu_display(struct menu *m)
puts(m->title);
putc('\n');
}
- menu_display_statusline(m);
+ menu_display_statusline(m->data);
menu_items_iter(m, menu_item_print, NULL);
}
@@ -204,18 +206,25 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)
menu_display(m);
- readret = readline_into_buffer("Enter choice: ", cbuf,
- m->timeout / 10);
-
- if (readret >= 0) {
- choice_item = menu_item_by_key(m, cbuf);
+ if (!m->item_data_choice) {
+ readret = readline_into_buffer("Enter choice: ", cbuf,
+ m->timeout / 10);
+
+ if (readret >= 0) {
+ choice_item = menu_item_by_key(m, cbuf);
+ if (!choice_item)
+ printf("%s not found\n", cbuf);
+ } else
+ return menu_default_choice(m, choice);
+ } else {
+ char *key = m->item_data_choice(m->data);
+ if (!key)
+ return menu_default_choice(m, choice);
+ choice_item = menu_item_by_key(m, key);
+ }
- if (!choice_item) {
- printf("%s not found\n", cbuf);
- m->timeout = 0;
- }
- } else
- return menu_default_choice(m, choice);
+ if (!choice_item)
+ m->timeout = 0;
}
*choice = choice_item->data;
@@ -352,7 +361,9 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data)
* insufficient memory available to create the menu.
*/
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *))
+ void (*item_data_print)(void *),
+ char *(*item_data_choice)(void *),
+ void *menu_data)
{
struct menu *m;
@@ -365,6 +376,8 @@ struct menu *menu_create(char *title, int timeout, int prompt,
m->prompt = prompt;
m->timeout = timeout;
m->item_data_print = item_data_print;
+ m->item_data_choice = item_data_choice;
+ m->data = menu_data;
if (title) {
m->title = strdup(title);
--git a/include/menu.h b/include/menu.h
index 7af5fdb..00e8975 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -21,12 +21,14 @@
struct menu;
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *));
+ void (*item_data_print)(void *),
+ char *(*item_data_choice)(void *),
+ void *menu_data);
int menu_default_set(struct menu *m, char *item_key);
int menu_get_choice(struct menu *m, void **choice);
int menu_item_add(struct menu *m, char *item_key, void *item_data);
int menu_destroy(struct menu *m);
-void menu_display_statusline(struct menu *m);
+void menu_display_statusline(void *menu_data);
#if defined(CONFIG_MENU_SHOW)
int menu_show(int bootdelay);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v2 2/4] New command bootmenu: ANSI terminal Boot Menu support
2012-11-01 11:39 ` [U-Boot] [PATCH v2 0/4] ANSI terminal Bootmenu Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 1/4] menu: Added support to use user defined functions Pali Rohár
@ 2012-11-01 11:39 ` Pali Rohár
2012-11-13 8:27 ` Wolfgang Denk
2012-11-01 11:39 ` [U-Boot] [PATCH v2 3/4] New command clear: Clear the ANSI terminal Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 4/4] RX-51: Add support for bootmenu Pali Rohár
3 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2012-11-01 11:39 UTC (permalink / raw)
To: u-boot
This patch adding ANSI terminal bootmenu command. It is extension to generic
menu which provide output for ANSI terminals.
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
---
Changes in v2:
- Added commit message
- Removed bootmenu from include/config_cmd_all.h
- Moved ANSI escape codes from include/common.h to include/ansi.h
- Fixed style and indentation problems
- Use mdelay instead udelay
- Removed autoboot delay message when some key is pressed
common/Makefile | 1 +
| 471 +++++++++++++++++++++++++++++++++++++++++++++++++
| 61 +++++++
include/ansi.h | 42 +++++
4 files changed, 575 insertions(+)
create mode 100644 common/cmd_bootmenu.c
create mode 100644 doc/README.bootmenu
create mode 100644 include/ansi.h
diff --git a/common/Makefile b/common/Makefile
index a4eb477..1435992 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -67,6 +67,7 @@ COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o
COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
+COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
--git a/common/cmd_bootmenu.c b/common/cmd_bootmenu.c
new file mode 100644
index 0000000..908e13f
--- /dev/null
+++ b/common/cmd_bootmenu.c
@@ -0,0 +1,471 @@
+/*
+ * (C) Copyright 2011-2012 Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <ansi.h>
+#include <menu.h>
+#include <hush.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <linux/string.h>
+
+struct bootmenu_entry {
+ int num; /* unique number 0..99 */
+ char key[3]; /* key idetifier of number */
+ char *title; /* title of entry */
+ char *command; /* hush command of entry */
+ struct bootmenu_data *menu; /* this bootmenu */
+ struct bootmenu_entry *next; /* next menu entry (num+1) */
+};
+
+struct bootmenu_data {
+ int delay; /* delay for autoboot */
+ int active; /* active menu entry */
+ int count; /* total count of menu entries */
+ struct bootmenu_entry *first; /* first menu entry */
+};
+
+static char *bootmenu_getoption(int n)
+{
+ char name[] = "bootmenu_\0\0";
+
+ if (n < 0 || n > 99)
+ return NULL;
+
+ sprintf(name+9, "%d", n);
+ return getenv(name);
+}
+
+static void bootmenu_print_entry(void *data)
+{
+ struct bootmenu_entry *entry = data;
+ int reverse = (entry->menu->active == entry->num);
+
+ /*
+ * Move cursor to line where entry will be drown (entry->num)
+ * First 3 lines contains Bootmenu header + 1 empty line
+ */
+ printf(ANSI_CURSOR_POSITION, entry->num + 4, 1);
+
+ if (reverse)
+ puts(ANSI_COLOR_REVERSE);
+
+ puts(" ");
+ puts(entry->title);
+ puts(ANSI_CLEAR_LINE_TO_END);
+
+ if (reverse)
+ puts(ANSI_COLOR_RESET);
+}
+
+static char *bootmenu_choice_entry(void *data)
+{
+ struct bootmenu_data *menu = data;
+ int i;
+
+ int key = 0; /* 0 - NONE, 1 - UP, 2 - DOWN, 3 - SELECT */
+ int esc = 0;
+
+ while (1) {
+
+ /* Autoboot was not stopped */
+ if (menu->delay >= 0) {
+
+ if (menu->delay > 0) {
+ printf(ANSI_CURSOR_POSITION, menu->count+5, 1);
+ printf(" Hit any key to stop autoboot: %2d ",
+ menu->delay);
+ }
+
+ while (menu->delay > 0) {
+
+ for (i = 0; i < 100; ++i) {
+
+ if (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ continue;
+ }
+
+ menu->delay = -1;
+ key = getc();
+
+ if (key == '\e') {
+ esc = 1;
+ key = 0;
+ } else if (key == '\r')
+ key = 3;
+ else
+ key = 0;
+
+ break;
+
+ }
+
+ if (menu->delay < 0)
+ break;
+
+ --menu->delay;
+ printf("\b\b\b%2d ", menu->delay);
+
+ }
+
+ printf(ANSI_CURSOR_POSITION, menu->count+5, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ if (menu->delay == 0)
+ key = 3;
+
+ /* Some key was pressed, so autoboot was stopped */
+ } else {
+
+ while (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ }
+
+ key = getc();
+
+ if (esc == 0) {
+
+ /* Start of ANSI escape sequence */
+ if (key == '\e') {
+ esc = 1;
+ key = 0;
+ }
+
+ } else if (esc == 1) {
+
+ if (key == '[') {
+ esc = 2;
+ key = 0;
+ } else
+ esc = 0;
+
+ } else if (esc == 2 || esc == 3) {
+
+ if (esc == 2 && key == '1') {
+ esc = 3;
+ key = 0;
+ } else
+ esc = 0;
+
+ /* key up was pressed */
+ if (key == 'A')
+ key = 1;
+ /* key down was pressed */
+ else if (key == 'B')
+ key = 2;
+ /* other key was pressed */
+ else
+ key = 0;
+
+ }
+
+ /* enter key was pressed */
+ if (key == '\r')
+ key = 3;
+
+ }
+
+ /* key up */
+ if (key == 1) {
+ if (menu->active > 0)
+ --menu->active;
+ return ""; /* invalid menu entry, regenerate menu */
+ /* key down */
+ } else if (key == 2) {
+ if (menu->active < menu->count-1)
+ ++menu->active;
+ return ""; /* invalid menu entry, regenerate menu */
+ /* enter */
+ } else if (key == 3) {
+ int i;
+ struct bootmenu_entry *iter = menu->first;
+ for (i = 0; i < menu->active; ++i)
+ iter = iter->next;
+ return iter->key;
+ }
+
+ }
+
+ /* never happends */
+ debug("bootmenu: this should not happen");
+ return NULL;
+}
+
+static struct bootmenu_data *bootmenu_create(int delay)
+{
+ int i = 0;
+ const char *option;
+ struct bootmenu_data *menu;
+ struct bootmenu_entry *iter = NULL;
+
+ int len;
+ char *sep;
+ struct bootmenu_entry *entry;
+
+ menu = malloc(sizeof(struct bootmenu_data));
+ if (!menu)
+ return NULL;
+
+ menu->delay = delay;
+ menu->active = 0;
+ menu->first = NULL;
+
+ while ((option = bootmenu_getoption(i))) {
+
+ sep = strchr(option, '=');
+ if (!sep)
+ break;
+
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ len = sep-option;
+ entry->title = malloc(len+1);
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->title, option, len);
+ entry->title[len] = 0;
+
+ len = strlen(sep+1);
+ entry->command = malloc(len+1);
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->command, sep+1, len);
+ entry->command[len] = 0;
+
+ sprintf(entry->key, "%d", i);
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+
+ if (i >= 100)
+ break;
+
+ }
+
+ /* Add U-Boot console entry at the end */
+ if (i < 100) {
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ entry->title = strdup("U-Boot console");
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+
+ entry->command = strdup("");
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+
+ }
+
+ menu->count = i;
+ return menu;
+
+cleanup:
+ iter = menu->first;
+ while (iter) {
+ entry = iter->next;
+ free(iter->title);
+ free(iter->command);
+ free(iter);
+ iter = entry;
+ }
+ free(menu);
+ return NULL;
+}
+
+static void bootmenu_destroy(struct bootmenu_data *menu)
+{
+ struct bootmenu_entry *iter = menu->first;
+ struct bootmenu_entry *next;
+ while (iter) {
+ next = iter->next;
+ free(iter->title);
+ free(iter->command);
+ free(iter);
+ iter = next;
+ }
+ free(menu);
+}
+
+static void bootmenu_show(int delay)
+{
+ int init = 0;
+ void *choice = NULL;
+ char *title = NULL;
+ char *command = NULL;
+ struct menu *menu;
+ struct bootmenu_data *bootmenu;
+ struct bootmenu_entry *iter;
+ char *option, *sep;
+
+ /* If delay is 0 do not create menu, just run first entry */
+ if (delay == 0) {
+ option = bootmenu_getoption(0);
+ if (!option)
+ return;
+ sep = strchr(option, '=');
+ if (!sep)
+ return;
+ run_command(sep+1, 0);
+ return;
+ }
+
+ bootmenu = bootmenu_create(delay);
+ if (!bootmenu)
+ return;
+
+ menu = menu_create(NULL, bootmenu->delay, (bootmenu->delay >= 0),
+ bootmenu_print_entry, bootmenu_choice_entry, bootmenu);
+ if (!menu)
+ return;
+
+ for (iter = bootmenu->first; iter; iter = iter->next)
+ if (!menu_item_add(menu, iter->key, iter))
+ goto cleanup;
+
+ /* Default menu entry is always first */
+ menu_default_set(menu, "0");
+
+ puts(ANSI_CURSOR_HIDE);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+
+ init = 1;
+
+ if (menu_get_choice(menu, &choice)) {
+ iter = choice;
+ title = strdup(iter->title);
+ command = strdup(iter->command);
+ }
+
+cleanup:
+ menu_destroy(menu);
+ bootmenu_destroy(bootmenu);
+
+ if (init) {
+ puts(ANSI_CURSOR_SHOW);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ }
+
+ if (title && command) {
+ printf("Starting entry '%s'\n", title);
+ free(title);
+ run_command(command, 0);
+ free(command);
+ }
+
+#ifdef CONFIG_POSTBOOTMENU
+ run_command(CONFIG_POSTBOOTMENU, 0);
+#endif
+}
+
+void menu_display_statusline(void *data)
+{
+ struct bootmenu_data *menu = data;
+
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, 2, 1);
+ puts(" *** U-Boot BOOT MENU ***");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, 3, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ /* First 3 lines are bootmenu header + 2 empty lines between entries */
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
+ puts(" Press UP/DOWN to move, ENTER to select");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
+ puts(ANSI_CLEAR_LINE);
+}
+
+int menu_show(int bootdelay)
+{
+ bootmenu_show(bootdelay);
+ return -1; /* -1 - abort boot and run monitor code */
+}
+
+int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ char *delay_str = NULL;
+ int delay = 10;
+
+ if (argc >= 2)
+ delay_str = argv[1];
+
+ if (!delay_str)
+ delay_str = getenv("bootmenu_delay");
+
+ if (delay_str)
+ delay = (int)simple_strtol(delay_str, NULL, 10);
+
+ bootmenu_show(delay);
+ return 0;
+}
+
+U_BOOT_CMD(
+ bootmenu, 2, 1, do_bootmenu,
+ "ANSI terminal bootmenu",
+ "[delay]\n"
+ " - show ANSI terminal bootmenu with autoboot delay (default 10s)"
+);
--git a/doc/README.bootmenu b/doc/README.bootmenu
new file mode 100644
index 0000000..69ef93b
--- /dev/null
+++ b/doc/README.bootmenu
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2011-2012 Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+This is ANSI terminal BootMenu command. It is extension to generic menu,
+which provide output for ANSI terminals.
+
+Configuration is done via env variables bootmenu_delay and bootmenu_<num>:
+
+ bootmenu_delay=<delay>
+ bootmenu_<num>="<title>=<commands>"
+
+ (title and commands are separated by first char '=')
+
+ <delay> is delay in seconds of autobooting first entry
+ <num> is boot menu entry, starting from zero
+ <title> is text shown in boot screen
+ <commands> are commands which will be executed when menu entry is selected
+
+First argument of bootmenu command override bootmenu_delay env
+If env bootmenu_delay or bootmenu arg is not specified, delay is 10 seconds
+If delay is 0, no entry will be shown on screen and first will be called
+If delay is less then 0, no autoboot delay will be used
+Boot Menu will stop finding next menu entry if last was not defined
+Boot Menu always add menu entry "U-Boot console" at end of all entries
+
+Example using:
+
+ setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set first menu entry
+ setenv bootmenu_1 Boot 2. kernel=bootm 0x83000000 # Set second menu entry
+ setenv bootmenu_2 Reset board=reset # Set third menu entry
+ setenv bootmenu_3 U-Boot boot order=boot # Set fourth menu entry
+ setenv bootmenu_4 # Empty string is end of all bootmenu entries
+ bootmenu 20 # Run bootmenu with autoboot delay 20s
+
+
+To enable ANSI bootmenu comamnd add these definitions to board code:
+
+ #define CONFIG_BOOTDELAY 30
+ #define CONFIG_AUTOBOOT_KEYED
+ #define CONFIG_MENU
+ #define CONFIG_MENU_SHOW
+ #define CONFIG_CMD_BOOTMENU
diff --git a/include/ansi.h b/include/ansi.h
new file mode 100644
index 0000000..0e40b1d
--- /dev/null
+++ b/include/ansi.h
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2012
+ * Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * ANSI terminal
+ */
+
+#define ANSI_CURSOR_UP "\e[%dA"
+#define ANSI_CURSOR_DOWN "\e[%dB"
+#define ANSI_CURSOR_FORWARD "\e[%dC"
+#define ANSI_CURSOR_BACK "\e[%dD"
+#define ANSI_CURSOR_NEXTLINE "\e[%dE"
+#define ANSI_CURSOR_PREVIOUSLINE "\e[%dF"
+#define ANSI_CURSOR_COLUMN "\e[%dG"
+#define ANSI_CURSOR_POSITION "\e[%d;%dH"
+#define ANSI_CURSOR_SHOW "\e[?25h"
+#define ANSI_CURSOR_HIDE "\e[?25l"
+#define ANSI_CLEAR_CONSOLE "\e[2J"
+#define ANSI_CLEAR_LINE_TO_END "\e[0K"
+#define ANSI_CLEAR_LINE "\e[2K"
+#define ANSI_COLOR_RESET "\e[0m"
+#define ANSI_COLOR_REVERSE "\e[7m"
--
1.7.10.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v2 3/4] New command clear: Clear the ANSI terminal
2012-11-01 11:39 ` [U-Boot] [PATCH v2 0/4] ANSI terminal Bootmenu Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 1/4] menu: Added support to use user defined functions Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 2/4] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
@ 2012-11-01 11:39 ` Pali Rohár
2012-11-13 8:09 ` Wolfgang Denk
2012-11-01 11:39 ` [U-Boot] [PATCH v2 4/4] RX-51: Add support for bootmenu Pali Rohár
3 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2012-11-01 11:39 UTC (permalink / raw)
To: u-boot
This patch adding new simple command clear which clear ANSI terminal.
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
Cc: Marcel Mol <marcel@mesa.nl>
---
This patch was in Nokia RX-51 patch series (v2).
Changes since RX-51 patch v2:
- Removed from include/config_cmd_all.h
- Removed ANSI escape codes (now in BootMenu command patch)
Changes since original version:
- Renamed command clr to clear
- Use puts instead printf
- Move cursor to pos1,1
common/Makefile | 1 +
common/cmd_clear.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
create mode 100644 common/cmd_clear.c
diff --git a/common/Makefile b/common/Makefile
index 1435992..328ca49 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -70,6 +70,7 @@ COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
+COBJS-$(CONFIG_CMD_CLEAR) += cmd_clear.o
COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o
COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o
diff --git a/common/cmd_clear.c b/common/cmd_clear.c
new file mode 100644
index 0000000..29b4718
--- /dev/null
+++ b/common/cmd_clear.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011
+ * Marcel Mol, MESA Consulting, marcel at mesa.nl
+ *
+ * Copyright 2011
+ * Pali Roh?r, pali.rohar at gmail.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <ansi.h>
+
+static int do_clear(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ return 0;
+}
+
+U_BOOT_CMD(
+ clear, CONFIG_SYS_MAXARGS, 1, do_clear,
+ "clear",
+ "\n"
+ " - clear screen and move cursor to top of screen"
+);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v2 4/4] RX-51: Add support for bootmenu
2012-11-01 11:39 ` [U-Boot] [PATCH v2 0/4] ANSI terminal Bootmenu Pali Rohár
` (2 preceding siblings ...)
2012-11-01 11:39 ` [U-Boot] [PATCH v2 3/4] New command clear: Clear the ANSI terminal Pali Rohár
@ 2012-11-01 11:39 ` Pali Rohár
3 siblings, 0 replies; 37+ messages in thread
From: Pali Rohár @ 2012-11-01 11:39 UTC (permalink / raw)
To: u-boot
* default bootmenu entries:
attached kernel, internal eMMC memory, external SD card, u-boot boot order
* in CONFIG_PREBOOT try load bootmenu.scr from first FAT partition of internal
eMMC memory (also known as MyDocs) which (should) overwrite default bootmenu
entries
* when keyboard slide is closed boot first menu entry
* when keyborad slide is open in show bootmenu
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
Acked-by: Tom Rini <trini@ti.com>
---
This patch was in Nokia RX-51 patch series.
Changes since RX-51 patch:
- Rebased on last Nokia RX-51 patch v5
Changes since original version:
- Fixed name of env variables
include/configs/nokia_rx51.h | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/include/configs/nokia_rx51.h b/include/configs/nokia_rx51.h
index 8506604..cd31d21 100644
--- a/include/configs/nokia_rx51.h
+++ b/include/configs/nokia_rx51.h
@@ -148,6 +148,7 @@
#define CONFIG_CMDLINE_EDITING /* add command line history */
#define CONFIG_AUTO_COMPLETE /* add autocompletion support */
+#define CONFIG_CMD_BOOTMENU /* ANSI terminal Boot Menu */
#define CONFIG_CMD_CLEAR /* ANSI terminal clear screen command */
#ifdef ONENAND_SUPPORT
@@ -287,8 +288,6 @@ int rx51_kp_getc(void);
#endif
/* Environment information */
-#define CONFIG_BOOTDELAY 3
-
#define CONFIG_EXTRA_ENV_SETTINGS \
"mtdparts=" MTDPARTS_DEFAULT "\0" \
"usbtty=cdc_acm\0" \
@@ -360,10 +359,25 @@ int rx51_kp_getc(void);
"fi\0" \
"emmcboot=setenv mmcnum 1; run trymmcboot\0" \
"sdboot=setenv mmcnum 0; run trymmcboot\0" \
+ "menucmd=bootmenu\0" \
+ "bootmenu_0=Attached kernel=run attachboot\0" \
+ "bootmenu_1=Internal eMMC=run emmcboot\0" \
+ "bootmenu_2=External SD card=run sdboot\0" \
+ "bootmenu_3=U-Boot boot order=boot\0" \
+ "bootmenu_delay=30\0" \
""
#define CONFIG_PREBOOT \
- "if run slide; then true; else run attachboot; fi;" \
+ "setenv mmcnum 1; setenv mmcpart 1; setenv mmctype fat;" \
+ "setenv mmcscriptfile bootmenu.scr;" \
+ "run trymmcscriptboot;" \
+ "if run slide; then true; else " \
+ "setenv bootmenu_delay 0;" \
+ "setenv bootdelay 0;" \
+ "fi"
+
+#define CONFIG_POSTBOOTMENU \
+ "echo;" \
"echo Extra commands:;" \
"echo run sercon - Use serial port for control.;" \
"echo run usbcon - Use usbtty for control.;" \
@@ -379,6 +393,11 @@ int rx51_kp_getc(void);
"run attachboot;" \
"echo"
+#define CONFIG_BOOTDELAY 30
+#define CONFIG_AUTOBOOT_KEYED
+#define CONFIG_MENU
+#define CONFIG_MENU_SHOW
+
/*
* Miscellaneous configurable options
*/
--
1.7.10.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v2 3/4] New command clear: Clear the ANSI terminal
2012-11-01 11:39 ` [U-Boot] [PATCH v2 3/4] New command clear: Clear the ANSI terminal Pali Rohár
@ 2012-11-13 8:09 ` Wolfgang Denk
0 siblings, 0 replies; 37+ messages in thread
From: Wolfgang Denk @ 2012-11-13 8:09 UTC (permalink / raw)
To: u-boot
Dear Pali Roh?r,
In message <1351769953-13560-4-git-send-email-pali.rohar@gmail.com> you wrote:
> This patch adding new simple command clear which clear ANSI terminal.
Please note that this duplicates or affects existing functionality;
for example, common/lcd.c implements the "cls" = Clear Screen
command.
If we add such more globnal support now, this should be unified (in a
backward compatible) way with the existing code.
Thanks.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Real Programmers always confuse Christmas and Halloween because
OCT 31 == DEC 25 ! - Andrew Rutherford (andrewr at ucs.adelaide.edu.au)
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v2 2/4] New command bootmenu: ANSI terminal Boot Menu support
2012-11-01 11:39 ` [U-Boot] [PATCH v2 2/4] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
@ 2012-11-13 8:27 ` Wolfgang Denk
2012-11-14 22:38 ` Pali Rohár
0 siblings, 1 reply; 37+ messages in thread
From: Wolfgang Denk @ 2012-11-13 8:27 UTC (permalink / raw)
To: u-boot
Dear Pali Roh?r,
In message <1351769953-13560-3-git-send-email-pali.rohar@gmail.com> you wrote:
> This patch adding ANSI terminal bootmenu command. It is extension to generic
> menu which provide output for ANSI terminals.
...
> + if (key == '\e') {
> + esc = 1;
> + key = 0;
> + } else if (key == '\r')
> + key = 3;
> + else
> + key = 0;
use switch() ?
> + if (esc == 0) {
> +
> + /* Start of ANSI escape sequence */
> + if (key == '\e') {
> + esc = 1;
> + key = 0;
> + }
> +
> + } else if (esc == 1) {
> +
> + if (key == '[') {
> + esc = 2;
> + key = 0;
> + } else
> + esc = 0;
> +
> + } else if (esc == 2 || esc == 3) {
> +
> + if (esc == 2 && key == '1') {
> + esc = 3;
> + key = 0;
> + } else
> + esc = 0;
> +
> + /* key up was pressed */
> + if (key == 'A')
> + key = 1;
> + /* key down was pressed */
> + else if (key == 'B')
> + key = 2;
> + /* other key was pressed */
> + else
> + key = 0;
> +
> + }
use switch() ?
Can we please avoid using hard-coded magic constants like 'A', 'B'
etc. here?
> + /* key up */
> + if (key == 1) {
> + if (menu->active > 0)
> + --menu->active;
> + return ""; /* invalid menu entry, regenerate menu */
> + /* key down */
> + } else if (key == 2) {
> + if (menu->active < menu->count-1)
> + ++menu->active;
> + return ""; /* invalid menu entry, regenerate menu */
> + /* enter */
> + } else if (key == 3) {
> + int i;
> + struct bootmenu_entry *iter = menu->first;
> + for (i = 0; i < menu->active; ++i)
> + iter = iter->next;
> + return iter->key;
> + }
use switch() ?
> + /* never happends */
Typo.
> + while ((option = bootmenu_getoption(i))) {
> +
> + sep = strchr(option, '=');
> + if (!sep)
> + break;
Is there any specific reason for inventing yet another data format
here? Can we not for example re-use what we already have in the
hwconfig command, and use common code for parsing the format?
Using a '=' as separator here is not a good idea, IMO.
> + /* Add U-Boot console entry at the end */
> + if (i < 100) {
Magic constant 100 ?
> +cleanup:
> + iter = menu->first;
> + while (iter) {
> + entry = iter->next;
> + free(iter->title);
> + free(iter->command);
> + free(iter);
> + iter = entry;
> + }
> + free(menu);
Make this a separate function?
> +static void bootmenu_destroy(struct bootmenu_data *menu)
> +{
> + struct bootmenu_entry *iter = menu->first;
> + struct bootmenu_entry *next;
> + while (iter) {
> + next = iter->next;
> + free(iter->title);
> + free(iter->command);
> + free(iter);
> + iter = next;
> + }
> + free(menu);
and use it here again?
> + /* If delay is 0 do not create menu, just run first entry */
> + if (delay == 0) {
> + option = bootmenu_getoption(0);
> + if (!option)
> + return;
> + sep = strchr(option, '=');
> + if (!sep)
> + return;
That would be an error condition, would it not? Should this not raise
some error message, then?
> + for (iter = bootmenu->first; iter; iter = iter->next)
> + if (!menu_item_add(menu, iter->key, iter))
> + goto cleanup;
Need braces for multi-line "for".
> +int menu_show(int bootdelay)
> +{
> + bootmenu_show(bootdelay);
> + return -1; /* -1 - abort boot and run monitor code */
> +}
If this function never returns anything else, why do we need the
return value at all?
> +int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
> +{
> + char *delay_str = NULL;
> + int delay = 10;
> +
> + if (argc >= 2)
> + delay_str = argv[1];
> +
> + if (!delay_str)
> + delay_str = getenv("bootmenu_delay");
> +
> + if (delay_str)
> + delay = (int)simple_strtol(delay_str, NULL, 10);
> +
> + bootmenu_show(delay);
> + return 0;
> +}
Umm... don't we handle any errors at all?
> +This is ANSI terminal BootMenu command. It is extension to generic menu,
Please no camel-caps.
> +First argument of bootmenu command override bootmenu_delay env
I cannot parse this.
> +If env bootmenu_delay or bootmenu arg is not specified, delay is 10 seconds
Why not using CONFIG_BOOTDELAY as default instead?
> +If delay is 0, no entry will be shown on screen and first will be called
> +If delay is less then 0, no autoboot delay will be used
What will happen then? How is this different from delay==0 ?
> +Boot Menu will stop finding next menu entry if last was not defined
I cannot parse this.
> +Boot Menu always add menu entry "U-Boot console" at end of all entries
> +
> +Example using:
> +
> + setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set first menu entry
> + setenv bootmenu_1 Boot 2. kernel=bootm 0x83000000 # Set second menu entry
> + setenv bootmenu_2 Reset board=reset # Set third menu entry
> + setenv bootmenu_3 U-Boot boot order=boot # Set fourth menu entry
> + setenv bootmenu_4 # Empty string is end of all bootmenu entries
> + bootmenu 20 # Run bootmenu with autoboot delay 20s
You might give an example here what the resulting screen will look
like.
> +To enable ANSI bootmenu comamnd add these definitions to board code:
Typo.
> + #define CONFIG_BOOTDELAY 30
> + #define CONFIG_AUTOBOOT_KEYED
Do we really need CONFIG_AUTOBOOT_KEYED ?
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Wenn das dann in die Hose geht, nehme ich es auf meine Kappe.
-- Rudi V?ller, 15. Nov 2003
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v2 2/4] New command bootmenu: ANSI terminal Boot Menu support
2012-11-13 8:27 ` Wolfgang Denk
@ 2012-11-14 22:38 ` Pali Rohár
0 siblings, 0 replies; 37+ messages in thread
From: Pali Rohár @ 2012-11-14 22:38 UTC (permalink / raw)
To: u-boot
Hi, I will fix all mentioned style problems.
On Tuesday 13 November 2012 09:27:41 Wolfgang Denk wrote:
> > + /* key up was pressed */
> > + if (key == 'A')
> > + key = 1;
> > + /* key down was pressed */
> > + else if (key == 'B')
> > + key = 2;
> > + /* other key was pressed */
> > + else
> > + key = 0;
> > +
> > + }
>
> use switch() ?
>
> Can we please avoid using hard-coded magic constants like 'A',
> 'B' etc. here?
>
And what to use? ANSI sequence for key up is \e[1A (down is B).
>
> > + while ((option = bootmenu_getoption(i))) {
> > +
> > + sep = strchr(option, '=');
> > + if (!sep)
> > + break;
>
> Is there any specific reason for inventing yet another data
> format here? Can we not for example re-use what we already
> have in the hwconfig command, and use common code for parsing
> the format?
>
> Using a '=' as separator here is not a good idea, IMO.
>
So which char is better for separator? Bootmenu line has config
"name=command" and I think '=' is the best char for separating
key and value pair.
> > + /* Add U-Boot console entry at the end */
> > + if (i < 100) {
>
> Magic constant 100 ?
>
<i>-th menu entry is stored in env bootmenu_<i> (you can look to
README for API). So I need to create string "bootmenu_<i>" and
call getenv. I think it is very bad idea to use malloc for very
allocating string of size: strlen("bootmenu_") + log10(i) + 2.
I'm using array of size strlen("bootmenu_") + 3 allocated at
stack which is enught for number less then 100. And I think 100
menu entries in uboot is really a lot of. If you do not think I
can increase number to 1000 or 10000 (which increase size of
string +2)...
> > +cleanup:
> > + iter = menu->first;
> > + while (iter) {
> > + entry = iter->next;
> > + free(iter->title);
> > + free(iter->command);
> > + free(iter);
> > + iter = entry;
> > + }
> > + free(menu);
>
> Make this a separate function?
>
Same as function bootmenu_destroy, so I changed code to call
bootmenu_destroy.
>
> > + /* If delay is 0 do not create menu, just run first entry
> > */
> > + if (delay == 0) {
> > + option = bootmenu_getoption(0);
> > + if (!option)
> > + return;
> > + sep = strchr(option, '=');
> > + if (!sep)
> > + return;
>
> That would be an error condition, would it not? Should this
> not raise some error message, then?
>
Ok, I added error message.
> > +int menu_show(int bootdelay)
> > +{
> > + bootmenu_show(bootdelay);
> > + return -1; /* -1 - abort boot and run monitor code */
> > +}
>
> If this function never returns anything else, why do we need
> the return value at all?
>
You can see that this function is not static. Reason is that
menu_show is uboot API function which must return int. -1 means
abort booting and run monitor code.
> > +int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char
> > *const argv[]) +{
> > + char *delay_str = NULL;
> > + int delay = 10;
> > +
> > + if (argc >= 2)
> > + delay_str = argv[1];
> > +
> > + if (!delay_str)
> > + delay_str = getenv("bootmenu_delay");
> > +
> > + if (delay_str)
> > + delay = (int)simple_strtol(delay_str, NULL, 10);
> > +
> > + bootmenu_show(delay);
> > + return 0;
> > +}
>
> Umm... don't we handle any errors at all?
>
I do not understand what you mean.
> > +First argument of bootmenu command override bootmenu_delay
> > env
> I cannot parse this.
>
First argument of bootmenu command is delay and override env
bootmenu_delay.
> > +If env bootmenu_delay or bootmenu arg is not specified,
> > delay is 10 seconds
> Why not using CONFIG_BOOTDELAY as default instead?
>
Ok.
> > +If delay is 0, no entry will be shown on screen and first
> > will be called +If delay is less then 0, no autoboot delay
> > will be used
> What will happen then? How is this different from delay==0 ?
>
If delay is less then 0, bootmenu will be shown and autoboot
will be disabled. So there will not be any timer which
automatically boot first entry in time $delay.
> > +Boot Menu always add menu entry "U-Boot console" at end of
> > all entries +
> > +Example using:
> > +
> > + setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set
> > first menu entry + setenv bootmenu_1 Boot 2. kernel=bootm
> > 0x83000000 # Set second menu entry + setenv bootmenu_2
> > Reset board=reset # Set third menu entry +
> > setenv bootmenu_3 U-Boot boot order=boot # Set
> > fourth menu entry + setenv bootmenu_4 # Empty string is
> > end of all bootmenu entries + bootmenu 20 # Run
> > bootmenu with autoboot delay 20s
> You might give an example here what the resulting screen will
> look like.
>
Ok, I can here text output. If you want to see screenshot from
bootmenu rendered to framebuffer (in qemu) here is:
http://atrey.karlin.mff.cuni.cz/~pali/u-boot-bootmenu.png
>
> > + #define CONFIG_BOOTDELAY 30
> > + #define CONFIG_AUTOBOOT_KEYED
>
> Do we really need CONFIG_AUTOBOOT_KEYED ?
>
Yes, because menu_show() call in common/main.c is called only of
CONFIG_AUTOBOOT_KEYED is defined. You can look at this condition.
--
Pali Roh?r
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20121114/43f0332a/attachment.pgp>
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v3 0/4] ANSI terminal Bootmenu
2012-05-27 16:38 [U-Boot] [PATCH 0/2] ANSI terminal Bootmenu Pali Rohár
` (2 preceding siblings ...)
2012-11-01 11:39 ` [U-Boot] [PATCH v2 0/4] ANSI terminal Bootmenu Pali Rohár
@ 2013-02-01 15:07 ` Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 1/4] menu: Added support to use user defined functions Pali Rohár
` (3 more replies)
3 siblings, 4 replies; 37+ messages in thread
From: Pali Rohár @ 2013-02-01 15:07 UTC (permalink / raw)
To: u-boot
This patch series adds ANSI terminal Bootmenu command. It use generic menu
code for creating menu structures, but use own functions for drawing menu on
ANSI terminal. First patch modify generic menu code for using other functions
for printing and choosing menu entry, second patch is bootmenu command itself.
Third and fourth patches were new in v2. Third adding new command clear which
clear ANSI terminal and fourth adding bootmenu support to Nokia RX-51 board.
Pali Roh?r (4):
menu: Added support to use user defined functions
New command bootmenu: ANSI terminal Boot Menu support
New command clear: Clear the ANSI terminal
RX-51: Add support for bootmenu
board/ait/cam_enc_4xx/cam_enc_4xx.c | 5 +-
common/Makefile | 2 +
common/cmd_bootmenu.c | 515 +++++++++++++++++++++++++++++++++++
common/cmd_clear.c | 43 +++
common/cmd_pxe.c | 3 +-
common/menu.c | 43 ++-
doc/README.bootmenu | 86 ++++++
include/ansi.h | 42 +++
include/configs/nokia_rx51.h | 25 +-
include/menu.h | 6 +-
10 files changed, 747 insertions(+), 23 deletions(-)
create mode 100644 common/cmd_bootmenu.c
create mode 100644 common/cmd_clear.c
create mode 100644 doc/README.bootmenu
create mode 100644 include/ansi.h
--
1.7.10.4
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v3 1/4] menu: Added support to use user defined functions
2013-02-01 15:07 ` [U-Boot] [PATCH v3 0/4] ANSI terminal Bootmenu Pali Rohár
@ 2013-02-01 15:07 ` Pali Rohár
2013-03-24 0:50 ` [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function Anatolij Gustschin
2013-02-01 15:07 ` [U-Boot] [PATCH v3 2/4] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
` (2 subsequent siblings)
3 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2013-02-01 15:07 UTC (permalink / raw)
To: u-boot
* In menu_interactive_choice can be used user specified function
item_data_choice (instead hardcoded function which read input
from standard input)
* Added option to specify user data for menu
* menu_display_statusline will pass pointer to user data
(instead pointer to menu)
* This patch is needed for creating ANSI bootmenu
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
---
No changes in v3
Changes in v2:
- Rebased on next
board/ait/cam_enc_4xx/cam_enc_4xx.c | 5 ++--
common/cmd_pxe.c | 3 ++-
| 43 +++++++++++++++++++++++------------
| 6 +++--
4 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c
index 32b28f9..5078b01 100644
--- a/board/ait/cam_enc_4xx/cam_enc_4xx.c
+++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c
@@ -561,7 +561,8 @@ static char *menu_handle(struct menu_display *display)
char *s;
char temp[6][200];
- m = menu_create(display->title, display->timeout, 1, ait_menu_print);
+ m = menu_create(display->title, display->timeout, 1, ait_menu_print,
+ NULL, NULL);
for (i = 0; display->menulist[i]; i++) {
sprintf(key, "%d", i + 1);
@@ -1097,7 +1098,7 @@ int menu_show(int bootdelay)
return MENU_EXIT;
}
-void menu_display_statusline(struct menu *m)
+void menu_display_statusline(void *data)
{
char *s1, *s2;
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index ee75db9..2dbd49c 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -1280,7 +1280,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/*
* Create a menu and add items for all the labels.
*/
- m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print);
+ m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
+ NULL, NULL);
if (!m)
return NULL;
--git a/common/menu.c b/common/menu.c
index 6b2a2db..8b27c10 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -47,6 +47,8 @@ struct menu {
char *title;
int prompt;
void (*item_data_print)(void *);
+ char *(*item_data_choice)(void *);
+ void *data;
struct list_head items;
};
@@ -113,11 +115,11 @@ static inline void *menu_item_destroy(struct menu *m,
return NULL;
}
-void __menu_display_statusline(struct menu *m)
+void __menu_display_statusline(void *menu_data)
{
return;
}
-void menu_display_statusline(struct menu *m)
+void menu_display_statusline(void *menu_data)
__attribute__ ((weak, alias("__menu_display_statusline")));
/*
@@ -130,7 +132,7 @@ static inline void menu_display(struct menu *m)
puts(m->title);
putc('\n');
}
- menu_display_statusline(m);
+ menu_display_statusline(m->data);
menu_items_iter(m, menu_item_print, NULL);
}
@@ -204,18 +206,25 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)
menu_display(m);
- readret = readline_into_buffer("Enter choice: ", cbuf,
- m->timeout / 10);
-
- if (readret >= 0) {
- choice_item = menu_item_by_key(m, cbuf);
+ if (!m->item_data_choice) {
+ readret = readline_into_buffer("Enter choice: ", cbuf,
+ m->timeout / 10);
+
+ if (readret >= 0) {
+ choice_item = menu_item_by_key(m, cbuf);
+ if (!choice_item)
+ printf("%s not found\n", cbuf);
+ } else
+ return menu_default_choice(m, choice);
+ } else {
+ char *key = m->item_data_choice(m->data);
+ if (!key)
+ return menu_default_choice(m, choice);
+ choice_item = menu_item_by_key(m, key);
+ }
- if (!choice_item) {
- printf("%s not found\n", cbuf);
- m->timeout = 0;
- }
- } else
- return menu_default_choice(m, choice);
+ if (!choice_item)
+ m->timeout = 0;
}
*choice = choice_item->data;
@@ -352,7 +361,9 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data)
* insufficient memory available to create the menu.
*/
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *))
+ void (*item_data_print)(void *),
+ char *(*item_data_choice)(void *),
+ void *menu_data)
{
struct menu *m;
@@ -365,6 +376,8 @@ struct menu *menu_create(char *title, int timeout, int prompt,
m->prompt = prompt;
m->timeout = timeout;
m->item_data_print = item_data_print;
+ m->item_data_choice = item_data_choice;
+ m->data = menu_data;
if (title) {
m->title = strdup(title);
--git a/include/menu.h b/include/menu.h
index 7af5fdb..00e8975 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -21,12 +21,14 @@
struct menu;
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *));
+ void (*item_data_print)(void *),
+ char *(*item_data_choice)(void *),
+ void *menu_data);
int menu_default_set(struct menu *m, char *item_key);
int menu_get_choice(struct menu *m, void **choice);
int menu_item_add(struct menu *m, char *item_key, void *item_data);
int menu_destroy(struct menu *m);
-void menu_display_statusline(struct menu *m);
+void menu_display_statusline(void *menu_data);
#if defined(CONFIG_MENU_SHOW)
int menu_show(int bootdelay);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v3 2/4] New command bootmenu: ANSI terminal Boot Menu support
2013-02-01 15:07 ` [U-Boot] [PATCH v3 0/4] ANSI terminal Bootmenu Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 1/4] menu: Added support to use user defined functions Pali Rohár
@ 2013-02-01 15:07 ` Pali Rohár
2013-03-24 0:53 ` [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support Anatolij Gustschin
2013-02-01 15:07 ` [U-Boot] [PATCH v3 3/4] New command clear: Clear the ANSI terminal Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 4/4] RX-51: Add support for bootmenu Pali Rohár
3 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2013-02-01 15:07 UTC (permalink / raw)
To: u-boot
This patch adding ANSI terminal bootmenu command. It is extension to generic
menu which provide output for ANSI terminals.
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
---
Changes in v3:
- Do not use hardcoded numbers, added MAX_COUNT and MAX_ENV_SIZE
- Use unsigned short int for menu number
- Use enum bootmenu_key for key selection
- Separate loop code from function bootmenu_choice_entry to bootmenu_loop and bootmenu_autoboot_loop
- Updated README, added example
- Use switches, added braces, fix style problems
Changes in v2:
- Added commit message
- Removed bootmenu from include/config_cmd_all.h
- Moved ANSI escape codes from include/common.h to include/ansi.h
- Fixed style and indentation problems
- Use mdelay instead udelay
- Removed autoboot delay message when some key is pressed
common/Makefile | 1 +
| 515 +++++++++++++++++++++++++++++++++++++++++++++++++
| 86 +++++++++
include/ansi.h | 42 ++++
4 files changed, 644 insertions(+)
create mode 100644 common/cmd_bootmenu.c
create mode 100644 doc/README.bootmenu
create mode 100644 include/ansi.h
diff --git a/common/Makefile b/common/Makefile
index 54fcc81..0bd82a9 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -71,6 +71,7 @@ COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o
COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
+COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
--git a/common/cmd_bootmenu.c b/common/cmd_bootmenu.c
new file mode 100644
index 0000000..b4787ee
--- /dev/null
+++ b/common/cmd_bootmenu.c
@@ -0,0 +1,515 @@
+/*
+ * (C) Copyright 2011-2013 Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <ansi.h>
+#include <menu.h>
+#include <hush.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <linux/string.h>
+
+/* maximum bootmenu entries */
+#define MAX_COUNT 99
+
+/* maximal size of bootmenu env
+ * 9 = strlen("bootmenu_")
+ * 2 = strlen(MAX_COUNT)
+ * 1 = NULL term
+ */
+#define MAX_ENV_SIZE (9+2+1)
+
+struct bootmenu_entry {
+ unsigned short int num; /* unique number 0 .. MAX_COUNT */
+ char key[3]; /* key identifier of number */
+ char *title; /* title of entry */
+ char *command; /* hush command of entry */
+ struct bootmenu_data *menu; /* this bootmenu */
+ struct bootmenu_entry *next; /* next menu entry (num+1) */
+};
+
+struct bootmenu_data {
+ int delay; /* delay for autoboot */
+ int active; /* active menu entry */
+ int count; /* total count of menu entries */
+ struct bootmenu_entry *first; /* first menu entry */
+};
+
+enum bootmenu_key {
+ KEY_NONE = 0,
+ KEY_UP,
+ KEY_DOWN,
+ KEY_SELECT,
+};
+
+static char *bootmenu_getoption(unsigned short int n)
+{
+ char name[MAX_ENV_SIZE] = "bootmenu_";
+
+ if (n > MAX_COUNT)
+ return NULL;
+
+ sprintf(name+9, "%d", n);
+ return getenv(name);
+}
+
+static void bootmenu_print_entry(void *data)
+{
+ struct bootmenu_entry *entry = data;
+ int reverse = (entry->menu->active == entry->num);
+
+ /*
+ * Move cursor to line where entry will be drown (entry->num)
+ * First 3 lines contains Bootmenu header + 1 empty line
+ */
+ printf(ANSI_CURSOR_POSITION, entry->num + 4, 1);
+
+ if (reverse)
+ puts(ANSI_COLOR_REVERSE);
+
+ puts(" ");
+ puts(entry->title);
+ puts(ANSI_CLEAR_LINE_TO_END);
+
+ if (reverse)
+ puts(ANSI_COLOR_RESET);
+}
+
+static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc)
+{
+ int i, c;
+
+ if (menu->delay > 0) {
+ printf(ANSI_CURSOR_POSITION, menu->count+5, 1);
+ printf(" Hit any key to stop autoboot: %2d ",
+ menu->delay);
+ }
+
+ while (menu->delay > 0) {
+
+ for (i = 0; i < 100; ++i) {
+
+ if (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ continue;
+ }
+
+ menu->delay = -1;
+ c = getc();
+
+ switch (c) {
+ case '\e':
+ *esc = 1;
+ *key = KEY_NONE;
+ break;
+ case '\r':
+ *key = KEY_SELECT;
+ break;
+ default:
+ *key = KEY_NONE;
+ break;
+ }
+
+ break;
+
+ }
+
+ if (menu->delay < 0)
+ break;
+
+ --menu->delay;
+ printf("\b\b\b%2d ", menu->delay);
+
+ }
+
+ printf(ANSI_CURSOR_POSITION, menu->count+5, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ if (menu->delay == 0)
+ *key = KEY_SELECT;
+}
+
+static void bootmenu_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc)
+{
+ int c;
+
+ while (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ }
+
+ c = getc();
+
+ switch (*esc) {
+
+ case 0:
+ /* First char of ANSI escape sequence '\e' */
+ if (c == '\e') {
+ *esc = 1;
+ *key = KEY_NONE;
+ }
+ break;
+
+ case 1:
+ /* Second char of ANSI '[' */
+ if (c == '[') {
+ *esc = 2;
+ *key = KEY_NONE;
+ } else
+ *esc = 0;
+ break;
+
+ case 2:
+ case 3:
+ /* Third char of ANSI (number '1') - optional */
+ if (*esc == 2 && c == '1') {
+ *esc = 3;
+ *key = KEY_NONE;
+ break;
+ }
+
+ *esc = 0;
+
+ /* ANSI 'A' - key up was pressed */
+ if (c == 'A')
+ *key = KEY_UP;
+ /* ANSI 'B' - key down was pressed */
+ else if (c == 'B')
+ *key = KEY_DOWN;
+ /* other key was pressed */
+ else
+ *key = KEY_NONE;
+
+ break;
+
+ }
+
+ /* enter key was pressed */
+ if (c == '\r')
+ *key = KEY_SELECT;
+}
+
+static char *bootmenu_choice_entry(void *data)
+{
+ struct bootmenu_data *menu = data;
+ struct bootmenu_entry *iter;
+ enum bootmenu_key key = KEY_NONE;
+ int esc = 0;
+ int i;
+
+ while (1) {
+
+ /* Autoboot was not stopped */
+ if (menu->delay >= 0) {
+ bootmenu_autoboot_loop(menu, &key, &esc);
+ /* Some key was pressed, so autoboot was stopped */
+ } else {
+ bootmenu_loop(menu, &key, &esc);
+ }
+
+ switch (key) {
+ case KEY_UP:
+ if (menu->active > 0)
+ --menu->active;
+ return ""; /* invalid menu entry, regenerate menu */
+ case KEY_DOWN:
+ if (menu->active < menu->count-1)
+ ++menu->active;
+ return ""; /* invalid menu entry, regenerate menu */
+ case KEY_SELECT:
+ iter = menu->first;
+ for (i = 0; i < menu->active; ++i)
+ iter = iter->next;
+ return iter->key;
+ default:
+ break;
+ }
+
+ }
+
+ /* never happends */
+ debug("bootmenu: this should not happen");
+ return NULL;
+}
+
+static void bootmenu_destroy(struct bootmenu_data *menu)
+{
+ struct bootmenu_entry *iter = menu->first;
+ struct bootmenu_entry *next;
+ while (iter) {
+ next = iter->next;
+ free(iter->title);
+ free(iter->command);
+ free(iter);
+ iter = next;
+ }
+ free(menu);
+}
+
+static struct bootmenu_data *bootmenu_create(int delay)
+{
+ unsigned short int i = 0;
+ const char *option;
+ struct bootmenu_data *menu;
+ struct bootmenu_entry *iter = NULL;
+
+ int len;
+ char *sep;
+ struct bootmenu_entry *entry;
+
+ menu = malloc(sizeof(struct bootmenu_data));
+ if (!menu)
+ return NULL;
+
+ menu->delay = delay;
+ menu->active = 0;
+ menu->first = NULL;
+
+ while ((option = bootmenu_getoption(i))) {
+
+ sep = strchr(option, '=');
+ if (!sep)
+ break;
+
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ len = sep-option;
+ entry->title = malloc(len+1);
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->title, option, len);
+ entry->title[len] = 0;
+
+ len = strlen(sep+1);
+ entry->command = malloc(len+1);
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->command, sep+1, len);
+ entry->command[len] = 0;
+
+ sprintf(entry->key, "%d", i);
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+
+ if (i > MAX_COUNT)
+ break;
+
+ }
+
+ /* Add U-Boot console entry at the end */
+ if (i <= MAX_COUNT) {
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ entry->title = strdup("U-Boot console");
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+
+ entry->command = strdup("");
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+
+ }
+
+ menu->count = i;
+ return menu;
+
+cleanup:
+ bootmenu_destroy(menu);
+ return NULL;
+}
+
+static void bootmenu_show(int delay)
+{
+ int init = 0;
+ void *choice = NULL;
+ char *title = NULL;
+ char *command = NULL;
+ struct menu *menu;
+ struct bootmenu_data *bootmenu;
+ struct bootmenu_entry *iter;
+ char *option, *sep;
+
+ /* If delay is 0 do not create menu, just run first entry */
+ if (delay == 0) {
+ option = bootmenu_getoption(0);
+ if (!option) {
+ printf("bootmenu option 0 was not found\n");
+ return;
+ }
+ sep = strchr(option, '=');
+ if (!sep) {
+ printf("bootmenu option 0 is invalid\n");
+ return;
+ }
+ run_command(sep+1, 0);
+ return;
+ }
+
+ bootmenu = bootmenu_create(delay);
+ if (!bootmenu)
+ return;
+
+ menu = menu_create(NULL, bootmenu->delay, (bootmenu->delay >= 0),
+ bootmenu_print_entry, bootmenu_choice_entry, bootmenu);
+ if (!menu)
+ return;
+
+ for (iter = bootmenu->first; iter; iter = iter->next) {
+ if (!menu_item_add(menu, iter->key, iter))
+ goto cleanup;
+ }
+
+ /* Default menu entry is always first */
+ menu_default_set(menu, "0");
+
+ puts(ANSI_CURSOR_HIDE);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+
+ init = 1;
+
+ if (menu_get_choice(menu, &choice)) {
+ iter = choice;
+ title = strdup(iter->title);
+ command = strdup(iter->command);
+ }
+
+cleanup:
+ menu_destroy(menu);
+ bootmenu_destroy(bootmenu);
+
+ if (init) {
+ puts(ANSI_CURSOR_SHOW);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ }
+
+ if (title && command) {
+ printf("Starting entry '%s'\n", title);
+ free(title);
+ run_command(command, 0);
+ free(command);
+ }
+
+#ifdef CONFIG_POSTBOOTMENU
+ run_command(CONFIG_POSTBOOTMENU, 0);
+#endif
+}
+
+void menu_display_statusline(void *data)
+{
+ struct bootmenu_data *menu = data;
+
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, 2, 1);
+ puts(" *** U-Boot BOOT MENU ***");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, 3, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ /* First 3 lines are bootmenu header + 2 empty lines between entries */
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
+ puts(" Press UP/DOWN to move, ENTER to select");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
+ puts(ANSI_CLEAR_LINE);
+}
+
+#ifdef CONFIG_MENU_SHOW
+int menu_show(int bootdelay)
+{
+ bootmenu_show(bootdelay);
+ return -1; /* -1 - abort boot and run monitor code */
+}
+#endif
+
+int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ char *delay_str = NULL;
+ int delay = 10;
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+ delay = CONFIG_BOOTDELAY;
+#endif
+
+ if (argc >= 2)
+ delay_str = argv[1];
+
+ if (!delay_str)
+ delay_str = getenv("bootmenu_delay");
+
+ if (delay_str)
+ delay = (int)simple_strtol(delay_str, NULL, 10);
+
+ bootmenu_show(delay);
+ return 0;
+}
+
+U_BOOT_CMD(
+ bootmenu, 2, 1, do_bootmenu,
+ "ANSI terminal bootmenu",
+ "[delay]\n"
+ " - show ANSI terminal bootmenu with autoboot delay"
+);
--git a/doc/README.bootmenu b/doc/README.bootmenu
new file mode 100644
index 0000000..71a9aa6
--- /dev/null
+++ b/doc/README.bootmenu
@@ -0,0 +1,86 @@
+/*
+ * (C) Copyright 2011-2012 Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+This is ANSI terminal bootmenu command. It is extension to generic menu,
+which provide output for ANSI terminals.
+
+Configuration is done via env variables bootmenu_delay and bootmenu_<num>:
+
+ bootmenu_delay=<delay>
+ bootmenu_<num>="<title>=<commands>"
+
+ (title and commands are separated by first char '=')
+
+ <delay> is delay in seconds of autobooting first entry
+ <num> is boot menu entry, starting from zero
+ <title> is text shown in boot screen
+ <commands> are commands which will be executed when menu entry is selected
+
+First argument of bootmenu command is delay and override env bootmenu_delay
+If env bootmenu_delay or bootmenu arg is not specified, default delay is
+CONFIG_BOOTDELAY. If delay is 0, no entry will be shown on screen and first
+will be called. If delay is less then 0, bootmenu will be shown and autoboot
+will be disabled. Bootmenu always add menu entry "U-Boot console" at end of
+all entries.
+
+
+Example using:
+
+ setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set first menu entry
+ setenv bootmenu_1 Boot 2. kernel=bootm 0x83000000 # Set second menu entry
+ setenv bootmenu_2 Reset board=reset # Set third menu entry
+ setenv bootmenu_3 U-Boot boot order=boot # Set fourth menu entry
+ setenv bootmenu_4 # Empty string is end of all bootmenu entries
+ bootmenu 20 # Run bootmenu with autoboot delay 20s
+
+
+This example will be rendered as:
+
+--------------------------------------------
+| |
+| *** U-Boot BOOT MENU *** |
+| |
+|#####Boot 1. kernel#######################|
+| Boot 2. kernel |
+| Reset board |
+| U-Boot boot order |
+| U-Boot console |
+| |
+| Hit any key to stop autoboot: 20 |
+| Press UP/DOWN to move, ENTER to select |
+| |
+--------------------------------------------
+
+(selected line is highlighted - has inverted background and text colors)
+
+
+To enable ANSI bootmenu command add these definitions to board code:
+
+ #define CONFIG_CMD_BOOTMENU
+ #define CONFIG_MENU
+
+
+To run ANSI bootmenu at startup add these additional definitions:
+
+ #define CONFIG_AUTOBOOT_KEYED
+ #define CONFIG_BOOTDELAY 30
+ #define CONFIG_MENU_SHOW
diff --git a/include/ansi.h b/include/ansi.h
new file mode 100644
index 0000000..0e40b1d
--- /dev/null
+++ b/include/ansi.h
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2012
+ * Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * ANSI terminal
+ */
+
+#define ANSI_CURSOR_UP "\e[%dA"
+#define ANSI_CURSOR_DOWN "\e[%dB"
+#define ANSI_CURSOR_FORWARD "\e[%dC"
+#define ANSI_CURSOR_BACK "\e[%dD"
+#define ANSI_CURSOR_NEXTLINE "\e[%dE"
+#define ANSI_CURSOR_PREVIOUSLINE "\e[%dF"
+#define ANSI_CURSOR_COLUMN "\e[%dG"
+#define ANSI_CURSOR_POSITION "\e[%d;%dH"
+#define ANSI_CURSOR_SHOW "\e[?25h"
+#define ANSI_CURSOR_HIDE "\e[?25l"
+#define ANSI_CLEAR_CONSOLE "\e[2J"
+#define ANSI_CLEAR_LINE_TO_END "\e[0K"
+#define ANSI_CLEAR_LINE "\e[2K"
+#define ANSI_COLOR_RESET "\e[0m"
+#define ANSI_COLOR_REVERSE "\e[7m"
--
1.7.10.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v3 3/4] New command clear: Clear the ANSI terminal
2013-02-01 15:07 ` [U-Boot] [PATCH v3 0/4] ANSI terminal Bootmenu Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 1/4] menu: Added support to use user defined functions Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 2/4] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
@ 2013-02-01 15:07 ` Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 4/4] RX-51: Add support for bootmenu Pali Rohár
3 siblings, 0 replies; 37+ messages in thread
From: Pali Rohár @ 2013-02-01 15:07 UTC (permalink / raw)
To: u-boot
This patch adding new simple command clear which clear ANSI terminal.
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
Cc: Marcel Mol <marcel@mesa.nl>
---
No changes in v3
This patch was in Nokia RX-51 patch series (v2).
Changes since RX-51 patch v2:
- Removed from include/config_cmd_all.h
- Removed ANSI escape codes (now in BootMenu command patch)
Changes since original version:
- Renamed command clr to clear
- Use puts instead printf
- Move cursor to pos1,1
common/Makefile | 1 +
common/cmd_clear.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
create mode 100644 common/cmd_clear.c
diff --git a/common/Makefile b/common/Makefile
index 0bd82a9..4a0519b 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -76,6 +76,7 @@ COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
COBJS-$(CONFIG_CMD_CBFS) += cmd_cbfs.o
+COBJS-$(CONFIG_CMD_CLEAR) += cmd_clear.o
COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o
COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o
diff --git a/common/cmd_clear.c b/common/cmd_clear.c
new file mode 100644
index 0000000..29b4718
--- /dev/null
+++ b/common/cmd_clear.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011
+ * Marcel Mol, MESA Consulting, marcel at mesa.nl
+ *
+ * Copyright 2011
+ * Pali Roh?r, pali.rohar at gmail.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <ansi.h>
+
+static int do_clear(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ return 0;
+}
+
+U_BOOT_CMD(
+ clear, CONFIG_SYS_MAXARGS, 1, do_clear,
+ "clear",
+ "\n"
+ " - clear screen and move cursor to top of screen"
+);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v3 4/4] RX-51: Add support for bootmenu
2013-02-01 15:07 ` [U-Boot] [PATCH v3 0/4] ANSI terminal Bootmenu Pali Rohár
` (2 preceding siblings ...)
2013-02-01 15:07 ` [U-Boot] [PATCH v3 3/4] New command clear: Clear the ANSI terminal Pali Rohár
@ 2013-02-01 15:07 ` Pali Rohár
2013-03-07 15:15 ` Pali Rohár
3 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2013-02-01 15:07 UTC (permalink / raw)
To: u-boot
* default bootmenu entries:
attached kernel, internal eMMC memory, external SD card, u-boot boot order
* in CONFIG_PREBOOT try load bootmenu.scr from first FAT partition of internal
eMMC memory (also known as MyDocs) which (should) overwrite default bootmenu
entries
* when keyboard slide is closed boot first menu entry
* when keyborad slide is open in show bootmenu
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
Acked-by: Tom Rini <trini@ti.com>
---
No changes in v3
This patch was in Nokia RX-51 patch series.
Changes since RX-51 patch:
- Rebased on last Nokia RX-51 patch v5
Changes since original version:
- Fixed name of env variables
include/configs/nokia_rx51.h | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/include/configs/nokia_rx51.h b/include/configs/nokia_rx51.h
index 8506604..cd31d21 100644
--- a/include/configs/nokia_rx51.h
+++ b/include/configs/nokia_rx51.h
@@ -148,6 +148,7 @@
#define CONFIG_CMDLINE_EDITING /* add command line history */
#define CONFIG_AUTO_COMPLETE /* add autocompletion support */
+#define CONFIG_CMD_BOOTMENU /* ANSI terminal Boot Menu */
#define CONFIG_CMD_CLEAR /* ANSI terminal clear screen command */
#ifdef ONENAND_SUPPORT
@@ -287,8 +288,6 @@ int rx51_kp_getc(void);
#endif
/* Environment information */
-#define CONFIG_BOOTDELAY 3
-
#define CONFIG_EXTRA_ENV_SETTINGS \
"mtdparts=" MTDPARTS_DEFAULT "\0" \
"usbtty=cdc_acm\0" \
@@ -360,10 +359,25 @@ int rx51_kp_getc(void);
"fi\0" \
"emmcboot=setenv mmcnum 1; run trymmcboot\0" \
"sdboot=setenv mmcnum 0; run trymmcboot\0" \
+ "menucmd=bootmenu\0" \
+ "bootmenu_0=Attached kernel=run attachboot\0" \
+ "bootmenu_1=Internal eMMC=run emmcboot\0" \
+ "bootmenu_2=External SD card=run sdboot\0" \
+ "bootmenu_3=U-Boot boot order=boot\0" \
+ "bootmenu_delay=30\0" \
""
#define CONFIG_PREBOOT \
- "if run slide; then true; else run attachboot; fi;" \
+ "setenv mmcnum 1; setenv mmcpart 1; setenv mmctype fat;" \
+ "setenv mmcscriptfile bootmenu.scr;" \
+ "run trymmcscriptboot;" \
+ "if run slide; then true; else " \
+ "setenv bootmenu_delay 0;" \
+ "setenv bootdelay 0;" \
+ "fi"
+
+#define CONFIG_POSTBOOTMENU \
+ "echo;" \
"echo Extra commands:;" \
"echo run sercon - Use serial port for control.;" \
"echo run usbcon - Use usbtty for control.;" \
@@ -379,6 +393,11 @@ int rx51_kp_getc(void);
"run attachboot;" \
"echo"
+#define CONFIG_BOOTDELAY 30
+#define CONFIG_AUTOBOOT_KEYED
+#define CONFIG_MENU
+#define CONFIG_MENU_SHOW
+
/*
* Miscellaneous configurable options
*/
--
1.7.10.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v3 4/4] RX-51: Add support for bootmenu
2013-02-01 15:07 ` [U-Boot] [PATCH v3 4/4] RX-51: Add support for bootmenu Pali Rohár
@ 2013-03-07 15:15 ` Pali Rohár
2013-03-28 23:26 ` Anatolij Gustschin
0 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2013-03-07 15:15 UTC (permalink / raw)
To: u-boot
Hi, I'm sending new version of patch which try to use also ext filesystem (not only fat)
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function
2013-02-01 15:07 ` [U-Boot] [PATCH v3 1/4] menu: Added support to use user defined functions Pali Rohár
@ 2013-03-24 0:50 ` Anatolij Gustschin
2013-03-24 0:52 ` [U-Boot] [PATCH] menu: export menu_default_choice() function Anatolij Gustschin
2013-03-28 15:26 ` [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function Anatolij Gustschin
0 siblings, 2 replies; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-24 0:50 UTC (permalink / raw)
To: u-boot
From: Pali Roh?r <pali.rohar@gmail.com>
Selecting menu items is currently done in menu_interactive_choice()
by reading the user input strings from standard input.
Extend menu_interactive_choice() to support user defined function
for selecting menu items. This function and its argument can be
specified when creating the menu.
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Changes in v4:
- slightly rename the new item choice callback and its argument
- add documentation for added item choice callback
- search for menu item key only if the choice callback
returned a key (not NULL)
- do not change menu_display_statusline() function argument
(previous patch changed this menu API function but didn't
update documentation for this change. This change is
actually not needed, menu item data can be obtained by
exported menu_default_choice())
- revise commit log
No changes in v3
Changes in v2:
- Rebased on next
board/ait/cam_enc_4xx/cam_enc_4xx.c | 3 +-
common/cmd_pxe.c | 3 +-
| 42 +++++++++++++++++++++++++---------
| 4 ++-
| 4 ++-
5 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c
index 32b28f9..644c445 100644
--- a/board/ait/cam_enc_4xx/cam_enc_4xx.c
+++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c
@@ -561,7 +561,8 @@ static char *menu_handle(struct menu_display *display)
char *s;
char temp[6][200];
- m = menu_create(display->title, display->timeout, 1, ait_menu_print);
+ m = menu_create(display->title, display->timeout, 1, ait_menu_print,
+ NULL, NULL);
for (i = 0; display->menulist[i]; i++) {
sprintf(key, "%d", i + 1);
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index ee75db9..2dbd49c 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -1280,7 +1280,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/*
* Create a menu and add items for all the labels.
*/
- m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print);
+ m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
+ NULL, NULL);
if (!m)
return NULL;
--git a/common/menu.c b/common/menu.c
index 6b2a2db..322b75e 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -47,6 +47,8 @@ struct menu {
char *title;
int prompt;
void (*item_data_print)(void *);
+ char *(*item_choice)(void *);
+ void *item_choice_data;
struct list_head items;
};
@@ -204,18 +206,26 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)
menu_display(m);
- readret = readline_into_buffer("Enter choice: ", cbuf,
- m->timeout / 10);
+ if (!m->item_choice) {
+ readret = readline_into_buffer("Enter choice: ", cbuf,
+ m->timeout / 10);
- if (readret >= 0) {
- choice_item = menu_item_by_key(m, cbuf);
-
- if (!choice_item) {
- printf("%s not found\n", cbuf);
- m->timeout = 0;
+ if (readret >= 0) {
+ choice_item = menu_item_by_key(m, cbuf);
+ if (!choice_item)
+ printf("%s not found\n", cbuf);
+ } else {
+ return menu_default_choice(m, choice);
}
- } else
- return menu_default_choice(m, choice);
+ } else {
+ char *key = m->item_choice(m->item_choice_data);
+
+ if (key)
+ choice_item = menu_item_by_key(m, key);
+ }
+
+ if (!choice_item)
+ m->timeout = 0;
}
*choice = choice_item->data;
@@ -348,11 +358,19 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data)
* what must be entered to select an item, the item_data_print function should
* make it obvious what the key for each entry is.
*
+ * item_choice - If not NULL, will be called when asking the user to choose an
+ * item. Returns a key string corresponding to the choosen item or NULL if
+ * no item has been selected.
+ *
+ * item_choice_data - Will be passed as the argument to the item_choice function
+ *
* Returns a pointer to the menu if successful, or NULL if there is
* insufficient memory available to create the menu.
*/
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *))
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
+ void *item_choice_data)
{
struct menu *m;
@@ -365,6 +383,8 @@ struct menu *menu_create(char *title, int timeout, int prompt,
m->prompt = prompt;
m->timeout = timeout;
m->item_data_print = item_data_print;
+ m->item_choice = item_choice;
+ m->item_choice_data = item_choice_data;
if (title) {
m->title = strdup(title);
--git a/doc/README.menu b/doc/README.menu
index 6ce6bba..c949398 100644
--- a/doc/README.menu
+++ b/doc/README.menu
@@ -51,7 +51,9 @@ struct menu;
* menu_create() - Creates a menu handle with default settings
*/
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *));
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
+ void *item_choice_data);
/*
* menu_item_add() - Adds or replaces a menu item
--git a/include/menu.h b/include/menu.h
index 7af5fdb..f4dd5af 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -21,7 +21,9 @@
struct menu;
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *));
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
+ void *item_choice_data);
int menu_default_set(struct menu *m, char *item_key);
int menu_get_choice(struct menu *m, void **choice);
int menu_item_add(struct menu *m, char *item_key, void *item_data);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH] menu: export menu_default_choice() function
2013-03-24 0:50 ` [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function Anatolij Gustschin
@ 2013-03-24 0:52 ` Anatolij Gustschin
2013-03-28 15:26 ` Anatolij Gustschin
2013-03-28 15:26 ` [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function Anatolij Gustschin
1 sibling, 1 reply; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-24 0:52 UTC (permalink / raw)
To: u-boot
Checking the default menu item and obtaining its data can
be useful in custom menu code. Export menu_default_choice()
function which serves this purpose.
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
| 2 +-
| 5 +++++
| 1 +
3 files changed, 7 insertions(+), 1 deletions(-)
--git a/common/menu.c b/common/menu.c
index 322b75e..64b461a 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -176,7 +176,7 @@ static inline struct menu_item *menu_item_by_key(struct menu *m,
* Set *choice to point to the default item's data, if any default item was
* set, and returns 1. If no default item was set, returns -ENOENT.
*/
-static inline int menu_default_choice(struct menu *m, void **choice)
+int menu_default_choice(struct menu *m, void **choice)
{
if (m->default_item) {
*choice = m->default_item->data;
--git a/doc/README.menu b/doc/README.menu
index c949398..a8999ca 100644
--- a/doc/README.menu
+++ b/doc/README.menu
@@ -66,6 +66,11 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data);
int menu_default_set(struct menu *m, char *item_key);
/*
+ * menu_default_choice() - Set *choice to point to the default item's data
+ */
+int menu_default_choice(struct menu *m, void **choice);
+
+/*
* menu_get_choice() - Returns the user's selected menu entry, or the
* default if the menu is set to not prompt or the timeout expires.
*/
--git a/include/menu.h b/include/menu.h
index f4dd5af..d8200ee 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -29,6 +29,7 @@ int menu_get_choice(struct menu *m, void **choice);
int menu_item_add(struct menu *m, char *item_key, void *item_data);
int menu_destroy(struct menu *m);
void menu_display_statusline(struct menu *m);
+int menu_default_choice(struct menu *m, void **choice);
#if defined(CONFIG_MENU_SHOW)
int menu_show(int bootdelay);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support
2013-02-01 15:07 ` [U-Boot] [PATCH v3 2/4] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
@ 2013-03-24 0:53 ` Anatolij Gustschin
2013-03-25 19:29 ` Anatolij Gustschin
2013-03-28 15:32 ` Anatolij Gustschin
0 siblings, 2 replies; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-24 0:53 UTC (permalink / raw)
To: u-boot
From: Pali Roh?r <pali.rohar@gmail.com>
The "bootmenu" command uses U-Boot menu interfaces and provides
a simple mechanism for creating menus with several boot items.
When running this command the menu will be assembled as defined
by a set of environment variables which contain a title and
command key-value pairs. The "Up" and "Down" keys are used for
navigation through the items. Current active menu item is
highlighted and can be selected using the "Enter" key.
The command interprets and generates various ANSI escape
sequencies, so for proper menu rendering and item selection
the used terminal should support them.
Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
[agust: various fixes and documentation updates]
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Changes in v4:
- coding style fixes
- highlight only the menu entry title, not the whole line
- don't return empty strings in bootmenu_choice_entry()
to avoid useless searching for menu keys in the menu
item list. Empty key strings won't be found anyway, so
for down and up keys just return NULL in this function
to indicate that no item selection happened yet
- print error message if invalid bootmenu environment
variable without title/command separator found
- if number of menu items is equal to MAX_COUNT, the
U-Boot console selection entry won't be generated.
Fix it so that documented and real behaviour match
- include entry key initialisation fix for proper
menu behaviour when running in sandbox (without it
the item selection by up/down keys didn't work
in sandbox)
- use puts() instead of printf() where appropriate
- always use 1 for prompt argument for menu_create()
so that the bootmenu command works as documented when
using a negative delay value
- call bootmenu_destroy() in the case if menu_create()
fails (avoid memory leaks)
- don't display the title of selected item before
running the commands (but do it only if debugging
is enabled)
- don't change the argument of menu_display_statusline(),
use exported menu_default_choice() instead and obtain
the needed bootmenu data pointer in the custom
menu_display_statusline() function
- use lower case in menu header
- update documentation in readme file for the command
Changes in v3:
- Do not use hardcoded numbers, added MAX_COUNT and MAX_ENV_SIZE
- Use unsigned short int for menu number
- Use enum bootmenu_key for key selection
- Separate loop code from function bootmenu_choice_entry to bootmenu_loop and bootmenu_autoboot_loop
- Updated README, added example
- Use switches, added braces, fix style problems
Changes in v2:
- Added commit message
- Removed bootmenu from include/config_cmd_all.h
- Moved ANSI escape codes from include/common.h to include/ansi.h
- Fixed style and indentation problems
- Use mdelay instead udelay
- Removed autoboot delay message when some key is pressed
common/Makefile | 1 +
| 517 +++++++++++++++++++++++++++++++++++++++++++++++++
| 115 +++++++++++
include/ansi.h | 42 ++++
4 files changed, 675 insertions(+), 0 deletions(-)
create mode 100644 common/cmd_bootmenu.c
create mode 100644 doc/README.bootmenu
create mode 100644 include/ansi.h
diff --git a/common/Makefile b/common/Makefile
index 1abf4ea..f631311 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -75,6 +75,7 @@ COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o
COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
+COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
--git a/common/cmd_bootmenu.c b/common/cmd_bootmenu.c
new file mode 100644
index 0000000..a3cbffa
--- /dev/null
+++ b/common/cmd_bootmenu.c
@@ -0,0 +1,517 @@
+/*
+ * (C) Copyright 2011-2013 Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <ansi.h>
+#include <menu.h>
+#include <hush.h>
+#include <watchdog.h>
+#include <malloc.h>
+#include <linux/string.h>
+
+/* maximum bootmenu entries */
+#define MAX_COUNT 99
+
+/* maximal size of bootmenu env
+ * 9 = strlen("bootmenu_")
+ * 2 = strlen(MAX_COUNT)
+ * 1 = NULL term
+ */
+#define MAX_ENV_SIZE (9 + 2 + 1)
+
+struct bootmenu_entry {
+ unsigned short int num; /* unique number 0 .. MAX_COUNT */
+ char key[3]; /* key identifier of number */
+ char *title; /* title of entry */
+ char *command; /* hush command of entry */
+ struct bootmenu_data *menu; /* this bootmenu */
+ struct bootmenu_entry *next; /* next menu entry (num+1) */
+};
+
+struct bootmenu_data {
+ int delay; /* delay for autoboot */
+ int active; /* active menu entry */
+ int count; /* total count of menu entries */
+ struct bootmenu_entry *first; /* first menu entry */
+};
+
+enum bootmenu_key {
+ KEY_NONE = 0,
+ KEY_UP,
+ KEY_DOWN,
+ KEY_SELECT,
+};
+
+static char *bootmenu_getoption(unsigned short int n)
+{
+ char name[MAX_ENV_SIZE] = "bootmenu_";
+
+ if (n > MAX_COUNT)
+ return NULL;
+
+ sprintf(name + 9, "%d", n);
+ return getenv(name);
+}
+
+static void bootmenu_print_entry(void *data)
+{
+ struct bootmenu_entry *entry = data;
+ int reverse = (entry->menu->active == entry->num);
+
+ /*
+ * Move cursor to line where the entry will be drown (entry->num)
+ * First 3 lines contain bootmenu header + 1 empty line
+ */
+ printf(ANSI_CURSOR_POSITION, entry->num + 4, 1);
+
+ puts(" ");
+
+ if (reverse)
+ puts(ANSI_COLOR_REVERSE);
+
+ puts(entry->title);
+
+ if (reverse)
+ puts(ANSI_COLOR_RESET);
+}
+
+static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc)
+{
+ int i, c;
+
+ if (menu->delay > 0) {
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ printf(" Hit any key to stop autoboot: %2d ", menu->delay);
+ }
+
+ while (menu->delay > 0) {
+ for (i = 0; i < 100; ++i) {
+ if (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ continue;
+ }
+
+ menu->delay = -1;
+ c = getc();
+
+ switch (c) {
+ case '\e':
+ *esc = 1;
+ *key = KEY_NONE;
+ break;
+ case '\r':
+ *key = KEY_SELECT;
+ break;
+ default:
+ *key = KEY_NONE;
+ break;
+ }
+
+ break;
+ }
+
+ if (menu->delay < 0)
+ break;
+
+ --menu->delay;
+ printf("\b\b\b%2d ", menu->delay);
+ }
+
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ if (menu->delay == 0)
+ *key = KEY_SELECT;
+}
+
+static void bootmenu_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc)
+{
+ int c;
+
+ while (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ }
+
+ c = getc();
+
+ switch (*esc) {
+ case 0:
+ /* First char of ANSI escape sequence '\e' */
+ if (c == '\e') {
+ *esc = 1;
+ *key = KEY_NONE;
+ }
+ break;
+ case 1:
+ /* Second char of ANSI '[' */
+ if (c == '[') {
+ *esc = 2;
+ *key = KEY_NONE;
+ } else {
+ *esc = 0;
+ }
+ break;
+ case 2:
+ case 3:
+ /* Third char of ANSI (number '1') - optional */
+ if (*esc == 2 && c == '1') {
+ *esc = 3;
+ *key = KEY_NONE;
+ break;
+ }
+
+ *esc = 0;
+
+ /* ANSI 'A' - key up was pressed */
+ if (c == 'A')
+ *key = KEY_UP;
+ /* ANSI 'B' - key down was pressed */
+ else if (c == 'B')
+ *key = KEY_DOWN;
+ /* other key was pressed */
+ else
+ *key = KEY_NONE;
+
+ break;
+ }
+
+ /* enter key was pressed */
+ if (c == '\r')
+ *key = KEY_SELECT;
+}
+
+static char *bootmenu_choice_entry(void *data)
+{
+ struct bootmenu_data *menu = data;
+ struct bootmenu_entry *iter;
+ enum bootmenu_key key = KEY_NONE;
+ int esc = 0;
+ int i;
+
+ while (1) {
+ if (menu->delay >= 0) {
+ /* Autoboot was not stopped */
+ bootmenu_autoboot_loop(menu, &key, &esc);
+ } else {
+ /* Some key was pressed, so autoboot was stopped */
+ bootmenu_loop(menu, &key, &esc);
+ }
+
+ switch (key) {
+ case KEY_UP:
+ if (menu->active > 0)
+ --menu->active;
+ /* no menu key selected, regenerate menu */
+ return NULL;
+ case KEY_DOWN:
+ if (menu->active < menu->count - 1)
+ ++menu->active;
+ /* no menu key selected, regenerate menu */
+ return NULL;
+ case KEY_SELECT:
+ iter = menu->first;
+ for (i = 0; i < menu->active; ++i)
+ iter = iter->next;
+ return iter->key;
+ default:
+ break;
+ }
+ }
+
+ /* never happens */
+ debug("bootmenu: this should not happen");
+ return NULL;
+}
+
+static void bootmenu_destroy(struct bootmenu_data *menu)
+{
+ struct bootmenu_entry *iter = menu->first;
+ struct bootmenu_entry *next;
+
+ while (iter) {
+ next = iter->next;
+ free(iter->title);
+ free(iter->command);
+ free(iter);
+ iter = next;
+ }
+ free(menu);
+}
+
+static struct bootmenu_data *bootmenu_create(int delay)
+{
+ unsigned short int i = 0;
+ const char *option;
+ struct bootmenu_data *menu;
+ struct bootmenu_entry *iter = NULL;
+
+ int len;
+ char *sep;
+ struct bootmenu_entry *entry;
+
+ menu = malloc(sizeof(struct bootmenu_data));
+ if (!menu)
+ return NULL;
+
+ menu->delay = delay;
+ menu->active = 0;
+ menu->first = NULL;
+
+ while ((option = bootmenu_getoption(i))) {
+ sep = strchr(option, '=');
+ if (!sep) {
+ printf("Invalid bootmenu entry: %s\n", option);
+ break;
+ }
+
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ len = sep-option;
+ entry->title = malloc(len + 1);
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->title, option, len);
+ entry->title[len] = 0;
+
+ len = strlen(sep + 1);
+ entry->command = malloc(len + 1);
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+ memcpy(entry->command, sep + 1, len);
+ entry->command[len] = 0;
+
+ sprintf(entry->key, "%d", i);
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+
+ if (i == MAX_COUNT - 1)
+ break;
+ }
+
+ /* Add U-Boot console entry at the end */
+ if (i <= MAX_COUNT - 1) {
+ entry = malloc(sizeof(struct bootmenu_entry));
+ if (!entry)
+ goto cleanup;
+
+ entry->title = strdup("U-Boot console");
+ if (!entry->title) {
+ free(entry);
+ goto cleanup;
+ }
+
+ entry->command = strdup("");
+ if (!entry->command) {
+ free(entry->title);
+ free(entry);
+ goto cleanup;
+ }
+
+ sprintf(entry->key, "%d", i);
+
+ entry->num = i;
+ entry->menu = menu;
+ entry->next = NULL;
+
+ if (!iter)
+ menu->first = entry;
+ else
+ iter->next = entry;
+
+ iter = entry;
+ ++i;
+ }
+
+ menu->count = i;
+ return menu;
+
+cleanup:
+ bootmenu_destroy(menu);
+ return NULL;
+}
+
+static void bootmenu_show(int delay)
+{
+ int init = 0;
+ void *choice = NULL;
+ char *title = NULL;
+ char *command = NULL;
+ struct menu *menu;
+ struct bootmenu_data *bootmenu;
+ struct bootmenu_entry *iter;
+ char *option, *sep;
+
+ /* If delay is 0 do not create menu, just run first entry */
+ if (delay == 0) {
+ option = bootmenu_getoption(0);
+ if (!option) {
+ puts("bootmenu option 0 was not found\n");
+ return;
+ }
+ sep = strchr(option, '=');
+ if (!sep) {
+ puts("bootmenu option 0 is invalid\n");
+ return;
+ }
+ run_command(sep+1, 0);
+ return;
+ }
+
+ bootmenu = bootmenu_create(delay);
+ if (!bootmenu)
+ return;
+
+ menu = menu_create(NULL, bootmenu->delay, 1, bootmenu_print_entry,
+ bootmenu_choice_entry, bootmenu);
+ if (!menu) {
+ bootmenu_destroy(bootmenu);
+ return;
+ }
+
+ for (iter = bootmenu->first; iter; iter = iter->next) {
+ if (!menu_item_add(menu, iter->key, iter))
+ goto cleanup;
+ }
+
+ /* Default menu entry is always first */
+ menu_default_set(menu, "0");
+
+ puts(ANSI_CURSOR_HIDE);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+
+ init = 1;
+
+ if (menu_get_choice(menu, &choice)) {
+ iter = choice;
+ title = strdup(iter->title);
+ command = strdup(iter->command);
+ }
+
+cleanup:
+ menu_destroy(menu);
+ bootmenu_destroy(bootmenu);
+
+ if (init) {
+ puts(ANSI_CURSOR_SHOW);
+ puts(ANSI_CLEAR_CONSOLE);
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ }
+
+ if (title && command) {
+ debug("Starting entry '%s'\n", title);
+ free(title);
+ run_command(command, 0);
+ free(command);
+ }
+
+#ifdef CONFIG_POSTBOOTMENU
+ run_command(CONFIG_POSTBOOTMENU, 0);
+#endif
+}
+
+void menu_display_statusline(struct menu *m)
+{
+ struct bootmenu_entry *entry;
+ struct bootmenu_data *menu;
+
+ if (menu_default_choice(m, (void *)&entry) < 0)
+ return;
+
+ menu = entry->menu;
+
+ printf(ANSI_CURSOR_POSITION, 1, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, 2, 1);
+ puts(" *** U-Boot Boot Menu ***");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, 3, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ /* First 3 lines are bootmenu header + 2 empty lines between entries */
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ puts(ANSI_CLEAR_LINE);
+ printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
+ puts(" Press UP/DOWN to move, ENTER to select");
+ puts(ANSI_CLEAR_LINE_TO_END);
+ printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
+ puts(ANSI_CLEAR_LINE);
+}
+
+#ifdef CONFIG_MENU_SHOW
+int menu_show(int bootdelay)
+{
+ bootmenu_show(bootdelay);
+ return -1; /* -1 - abort boot and run monitor code */
+}
+#endif
+
+int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ char *delay_str = NULL;
+ int delay = 10;
+
+#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
+ delay = CONFIG_BOOTDELAY;
+#endif
+
+ if (argc >= 2)
+ delay_str = argv[1];
+
+ if (!delay_str)
+ delay_str = getenv("bootmenu_delay");
+
+ if (delay_str)
+ delay = (int)simple_strtol(delay_str, NULL, 10);
+
+ bootmenu_show(delay);
+ return 0;
+}
+
+U_BOOT_CMD(
+ bootmenu, 2, 1, do_bootmenu,
+ "ANSI terminal bootmenu",
+ "[delay]\n"
+ " - show ANSI terminal bootmenu with autoboot delay"
+);
--git a/doc/README.bootmenu b/doc/README.bootmenu
new file mode 100644
index 0000000..9e85b40
--- /dev/null
+++ b/doc/README.bootmenu
@@ -0,0 +1,115 @@
+/*
+ * (C) Copyright 2011-2012 Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ANSI terminal bootmenu command
+
+The "bootmenu" command uses U-Boot menu interfaces and provides
+a simple mechanism for creating menus with different boot items.
+The cursor keys "Up" and "Down" are used for navigation through
+the items. Current active menu item is highlighted and can be
+selected using the "Enter" key. The selection of the highlighted
+menu entry invokes an U-Boot command (or a list of commands)
+associated with this menu entry.
+
+The "bootmenu" command interprets ANSI escape sequencies, so
+an ANSI terminal is required for proper menu rendering and item
+selection.
+
+The assembling of the menu is done via a set of environment variables
+"bootmenu_<num>" and "bootmenu_delay", i.e.:
+
+ bootmenu_delay=<delay>
+ bootmenu_<num>="<title>=<commands>"
+
+ <delay> is the autoboot delay in seconds, after which the first
+ menu entry will be selected automatically
+
+ <num> is the boot menu entry number, starting from zero
+
+ <title> is the text of the menu entry shown on the console
+ or on the boot screen
+
+ <commands> are commands which will be executed when a menu
+ entry is selected
+
+ (title and commands are separated by first appearance of '='
+ character in the environment variable)
+
+First (optional) argument of the "bootmenu" command is a delay specifier
+and it overrides the delay value defined by "bootmenu_delay" environment
+variable. If the environment variable "bootmenu_delay" is not set or if
+the argument of the "bootmenu" command is not specified, the default delay
+will be CONFIG_BOOTDELAY. If delay is 0, no menu entries will be shown on
+the console (or on the screen) and the command of the first menu entry will
+be called immediately. If delay is less then 0, bootmenu will be shown and
+autoboot will be disabled.
+
+Bootmenu always adds menu entry "U-Boot console" at the end of all menu
+entries specified by environment variables. When selecting this entry
+the bootmenu terminates and the usual U-Boot command prompt is presented
+to the user.
+
+Example environment:
+
+ setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set first menu entry
+ setenv bootmenu_1 Boot 2. kernel=bootm 0x83000000 # Set second menu entry
+ setenv bootmenu_2 Reset board=reset # Set third menu entry
+ setenv bootmenu_3 U-Boot boot order=boot # Set fourth menu entry
+ bootmenu 20 # Run bootmenu with autoboot delay 20s
+
+
+The above example will be rendered as below
+(without decorating rectangle):
+
+????????????????????????????????????????????
+? ?
+? *** U-Boot Boot Menu *** ?
+? ?
+? Boot 1. kernel ?
+? Boot 2. kernel ?
+? Reset board ?
+? U-Boot boot order ?
+? U-Boot console ?
+? ?
+? Hit any key to stop autoboot: 20 ?
+? Press UP/DOWN to move, ENTER to select ?
+? ?
+????????????????????????????????????????????
+
+Selected menu entry will be highlighted - it will have inverted
+background and text colors.
+
+To enable the "bootmenu" command add following definitions to the
+board config file:
+
+ #define CONFIG_CMD_BOOTMENU
+ #define CONFIG_MENU
+
+To run the bootmenu at startup add these additional definitions:
+
+ #define CONFIG_AUTOBOOT_KEYED
+ #define CONFIG_BOOTDELAY 30
+ #define CONFIG_MENU_SHOW
+
+When you intend to use the bootmenu on color frame buffer console,
+make sure to additionally define CONFIG_CFB_CONSOLE_ANSI in the
+board config file.
diff --git a/include/ansi.h b/include/ansi.h
new file mode 100644
index 0000000..0e40b1d
--- /dev/null
+++ b/include/ansi.h
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2012
+ * Pali Roh?r <pali.rohar@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * ANSI terminal
+ */
+
+#define ANSI_CURSOR_UP "\e[%dA"
+#define ANSI_CURSOR_DOWN "\e[%dB"
+#define ANSI_CURSOR_FORWARD "\e[%dC"
+#define ANSI_CURSOR_BACK "\e[%dD"
+#define ANSI_CURSOR_NEXTLINE "\e[%dE"
+#define ANSI_CURSOR_PREVIOUSLINE "\e[%dF"
+#define ANSI_CURSOR_COLUMN "\e[%dG"
+#define ANSI_CURSOR_POSITION "\e[%d;%dH"
+#define ANSI_CURSOR_SHOW "\e[?25h"
+#define ANSI_CURSOR_HIDE "\e[?25l"
+#define ANSI_CLEAR_CONSOLE "\e[2J"
+#define ANSI_CLEAR_LINE_TO_END "\e[0K"
+#define ANSI_CLEAR_LINE "\e[2K"
+#define ANSI_COLOR_RESET "\e[0m"
+#define ANSI_COLOR_REVERSE "\e[7m"
--
1.7.5.4
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support
2013-03-24 0:53 ` [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support Anatolij Gustschin
@ 2013-03-25 19:29 ` Anatolij Gustschin
2013-03-26 15:19 ` Pali Rohár
2013-03-28 15:32 ` Anatolij Gustschin
1 sibling, 1 reply; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-25 19:29 UTC (permalink / raw)
To: u-boot
Hi,
On Sun, 24 Mar 2013 01:53:08 +0100
Anatolij Gustschin <agust@denx.de> wrote:
> From: Pali Roh?r <pali.rohar@gmail.com>
>
> The "bootmenu" command uses U-Boot menu interfaces and provides
> a simple mechanism for creating menus with several boot items.
Could you please test v4 patches. I've tested them in sandbox and
on a frame buffer device (cfb_console) and didn't see any issues.
I'm going to apply these patches in a few days.
Thanks,
Anatolij
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support
2013-03-25 19:29 ` Anatolij Gustschin
@ 2013-03-26 15:19 ` Pali Rohár
2013-03-28 15:29 ` Anatolij Gustschin
0 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2013-03-26 15:19 UTC (permalink / raw)
To: u-boot
On Monday 25 March 2013 20:29:23 Anatolij Gustschin wrote:
> Hi,
>
> On Sun, 24 Mar 2013 01:53:08 +0100
>
> Anatolij Gustschin <agust@denx.de> wrote:
> > From: Pali Roh?r <pali.rohar@gmail.com>
> >
> > The "bootmenu" command uses U-Boot menu interfaces and
> > provides a simple mechanism for creating menus with several
> > boot items.
>
> Could you please test v4 patches. I've tested them in sandbox
> and on a frame buffer device (cfb_console) and didn't see any
> issues. I'm going to apply these patches in a few days.
>
> Thanks,
>
> Anatolij
Hi,
I tested them on Nokia N900 and in qemu (hw n900). Working fine.
--
Pali Roh?r
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130326/be319d2c/attachment.pgp>
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function
2013-03-24 0:50 ` [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function Anatolij Gustschin
2013-03-24 0:52 ` [U-Boot] [PATCH] menu: export menu_default_choice() function Anatolij Gustschin
@ 2013-03-28 15:26 ` Anatolij Gustschin
1 sibling, 0 replies; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-28 15:26 UTC (permalink / raw)
To: u-boot
On Sun, 24 Mar 2013 01:50:40 +0100
Anatolij Gustschin <agust@denx.de> wrote:
> From: Pali Roh?r <pali.rohar@gmail.com>
>
> Selecting menu items is currently done in menu_interactive_choice()
> by reading the user input strings from standard input.
>
> Extend menu_interactive_choice() to support user defined function
> for selecting menu items. This function and its argument can be
> specified when creating the menu.
>
> Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> ---
> Changes in v4:
> - slightly rename the new item choice callback and its argument
> - add documentation for added item choice callback
> - search for menu item key only if the choice callback
> returned a key (not NULL)
> - do not change menu_display_statusline() function argument
> (previous patch changed this menu API function but didn't
> update documentation for this change. This change is
> actually not needed, menu item data can be obtained by
> exported menu_default_choice())
> - revise commit log
>
> No changes in v3
>
> Changes in v2:
> - Rebased on next
>
> board/ait/cam_enc_4xx/cam_enc_4xx.c | 3 +-
> common/cmd_pxe.c | 3 +-
> common/menu.c | 42 +++++++++++++++++++++++++---------
> doc/README.menu | 4 ++-
> include/menu.h | 4 ++-
> 5 files changed, 41 insertions(+), 15 deletions(-)
applied to staging/agust at denx.de. Thanks.
Anatolij
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH] menu: export menu_default_choice() function
2013-03-24 0:52 ` [U-Boot] [PATCH] menu: export menu_default_choice() function Anatolij Gustschin
@ 2013-03-28 15:26 ` Anatolij Gustschin
0 siblings, 0 replies; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-28 15:26 UTC (permalink / raw)
To: u-boot
On Sun, 24 Mar 2013 01:52:04 +0100
Anatolij Gustschin <agust@denx.de> wrote:
> Checking the default menu item and obtaining its data can
> be useful in custom menu code. Export menu_default_choice()
> function which serves this purpose.
>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> ---
> common/menu.c | 2 +-
> doc/README.menu | 5 +++++
> include/menu.h | 1 +
> 3 files changed, 7 insertions(+), 1 deletions(-)
applied to staging/agust at denx.de. Thanks.
Anatolij
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support
2013-03-26 15:19 ` Pali Rohár
@ 2013-03-28 15:29 ` Anatolij Gustschin
0 siblings, 0 replies; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-28 15:29 UTC (permalink / raw)
To: u-boot
Hi,
On Tue, 26 Mar 2013 16:19:35 +0100
Pali Roh?r <pali.rohar@gmail.com> wrote:
...
> I tested them on Nokia N900 and in qemu (hw n900). Working fine.
Thanks for testing!
Anatolij
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support
2013-03-24 0:53 ` [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support Anatolij Gustschin
2013-03-25 19:29 ` Anatolij Gustschin
@ 2013-03-28 15:32 ` Anatolij Gustschin
2013-03-28 19:18 ` Pali Rohár
1 sibling, 1 reply; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-28 15:32 UTC (permalink / raw)
To: u-boot
On Sun, 24 Mar 2013 01:53:08 +0100
Anatolij Gustschin <agust@denx.de> wrote:
> From: Pali Roh?r <pali.rohar@gmail.com>
>
> The "bootmenu" command uses U-Boot menu interfaces and provides
> a simple mechanism for creating menus with several boot items.
> When running this command the menu will be assembled as defined
> by a set of environment variables which contain a title and
> command key-value pairs. The "Up" and "Down" keys are used for
> navigation through the items. Current active menu item is
> highlighted and can be selected using the "Enter" key.
>
> The command interprets and generates various ANSI escape
> sequencies, so for proper menu rendering and item selection
> the used terminal should support them.
>
> Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
> [agust: various fixes and documentation updates]
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> ---
> Changes in v4:
> - coding style fixes
> - highlight only the menu entry title, not the whole line
> - don't return empty strings in bootmenu_choice_entry()
> to avoid useless searching for menu keys in the menu
> item list. Empty key strings won't be found anyway, so
> for down and up keys just return NULL in this function
> to indicate that no item selection happened yet
> - print error message if invalid bootmenu environment
> variable without title/command separator found
> - if number of menu items is equal to MAX_COUNT, the
> U-Boot console selection entry won't be generated.
> Fix it so that documented and real behaviour match
> - include entry key initialisation fix for proper
> menu behaviour when running in sandbox (without it
> the item selection by up/down keys didn't work
> in sandbox)
> - use puts() instead of printf() where appropriate
> - always use 1 for prompt argument for menu_create()
> so that the bootmenu command works as documented when
> using a negative delay value
> - call bootmenu_destroy() in the case if menu_create()
> fails (avoid memory leaks)
> - don't display the title of selected item before
> running the commands (but do it only if debugging
> is enabled)
> - don't change the argument of menu_display_statusline(),
> use exported menu_default_choice() instead and obtain
> the needed bootmenu data pointer in the custom
> menu_display_statusline() function
> - use lower case in menu header
> - update documentation in readme file for the command
>
> Changes in v3:
> - Do not use hardcoded numbers, added MAX_COUNT and MAX_ENV_SIZE
> - Use unsigned short int for menu number
> - Use enum bootmenu_key for key selection
> - Separate loop code from function bootmenu_choice_entry to bootmenu_loop and bootmenu_autoboot_loop
> - Updated README, added example
> - Use switches, added braces, fix style problems
>
> Changes in v2:
> - Added commit message
> - Removed bootmenu from include/config_cmd_all.h
> - Moved ANSI escape codes from include/common.h to include/ansi.h
> - Fixed style and indentation problems
> - Use mdelay instead udelay
> - Removed autoboot delay message when some key is pressed
>
> common/Makefile | 1 +
> common/cmd_bootmenu.c | 517 +++++++++++++++++++++++++++++++++++++++++++++++++
> doc/README.bootmenu | 115 +++++++++++
> include/ansi.h | 42 ++++
> 4 files changed, 675 insertions(+), 0 deletions(-)
> create mode 100644 common/cmd_bootmenu.c
> create mode 100644 doc/README.bootmenu
> create mode 100644 include/ansi.h
applied to staging/agust at denx.de. Thanks.
Anatolij
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support
2013-03-28 15:32 ` Anatolij Gustschin
@ 2013-03-28 19:18 ` Pali Rohár
2013-03-28 23:13 ` Anatolij Gustschin
0 siblings, 1 reply; 37+ messages in thread
From: Pali Rohár @ 2013-03-28 19:18 UTC (permalink / raw)
To: u-boot
On Thursday 28 March 2013 16:32:47 Anatolij Gustschin wrote:
> On Sun, 24 Mar 2013 01:53:08 +0100
>
> Anatolij Gustschin <agust@denx.de> wrote:
> > From: Pali Roh?r <pali.rohar@gmail.com>
> >
> > The "bootmenu" command uses U-Boot menu interfaces and
> > provides a simple mechanism for creating menus with several
> > boot items. When running this command the menu will be
> > assembled as defined by a set of environment variables
> > which contain a title and command key-value pairs. The "Up"
> > and "Down" keys are used for navigation through the items.
> > Current active menu item is highlighted and can be selected
> > using the "Enter" key.
> >
> > The command interprets and generates various ANSI escape
> > sequencies, so for proper menu rendering and item selection
> > the used terminal should support them.
> >
> > Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
> > [agust: various fixes and documentation updates]
> > Signed-off-by: Anatolij Gustschin <agust@denx.de>
>
> applied to staging/agust at denx.de. Thanks.
>
> Anatolij
Hi, can you include also two next patches from this series?
http://patchwork.ozlabs.org/patch/217492/
http://patchwork.ozlabs.org/patch/225868/
--
Pali Roh?r
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130328/c73ef5af/attachment.pgp>
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support
2013-03-28 19:18 ` Pali Rohár
@ 2013-03-28 23:13 ` Anatolij Gustschin
2013-03-29 6:51 ` Pali Rohár
0 siblings, 1 reply; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-28 23:13 UTC (permalink / raw)
To: u-boot
Hi,
On Thu, 28 Mar 2013 20:18:48 +0100
Pali Roh?r <pali.rohar@gmail.com> wrote:
...
>
> Hi, can you include also two next patches from this series?
>
> http://patchwork.ozlabs.org/patch/217492/
> http://patchwork.ozlabs.org/patch/225868/
These patches are in my queue, I didn't forgot about them :-)
Regarding the "clear" command Wolfgang had some reservations since
we already have "cls" command for LCDs. Wolfgang suggested to
unify with the existing command in a backward compatible way.
I'm going to submit a patch which tries to do this.
The v3 4/4 patch can be applied as is, I think.
Thanks,
Anatolij
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v3 4/4] RX-51: Add support for bootmenu
2013-03-07 15:15 ` Pali Rohár
@ 2013-03-28 23:26 ` Anatolij Gustschin
0 siblings, 0 replies; 37+ messages in thread
From: Anatolij Gustschin @ 2013-03-28 23:26 UTC (permalink / raw)
To: u-boot
Hi,
On Thu, 7 Mar 2013 16:15:19 +0100
Pali Roh?r <pali.rohar@gmail.com> wrote:
...
> attached kernel, internal eMMC memory, external SD card, u-boot boot order
>
> * in CONFIG_PREBOOT try load bootmenu.scr from first partition of internal
> eMMC memory (also known as MyDocs) which (should) overwrite default bootmenu
> entries
>
> * when keyboard slide is closed boot first menu entry
>
> * when keyborad slide is open show bootmenu
>
> Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
> ---
> include/configs/nokia_rx51.h | 40 +++++++++++++++++++++++++++++++++++++---
> 1 file changed, 37 insertions(+), 3 deletions(-)
with slightly revised commit log, applied to staging/agust at denx.de.
Thanks,
Anatolij
^ permalink raw reply [flat|nested] 37+ messages in thread
* [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support
2013-03-28 23:13 ` Anatolij Gustschin
@ 2013-03-29 6:51 ` Pali Rohár
0 siblings, 0 replies; 37+ messages in thread
From: Pali Rohár @ 2013-03-29 6:51 UTC (permalink / raw)
To: u-boot
On Friday 29 March 2013 00:13:30 Anatolij Gustschin wrote:
> Hi,
>
> On Thu, 28 Mar 2013 20:18:48 +0100
> Pali Roh?r <pali.rohar@gmail.com> wrote:
> ...
>
> > Hi, can you include also two next patches from this series?
> >
> > http://patchwork.ozlabs.org/patch/217492/
> > http://patchwork.ozlabs.org/patch/225868/
>
> These patches are in my queue, I didn't forgot about them :-)
>
> Regarding the "clear" command Wolfgang had some reservations
> since we already have "cls" command for LCDs. Wolfgang
> suggested to unify with the existing command in a backward
> compatible way. I'm going to submit a patch which tries to do
> this.
>
> The v3 4/4 patch can be applied as is, I think.
>
> Thanks,
>
> Anatolij
Ok, thanks!
--
Pali Roh?r
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130329/77d62547/attachment.pgp>
^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2013-03-29 6:51 UTC | newest]
Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-27 16:38 [U-Boot] [PATCH 0/2] ANSI terminal Bootmenu Pali Rohár
2012-05-27 16:38 ` [U-Boot] [PATCH 1/2] menu: Added support to use user defined functions Pali Rohár
2012-06-03 9:59 ` Marek Vasut
2012-06-03 10:05 ` Pali Rohár
2012-06-03 10:27 ` Marek Vasut
2012-05-27 16:38 ` [U-Boot] [PATCH 2/2] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
2012-06-03 10:06 ` Marek Vasut
2012-06-03 16:22 ` Luka Perkov
2012-06-03 18:27 ` Marek Vasut
2012-06-03 21:20 ` Luka Perkov
2012-11-01 11:39 ` [U-Boot] [PATCH v2 0/4] ANSI terminal Bootmenu Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 1/4] menu: Added support to use user defined functions Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 2/4] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
2012-11-13 8:27 ` Wolfgang Denk
2012-11-14 22:38 ` Pali Rohár
2012-11-01 11:39 ` [U-Boot] [PATCH v2 3/4] New command clear: Clear the ANSI terminal Pali Rohár
2012-11-13 8:09 ` Wolfgang Denk
2012-11-01 11:39 ` [U-Boot] [PATCH v2 4/4] RX-51: Add support for bootmenu Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 0/4] ANSI terminal Bootmenu Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 1/4] menu: Added support to use user defined functions Pali Rohár
2013-03-24 0:50 ` [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function Anatolij Gustschin
2013-03-24 0:52 ` [U-Boot] [PATCH] menu: export menu_default_choice() function Anatolij Gustschin
2013-03-28 15:26 ` Anatolij Gustschin
2013-03-28 15:26 ` [U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function Anatolij Gustschin
2013-02-01 15:07 ` [U-Boot] [PATCH v3 2/4] New command bootmenu: ANSI terminal Boot Menu support Pali Rohár
2013-03-24 0:53 ` [U-Boot] [PATCH v4 2/4] New command bootmenu: ANSI terminal boot menu support Anatolij Gustschin
2013-03-25 19:29 ` Anatolij Gustschin
2013-03-26 15:19 ` Pali Rohár
2013-03-28 15:29 ` Anatolij Gustschin
2013-03-28 15:32 ` Anatolij Gustschin
2013-03-28 19:18 ` Pali Rohár
2013-03-28 23:13 ` Anatolij Gustschin
2013-03-29 6:51 ` Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 3/4] New command clear: Clear the ANSI terminal Pali Rohár
2013-02-01 15:07 ` [U-Boot] [PATCH v3 4/4] RX-51: Add support for bootmenu Pali Rohár
2013-03-07 15:15 ` Pali Rohár
2013-03-28 23:26 ` Anatolij Gustschin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox