bbba2448cd
nsh_syscmds.c: In function ‘cmd_rpmsg_once’: nsh_syscmds.c:567:13: error: ‘RPMSGIOC_PANIC’ undeclared (first use in this function) 567 | cmd = RPMSGIOC_PANIC; | ^~~~~~~~~~~~~~ nsh_syscmds.c:567:13: note: each undeclared identifier is reported only once for each function it appears in nsh_syscmds.c:571:13: error: ‘RPMSGIOC_DUMP’ undeclared (first use in this function); did you mean ‘FIOC_DUMP’? 571 | cmd = RPMSGIOC_DUMP; Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
922 lines
23 KiB
C
922 lines
23 KiB
C
/****************************************************************************
|
|
* apps/nshlib/nsh_syscmds.c
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you 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 <nuttx/config.h>
|
|
|
|
#include <nuttx/power/pm.h>
|
|
#include <nuttx/rpmsg/rpmsg.h>
|
|
#include <nuttx/rptun/rptun.h>
|
|
#include <nuttx/streams.h>
|
|
#include <sys/boardctl.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/utsname.h>
|
|
#include <dirent.h>
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
|
|
#include "nsh.h"
|
|
#include "nsh_console.h"
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_BOARD_CUSTOM
|
|
# ifndef CONFIG_ARCH_BOARD_CUSTOM_NAME
|
|
# define BOARD_NAME g_unknown
|
|
# else
|
|
# define BOARD_NAME CONFIG_ARCH_BOARD_CUSTOM_NAME
|
|
# endif
|
|
#else
|
|
# ifndef CONFIG_ARCH_BOARD
|
|
# define BOARD_NAME g_unknown
|
|
# else
|
|
# define BOARD_NAME CONFIG_ARCH_BOARD
|
|
# endif
|
|
#endif
|
|
|
|
#define UNAME_KERNEL (1 << 0)
|
|
#define UNAME_NODE (1 << 1)
|
|
#define UNAME_RELEASE (1 << 2)
|
|
#define UNAME_VERSION (1 << 3)
|
|
#define UNAME_MACHINE (1 << 4)
|
|
#define UNAME_PLATFORM (1 << 5)
|
|
#define UNAME_UNKNOWN (1 << 6)
|
|
|
|
#ifdef CONFIG_NET
|
|
# define UNAME_ALL (UNAME_KERNEL | UNAME_NODE | UNAME_RELEASE | \
|
|
UNAME_VERSION | UNAME_MACHINE | UNAME_PLATFORM)
|
|
#else
|
|
# define UNAME_ALL (UNAME_KERNEL | UNAME_RELEASE | UNAME_VERSION | \
|
|
UNAME_MACHINE | UNAME_PLATFORM)
|
|
#endif
|
|
|
|
#ifndef CONFIG_NSH_PROC_MOUNTPOINT
|
|
# define CONFIG_NSH_PROC_MOUNTPOINT "/proc"
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Private Data
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_NSH_DISABLE_UNAME
|
|
static const char g_unknown[] = "unknown";
|
|
#endif
|
|
|
|
#if defined(CONFIG_BOARDCTL_RESET_CAUSE) && !defined(CONFIG_NSH_DISABLE_RESET_CAUSE)
|
|
|
|
/* Keep update with nuttx kernel definition */
|
|
|
|
static FAR const char *const g_resetcause[] =
|
|
{
|
|
"none",
|
|
"power_on",
|
|
"rtc_watchdog",
|
|
"brown_out",
|
|
"core_soft_reset",
|
|
"core_deep_sleep",
|
|
"core_main_watchdog",
|
|
"core_rtc_watchdog",
|
|
"cpu_main_watchdog",
|
|
"cpu_soft_reset",
|
|
"cpu_rtc_watchdog",
|
|
"pin",
|
|
"lowpower",
|
|
"unkown"
|
|
};
|
|
#endif
|
|
|
|
#if (defined(CONFIG_BOARDCTL_RESET) && !defined(CONFIG_NSH_DISABLE_REBOOT)) || \
|
|
(defined(CONFIG_BOARDCTL_RESET_CAUSE) && !defined(CONFIG_NSH_DISABLE_RESET_CAUSE))
|
|
static FAR const char * const g_resetflag[] =
|
|
{
|
|
"reboot",
|
|
"assert",
|
|
"panic",
|
|
"bootloader",
|
|
"recovery",
|
|
"factory",
|
|
NULL
|
|
};
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Private Types
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RPMSG) && !defined(CONFIG_NSH_DISABLE_RPMSG)
|
|
typedef CODE int (*cmd_rpmsg_cb_t)(FAR int *cmd, FAR unsigned long * val,
|
|
FAR char **argv);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_shutdown
|
|
****************************************************************************/
|
|
|
|
#if (defined(CONFIG_BOARDCTL_POWEROFF) || defined(CONFIG_BOARDCTL_RESET)) && \
|
|
!defined(CONFIG_NSH_DISABLE_SHUTDOWN)
|
|
|
|
int cmd_shutdown(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
#if defined(CONFIG_BOARDCTL_POWEROFF) && defined(CONFIG_BOARDCTL_RESET)
|
|
/* If both shutdown and reset are supported, then a single option may
|
|
* be provided to select the reset behavior (--reboot). We know here
|
|
* that argc is either 1 or 2.
|
|
*/
|
|
|
|
if (argc == 2)
|
|
{
|
|
/* Verify that the single argument is --reboot */
|
|
|
|
if (strcmp(argv[1], "--reboot") != 0)
|
|
{
|
|
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
|
|
return ERROR;
|
|
}
|
|
|
|
/* Invoke the BOARDIOC_RESET board control to reset the board. If
|
|
* the board_reset() function returns, then it was not possible to
|
|
* reset the board due to some constraints.
|
|
*/
|
|
|
|
boardctl(BOARDIOC_RESET, 0);
|
|
}
|
|
else
|
|
{
|
|
/* Invoke the BOARDIOC_POWEROFF board control to shutdown the board.
|
|
* If the board_power_off function returns, then it was not possible
|
|
* to power-off the* board due to some constraints.
|
|
*/
|
|
|
|
boardctl(BOARDIOC_POWEROFF, 0);
|
|
}
|
|
|
|
#elif defined(CONFIG_BOARDCTL_RESET)
|
|
/* Only reset behavior is supported and we already know that exactly one
|
|
* argument has been provided.
|
|
*/
|
|
|
|
/* Verify that the single argument is --reboot */
|
|
|
|
if (strcmp(argv[1], "--reboot") != 0)
|
|
{
|
|
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
|
|
return ERROR;
|
|
}
|
|
|
|
/* Invoke the BOARDIOC_RESET board control to reset the board. If
|
|
* the board_reset() function returns, then it was not possible to
|
|
* reset the board due to some constraints.
|
|
*/
|
|
|
|
boardctl(BOARDIOC_RESET, 0);
|
|
|
|
#else
|
|
/* Only the reset behavior is supported and we already know that there is
|
|
* no argument to the command.
|
|
*/
|
|
|
|
/* Invoke the BOARDIOC_POWEROFF board control to shutdown the board. If
|
|
* the board_power_off function returns, then it was not possible to power-
|
|
* off the board due to some constraints.
|
|
*/
|
|
|
|
boardctl(BOARDIOC_POWEROFF, 0);
|
|
#endif
|
|
|
|
/* boardctl() will not return in any case. It if does, it means that
|
|
* there was a problem with the shutdown/reset operation.
|
|
*/
|
|
|
|
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "boardctl", NSH_ERRNO);
|
|
return ERROR;
|
|
}
|
|
#endif /* CONFIG_BOARDCTL_POWEROFF && !CONFIG_NSH_DISABLE_SHUTDOWN */
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_pmconfig
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_PM) && !defined(CONFIG_NSH_DISABLE_PMCONFIG)
|
|
static int cmd_pmconfig_recursive(FAR struct nsh_vtbl_s *vtbl,
|
|
FAR const char *dirpath,
|
|
FAR struct dirent *entryp,
|
|
FAR void *pvarg)
|
|
{
|
|
FAR char *path;
|
|
int ret = ERROR;
|
|
|
|
if (DIRENT_ISDIRECTORY(entryp->d_type))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
path = nsh_getdirpath(vtbl, dirpath, entryp->d_name);
|
|
if (path)
|
|
{
|
|
nsh_output(vtbl, "\n%s:\n", path);
|
|
ret = nsh_catfile(vtbl, pvarg, path);
|
|
free(path);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int cmd_pmconfig(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
struct boardioc_pm_ctrl_s ctrl =
|
|
{
|
|
};
|
|
|
|
if (argc <= 2)
|
|
{
|
|
int next_state;
|
|
int last_state;
|
|
|
|
if (argc == 2)
|
|
{
|
|
ctrl.domain = atoi(argv[1]);
|
|
if (ctrl.domain < 0 || ctrl.domain >= CONFIG_PM_NDOMAINS)
|
|
{
|
|
nsh_error(vtbl, g_fmtargrange, argv[1]);
|
|
return ERROR;
|
|
}
|
|
}
|
|
|
|
ctrl.action = BOARDIOC_PM_QUERYSTATE;
|
|
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
|
|
last_state = ctrl.state;
|
|
|
|
ctrl.action = BOARDIOC_PM_CHECKSTATE;
|
|
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
|
|
next_state = ctrl.state;
|
|
|
|
nsh_output(vtbl, "Last state %d, Next state %d\n",
|
|
last_state, next_state);
|
|
|
|
return nsh_foreach_direntry(vtbl, argv[0],
|
|
CONFIG_NSH_PROC_MOUNTPOINT "/pm",
|
|
cmd_pmconfig_recursive, argv[0]);
|
|
}
|
|
else if (argc <= 4)
|
|
{
|
|
if (argc == 4)
|
|
{
|
|
ctrl.domain = atoi(argv[3]);
|
|
if (ctrl.domain < 0 || ctrl.domain >= CONFIG_PM_NDOMAINS)
|
|
{
|
|
nsh_error(vtbl, g_fmtargrange, argv[3]);
|
|
return ERROR;
|
|
}
|
|
}
|
|
|
|
if (strcmp(argv[1], "stay") == 0)
|
|
{
|
|
ctrl.action = BOARDIOC_PM_STAY;
|
|
}
|
|
else if (strcmp(argv[1], "relax") == 0)
|
|
{
|
|
ctrl.action = BOARDIOC_PM_RELAX;
|
|
}
|
|
else
|
|
{
|
|
nsh_output(vtbl, g_fmtarginvalid, argv[1]);
|
|
return ERROR;
|
|
}
|
|
|
|
if (strcmp(argv[2], "normal") == 0)
|
|
{
|
|
ctrl.state = PM_NORMAL;
|
|
}
|
|
else if (strcmp(argv[2], "idle") == 0)
|
|
{
|
|
ctrl.state = PM_IDLE;
|
|
}
|
|
else if (strcmp(argv[2], "standby") == 0)
|
|
{
|
|
ctrl.state = PM_STANDBY;
|
|
}
|
|
else if (strcmp(argv[2], "sleep") == 0)
|
|
{
|
|
ctrl.state = PM_SLEEP;
|
|
}
|
|
else
|
|
{
|
|
nsh_output(vtbl, g_fmtarginvalid, argv[2]);
|
|
return ERROR;
|
|
}
|
|
|
|
boardctl(BOARDIOC_PM_CONTROL, (uintptr_t)&ctrl);
|
|
}
|
|
else
|
|
{
|
|
nsh_error(vtbl, g_fmttoomanyargs, argv[0]);
|
|
return ERROR;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_poweroff
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_BOARDCTL_POWEROFF) && !defined(CONFIG_NSH_DISABLE_POWEROFF)
|
|
int cmd_poweroff(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
/* Invoke the BOARDIOC_POWEROFF board control to shutdown the board. If
|
|
* the board_power_off function returns, then it was not possible to power-
|
|
* off the board due to some constraints.
|
|
*/
|
|
|
|
if (argc > 1)
|
|
{
|
|
boardctl(BOARDIOC_POWEROFF, atoi(argv[1]));
|
|
}
|
|
else
|
|
{
|
|
boardctl(BOARDIOC_POWEROFF, 0);
|
|
}
|
|
|
|
/* boardctl() will not return in any case. It if does, it means that
|
|
* there was a problem with the shutdown operation.
|
|
*/
|
|
|
|
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "boardctl", NSH_ERRNO);
|
|
return ERROR;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_switchboot
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_BOARDCTL_SWITCH_BOOT) && !defined(CONFIG_NSH_DISABLE_SWITCHBOOT)
|
|
int cmd_switchboot(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
if (argc != 2)
|
|
{
|
|
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
|
|
return ERROR;
|
|
}
|
|
|
|
boardctl(BOARDIOC_SWITCH_BOOT, (uintptr_t)argv[1]);
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_boot
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_BOARDCTL_BOOT_IMAGE) && !defined(CONFIG_NSH_DISABLE_BOOT)
|
|
int cmd_boot(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
struct boardioc_boot_info_s info;
|
|
|
|
memset(&info, 0, sizeof(info));
|
|
|
|
/* Invoke the BOARDIOC_BOOT_IMAGE board control to reset the board. If
|
|
* the board_boot_image() function returns, then it was not possible to
|
|
* boot the image due to some constraints.
|
|
*/
|
|
|
|
switch (argc)
|
|
{
|
|
default:
|
|
info.header_size = strtoul(argv[2], NULL, 0);
|
|
|
|
/* Go through */
|
|
|
|
case 1:
|
|
info.path = argv[1];
|
|
|
|
/* Go through */
|
|
|
|
case 0:
|
|
|
|
/* Nothing to do */
|
|
|
|
break;
|
|
}
|
|
|
|
boardctl(BOARDIOC_BOOT_IMAGE, (uintptr_t)&info);
|
|
|
|
/* boardctl() will not return in this case. It if does, it means that
|
|
* there was a problem with the boot operation.
|
|
*/
|
|
|
|
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "boardctl", NSH_ERRNO);
|
|
return ERROR;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_reboot
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_BOARDCTL_RESET) && !defined(CONFIG_NSH_DISABLE_REBOOT)
|
|
int cmd_reboot(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
/* Invoke the BOARDIOC_RESET board control to reset the board. If
|
|
* the board_reset() function returns, then it was not possible to
|
|
* reset the board due to some constraints.
|
|
*/
|
|
|
|
if (argc > 1)
|
|
{
|
|
int i = 0;
|
|
|
|
while (g_resetflag[i] != NULL)
|
|
{
|
|
if (strcmp(g_resetflag[i], argv[1]) == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
if (g_resetflag[i])
|
|
{
|
|
boardctl(BOARDIOC_RESET, i);
|
|
}
|
|
else
|
|
{
|
|
boardctl(BOARDIOC_RESET, atoi(argv[1]));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
boardctl(BOARDIOC_RESET, 0);
|
|
}
|
|
|
|
/* boardctl() will not return in this case. It if does, it means that
|
|
* there was a problem with the reset operation.
|
|
*/
|
|
|
|
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "boardctl", NSH_ERRNO);
|
|
return ERROR;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_BOARDCTL_RESET_CAUSE) && !defined(CONFIG_NSH_DISABLE_RESET_CAUSE)
|
|
int cmd_reset_cause(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
UNUSED(argc);
|
|
|
|
int ret;
|
|
struct boardioc_reset_cause_s cause;
|
|
|
|
memset(&cause, 0, sizeof(cause));
|
|
ret = boardctl(BOARDIOC_RESET_CAUSE, (uintptr_t)&cause);
|
|
if (ret < 0)
|
|
{
|
|
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "boardctl", NSH_ERRNO);
|
|
return ERROR;
|
|
}
|
|
|
|
if (cause.cause != BOARDIOC_RESETCAUSE_CPU_SOFT)
|
|
{
|
|
nsh_output(vtbl, "%s(%lu)\n",
|
|
g_resetcause[cause.cause], cause.flag);
|
|
}
|
|
else
|
|
{
|
|
nsh_output(vtbl, "%s(%s)\n",
|
|
g_resetcause[cause.cause], g_resetflag[cause.flag]);
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_irq_affinity
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_BOARDCTL_IRQ_AFFINITY) && !defined(CONFIG_NSH_DISABLE_IRQ_AFFINITY)
|
|
int cmd_irq_affinity(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
unsigned int affinity[2];
|
|
|
|
if (argc == 3)
|
|
{
|
|
affinity[0] = strtoul(argv[1], NULL, 0);
|
|
affinity[1] = strtoul(argv[2], NULL, 0);
|
|
|
|
if (affinity[1] == 0)
|
|
{
|
|
affinity[1] = 0x1;
|
|
}
|
|
|
|
return boardctl(BOARDIOC_IRQ_AFFINITY, (uintptr_t)affinity);
|
|
}
|
|
|
|
return ERROR;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_rpmsg
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RPMSG) && !defined(CONFIG_NSH_DISABLE_RPMSG)
|
|
static int cmd_rpmsg_once(FAR struct nsh_vtbl_s *vtbl,
|
|
FAR const char *path, FAR char **argv,
|
|
cmd_rpmsg_cb_t rpmsg_cb)
|
|
{
|
|
#ifdef CONFIG_RPMSG_PING
|
|
struct rpmsg_ping_s ping;
|
|
#endif
|
|
unsigned long val = 0;
|
|
int cmd;
|
|
int fd;
|
|
|
|
if (strcmp(argv[1], "panic") == 0)
|
|
{
|
|
cmd = RPMSGIOC_PANIC;
|
|
}
|
|
else if (strcmp(argv[1], "dump") == 0)
|
|
{
|
|
cmd = RPMSGIOC_DUMP;
|
|
}
|
|
#ifdef CONFIG_RPMSG_PING
|
|
else if (strcmp(argv[1], "ping") == 0)
|
|
{
|
|
if (argv[3] == 0 || argv[4] == 0 ||
|
|
argv[5] == 0 || argv[6] == 0)
|
|
{
|
|
nsh_error(vtbl, g_fmtargrequired, argv[0]);
|
|
return ERROR;
|
|
}
|
|
|
|
ping.times = atoi(argv[3]);
|
|
ping.len = atoi(argv[4]);
|
|
ping.cmd = atoi(argv[5]);
|
|
ping.sleep = atoi(argv[6]);
|
|
|
|
cmd = RPMSGIOC_PING;
|
|
val = (unsigned long)&ping;
|
|
}
|
|
#endif
|
|
else if (rpmsg_cb && rpmsg_cb(&cmd, &val, argv) == OK)
|
|
{
|
|
/* Nothing */
|
|
}
|
|
else
|
|
{
|
|
nsh_output(vtbl, g_fmtarginvalid, argv[1]);
|
|
return ERROR;
|
|
}
|
|
|
|
fd = open(path, O_CLOEXEC);
|
|
if (fd < 0)
|
|
{
|
|
nsh_output(vtbl, g_fmtarginvalid, path);
|
|
return ERROR;
|
|
}
|
|
|
|
cmd = ioctl(fd, cmd, val);
|
|
|
|
close(fd);
|
|
|
|
return cmd;
|
|
}
|
|
|
|
static int cmd_rpmsg_recursive(FAR struct nsh_vtbl_s *vtbl,
|
|
FAR const char *dirpath,
|
|
FAR struct dirent *entryp,
|
|
FAR void *pvarg)
|
|
{
|
|
FAR char *path;
|
|
int ret = ERROR;
|
|
|
|
if (DIRENT_ISDIRECTORY(entryp->d_type))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
path = nsh_getdirpath(vtbl, dirpath, entryp->d_name);
|
|
if (path)
|
|
{
|
|
ret = cmd_rpmsg_once(vtbl, path, pvarg, NULL);
|
|
free(path);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int cmd_rpmsg_help(FAR struct nsh_vtbl_s *vtbl, int argc,
|
|
FAR char **argv)
|
|
{
|
|
nsh_output(vtbl, "%s <panic|dump> <path>\n", argv[0]);
|
|
#ifdef CONFIG_RPMSG_PING
|
|
nsh_output(vtbl, "%s ping <path> <times> <length> <cmd> "
|
|
"<period(ms)>\n\n", argv[0]);
|
|
nsh_output(vtbl, "<times> Number of ping operations.\n");
|
|
nsh_output(vtbl, "<length> The length of each ping packet.\n");
|
|
nsh_output(vtbl, "<cmd> Whether the peer acknowlege or "
|
|
"check data.\n");
|
|
nsh_output(vtbl, " Bit0 - Request need ack or not.\n");
|
|
nsh_output(vtbl, " Bit1 - Check the data or not.\n");
|
|
nsh_output(vtbl, " Bit2 - Random length or not.\n");
|
|
nsh_output(vtbl, " Bit4~7 - Request or response or other"
|
|
"command for future use.\n");
|
|
nsh_output(vtbl, "<sleep(ms)> Sleep interval between two operations.\n");
|
|
#endif
|
|
nsh_output(vtbl, "<path> Rpmsg device path.\n\n");
|
|
return OK;
|
|
}
|
|
|
|
int cmd_rpmsg(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
if (argc >= 2 && strcmp(argv[1], "-h") == 0)
|
|
{
|
|
nsh_output(vtbl, "usage:\n\n");
|
|
return cmd_rpmsg_help(vtbl, argc, argv);
|
|
}
|
|
|
|
if (argc < 3)
|
|
{
|
|
nsh_output(vtbl, g_fmtargrequired, argv[0]);
|
|
return ERROR;
|
|
}
|
|
|
|
if (strcmp(argv[2], "all") == 0)
|
|
{
|
|
return nsh_foreach_direntry(vtbl, "rpmsg", "/dev/rpmsg",
|
|
cmd_rpmsg_recursive, argv);
|
|
}
|
|
|
|
return cmd_rpmsg_once(vtbl, argv[2], argv, NULL);
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_rptun
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RPTUN) && !defined(CONFIG_NSH_DISABLE_RPTUN)
|
|
static int cmd_rptun_cb(FAR int *cmd, FAR unsigned long *val,
|
|
FAR char **argv)
|
|
{
|
|
if (strcmp(argv[1], "start") == 0)
|
|
{
|
|
*cmd = RPTUNIOC_START;
|
|
}
|
|
else if (strcmp(argv[1], "stop") == 0)
|
|
{
|
|
*cmd = RPTUNIOC_STOP;
|
|
}
|
|
else if (strcmp(argv[1], "reset") == 0)
|
|
{
|
|
*val = atoi(argv[3]);
|
|
*cmd = RPTUNIOC_RESET;
|
|
}
|
|
else
|
|
{
|
|
return ERROR;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
static int cmd_rptun_recursive(FAR struct nsh_vtbl_s *vtbl,
|
|
FAR const char *dirpath,
|
|
FAR struct dirent *entryp,
|
|
FAR void *pvarg)
|
|
{
|
|
FAR char *path;
|
|
int ret = ERROR;
|
|
|
|
if (DIRENT_ISDIRECTORY(entryp->d_type))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
path = nsh_getdirpath(vtbl, dirpath, entryp->d_name);
|
|
if (path)
|
|
{
|
|
ret = cmd_rpmsg_once(vtbl, path, pvarg, cmd_rptun_cb);
|
|
free(path);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int cmd_rptun(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
if (argc >= 2 && strcmp(argv[1], "-h") == 0)
|
|
{
|
|
nsh_output(vtbl, "usage:\n\n");
|
|
nsh_output(vtbl, "rptun <start|stop> <path>\n");
|
|
nsh_output(vtbl, "rptun <reset> <path> <resetvalue>\n");
|
|
return cmd_rpmsg_help(vtbl, argc, argv);
|
|
}
|
|
|
|
if (argc < 3)
|
|
{
|
|
nsh_output(vtbl, g_fmtargrequired, argv[0]);
|
|
return ERROR;
|
|
}
|
|
|
|
if (strcmp(argv[2], "all") == 0)
|
|
{
|
|
return nsh_foreach_direntry(vtbl, "rptun", "/dev/rptun",
|
|
cmd_rptun_recursive, argv);
|
|
}
|
|
|
|
return cmd_rpmsg_once(vtbl, argv[2], argv, cmd_rptun_cb);
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: cmd_uname
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_NSH_DISABLE_UNAME
|
|
int cmd_uname(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
|
|
{
|
|
FAR const char *str;
|
|
struct lib_memoutstream_s stream;
|
|
struct utsname info;
|
|
struct utsname output;
|
|
unsigned int set;
|
|
int option;
|
|
bool badarg;
|
|
bool first;
|
|
int ret;
|
|
int i;
|
|
|
|
/* Get the uname options */
|
|
|
|
set = 0;
|
|
badarg = false;
|
|
|
|
while ((option = getopt(argc, argv, "asonrvmpi")) != ERROR)
|
|
{
|
|
switch (option)
|
|
{
|
|
case 'a':
|
|
set = UNAME_ALL;
|
|
break;
|
|
|
|
case 'o':
|
|
case 's':
|
|
set |= UNAME_KERNEL;
|
|
break;
|
|
|
|
#ifdef CONFIG_NET
|
|
case 'n':
|
|
set |= UNAME_NODE;
|
|
break;
|
|
#endif
|
|
|
|
case 'r':
|
|
set |= UNAME_RELEASE;
|
|
break;
|
|
|
|
case 'v':
|
|
set |= UNAME_VERSION;
|
|
break;
|
|
|
|
case 'm':
|
|
set |= UNAME_MACHINE;
|
|
break;
|
|
|
|
case 'p':
|
|
if (set != UNAME_ALL)
|
|
{
|
|
set |= UNAME_UNKNOWN;
|
|
}
|
|
break;
|
|
|
|
case 'i':
|
|
set |= UNAME_PLATFORM;
|
|
break;
|
|
|
|
case '?':
|
|
default:
|
|
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
|
|
badarg = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* If a bad argument was encountered, then return without processing the
|
|
* command
|
|
*/
|
|
|
|
if (badarg)
|
|
{
|
|
return ERROR;
|
|
}
|
|
|
|
/* If nothing is provided on the command line, the default is -s */
|
|
|
|
if (set == 0)
|
|
{
|
|
set = UNAME_KERNEL;
|
|
}
|
|
|
|
/* Get uname data */
|
|
|
|
ret = uname(&info);
|
|
if (ret < 0)
|
|
{
|
|
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "uname", NSH_ERRNO);
|
|
return ERROR;
|
|
}
|
|
|
|
/* Process each option */
|
|
|
|
first = true;
|
|
lib_memoutstream(&stream, (FAR char *)&output, sizeof(output));
|
|
for (i = 0; set != 0; i++)
|
|
{
|
|
unsigned int mask = (1 << i);
|
|
if ((set & mask) != 0)
|
|
{
|
|
set &= ~mask;
|
|
switch (i)
|
|
{
|
|
case 0: /* print the kernel/operating system name */
|
|
str = info.sysname;
|
|
break;
|
|
|
|
#ifdef CONFIG_NET
|
|
case 1: /* Print noname */
|
|
str = info.nodename;
|
|
break;
|
|
#endif
|
|
case 2: /* Print the kernel release */
|
|
str = info.release;
|
|
break;
|
|
|
|
case 3: /* Print the kernel version */
|
|
str = info.version;
|
|
break;
|
|
|
|
case 4: /* Print the machine hardware name */
|
|
str = info.machine;
|
|
break;
|
|
|
|
case 5: /* Print the machine platform name */
|
|
str = BOARD_NAME;
|
|
break;
|
|
|
|
case 6: /* Print "unknown" */
|
|
str = g_unknown;
|
|
break;
|
|
|
|
default:
|
|
nsh_error(vtbl, g_fmtarginvalid, argv[0]);
|
|
return ERROR;
|
|
}
|
|
|
|
if (!first)
|
|
{
|
|
lib_stream_putc(&stream, ' ');
|
|
}
|
|
|
|
lib_stream_puts(&stream, str, strlen(str));
|
|
first = false;
|
|
}
|
|
}
|
|
|
|
lib_stream_putc(&stream, '\n');
|
|
nsh_write(vtbl, stream.buffer, stream.common.nput);
|
|
return OK;
|
|
}
|
|
#endif
|