shell: add new APIs to get the backend instances

Added some new APIs to get the backend instances more easily,
so that dev does not need to rely on `shell_backend_*_get_ptr`,
which looks more like a hack to access a local variable.

These APIs are basically copied from the log backend
implementation.

Added testcase for the APIs.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
Yong Cong Sin 2023-10-20 19:58:00 +08:00 committed by Carles Cufí
commit a068288091
6 changed files with 139 additions and 0 deletions

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2023 Meta
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef SHELL_BACKEND_H__
#define SHELL_BACKEND_H__
#include <zephyr/types.h>
#include <zephyr/shell/shell.h>
#include <zephyr/sys/iterable_sections.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get backend.
*
* @param[in] idx Pointer to the backend instance.
*
* @return Pointer to the backend instance.
*/
static inline const struct shell *shell_backend_get(uint32_t idx)
{
const struct shell *backend;
STRUCT_SECTION_GET(shell, idx, &backend);
return backend;
}
/**
* @brief Get number of backends.
*
* @return Number of backends.
*/
static inline int shell_backend_count_get(void)
{
int cnt;
STRUCT_SECTION_COUNT(shell, &cnt);
return cnt;
}
/**
* @brief Get backend by name.
*
* @param[in] backend_name Name of the backend as defined by the SHELL_DEFINE.
*
* @retval Pointer to the backend instance if found, NULL if backend is not found.
*/
const struct shell *shell_backend_get_by_name(const char *backend_name);
#ifdef __cplusplus
}
#endif
#endif /* SHELL_BACKEND_H__ */

View file

@ -1488,6 +1488,17 @@ void shell_process(const struct shell *sh)
z_flag_processing_set(sh, false); z_flag_processing_set(sh, false);
} }
const struct shell *shell_backend_get_by_name(const char *backend_name)
{
STRUCT_SECTION_FOREACH(shell, backend) {
if (strcmp(backend_name, backend->name) == 0) {
return backend;
}
}
return NULL;
}
/* This function mustn't be used from shell context to avoid deadlock. /* This function mustn't be used from shell context to avoid deadlock.
* However it can be used in shell command handlers. * However it can be used in shell command handlers.
*/ */

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(shell)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,8 @@
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_DUMMY=y
CONFIG_SHELL_BACKEND_SERIAL=y
CONFIG_SHELL_CMD_BUFF_SIZE=90
CONFIG_SHELL_PRINTF_BUFF_SIZE=15
CONFIG_SHELL_METAKEYS=n
CONFIG_LOG=n
CONFIG_ZTEST=y

View file

@ -0,0 +1,41 @@
/*
* Copyright 2023 Meta
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <zephyr/shell/shell.h>
#include <zephyr/shell/shell_backend.h>
#include <zephyr/shell/shell_dummy.h>
#include <zephyr/shell/shell_uart.h>
ZTEST(shell_backend, test_backend_apis)
{
const struct shell *sh_dummy = shell_backend_get_by_name("shell_dummy");
const struct shell *sh_uart = shell_backend_get_by_name("shell_uart");
zassert_equal(shell_backend_count_get(), 2, "Expecting 2, got %d",
shell_backend_count_get());
zassert_equal_ptr(sh_dummy, shell_backend_dummy_get_ptr(),
"Unexpected shell_dummy backend");
zassert_equal_ptr(sh_uart, shell_backend_uart_get_ptr(), "Unexpected shell_uart backend");
zassert_equal_ptr(shell_backend_get_by_name("blah"), NULL, "Should be NULL if not found");
zassert_equal_ptr(shell_backend_get(0), sh_dummy < sh_uart ? sh_dummy : sh_uart,
"Unexpected backend at index 0");
zassert_equal_ptr(shell_backend_get(1), sh_dummy < sh_uart ? sh_uart : sh_dummy,
"Unexpected backend at index 1");
}
static void *shell_setup(void)
{
/* Let the shell backend initialize. */
k_usleep(10);
return NULL;
}
ZTEST_SUITE(shell_backend, NULL, shell_setup, NULL, NULL, NULL);

View file

@ -0,0 +1,10 @@
tests:
shell.backend:
min_flash: 64
min_ram: 32
tags:
- shell
filter: ( CONFIG_SHELL )
platform_allow:
- qemu_x86
- qemu_riscv32