summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian J. Nemec <bnemec@chromium.org>2020-04-01 17:35:40 -0700
committerCommit Bot <commit-bot@chromium.org>2020-04-02 09:27:49 +0000
commitf648164f18293a2b3e2c5e0b766a8edef787ee9d (patch)
treeb331c2786bc6a2e6c51b02598bfda52a99245c0a
parent7dfdde8b60d02a350111552842db758fa1391307 (diff)
downloadchrome-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.c44
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();