diff options
author | Brian J. Nemec <bnemec@chromium.org> | 2020-04-01 17:35:40 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-04-02 09:27:49 +0000 |
commit | f648164f18293a2b3e2c5e0b766a8edef787ee9d (patch) | |
tree | b331c2786bc6a2e6c51b02598bfda52a99245c0a | |
parent | 7dfdde8b60d02a350111552842db758fa1391307 (diff) | |
download | chrome-ec-f648164f18293a2b3e2c5e0b766a8edef787ee9d.tar.gz |
ec: Reduced stack usage of gpioget console command
The gpioget console command has a ccprintf() function with over a dozen
parameters. This has excessive stack usage and can trigger stack
overflows. Split the 11 GPIO flags into unique calls with a loop.
This reduces the number of parameters that are passed and handled by
the ccprintf() at once and reduces stack usage.
BUG=chromium:1056780
BRANCH=none
TEST=Connected servod to servo_v4
looped the command 'dut-control servo_v4_uart_cmd:gpioget' 1000 times
TEST=Manual connection to device in the console and executed gpioget,
verified that the format is identical to before.
TEST=make buildall -j
Change-Id: Ied98bab92d68ec248d626375023da4547b052963
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2133368
Tested-by: Brian Nemec <bnemec@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Commit-Queue: Brian Nemec <bnemec@chromium.org>
-rw-r--r-- | common/gpio_commands.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/common/gpio_commands.c b/common/gpio_commands.c index f66b76a9dc..166f955df4 100644 --- a/common/gpio_commands.c +++ b/common/gpio_commands.c @@ -77,9 +77,28 @@ static enum ec_error_list set(const char *name, int value) /*****************************************************************************/ /* Console commands */ +struct gpio_flag_description { + const int bitfield; + const char* name; +}; + +const struct gpio_flag_description gpio_descriptions[] = { + {GPIO_INPUT, "I"}, + {GPIO_OUTPUT, "O"}, + {GPIO_LOW, "L"}, + {GPIO_HIGH, "H"}, + {GPIO_ANALOG, "A"}, + {GPIO_OPEN_DRAIN, "ODR"}, + {GPIO_PULL_UP, "PU"}, + {GPIO_PULL_DOWN, "PD"}, + {GPIO_ALTERNATE, "ALT"}, + {GPIO_SEL_1P8V, "1P8"}, + {GPIO_LOCKED, "LCK"} +}; + static void print_gpio_info(int gpio) { - int changed, v, flags; + int changed, v, flags, i; if (!gpio_is_implemented(gpio)) return; /* Skip unsupported signals */ @@ -92,20 +111,15 @@ static void print_gpio_info(int gpio) #endif changed = last_val_changed(gpio, v); - ccprintf(" %d%c %s%s%s%s%s%s%s%s%s%s%s%s\n", v, - (changed ? '*' : ' '), - (flags & GPIO_INPUT ? "I " : ""), - (flags & GPIO_OUTPUT ? "O " : ""), - (flags & GPIO_LOW ? "L " : ""), - (flags & GPIO_HIGH ? "H " : ""), - (flags & GPIO_ANALOG ? "A " : ""), - (flags & GPIO_OPEN_DRAIN ? "ODR " : ""), - (flags & GPIO_PULL_UP ? "PU " : ""), - (flags & GPIO_PULL_DOWN ? "PD " : ""), - (flags & GPIO_ALTERNATE ? "ALT " : ""), - (flags & GPIO_SEL_1P8V ? "1P8 " : ""), - (flags & GPIO_LOCKED ? "LCK " : ""), - gpio_get_name(gpio)); + /* Split the printf call into multiple calls to reduce the stack usage. */ + ccprintf(" %d%c ", v, (changed ? '*' : ' ')); + + for (i = 0; i < ARRAY_SIZE(gpio_descriptions); i++) { + if (flags & gpio_descriptions[i].bitfield) + ccprintf("%s ", gpio_descriptions[i].name); + } + + ccprintf("%s\n", gpio_get_name(gpio)); /* Flush console to avoid truncating output */ cflush(); |