1. SHELL Command Debugging

In order to facilitate the user to use the pc or other controllers to debug the functions of the development board (non-emulator debugging), we provide users with a shell command component, which is similar to the command operation under linux. The user sends commands on the PC or other control terminals, and sends the data to the shell of the development board through serial port, usb, Ethernet, Bluetooth, wifi, etc. The shell will read the received commands for analysis and scan the registered internal functions. After scanning the matching function, execute the matching function, and return the incoming key value and the result of the function execution to the pc or control terminal in real time . It should be noted that the controller side needs to send the key value of the standard keyboard. This demo will demonstrate how to use shell to debug commands through the serial port.

This shell component has the following functions:

  • Support standard keyboard character control

  • Support command auto completion

  • Support up and down keys to view historical commands

  • Support left and right keys to modify commands

  • Support file system and network system debugging

1.1. Prepare

  • PC control terminal uses serial terminal software: xshell or mobaxterm

  • Connection medium: usb to serial port or network or usb

1.2. Hardware Connection

This demo is based on BL706_IOT and the connection method is as follows

   GPIO function         GPIO pin
----------------------------------
    UART0_TX      <-->     GPIO14
    UART0_RX      <-->     GPIO15

1.3. Software Implementation

1.3.1. Shell porting to serial port

  • See examples/shell for the software code

1#define BSP_UART_CLOCK_SOURCE  ROOT_CLOCK_SOURCE_PLL_96M
2#define BSP_UART_CLOCK_DIV  0
  • Configure the UART device clock source, see bsp/board/bl706_iot/clock_config.h

1#define CONFIG_GPIO14_FUNC GPIO_FUN_UART0_TX
2#define CONFIG_GPIO15_FUNC GPIO_FUN_UART0_RX
  • Configure UART device multiplexing pins, see bsp/board/bl706_iot/pinmux_config.h

 1#define BSP_USING_UART0
 2
 3#if defined(BSP_USING_UART0)
 4#ifndef UART0_CONFIG
 5#define UART0_CONFIG \
 6{   \
 7.id = 0, \
 8.baudrate = 2000000,\
 9.databits = UART_DATA_LEN_8, \
10.stopbits = UART_STOP_ONE, \
11.parity = UART_PAR_NONE, \
12.fifo_threshold = 1, \
13}
14#endif
15#endif
  • Enable BSP_USING_UART0 and configure UART device configuration, see bsp/board/bl706_iot/peripheral_config.h

1bflb_platform_init();
  • In the bflb_platform_init function, we have registered and opened a serial port device for debugging, to provide users with a basic function of MSG for printing out messages. The specific implementation is as follows

1    uart_register(board_get_debug_uart_index(), "debug_log", DEVICE_OFLAG_RDWR);
2    struct device *uart = device_find("debug_log");
3
4    if (uart)
5    {
6        device_open(uart, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_INT_RX);
7        device_set_callback(uart, NULL);
8        device_control(uart, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT));
9    }
  • First call the uart_register function to register the UART device, currently register UART0

  • Then use the find function to find the handle corresponding to the device and save it in the uart handle

  • Finally use device_open to open the uart device with polling sending and interrupt receiving, the interrupt is closed by default and the receiving interrupt callback function is not registered

1struct device *uart = device_find("debug_log");
2if (uart) {
3    device_set_callback(uart, shell_irq_callback);
4    device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT));
5}
  • Register the receive interrupt service function for UART0 through the device_set_callback function. Open the UART_RX_FIFO_IT interrupt via the device_control function

1void shell_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
2{
3    uint8_t data;
4    if (state == UART_EVENT_RX_FIFO) {
5        data = *(uint8_t *)args;
6        shell_handler(data);
7    }
8}

-In the interrupt callback function, judge whether the state is UART_EVENT_RX_FIFO, and if it is, pass the received byte to the shell_handler function.

1shell_init();
  • Call shell_init to initialize the shell components.

1.3.2. SHELL Command Registration

Shell command registration uses the following two macros

 1void hellowd()
 2{
 3    MSG("hello World\r\n");
 4}
 5
 6int echo(int argc, char *argv[])
 7{
 8    MSG("%dparameter(s)\r\n", argc);
 9
10    for (uint8_t i = 1; i < argc; i++) {
11        MSG("%s\r\n", argv[i]);
12    }
13
14    return 0;
15}
16
17SHELL_CMD_EXPORT(hellowd, hellowd test)
18SHELL_CMD_EXPORT(echo, echo test)
 1void hellowd()
 2{
 3    MSG("hello World\r\n");
 4}
 5
 6int cmd_echo(int argc, char *argv[])
 7{
 8    MSG("%dparameter(s)\r\n", argc);
 9
10    for (uint8_t i = 1; i < argc; i++) {
11        MSG("%s\r\n", argv[i]);
12    }
13
14    return 0;
15}
16
17SHELL_CMD_EXPORT_ALIAS(hellowd, hellwd,hellowd test)
18SHELL_CMD_EXPORT_ALIAS(cmd_echo, echo,echo test)

1.4. Compile and Program

1 $ cd <sdk_path>/bl_mcu_sdk
2 $ make BOARD=bl706_iot APP=shell SUPPORT_SHELL=y

1.5. Experimental Phenomena

shell test