From 253a04b1fc517e905155be015d72c6ca4d20885d Mon Sep 17 00:00:00 2001 From: minju Date: Tue, 8 Aug 2017 17:35:01 +0900 Subject: [PATCH] Add new TASH Command named stkopt --- apps/system/utils/Kconfig | 7 ++ apps/system/utils/Makefile | 4 + apps/system/utils/kdbg_commands.h | 4 + apps/system/utils/kdbg_stackopt.c | 163 ++++++++++++++++++++++++++++++++++++++ apps/system/utils/kernelcmd.c | 3 + 5 files changed, 181 insertions(+) create mode 100755 apps/system/utils/kdbg_stackopt.c diff --git a/apps/system/utils/Kconfig b/apps/system/utils/Kconfig index e7b35c9..827b478 100644 --- a/apps/system/utils/Kconfig +++ b/apps/system/utils/Kconfig @@ -139,6 +139,13 @@ config STACKMONITOR_INTERVAL endif #ENABLE_STACKMONITOR +config ENABLE_STACKOPT + bool "Stack opt" + default y + depends on ENABLE_STACKMONITOR && TASH_COMMAND_INTERFACE + ---help--- + Measure optimal stack size of APP + config ENABLE_UPTIME bool "uptime" default y diff --git a/apps/system/utils/Makefile b/apps/system/utils/Makefile index 1336f3f..7017bce 100644 --- a/apps/system/utils/Makefile +++ b/apps/system/utils/Makefile @@ -138,6 +138,10 @@ ifeq ($(CONFIG_ENABLE_STACKMONITOR),y) CSRCS += kdbg_stackmonitor.c endif +ifeq ($(CONFIG_ENABLE_STACKOPT),y) +CSRCS += kdbg_stackopt.c +endif + ifeq ($(CONFIG_TTRACE),y) CSRCS += kdbg_ttrace.c endif diff --git a/apps/system/utils/kdbg_commands.h b/apps/system/utils/kdbg_commands.h index f4da48e..c991b14 100644 --- a/apps/system/utils/kdbg_commands.h +++ b/apps/system/utils/kdbg_commands.h @@ -73,6 +73,10 @@ int kdbg_ps(int argc, char **args); int kdbg_stackmonitor(int argc, char **args); #endif +#if defined(CONFIG_ENABLE_STACKOPT) +int kdbg_stackopt(int argc, char **args); +#endif + #if defined(CONFIG_TTRACE) int kdbg_ttrace(int argc, char **args); #endif diff --git a/apps/system/utils/kdbg_stackopt.c b/apps/system/utils/kdbg_stackopt.c new file mode 100755 index 0000000..0c4e798 --- /dev/null +++ b/apps/system/utils/kdbg_stackopt.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include "kdbg_utils.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#ifndef CONFIG_STACK_ALIGNMENT + +/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you + * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly! + */ + +#ifdef __ARM_EABI__ +#define CONFIG_STACK_ALIGNMENT 8 +#else +#define CONFIG_STACK_ALIGNMENT 4 +#endif +#endif + +#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT - 1) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Extern Data + ****************************************************************************/ +extern struct stkmon_save_s stkmon_arr[CONFIG_MAX_TASKS * 2]; +extern tash_taskinfo_t tash_taskinfo_list[]; + +static bool find_app(TASH_CMD_CALLBACK *cb, char *name) +{ + int cmd_idx; + bool flag = false; + char str[CONFIG_TASK_NAME_SIZE]; + int count = tash_get_cmdscount(); + + for (cmd_idx = 0; cmd_idx < count; cmd_idx++) { + if (tash_get_cmdpair(str, cb, cmd_idx) == OK) { + if (!strncmp(name, str, strlen(name) + 1)) { + flag = true; + break; + } + } + } + return flag; +} + +static int execute_app(char **args) +{ + int app_idx; + TASH_CMD_CALLBACK cb; + int pid = 0; + int pri = CONFIG_TASH_CMDTASK_PRIORITY; + long stack_size = CONFIG_TASH_CMDTASK_STACKSIZE; + + if (find_app(&cb, args[0])) { +#if defined(CONFIG_BUILTIN_APPS) + for (app_idx = 0; tash_taskinfo_list[app_idx].str != NULL; app_idx++) { + if (!strncmp(args[0], tash_taskinfo_list[app_idx].str, CONFIG_TASK_NAME_SIZE)) { + pri = tash_taskinfo_list[app_idx].task_prio; + stack_size = tash_taskinfo_list[app_idx].task_stacksize; + break; + } + } +#endif + pid = task_create(args[0], pri, stack_size, cb , &args[1]); + } + return pid; +} + +static int get_frame_size(int argc, char **args) +{ + int args_idx = 0; + size_t strtablen = 0; + size_t argvlen = (argc + 1) * sizeof(FAR char *); + size_t frame_size = 0; + + while (args[args_idx]) { + strtablen += (strlen(args[args_idx]) + 1); + args_idx++; + } + + frame_size = STACK_ALIGN_UP(argvlen + strtablen); + return frame_size; +} + +static void print_measure_result(pid_t pid, int argc, char **args) +{ + int stkmon_idx; + for (stkmon_idx = 0; stkmon_idx < CONFIG_MAX_TASKS * 2; stkmon_idx++) { + if (stkmon_arr[stkmon_idx].chk_pid == pid) { + break; + } + } + + printf("---------------------------------------------------------------\n"); + printf(">> Stack Size Measure Finish\n"); + printf("APP Name : %s\n", stkmon_arr[stkmon_idx].chk_name); + printf("Allocate %d stack size for measure\n", stkmon_arr[stkmon_idx].chk_stksize); + printf("Optimal Stack Size is %d\n", stkmon_arr[stkmon_idx].chk_peaksize + get_frame_size(argc, args)); + printf("If the arguments are changed, optimal stack size can be changed\n"); + printf("---------------------------------------------------------------\n"); + return; +} + +int kdbg_stackopt(int argc, char **args) +{ + int pid; + int status; + + if (argc < 2) { + printf("Invalid argument\n"); + goto usage; + } + + if (!strncmp(args[1], "--help", strlen("--help") + 1)) { + goto usage; + } + + if ((pid = execute_app(&args[1])) < 0) { + printf("Cannot create task\n"); + goto usage; + } else if (pid == 0) { + printf("%s : Cannot find APP\n", args[1]); + goto usage; + } else { + waitpid((pid_t)pid, &status, 0); + print_measure_result((pid_t)pid, argc - 1, &args[1]); + } + return OK; + +usage: + printf("\nUsage: %s NAME [ARGS]\n", args[0]); + printf("Measure optimal stack size of APP\n"); + printf("NAME is the name of the APP you want to measure the optimal stack size\n"); + printf("ARGS is the arguments of the APP named NAME\n"); + printf("If the arguments are changed, optimal stack size can be changed\n"); + return ERROR; +} diff --git a/apps/system/utils/kernelcmd.c b/apps/system/utils/kernelcmd.c index 6f010fa..a24ba59 100644 --- a/apps/system/utils/kernelcmd.c +++ b/apps/system/utils/kernelcmd.c @@ -58,6 +58,9 @@ const static tash_cmdlist_t kdbg_cmds[] = { #if defined(CONFIG_ENABLE_STACKMONITOR) {"stkmon", kdbg_stackmonitor, TASH_EXECMD_SYNC}, #endif +#if defined(CONFIG_ENABLE_STACKOPT) + {"stkopt", kdbg_stackopt, TASH_EXECMD_ASYNC}, +#endif #if defined(CONFIG_TTRACE) {"ttrace", kdbg_ttrace, TASH_EXECMD_SYNC}, #endif -- 2.7.4