[U-Boot] [RFC PATCH 04/14] dfu: allow to manage DFU on several devices
Lukasz Majewski
lukma at denx.de
Mon Jul 22 08:04:21 UTC 2019
Hi Patrick,
> Add support of DFU for several interface/device
> with one command.
>
> The format for "dfu_alt_info" in this case is :
> interface with devstring'='alternate list (';' separated)
> and each interface is separated by '&'
>
> The previous behavior is always supported.
Good.
>
> One example for NOR (bootloaders) + NAND (rootfs in UBI):
>
> U-Boot> env set dfu_alt_info \
> "sf 0:0:10000000:0=spl part 0 1;u-boot part 0 2; \
> u-boot-env part 0 3&nand 0=UBI partubi 0,3"
>
> U-Boot> dfu 0 list
>
> DFU alt settings list:
> dev: SF alt: 0 name: spl layout: RAW_ADDR
> dev: SF alt: 1 name: ssbl layout: RAW_ADDR
> dev: SF alt: 2 name: u-boot-env layout: RAW_ADDR
> dev: NAND alt: 3 name: UBI layout: RAW_ADDR
>
> U-Boot> dfu 0
>
> $> dfu-util -l
>
> Found DFU: [0483:5720] ver=9999, devnum=96, cfg=1, intf=0, alt=3,
> name="UBI", serial="002700333338511934383330" Found DFU: [0483:5720]
> ver=9999, devnum=96, cfg=1, intf=0, alt=2, name="u-boot-env",
> serial="002700333338511934383330" Found DFU: [0483:5720] ver=9999,
> devnum=96, cfg=1, intf=0, alt=1, name="u-boot",
> serial="002700333338511934383330" Found DFU: [0483:5720] ver=9999,
> devnum=96, cfg=1, intf=0, alt=0, name="spl",
> serial="002700333338511934383330"
>
Please add this info (with above example usage) to ./doc/README.dfu (in
a similar way as I did it some time ago for ./doc/README.dfutftp).
I also think that it would be beneficial for the community to add a
separate entry (in this file) for the description of ST's way to
program their platform with this code.
(I mean simple howto for people who would like to start playing around
with ST & U-Boot & DFU).
> Signed-off-by: Patrick Delaunay <patrick.delaunay at st.com>
> ---
>
> cmd/dfu.c | 21 +++++++++++--------
> drivers/dfu/dfu.c | 60
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files
> changed, 72 insertions(+), 9 deletions(-)
>
> diff --git a/cmd/dfu.c b/cmd/dfu.c
> index 91a750a..33491d0 100644
> --- a/cmd/dfu.c
> +++ b/cmd/dfu.c
> @@ -21,23 +21,28 @@
> static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const
> argv[]) {
>
> - if (argc < 4)
> + if (argc < 2)
> return CMD_RET_USAGE;
>
> #ifdef CONFIG_DFU_OVER_USB
> char *usb_controller = argv[1];
> #endif
> #if defined(CONFIG_DFU_OVER_USB) || defined(CONFIG_DFU_OVER_TFTP)
> - char *interface = argv[2];
> - char *devstring = argv[3];
> + char *interface = NULL;
> + char *devstring = NULL;
> +
> + if (argc >= 4) {
> + interface = argv[2];
> + devstring = argv[3];
> + }
> #endif
>
> int ret = 0;
> #ifdef CONFIG_DFU_OVER_TFTP
> unsigned long addr = 0;
> if (!strcmp(argv[1], "tftp")) {
> - if (argc == 5)
> - addr = simple_strtoul(argv[4], NULL, 0);
> + if (argc == 5 || argc == 3)
> + addr = simple_strtoul(argv[argc - 1], NULL,
> 0);
> return update_tftp(addr, interface, devstring);
> }
> @@ -48,7 +53,7 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int
> argc, char * const argv[]) goto done;
>
> ret = CMD_RET_SUCCESS;
> - if (argc > 4 && strcmp(argv[4], "list") == 0) {
> + if (strcmp(argv[argc - 1], "list") == 0) {
> dfu_show_entities();
> goto done;
> }
> @@ -67,7 +72,7 @@ U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
> "Device Firmware Upgrade",
> ""
> #ifdef CONFIG_DFU_OVER_USB
> - "<USB_controller> <interface> <dev> [list]\n"
> + "<USB_controller> [<interface> <dev>] [list]\n"
> " - device firmware upgrade via <USB_controller>\n"
> " on device <dev>, attached to interface\n"
> " <interface>\n"
> @@ -77,7 +82,7 @@ U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
> #ifdef CONFIG_DFU_OVER_USB
> "dfu "
> #endif
> - "tftp <interface> <dev> [<addr>]\n"
> + "tftp [<interface> <dev>] [<addr>]\n"
> " - device firmware upgrade via TFTP\n"
> " on device <dev>, attached to interface\n"
> " <interface>\n"
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index 79a652e..01ec690 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -52,6 +52,54 @@ static int dfu_find_alt_num(const char *s)
> return ++i;
> }
>
> +/*
> + * treat dfu_alt_info with several interface information
> + * to allow DFU on several device with one command,
> + * the string format is
> + * interface devstring'='alternate list (';' separated)
> + * and each interface separated by '&'
> + */
> +int dfu_config_interfaces(char *env)
> +{
> + struct dfu_entity *dfu;
> + char *s, *i, *d, *a, *part;
> + int ret = -EINVAL;
> + int n = 1;
> +
> + s = env;
> + for (; *s; s++) {
> + if (*s == ';')
> + n++;
> + if (*s == '&')
> + n++;
> + }
> + ret = dfu_alt_init(n, &dfu);
> + if (ret)
> + return ret;
> +
> + s = env;
> + while (s) {
> + ret = -EINVAL;
> + i = strsep(&s, " ");
> + if (!i)
> + break;
> + d = strsep(&s, "=");
> + if (!d)
> + break;
> + a = strsep(&s, "&");
> + if (!a)
> + a = s;
> + do {
> + part = strsep(&a, ";");
> + ret = dfu_alt_add(dfu, i, d, part);
> + if (ret)
> + return ret;
> + } while (a);
> + }
> +
> + return ret;
> +}
> +
> int dfu_init_env_entities(char *interface, char *devstr)
> {
> const char *str_env;
> @@ -68,7 +116,11 @@ int dfu_init_env_entities(char *interface, char
> *devstr) }
>
> env_bkp = strdup(str_env);
> - ret = dfu_config_entities(env_bkp, interface, devstr);
> + if (!interface && !devstr)
> + ret = dfu_config_interfaces(env_bkp);
> + else
> + ret = dfu_config_entities(env_bkp, interface,
> devstr); +
> if (ret) {
> pr_err("DFU entities configuration failed!\n");
> pr_err("(partition table does not match
> dfu_alt_info?)\n"); @@ -82,6 +134,7 @@ done:
>
> static unsigned char *dfu_buf;
> static unsigned long dfu_buf_size;
> +static enum dfu_device_type dfu_buf_device_type;
>
> unsigned char *dfu_free_buf(void)
> {
> @@ -99,6 +152,10 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu)
> {
> char *s;
>
> + /* manage several entity with several contraint */
> + if (dfu_buf && dfu->dev_type != dfu_buf_device_type)
> + dfu_free_buf();
> +
> if (dfu_buf != NULL)
> return dfu_buf;
>
> @@ -117,6 +174,7 @@ unsigned char *dfu_get_buf(struct dfu_entity *dfu)
> printf("%s: Could not memalign 0x%lx bytes\n",
> __func__, dfu_buf_size);
>
> + dfu_buf_device_type = dfu->dev_type;
> return dfu_buf;
> }
>
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190722/1796a3f1/attachment.sig>
More information about the U-Boot
mailing list