SDK updated
This commit is contained in:
commit
c10dc0352f
91
.gitignore
vendored
Normal file
91
.gitignore
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
# ---> C
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# ---> C++
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
#Exceptions
|
||||
bin/w800
|
||||
!bin/build/w800/lib/
|
8
.vscode/settings.json
vendored
Normal file
8
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"nano_shell_interface.h": "c",
|
||||
"wm_include.h": "c",
|
||||
"wm_osal.h": "c",
|
||||
"wm_os_config.h": "c"
|
||||
}
|
||||
}
|
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
MIT License Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
108
Makefile
Normal file
108
Makefile
Normal file
@ -0,0 +1,108 @@
|
||||
TOP_DIR := .
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR # {
|
||||
GEN_IMAGES= $(TARGET).elf
|
||||
GEN_BINS = $(TARGET).bin
|
||||
SUBDIRS = \
|
||||
$(TOP_DIR)/app \
|
||||
$(TOP_DIR)/app/app_lib \
|
||||
$(TOP_DIR)/app/third_party/nano-shell-master \
|
||||
$(TOP_DIR)/app/third_party/driver/NRF24L01P
|
||||
endif # } PDIR
|
||||
|
||||
ifndef PDIR # {
|
||||
ifeq ($(USE_LIB), 0)
|
||||
SUBDIRS += \
|
||||
$(TOP_DIR)/platform/arch \
|
||||
$(TOP_DIR)/platform/common \
|
||||
$(TOP_DIR)/platform/drivers \
|
||||
$(TOP_DIR)/platform/sys \
|
||||
$(TOP_DIR)/src/network \
|
||||
$(TOP_DIR)/src/os \
|
||||
$(TOP_DIR)/src/app
|
||||
ifeq ($(USE_NIMBLE), 1)
|
||||
SUBDIRS += \
|
||||
$(TOP_DIR)/src/bt/blehost
|
||||
else
|
||||
SUBDIRS += \
|
||||
$(TOP_DIR)/src/bt/host
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
COMPONENTS_$(TARGET) = \
|
||||
$(TOP_DIR)/app/libuser$(LIB_EXT) \
|
||||
$(TOP_DIR)/app/app_lib/libapplib$(LIB_EXT) \
|
||||
$(TOP_DIR)/app/third_party/nano-shell-master/libnanoshell$(LIB_EXT) \
|
||||
$(TOP_DIR)/app/third_party/driver/NRF24L01P/libnrf24l01p$(LIB_EXT)
|
||||
|
||||
ifeq ($(USE_LIB), 0)
|
||||
COMPONENTS_$(TARGET) += \
|
||||
$(TOP_DIR)/platform/boot/libwmarch$(LIB_EXT) \
|
||||
$(TOP_DIR)/platform/common/libwmcommon$(LIB_EXT) \
|
||||
$(TOP_DIR)/platform/drivers/libdrivers$(LIB_EXT) \
|
||||
$(TOP_DIR)/platform/sys/libwmsys$(LIB_EXT) \
|
||||
$(TOP_DIR)/src/network/libnetwork$(LIB_EXT) \
|
||||
$(TOP_DIR)/src/os/libos$(LIB_EXT)
|
||||
ifeq ($(USE_NIMBLE), 1)
|
||||
COMPONENTS_$(TARGET) += \
|
||||
$(TOP_DIR)/src/bt/libblehost$(LIB_EXT) \
|
||||
$(TOP_DIR)/src/app/libapp$(LIB_EXT)
|
||||
else
|
||||
COMPONENTS_$(TARGET) += \
|
||||
$(TOP_DIR)/src/bt/libbthost_br_edr$(LIB_EXT) \
|
||||
$(TOP_DIR)/src/app/libapp_br_edr$(LIB_EXT)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
LINKLIB = \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libwlan$(LIB_EXT) \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libdsp$(LIB_EXT)
|
||||
|
||||
ifeq ($(USE_NIMBLE), 1)
|
||||
LINKLIB +=$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libbtcontroller$(LIB_EXT)
|
||||
else
|
||||
LINKLIB +=$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libbtcontroller_br_edr$(LIB_EXT)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
ifeq ($(USE_LIB), 1)
|
||||
LINKLIB += \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libwmarch$(LIB_EXT) \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libwmcommon$(LIB_EXT) \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libdrivers$(LIB_EXT) \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libnetwork$(LIB_EXT) \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libos$(LIB_EXT) \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libwmsys$(LIB_EXT)
|
||||
ifeq ($(USE_NIMBLE), 1)
|
||||
LINKLIB += \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libblehost$(LIB_EXT) \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libapp$(LIB_EXT)
|
||||
else
|
||||
LINKLIB += \
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libbthost_br_edr$(LIB_EXT)\
|
||||
$(TOP_DIR)/lib/$(CONFIG_ARCH_TYPE)/libapp_br_edr$(LIB_EXT)
|
||||
endif
|
||||
endif
|
||||
|
||||
LINKFLAGS_$(TARGET) = \
|
||||
$(LINKLIB)
|
||||
|
||||
CONFIGURATION_DEFINES =
|
||||
|
||||
DEFINES += \
|
||||
$(CONFIGURATION_DEFINES)
|
||||
|
||||
DDEFINES += \
|
||||
$(CONFIGURATION_DEFINES)
|
||||
|
||||
INCLUDES := $(INCLUDES) -I$(PDIR)include
|
||||
INCLUDES += -I ./
|
||||
|
||||
sinclude $(TOP_DIR)/tools/$(CONFIG_ARCH_TYPE)/rules.mk
|
||||
|
||||
.PHONY: FORCE
|
||||
FORCE:
|
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# W801_SDK_dev_env
|
||||
|
||||
## What does this repository contain ?
|
||||
This repository contains a working dev environment for the W801 MCU.
|
||||
It is a test platforme where I can try and learn the provided SDK API.
|
||||
So the software doesn't serve a particular purpose, it's more of a playing field.
|
||||
|
||||
## Getting started:
|
||||
TODO
|
15
app/Makefile
Normal file
15
app/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
TOP_DIR = ..
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libuser$(LIB_EXT)
|
||||
endif
|
||||
|
||||
#DEFINES +=
|
||||
|
||||
sinclude $(TOP_DIR)/tools/w800/rules.mk
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
15
app/app_lib/Makefile
Normal file
15
app/app_lib/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
TOP_DIR = ../..
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libapplib$(LIB_EXT)
|
||||
endif
|
||||
|
||||
#DEFINES +=
|
||||
|
||||
sinclude $(TOP_DIR)/tools/w800/rules.mk
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
13
app/app_lib/app_utils.c
Normal file
13
app/app_lib/app_utils.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include "app_utils.h"
|
||||
|
||||
static uint32_t millis_cnt = 0;
|
||||
|
||||
uint32_t millis(void)
|
||||
{
|
||||
return millis_cnt;
|
||||
}
|
||||
|
||||
void millis_run_cb(void *arg)
|
||||
{
|
||||
millis_cnt++;
|
||||
}
|
10
app/app_lib/app_utils.h
Normal file
10
app/app_lib/app_utils.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef APP_UTILS_H
|
||||
#define APP_UTILS_H
|
||||
|
||||
#include "wm_include.h"
|
||||
|
||||
uint32_t millis(void);
|
||||
|
||||
void millis_run_cb(void *arg);
|
||||
|
||||
#endif //APP_UTILS_H
|
270
app/main.c
Normal file
270
app/main.c
Normal file
@ -0,0 +1,270 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File Name : main.c
|
||||
*
|
||||
* Description: main
|
||||
*
|
||||
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author : dave
|
||||
*
|
||||
* Date : 2014-6-14
|
||||
*****************************************************************************/
|
||||
#include <string.h>
|
||||
#include "nano_shell_server_task.h"
|
||||
#include "wm_include.h"
|
||||
#include "wm_gpio_afsel.h"
|
||||
#include "nano_shell.h"
|
||||
#include "nano_shell_interface.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "FreeRTOSConfig.h"
|
||||
#include "app_common.h"
|
||||
#include "NRF24L01P.h"
|
||||
#include "app_utils.h"
|
||||
|
||||
tls_os_task_t nano_shell_task_handle = NULL;
|
||||
tls_os_task_t nano_shell_server_task_handle = NULL;
|
||||
extern s16 uart0_rx_callback(u16 len, void *user_data);
|
||||
extern s16 uart1_rx_callback(u16 len, void *user_data);
|
||||
|
||||
#define NANO_SHELL_TASK_STK_SIZE 640
|
||||
#define NANO_SHELL_SERVER_TASK_STK_SIZE 640
|
||||
#define PWM_STATUS_LED WM_IO_PB_25
|
||||
#define FADE_DOWN 1
|
||||
#define FADE_UP -1
|
||||
#define FADE_LOW_THRESHOLD 255
|
||||
#define FADE_HIGH_THRESHOLD 200
|
||||
#define PULSE_FAST 3
|
||||
#define PULSE_SLOW 12
|
||||
|
||||
|
||||
u8 pulse_rate = PULSE_SLOW;
|
||||
bool nrf_irq = false;
|
||||
|
||||
void tls_netif_status_event_cb(u8 status)
|
||||
{
|
||||
struct netif *netif = tls_get_netif();
|
||||
switch(status)
|
||||
{
|
||||
case NETIF_WIFI_JOIN_SUCCESS:
|
||||
shell_printf("Evt : NETIF_WIFI_JOIN_SUCCESS"NEW_LINE);
|
||||
break;
|
||||
case NETIF_WIFI_JOIN_FAILED:
|
||||
shell_printf("Evt : NETIF_WIFI_JOIN_FAILED"NEW_LINE);
|
||||
break;
|
||||
case NETIF_WIFI_DISCONNECTED:
|
||||
shell_printf("Evt : NETIF_WIFI_DISCONNECTED"NEW_LINE);
|
||||
pulse_rate = PULSE_SLOW;
|
||||
break;
|
||||
case NETIF_IP_NET_UP:
|
||||
shell_printf("Evt : NETIF_IP_NET_UP"NEW_LINE"ip addr : %v"NEW_LINE"netmask : %v"NEW_LINE"gateway : %v"NEW_LINE, netif->ip_addr.addr,
|
||||
netif->netmask.addr,
|
||||
netif->gw.addr);
|
||||
pulse_rate = PULSE_FAST;
|
||||
break;
|
||||
case NETIF_WIFI_SOFTAP_SUCCESS:
|
||||
shell_printf("Evt : NETIF_WIFI_SOFTAP_SUCCESS"NEW_LINE);
|
||||
break;
|
||||
case NETIF_WIFI_SOFTAP_FAILED:
|
||||
shell_printf("Evt : NETIF_WIFI_SOFTAP_FAILED"NEW_LINE);
|
||||
break;
|
||||
case NETIF_WIFI_SOFTAP_CLOSED:
|
||||
shell_printf("Evt : NETIF_WIFI_SOFTAP_CLOSED"NEW_LINE);
|
||||
pulse_rate = PULSE_SLOW;
|
||||
break;
|
||||
case NETIF_IP_NET2_UP:
|
||||
shell_printf("Evt : NETIF_IP_NET2_UP"NEW_LINE"ip addr : %v"NEW_LINE"netmask : %v"NEW_LINE"gateway : %v"NEW_LINE, netif->next->ip_addr.addr,
|
||||
netif->next->netmask.addr,
|
||||
netif->next->gw.addr);
|
||||
pulse_rate = PULSE_FAST;
|
||||
break;
|
||||
case NETIF_IPV6_NET_UP:
|
||||
shell_printf("Evt : NETIF_IPV6_NET_UP"NEW_LINE);
|
||||
break;
|
||||
default:
|
||||
shell_printf("Evt : UNKNOWN"NEW_LINE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void touchsensor_cb(u32 status)
|
||||
{
|
||||
shell_printf("Touch detected : status(%u)"NEW_LINE, status);
|
||||
}
|
||||
|
||||
void tls_gpio_irq_cb(void *arg)
|
||||
{
|
||||
tls_clr_gpio_irq_status(WM_IO_PB_07);
|
||||
}
|
||||
|
||||
void tls_gpio_pb11_irq_cb(void *arg)
|
||||
{
|
||||
tls_clr_gpio_irq_status(WM_IO_PB_11);
|
||||
nrf_irq = true;
|
||||
}
|
||||
|
||||
void delay_ms(uint32_t ms)
|
||||
{
|
||||
tls_os_time_delay(pdMS_TO_TICKS(ms));
|
||||
}
|
||||
|
||||
uint32_t elapsed_ms(void)
|
||||
{
|
||||
return millis();
|
||||
}
|
||||
|
||||
void CE_HIGH(void)
|
||||
{
|
||||
tls_gpio_write(WM_IO_PB_10, 1);
|
||||
}
|
||||
|
||||
void CE_LOW(void)
|
||||
{
|
||||
tls_gpio_write(WM_IO_PB_10, 0);
|
||||
}
|
||||
|
||||
void user_main(void *param)
|
||||
{
|
||||
u8 pwm_led_duty_cycle = 255;
|
||||
s8 fading_direction = FADE_UP;
|
||||
|
||||
//We initialize input/output used by the app
|
||||
wm_pwm3_config(PWM_STATUS_LED);
|
||||
tls_pwm_init(3, 1000, 0, 0);
|
||||
wm_uart1_tx_config(WM_IO_PB_06);
|
||||
wm_uart1_rx_config(WM_IO_PB_07);
|
||||
tls_gpio_irq_enable(WM_IO_PB_07, WM_GPIO_IRQ_TRIG_DOUBLE_EDGE);
|
||||
tls_gpio_isr_register(WM_IO_PB_07, &(tls_gpio_irq_cb), NULL);
|
||||
|
||||
//We set a a pin as touch sensor :
|
||||
wm_touch_sensor_config(WM_IO_PA_07);
|
||||
tls_touchsensor_threshold_config(1, 120);
|
||||
tls_touchsensor_init_config(1, 16, 16,1);
|
||||
tls_touchsensor_irq_enable(1);
|
||||
tls_touchsensor_irq_register(&(touchsensor_cb));
|
||||
|
||||
//We set the CE and IRQ pin for the NRF module
|
||||
tls_gpio_cfg(WM_IO_PB_10, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING); //CE pin
|
||||
tls_gpio_cfg(WM_IO_PB_11, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING); //IRQ pins
|
||||
tls_gpio_irq_enable(WM_IO_PB_11, WM_GPIO_IRQ_TRIG_FALLING_EDGE);
|
||||
tls_gpio_isr_register(WM_IO_PB_11, &(tls_gpio_pb11_irq_cb), NULL);
|
||||
|
||||
|
||||
//We init the uart 1
|
||||
tls_uart_port_init(TLS_UART_1, NULL, 0);
|
||||
|
||||
//We create and start a timer to run the millis counter
|
||||
struct tls_timer_cfg tmr_millis = {0};
|
||||
tmr_millis.arg = NULL;
|
||||
tmr_millis.is_repeat = true;
|
||||
tmr_millis.timeout = 1;
|
||||
tmr_millis.unit = TLS_TIMER_UNIT_MS;
|
||||
tmr_millis.callback = &(millis_run_cb);
|
||||
u8 tmr_millis_id = tls_timer_create(&tmr_millis);
|
||||
tls_timer_start(tmr_millis_id);
|
||||
|
||||
//We create a task for the nano_shell process
|
||||
u8 *nano_shell_task_stack = NULL, *nano_shell_server_task_stack = NULL;
|
||||
|
||||
tls_uart_rx_callback_register(TLS_UART_0, &(uart0_rx_callback), NULL);
|
||||
tls_uart_rx_callback_register(TLS_UART_1, &(uart1_rx_callback), NULL);
|
||||
|
||||
//we test the NRF lib here
|
||||
/*NRF24L01P_t NRF;
|
||||
shell_printf("Checking NRF setup."NEW_LINE);
|
||||
shell_printf("Setting SPI to 1 Mhz : %d."NEW_LINE, tls_spi_setup(SPI_DEFAULT_MODE, SPI_CS_ACTIVE_MODE, 8000000));
|
||||
shell_printf("NRF begin : %d."NEW_LINE, NRF24L01P_begin(&NRF));
|
||||
shell_printf("Is NRF connected : %d."NEW_LINE, NRF24L01P_isChipConnected(&NRF));
|
||||
//NRF24L01P_setChannel(&NRF, 2);
|
||||
NRF24L01P_setPALevel(&NRF, RF24_PA_LOW, false);
|
||||
//NRF24L01P_setDataRate(&NRF, RF24_250KBPS);
|
||||
//NRF24L01P_setRetries(&NRF, 8, 15);
|
||||
NRF24L01P_enableDynamicPayloads(&NRF);
|
||||
NRF24L01P_enableAckPayload(&NRF);
|
||||
NRF24L01P_maskIRQ(&NRF, true, true, false);
|
||||
|
||||
const uint8_t ADDR[5] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7};
|
||||
const uint8_t ack_pl[] = "1234567";
|
||||
NRF24L01P_openWritingPipe(&NRF, "1Node");
|
||||
NRF24L01P_openReadingPipe(&NRF, 1, "2Node");
|
||||
NRF24L01P_writeAckPayload(&NRF, 1, ack_pl, sizeof ack_pl);
|
||||
NRF24L01P_startListening(&NRF);
|
||||
shell_printf("NRF PA level : %d"NEW_LINE, NRF24L01P_getPALevel(&NRF));
|
||||
NRF24L01P_printDetails(&NRF);*/
|
||||
//uint8_t payload[32] = "Hello W801";
|
||||
//shell_printf("Sending payload : %d"NEW_LINE, NRF24L01P_write(&NRF, payload, sizeof payload));
|
||||
//NRF24L01P_printDetails(&NRF);
|
||||
|
||||
nano_shell_server_task_stack = tls_mem_alloc(sizeof(u32) * NANO_SHELL_SERVER_TASK_STK_SIZE);
|
||||
if(nano_shell_server_task_stack != NULL)
|
||||
{
|
||||
tls_os_status_t status = tls_os_task_create(
|
||||
&nano_shell_server_task_handle,
|
||||
"shll_srv",
|
||||
&(nano_shell_server_task),
|
||||
NULL,
|
||||
(void*) nano_shell_server_task_stack,
|
||||
NANO_SHELL_SERVER_TASK_STK_SIZE * sizeof(u32_t),
|
||||
62,
|
||||
0
|
||||
);
|
||||
if(status != TLS_OS_SUCCESS)
|
||||
shell_printf("Failed to create nano shell server task."NEW_LINE);
|
||||
}
|
||||
|
||||
nano_shell_task_stack = tls_mem_alloc(sizeof(u32) * NANO_SHELL_TASK_STK_SIZE);
|
||||
if(nano_shell_task_stack != NULL)
|
||||
{
|
||||
tls_os_task_create(
|
||||
&nano_shell_task_handle,
|
||||
"na_shell",
|
||||
&(nano_shell_loop),
|
||||
NULL,
|
||||
(void*) nano_shell_task_stack,
|
||||
NANO_SHELL_TASK_STK_SIZE * sizeof(u32),
|
||||
62,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
shell_printf("Registering netif callback."NEW_LINE);
|
||||
tls_netif_add_status_event(&(tls_netif_status_event_cb));
|
||||
|
||||
for(;;)
|
||||
{
|
||||
tls_pwm_duty_set(3, pwm_led_duty_cycle);
|
||||
if(pwm_led_duty_cycle == FADE_LOW_THRESHOLD)
|
||||
{
|
||||
fading_direction = FADE_UP;
|
||||
tls_os_time_delay(pdMS_TO_TICKS(pulse_rate == PULSE_SLOW ? 500 : 100));
|
||||
}
|
||||
else if(pwm_led_duty_cycle == FADE_HIGH_THRESHOLD)
|
||||
{
|
||||
fading_direction = FADE_DOWN;
|
||||
tls_os_time_delay(pdMS_TO_TICKS(pulse_rate == PULSE_SLOW ? 500 : 100));
|
||||
}
|
||||
|
||||
pwm_led_duty_cycle+=fading_direction;
|
||||
|
||||
tls_os_time_delay(pdMS_TO_TICKS(pulse_rate));
|
||||
|
||||
/*if(nrf_irq)
|
||||
{
|
||||
bool tx_ok, tx_fail, rx_ready;
|
||||
NRF24L01P_whatHappened(&NRF, &tx_ok, &tx_fail, &rx_ready);
|
||||
shell_printf("NRF event : tx_ok %d, tx_fail %d and rx_ready : %d, rx fifo full ? %u, tx fifo full ? %u"NEW_LINE, tx_ok, tx_fail, rx_ready, NRF24L01P_rxFifoFull(&NRF), NRF24L01P_txFifoFull(&NRF));
|
||||
|
||||
if(NRF24L01P_available(&NRF))
|
||||
{
|
||||
char payload[32] = "";
|
||||
NRF24L01P_read(&NRF, payload, 8);
|
||||
shell_printf("Received : #%s#\r\n", payload);
|
||||
NRF24L01P_writeAckPayload(&NRF, 1, ack_pl, sizeof ack_pl);
|
||||
}
|
||||
|
||||
nrf_irq = false;
|
||||
}*/
|
||||
}
|
||||
}
|
623
app/nano_shell_command.c
Normal file
623
app/nano_shell_command.c
Normal file
@ -0,0 +1,623 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "command/command.h"
|
||||
#include "wm_include.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "app_common.h"
|
||||
#include "nano_shell_interface.h"
|
||||
#include "wm_gpio_afsel.h"
|
||||
|
||||
extern int wm_printf(const char *fmt,...);
|
||||
extern u32 tls_mem_get_avail_heapsize(void);
|
||||
extern bool disconnect_client(void);
|
||||
|
||||
extern int demo_bt_enable();
|
||||
extern int demo_bt_destroy();
|
||||
extern int demo_ble_server_on();
|
||||
extern int demo_ble_server_off();
|
||||
|
||||
void tls_wifi_client_event_cb(u8 *mac, enum tls_wifi_client_event_type event)
|
||||
{
|
||||
struct tls_sta_info_t *mac_addr = (struct tls_sta_info_t *)mac;
|
||||
|
||||
shell_printf("Client event(%d), MAC : %M"NEW_LINE, event, mac_addr);
|
||||
}
|
||||
|
||||
void wifi_scan_result_cb(void)
|
||||
{
|
||||
u16 buffer_size = sizeof(struct tls_scan_bss_t) + sizeof(struct tls_bss_info_t) * 20;
|
||||
u8 *buf = tls_mem_alloc(buffer_size);
|
||||
if(buf == NULL)
|
||||
{
|
||||
shell_printf("Failed to allocate result buffer"NEW_LINE);
|
||||
return;
|
||||
}
|
||||
struct tls_scan_bss_t *scan_result = (struct tls_scan_bss_t *)buf;
|
||||
struct tls_bss_info_t *station_list = scan_result->bss;
|
||||
|
||||
tls_wifi_get_scan_rslt(buf, buffer_size);
|
||||
shell_printf("Found %u nearby station(s) - info size(%u/%u)"NEW_LINE,
|
||||
scan_result->count,
|
||||
scan_result->length,
|
||||
buffer_size);
|
||||
|
||||
for(u8 i = 0; i < scan_result->count; i++)
|
||||
{
|
||||
station_list[i].ssid[station_list[i].ssid_len] = '\0';
|
||||
shell_printf("station %u :"NEW_LINE"SSID : %s"NEW_LINE"BSSID : %02X:%02X:%02X:%02X:%02X:%02X"NEW_LINE"RSSI : %d dB"NEW_LINE"Channel : %u"NEW_LINE"Max DR : %u Mbps"NEW_LINE"Mode %u"NEW_LINE"Auth :%u"NEW_LINE"WPS supported : %u"NEW_LINE NEW_LINE,
|
||||
i,
|
||||
(char *)station_list[i].ssid,
|
||||
station_list[i].bssid[0], station_list[i].bssid[1], station_list[i].bssid[2], station_list[i].bssid[3], station_list[i].bssid[4], station_list[i].bssid[5],
|
||||
(s8)station_list[i].rssi,
|
||||
station_list[i].channel,
|
||||
station_list[i].max_data_rate,
|
||||
station_list[i].mode,
|
||||
station_list[i].privacy,
|
||||
station_list[i].wps_support);
|
||||
}
|
||||
|
||||
tls_mem_free(buf);
|
||||
}
|
||||
|
||||
void tls_wifi_data_ext_recv_cb(u8* data, u32 data_len, struct tls_wifi_ext_t *ext)
|
||||
{
|
||||
shell_printf("recv packet :"NEW_LINE"rssi : %d\nrate : %u"NEW_LINE, (s8)ext->rssi, ext->rx_rate);
|
||||
for(u32 i = 0; i < data_len; i++)
|
||||
{
|
||||
shell_printf("%02X", data[i]);
|
||||
if(i % 30 == 0)
|
||||
shell_printf(NEW_LINE);
|
||||
}
|
||||
shell_printf(NEW_LINE);
|
||||
}
|
||||
|
||||
void tls_rtc_irq_cb(void *arg)
|
||||
{
|
||||
struct tm rtc_time;
|
||||
tls_get_rtc(&rtc_time);
|
||||
|
||||
shell_printf("rtc isr called"NEW_LINE"time is :"NEW_LINE"%d:%d:%d %d/%d/%d"NEW_LINE,
|
||||
rtc_time.tm_hour,
|
||||
rtc_time.tm_min,
|
||||
rtc_time.tm_sec,
|
||||
rtc_time.tm_mday,
|
||||
rtc_time.tm_mon,
|
||||
rtc_time.tm_year);
|
||||
|
||||
tls_rtc_timer_stop();
|
||||
}
|
||||
|
||||
int _system(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "list_task") == 0)
|
||||
{
|
||||
char *buf = NULL;
|
||||
|
||||
buf = tls_mem_alloc(1024);
|
||||
if(NULL == buf)
|
||||
return 0;
|
||||
#if configUSE_TRACE_FACILITY
|
||||
vTaskList(buf);
|
||||
#endif
|
||||
shell_printf(NEW_LINE"%s"NEW_LINE"buf_len : %d"NEW_LINE, buf, strlen(buf));
|
||||
tls_mem_free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
else if(strcmp(argv[1], "ram_usage") == 0)
|
||||
{
|
||||
shell_printf("Free OS heap : %u/%u byte(s)"NEW_LINE"tls heap size : %u"NEW_LINE, xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE, tls_mem_get_avail_heapsize());
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of system actions :"NEW_LINE"list_task"NEW_LINE"ram_usage"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _reset(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
tls_sys_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _bus(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
char spi_recv_buff[32] = "";
|
||||
u32 fclk = SPI_DEFAULT_SPEED;
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "spi_init") == 0)
|
||||
{
|
||||
if(argc == 3)
|
||||
{
|
||||
fclk = strtoul(argv[2], NULL, 10);
|
||||
if(!fclk) fclk = SPI_DEFAULT_SPEED;
|
||||
}
|
||||
shell_printf("SPI init : %d, clk -> %u Hz"NEW_LINE, tls_spi_setup(SPI_DEFAULT_MODE, SPI_CS_ACTIVE_MODE, fclk), fclk);
|
||||
}
|
||||
else if(strcmp(argv[1], "spi_w") == 0)
|
||||
{
|
||||
shell_printf("Writing [%s](len : %d) to SPI"NEW_LINE, argv[2], strlen(argv[2]));
|
||||
if(tls_spi_write((u8*)argv[2], strlen(argv[2])) != TLS_SPI_STATUS_OK)
|
||||
{
|
||||
shell_printf("Failed to write to SPI"NEW_LINE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if(strcmp(argv[1], "spi_r") == 0)
|
||||
{
|
||||
if(tls_spi_read((u8*)spi_recv_buff, sizeof(spi_recv_buff) - 1) != TLS_SPI_STATUS_OK)
|
||||
{
|
||||
shell_printf("Failed to read from SPI"NEW_LINE);
|
||||
return 0;
|
||||
}
|
||||
shell_printf("Received [%s](len : %d) from SPI"NEW_LINE, spi_recv_buff, strlen(spi_recv_buff));
|
||||
}
|
||||
else if(strcmp(argv[1], "spi_wr") == 0)
|
||||
{
|
||||
if(tls_spi_read_with_cmd((u8 *) argv[2], strlen(argv[2]), (u8 *) spi_recv_buff, sizeof(spi_recv_buff) - 1) != TLS_SPI_STATUS_OK)
|
||||
{
|
||||
shell_printf("Failed to write & read combo using SPI"NEW_LINE);
|
||||
return 0;
|
||||
}
|
||||
shell_printf("Writing [%s](len : %d) to SPI"NEW_LINE, argv[2], strlen(argv[2]));
|
||||
shell_printf("Received [%s](len : %d) from SPI"NEW_LINE, spi_recv_buff, strlen(spi_recv_buff));
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of %s actions :"NEW_LINE"spi_init"NEW_LINE"spi_w"NEW_LINE"spi_r"NEW_LINE"spi_wr"NEW_LINE, argv[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _soft_ap(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "state") == 0)
|
||||
{
|
||||
shell_printf("SOFT AP state : %u"NEW_LINE, tls_wifi_softap_get_state());
|
||||
}
|
||||
else if(strcmp(argv[1], "create") == 0)
|
||||
{
|
||||
struct tls_softap_info_t ap_info;
|
||||
struct tls_ip_info_t ip_info;
|
||||
|
||||
tls_wifi_set_oneshot_flag(0);
|
||||
tls_wifi_softap_destroy();
|
||||
|
||||
shell_printf("Registering client event callback"NEW_LINE);
|
||||
tls_wifi_softap_client_event_register(&(tls_wifi_client_event_cb));
|
||||
|
||||
strncpy((char *)ap_info.ssid, argv[2], 32);
|
||||
ap_info.ssid[32] = '\0';
|
||||
ap_info.encrypt = IEEE80211_ENCRYT_TKIP_WPA2;
|
||||
ap_info.channel = 5;
|
||||
|
||||
ap_info.keyinfo.format = 1;
|
||||
ap_info.keyinfo.index = 1;
|
||||
ap_info.keyinfo.key_len = strlen(argv[3]);
|
||||
strncpy((char *)ap_info.keyinfo.key, argv[3], 63);
|
||||
|
||||
ip_info.ip_addr[0] = 192;
|
||||
ip_info.ip_addr[1] = 168;
|
||||
ip_info.ip_addr[2] = 1;
|
||||
ip_info.ip_addr[3] = 1;
|
||||
ip_info.netmask[0] = 255;
|
||||
ip_info.netmask[1] = 255;
|
||||
ip_info.netmask[2] = 255;
|
||||
ip_info.netmask[3] = 0;
|
||||
ip_info.dnsname[0] = '\0';
|
||||
|
||||
int result = tls_wifi_softap_create(&ap_info, &ip_info);
|
||||
shell_printf("Create AP with SSID : %s, key(%d) : %s -> %d"NEW_LINE, ap_info.ssid, ap_info.keyinfo.key_len, ap_info.keyinfo.key, result);
|
||||
}
|
||||
else if(strcmp(argv[1], "destroy") == 0)
|
||||
{
|
||||
tls_wifi_softap_client_event_register(NULL);
|
||||
tls_wifi_set_oneshot_flag(0);
|
||||
tls_wifi_softap_destroy();
|
||||
shell_printf("Stopping SOFT AP"NEW_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of soft_ap actions :"NEW_LINE"state"NEW_LINE"create <SSID> <PWD>"NEW_LINE"destroy"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _station(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "scan") == 0)
|
||||
{
|
||||
tls_wifi_scan_result_cb_register(&(wifi_scan_result_cb));
|
||||
|
||||
if(tls_wifi_scan() == WM_SUCCESS)
|
||||
{
|
||||
shell_printf("Scanning nearby stations..."NEW_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Failed to start wifi scan"NEW_LINE);
|
||||
}
|
||||
}
|
||||
else if(strcmp(argv[1], "state") == 0)
|
||||
{
|
||||
shell_printf("Station state : %u"NEW_LINE, tls_wifi_get_state());
|
||||
}
|
||||
else if(strcmp(argv[1], "connect") == 0)
|
||||
{
|
||||
shell_printf("Connecting to %s with pwd : %s"NEW_LINE, argv[2], argv[3]);
|
||||
if(tls_wifi_connect((u8 *)argv[2], strlen(argv[2]), (u8 *)argv[3], strlen(argv[3])) == WM_SUCCESS)
|
||||
{
|
||||
shell_printf("Connecting..."NEW_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Failed to connect !"NEW_LINE);
|
||||
}
|
||||
}
|
||||
else if(strcmp(argv[1], "disconnect") == 0)
|
||||
{
|
||||
shell_printf("Disconnecting from current station"NEW_LINE);
|
||||
tls_wifi_set_oneshot_flag(0);
|
||||
tls_wifi_disconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of station actions :"NEW_LINE"scan"NEW_LINE"state"NEW_LINE"connect <SSID> <PWD>"NEW_LINE"disconnect"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _cpu_temp(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
int temperature = adc_temp();
|
||||
|
||||
shell_printf("CPU temp is %d.%03d"NEW_LINE, temperature/1000, temperature%1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _wifi(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "off") == 0)
|
||||
{
|
||||
tls_wifi_softap_destroy();
|
||||
tls_wifi_disconnect();
|
||||
shell_printf("set one shot flg : %d"NEW_LINE,tls_wifi_set_oneshot_flag(0));
|
||||
shell_printf("Stopping WIFI interface"NEW_LINE);
|
||||
}
|
||||
else if(strcmp(argv[1], "error") == 0)
|
||||
{
|
||||
shell_printf("Error : %s"NEW_LINE, tls_wifi_get_errinfo(tls_wifi_get_errno()));
|
||||
}
|
||||
else if(strcmp(argv[1], "promiscuous_on") == 0)
|
||||
{
|
||||
shell_printf("WiFi promiscuous on"NEW_LINE);
|
||||
tls_wifi_data_ext_recv_cb_register(&(tls_wifi_data_ext_recv_cb));
|
||||
}
|
||||
else if(strcmp(argv[1], "promiscuous_off") == 0)
|
||||
{
|
||||
shell_printf("WiFi promiscuous off"NEW_LINE);
|
||||
tls_wifi_data_ext_recv_cb_register(NULL);
|
||||
}
|
||||
else if(strcmp(argv[1], "mode") == 0)
|
||||
{
|
||||
shell_printf("Mode is : %d"NEW_LINE, tls_wifi_get_oneshot_flag());
|
||||
}
|
||||
else if(strcmp(argv[1], "get_ip") == 0)
|
||||
{
|
||||
struct netif *netif = tls_get_netif();
|
||||
|
||||
if(netif)
|
||||
{
|
||||
shell_printf("netif 1"NEW_LINE"ip addr : %v"NEW_LINE"netmask : %v"NEW_LINE"gateway : %v"NEW_LINE, netif->ip_addr.addr,
|
||||
netif->netmask.addr,
|
||||
netif->gw.addr);
|
||||
|
||||
if(netif->next)
|
||||
{
|
||||
shell_printf("netif 2"NEW_LINE"ip addr : %v"NEW_LINE"netmask : %v"NEW_LINE"gateway : %v"NEW_LINE, netif->next->ip_addr.addr,
|
||||
netif->next->netmask.addr,
|
||||
netif->next->gw.addr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("No netif yet, connect to sta or create soft_ap !"NEW_LINE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of wifi actions :"NEW_LINE"off"NEW_LINE"error"NEW_LINE"promiscuous_on"NEW_LINE"promiscuous_off"NEW_LINE"mode"NEW_LINE"get_ip"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _wifi_sleep(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "query") == 0)
|
||||
{
|
||||
shell_printf("power saving : 0x%X, psm chip sleep : 0x%X"NEW_LINE,
|
||||
tls_wifi_get_psflag(),
|
||||
tls_wifi_get_psm_chipsleep_flag());
|
||||
}
|
||||
else if(strcmp(argv[1], "set") == 0)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of wifi_sleep actions :"NEW_LINE"query"NEW_LINE"set"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _pmu(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "sleep") == 0)
|
||||
{
|
||||
u32 duration = strtoul(argv[2], NULL, 10);
|
||||
shell_printf("Going to sleep mode for %u s"NEW_LINE, duration);
|
||||
tls_pmu_timer0_start(duration);
|
||||
tls_pmu_sleep_start();
|
||||
shell_printf("Waking up out of sleep mode"NEW_LINE);
|
||||
tls_pmu_timer0_stop();
|
||||
}
|
||||
else if(strcmp(argv[1], "standby") == 0)
|
||||
{
|
||||
u32 duration = strtoul(argv[2], NULL, 10);
|
||||
shell_printf("Going to standby mode for %u s"NEW_LINE, duration);
|
||||
tls_pmu_timer0_start(duration);
|
||||
tls_pmu_standby_start();
|
||||
shell_printf("Waking up out of standby mode"NEW_LINE);
|
||||
tls_pmu_timer0_stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of pmu actions :"NEW_LINE"sleep <duration(s)>"NEW_LINE"standby <duration(s)>"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _rtc(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "get") == 0)
|
||||
{
|
||||
struct tm rtc_time;
|
||||
tls_get_rtc(&rtc_time);
|
||||
|
||||
shell_printf("rtc time is :"NEW_LINE"%d:%d:%d %d/%d/%d"NEW_LINE,
|
||||
rtc_time.tm_hour,
|
||||
rtc_time.tm_min,
|
||||
rtc_time.tm_sec,
|
||||
rtc_time.tm_mday,
|
||||
rtc_time.tm_mon,
|
||||
rtc_time.tm_year);
|
||||
}
|
||||
else if(strcmp(argv[1], "set") == 0)
|
||||
{
|
||||
struct tm rtc_time;
|
||||
|
||||
rtc_time.tm_hour = strtoul(argv[2], NULL, 10);
|
||||
rtc_time.tm_min = strtoul(argv[3], NULL, 10);
|
||||
rtc_time.tm_sec = strtoul(argv[4], NULL, 10);
|
||||
rtc_time.tm_mday = strtoul(argv[5], NULL, 10);
|
||||
rtc_time.tm_mon = strtoul(argv[6], NULL, 10);
|
||||
rtc_time.tm_year = strtoul(argv[7], NULL, 10);
|
||||
|
||||
shell_printf("Setting rtc to :"NEW_LINE"%d:%d:%d %d/%d/%d"NEW_LINE"isr callback registered !"NEW_LINE,
|
||||
rtc_time.tm_hour,
|
||||
rtc_time.tm_min,
|
||||
rtc_time.tm_sec,
|
||||
rtc_time.tm_mday,
|
||||
rtc_time.tm_mon,
|
||||
rtc_time.tm_year);
|
||||
|
||||
tls_set_rtc(&rtc_time);
|
||||
tls_rtc_isr_register(&(tls_rtc_irq_cb), NULL);
|
||||
}
|
||||
else if(strcmp(argv[1], "alarm") == 0)
|
||||
{
|
||||
struct tm rtc_time;
|
||||
|
||||
rtc_time.tm_hour = strtoul(argv[2], NULL, 10);
|
||||
rtc_time.tm_min = strtoul(argv[3], NULL, 10);
|
||||
rtc_time.tm_sec = strtoul(argv[4], NULL, 10);
|
||||
rtc_time.tm_mday = strtoul(argv[5], NULL, 10);
|
||||
rtc_time.tm_mon = strtoul(argv[6], NULL, 10);
|
||||
rtc_time.tm_year = strtoul(argv[7], NULL, 10);
|
||||
|
||||
shell_printf("Setting rtc alarm to :"NEW_LINE"%d:%d:%d %d/%d/%d"NEW_LINE,
|
||||
rtc_time.tm_hour,
|
||||
rtc_time.tm_min,
|
||||
rtc_time.tm_sec,
|
||||
rtc_time.tm_mday,
|
||||
rtc_time.tm_mon,
|
||||
rtc_time.tm_year);
|
||||
|
||||
tls_rtc_timer_start(&(rtc_time));
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of rtc actions :"NEW_LINE"get"NEW_LINE"set <h> <m> <s> <d> <m> <y>"NEW_LINE"alarm <h> <m> <s> <d> <m> <y>"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _bluetooth(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "enable") == 0)
|
||||
{
|
||||
shell_printf("Enabling bluetooth : %d"NEW_LINE, demo_bt_enable());
|
||||
//shell_printf("Enabling bluetooth test"NEW_LINE);
|
||||
}
|
||||
else if(strcmp(argv[1], "disable") == 0)
|
||||
{
|
||||
shell_printf("Disabling bluetooth : %d"NEW_LINE, demo_bt_destroy());
|
||||
//shell_printf("Disabling bluetooth test"NEW_LINE);
|
||||
}
|
||||
else if(strcmp(argv[1], "start_demo") == 0)
|
||||
{
|
||||
shell_printf("Starting demo : %d"NEW_LINE"Use a BLE app to find the device"NEW_LINE, demo_ble_server_on());
|
||||
}
|
||||
else if(strcmp(argv[1], "stop_demo") == 0)
|
||||
{
|
||||
shell_printf("Stopping demo : %d"NEW_LINE, demo_ble_server_off());
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of bluetooth actions :"NEW_LINE"enable"NEW_LINE"disable"NEW_LINE"start_demo"NEW_LINE"stop_demo"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _telnet(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(argc > 1)
|
||||
{
|
||||
if(strcmp(argv[1], "dont_echo") == 0)
|
||||
{
|
||||
shell_printf("Disabling client echo"NEW_LINE"%c%c%c"NEW_LINE, 0xFF, 0xFB, 0x01);
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Unknown %s action"NEW_LINE, argv[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("List of %s actions :"NEW_LINE"dont_echo"NEW_LINE, argv[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int _exit_remote_access(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
if(disconnect_client())
|
||||
{
|
||||
shell_printf("Disconnected !"NEW_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
shell_printf("Not using remote access !"NEW_LINE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
NANO_SHELL_ADD_CMD(bus,
|
||||
_bus,
|
||||
"Command to interact with the SPI bus",
|
||||
" Use this command to send/receive data from the SPI bus"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(system,
|
||||
_system,
|
||||
"Query system information",
|
||||
" Use this command to get system information"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(reset,
|
||||
_reset,
|
||||
"Reset the system",
|
||||
" Use this command reset the system"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(soft_ap,
|
||||
_soft_ap,
|
||||
"Command to control SOFT AP",
|
||||
" Use this command to control the SOFT AP subsystem"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(station,
|
||||
_station,
|
||||
"Command to control STATION mode",
|
||||
" Use this command to connect to a WiFi access point"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(wifi,
|
||||
_wifi,
|
||||
"Command to control WIFI interface",
|
||||
" Use this command to control the WIFI interface"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(cpu_temp,
|
||||
_cpu_temp,
|
||||
"Command to read the CPU temperature",
|
||||
" Use this command to read the CPU temperature"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(wifi_sleep,
|
||||
_wifi_sleep,
|
||||
"Command to control WiFi sleep",
|
||||
" Use this command to control WiFi sleep feature"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(pmu,
|
||||
_pmu,
|
||||
"Command to control the power management unit",
|
||||
" Use this command to control power management unit feature"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(rtc,
|
||||
_rtc,
|
||||
"Command to query and set up the rtc",
|
||||
" Use this command to interact with the rtc module"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(bluetooth,
|
||||
_bluetooth,
|
||||
"Command to control bluetooth functionality",
|
||||
" Use this command to interact use bluetooth"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(telnet,
|
||||
_telnet,
|
||||
"Command to set the telnet session up",
|
||||
" Use this command to set telnet session parameters"NEW_LINE);
|
||||
NANO_SHELL_ADD_CMD(exit,
|
||||
_exit_remote_access,
|
||||
"Disconnect from Nano-Shell remote access",
|
||||
" Use this command to disconnect from Nano-Shell remote access"NEW_LINE);
|
101
app/nano_shell_port.c
Normal file
101
app/nano_shell_port.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include "wm_include.h"
|
||||
#include "shell_config.h"
|
||||
#include "shell_io/static_fifo.h"
|
||||
|
||||
static_fifo_declare(uart_char_fifo, 256, unsigned char, char);
|
||||
extern int sendchar(int ch);
|
||||
extern bool network_write_char(const char c);
|
||||
extern bool network_write_string(const char *str, size_t size);
|
||||
extern tls_os_task_t nano_shell_task_handle;
|
||||
|
||||
s16 uart0_rx_callback(u16 len, void *user_data)
|
||||
{
|
||||
(void)len;
|
||||
(void)user_data;
|
||||
|
||||
u8 buff[256] = "";
|
||||
int data_len = tls_uart_read(TLS_UART_0, (u8 *) buff, 256);
|
||||
for(int i = 0; i < data_len; i++)
|
||||
{
|
||||
fifo_push(uart_char_fifo, buff[i]);
|
||||
}
|
||||
|
||||
(void)tls_os_task_resume_from_isr(nano_shell_task_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s16 uart1_rx_callback(u16 len, void *user_data)
|
||||
{
|
||||
(void)len;
|
||||
(void)user_data;
|
||||
|
||||
u8 buff[256] = "";
|
||||
int data_len = tls_uart_read(TLS_UART_1, (u8 *) buff, 256);
|
||||
for(int i = 0; i < data_len; i++)
|
||||
{
|
||||
fifo_push(uart_char_fifo, buff[i]);
|
||||
}
|
||||
|
||||
(void)tls_os_task_resume_from_isr(nano_shell_task_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void network_rx_callback(u16 len, char *data)
|
||||
{
|
||||
if(!len)return;
|
||||
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
fifo_push(uart_char_fifo, data[i]);
|
||||
}
|
||||
|
||||
(void)tls_os_task_resume(nano_shell_task_handle);
|
||||
}
|
||||
|
||||
int shell_getc(char *ch)
|
||||
{
|
||||
if(is_fifo_empty(uart_char_fifo))
|
||||
{
|
||||
//If the fifo is empty then we can suspend the task since
|
||||
//it is only waiting for inputs to be processed
|
||||
tls_os_task_suspend(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*ch = fifo_pop_unsafe(uart_char_fifo);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int shell_printf(const char *format, ...)
|
||||
{
|
||||
static char shell_printf_buffer[CONFIG_SHELL_PRINTF_BUFFER_SIZE];
|
||||
|
||||
int length = 0;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
length = vsnprintf(shell_printf_buffer, CONFIG_SHELL_PRINTF_BUFFER_SIZE, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
(void)tls_uart_write(TLS_UART_0, shell_printf_buffer, length);
|
||||
(void)tls_uart_write(TLS_UART_1, shell_printf_buffer, length);
|
||||
(void)network_write_string(shell_printf_buffer, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
void shell_puts(const char *str)
|
||||
{
|
||||
(void)shell_printf(str);
|
||||
}
|
||||
|
||||
void shell_putc(char ch)
|
||||
{
|
||||
(void)shell_printf("%c", ch);
|
||||
}
|
||||
|
||||
void low_level_write_char(char ch)
|
||||
{
|
||||
(void)sendchar((int)ch);
|
||||
(void)tls_uart_write(TLS_UART_1, &ch, 1);
|
||||
(void)network_write_char(ch);
|
||||
}
|
198
app/nano_shell_server_task.c
Normal file
198
app/nano_shell_server_task.c
Normal file
@ -0,0 +1,198 @@
|
||||
#include "string.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "wm_include.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "FreeRTOSConfig.h"
|
||||
#include "nano_shell_server_task.h"
|
||||
#include "nano_shell_interface.h"
|
||||
#include "app_common.h"
|
||||
|
||||
extern void network_rx_callback(u16 len, char *data);
|
||||
|
||||
tls_os_mutex_t *socket_mutex = NULL;
|
||||
int nano_shell_srv_sock = 0, client_sock = 0;
|
||||
const char greeting_buffer[] = "\r\n"
|
||||
" _ _ ____ _ _ _\r\n"
|
||||
"| \\ | | __ _ _ __ ___ / ___|| |__ ___| | |\r\n"
|
||||
"| \\| |/ _` | '_ \\ / _ \\ \\___ \\| '_ \\ / _ \\ | |\r\n"
|
||||
"| |\\ | (_| | | | | (_) | ___) | | | | __/ | |\r\n"
|
||||
"|_| \\_|\\__,_|_| |_|\\___/ |____/|_| |_|\\___|_|_|\r\n"
|
||||
"\r\n"
|
||||
"Welcome to Nano-Shell remote access\r\n"
|
||||
"\r\n"
|
||||
" * Source: https://github.com/lebinlv/nano-shell\r\n"
|
||||
" * Copyright: (c) Liber 2020\r\n"
|
||||
"\r\n";
|
||||
char identity_buffer[250] = "";
|
||||
|
||||
bool network_write_char(const char c)
|
||||
{
|
||||
bool toReturn = false;
|
||||
|
||||
tls_os_mutex_acquire(socket_mutex, 0);
|
||||
if(client_sock > 0)
|
||||
{
|
||||
|
||||
if(send(client_sock, &c, 1, 0) < 0)
|
||||
{
|
||||
// Failed to send data to client because he probably disconnected
|
||||
// or the connection broke
|
||||
client_sock = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
toReturn = true;
|
||||
}
|
||||
}
|
||||
tls_os_mutex_release(socket_mutex);
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
bool network_write_string(const char *str, size_t size)
|
||||
{
|
||||
bool toReturn = false;
|
||||
|
||||
if(client_sock > 0)
|
||||
{
|
||||
tls_os_mutex_acquire(socket_mutex, 0);
|
||||
if(send(client_sock, str, size, 0) < 0)
|
||||
{
|
||||
// Failed to send data to client because he probably disconnected
|
||||
// or the connection broke
|
||||
client_sock = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
toReturn = true;
|
||||
}
|
||||
tls_os_mutex_release(socket_mutex);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
bool disconnect_client(void)
|
||||
{
|
||||
bool toReturn = false;
|
||||
|
||||
if(client_sock > 0)
|
||||
{
|
||||
if(shutdown(client_sock, SHUT_WR) < 0)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
toReturn = true;
|
||||
}
|
||||
client_sock = 0;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
void nano_shell_server_task(void* param)
|
||||
{
|
||||
(void)param;
|
||||
|
||||
bool setup_error = false;
|
||||
char recv_buffer[256] = "";
|
||||
|
||||
struct sockaddr_in nano_shell_srv_addr = { .sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(NANO_SHELL_SERVER_PORT)}, client_addr;
|
||||
socklen_t sockaddr_in_len = sizeof(struct sockaddr_in);
|
||||
|
||||
//We initialize the mutex
|
||||
if(tls_os_mutex_create(0, &socket_mutex) != TLS_OS_SUCCESS)
|
||||
{
|
||||
shell_printf("Failed to create the mutex."NEW_LINE);
|
||||
setup_error = true;
|
||||
}
|
||||
|
||||
//We setup the listening socket :
|
||||
if((nano_shell_srv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
||||
{
|
||||
shell_printf("Failed to create nano_shell listening socket."NEW_LINE);
|
||||
setup_error = true;
|
||||
}
|
||||
|
||||
if(bind(nano_shell_srv_sock, (struct sockaddr *) &nano_shell_srv_addr, sockaddr_in_len) < 0)
|
||||
{
|
||||
shell_printf("Failed to bind nano_shell listening socket to addr."NEW_LINE);
|
||||
setup_error = true;
|
||||
}
|
||||
|
||||
//We only wait for one connection at a time because the nano_shell is not multi user anyway
|
||||
if(listen(nano_shell_srv_sock, 0) < 0)
|
||||
{
|
||||
shell_printf("Failed to mark nano_shell_sock as a listening socket."NEW_LINE);
|
||||
setup_error = true;
|
||||
}
|
||||
|
||||
if(setup_error)
|
||||
{
|
||||
for(;;)
|
||||
tls_os_time_delay(portMAX_DELAY);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
client_sock = accept(nano_shell_srv_sock, (struct sockaddr *)&client_addr, &sockaddr_in_len);
|
||||
|
||||
if(client_sock < 0)
|
||||
{
|
||||
shell_printf("Failed to accept incoming connection."NEW_LINE);
|
||||
}
|
||||
|
||||
if(!network_write_string(greeting_buffer, sizeof greeting_buffer))
|
||||
{
|
||||
shell_printf("Failed to send greetings to client - errno(%d)."NEW_LINE, errno);
|
||||
}
|
||||
|
||||
sprintf(identity_buffer, "Connected from : %u.%u.%u.%u:%u"NEW_LINE NEW_LINE,((u8 *)&client_addr.sin_addr)[0],
|
||||
((u8 *)&client_addr.sin_addr)[1],
|
||||
((u8 *)&client_addr.sin_addr)[2],
|
||||
((u8 *)&client_addr.sin_addr)[3],
|
||||
ntohs(client_addr.sin_port));
|
||||
|
||||
if(!network_write_string(identity_buffer, strlen(identity_buffer)))
|
||||
{
|
||||
shell_printf("Failed to send greetings to client - errno(%d)."NEW_LINE, errno);
|
||||
}
|
||||
|
||||
for(;client_sock > 0;)
|
||||
{
|
||||
int result = recv(client_sock, recv_buffer, 255, 0);
|
||||
|
||||
if(result < 0)
|
||||
{
|
||||
shell_printf("Failed to receive data from client - errno(%d)."NEW_LINE"Closing connection."NEW_LINE, errno);
|
||||
if(close(client_sock) < 0)
|
||||
{
|
||||
shell_printf("Failed to close socket - errno(%d)."NEW_LINE, errno);
|
||||
}
|
||||
client_sock = 0;
|
||||
}
|
||||
else if(result == 0)
|
||||
{
|
||||
shell_printf("Client disconnected."NEW_LINE);
|
||||
if(close(client_sock) < 0)
|
||||
{
|
||||
shell_printf("Failed to close socket - errno(%d)."NEW_LINE, errno);
|
||||
}
|
||||
client_sock = 0;
|
||||
}
|
||||
else //We pass the received data to the nano shell process
|
||||
{
|
||||
//Need to remove the \n at the end
|
||||
char *pos = strchr(recv_buffer, '\r');
|
||||
if(pos)
|
||||
{
|
||||
*pos = '\n';
|
||||
result = pos + 1 - recv_buffer;
|
||||
}
|
||||
network_rx_callback(result, recv_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
app/nano_shell_server_task.h
Normal file
3
app/nano_shell_server_task.h
Normal file
@ -0,0 +1,3 @@
|
||||
#define NANO_SHELL_SERVER_PORT 23
|
||||
|
||||
void nano_shell_server_task(void* param);
|
14
app/third_party/driver/NRF24L01P/Makefile
vendored
Normal file
14
app/third_party/driver/NRF24L01P/Makefile
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
TOP_DIR = ../../../..
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libnrf24l01p$(LIB_EXT)
|
||||
endif
|
||||
|
||||
#DEFINES +=
|
||||
|
||||
sinclude $(TOP_DIR)/tools/w800/rules.mk
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
1153
app/third_party/driver/NRF24L01P/NRF24L01P.c
vendored
Normal file
1153
app/third_party/driver/NRF24L01P/NRF24L01P.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
192
app/third_party/driver/NRF24L01P/NRF24L01P.h
vendored
Normal file
192
app/third_party/driver/NRF24L01P/NRF24L01P.h
vendored
Normal file
@ -0,0 +1,192 @@
|
||||
#ifndef NRF24L01P_H
|
||||
#define NRF24L01P_H
|
||||
|
||||
#include "NRF24L01P_hw_interface.h"
|
||||
|
||||
/*PUBLIC API*/
|
||||
typedef enum rf24_datarate
|
||||
{
|
||||
/** (0) represents 1 Mbps */
|
||||
RF24_1MBPS = 0,
|
||||
/** (1) represents 2 Mbps */
|
||||
RF24_2MBPS,
|
||||
/** (2) represents 250 kbps */
|
||||
RF24_250KBPS
|
||||
} rf24_datarate_e;
|
||||
|
||||
typedef enum rf24_pa_dbm
|
||||
{
|
||||
/**
|
||||
* (0) represents:
|
||||
* nRF24L01 | Si24R1 with<br>lnaEnabled = 1 | Si24R1 with<br>lnaEnabled = 0
|
||||
* :-------:|:-----------------------------:|:----------------------------:
|
||||
* -18 dBm | -6 dBm | -12 dBm
|
||||
*/
|
||||
RF24_PA_MIN = 0,
|
||||
/**
|
||||
* (1) represents:
|
||||
* nRF24L01 | Si24R1 with<br>lnaEnabled = 1 | Si24R1 with<br>lnaEnabled = 0
|
||||
* :-------:|:-----------------------------:|:----------------------------:
|
||||
* -12 dBm | 0 dBm | -4 dBm
|
||||
*/
|
||||
RF24_PA_LOW,
|
||||
/**
|
||||
* (2) represents:
|
||||
* nRF24L01 | Si24R1 with<br>lnaEnabled = 1 | Si24R1 with<br>lnaEnabled = 0
|
||||
* :-------:|:-----------------------------:|:----------------------------:
|
||||
* -6 dBm | 3 dBm | 1 dBm
|
||||
*/
|
||||
RF24_PA_HIGH,
|
||||
/**
|
||||
* (3) represents:
|
||||
* nRF24L01 | Si24R1 with<br>lnaEnabled = 1 | Si24R1 with<br>lnaEnabled = 0
|
||||
* :-------:|:-----------------------------:|:----------------------------:
|
||||
* 0 dBm | 7 dBm | 4 dBm
|
||||
*/
|
||||
RF24_PA_MAX,
|
||||
/**
|
||||
* (4) This should not be used and remains for backward compatibility.
|
||||
*/
|
||||
RF24_PA_ERROR
|
||||
} rf24_pa_dbm_e;
|
||||
|
||||
typedef enum rf24_crclength
|
||||
{
|
||||
/** (0) represents no CRC checksum is used */
|
||||
RF24_CRC_DISABLED = 0,
|
||||
/** (1) represents CRC 8 bit checksum is used */
|
||||
RF24_CRC_8,
|
||||
/** (2) represents CRC 16 bit checksum is used */
|
||||
RF24_CRC_16
|
||||
} rf24_crclength_e;
|
||||
|
||||
typedef struct NRF24L01P
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t payload_size;
|
||||
bool dynamic_payloads_enabled;
|
||||
bool ack_payloads_enabled;
|
||||
uint8_t pipe0_reading_address[5];
|
||||
uint8_t addr_width;
|
||||
uint8_t config_reg;
|
||||
bool is_p_variant;
|
||||
bool failure_detected;
|
||||
} NRF24L01P_t;
|
||||
|
||||
bool NRF24L01P_begin(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_isChipConnected(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_startListening(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_stopListening(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_available(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_read(NRF24L01P_t *NRF, void *payload, uint8_t length);
|
||||
|
||||
bool NRF24L01P_write(NRF24L01P_t *NRF, const void *payload, uint8_t length);
|
||||
|
||||
void NRF24L01P_openWritingPipe(NRF24L01P_t *NRF, const uint8_t* address);
|
||||
|
||||
void NRF24L01P_openReadingPipe(NRF24L01P_t *NRF, uint8_t pipe, const uint8_t *address);
|
||||
|
||||
void NRF24L01P_printDetails(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_availablePipe(NRF24L01P_t *NRF, uint8_t *pipe);
|
||||
|
||||
bool NRF24L01P_rxFifoFull(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_txFifoFull(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_powerDown(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_powerUp(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_writeMulticast(NRF24L01P_t *NRF, const void *payload, uint8_t length, const bool multicast);
|
||||
|
||||
bool NRF24L01P_writeFast(NRF24L01P_t *NRF, const void *payload, uint8_t length);
|
||||
|
||||
bool NRF24L01P_writeFastMulticast(NRF24L01P_t *NRF, const void *payload, uint8_t length, const bool multicast);
|
||||
|
||||
bool NRF24L01P_writeBlocking(NRF24L01P_t *NRF, const void *payload, uint8_t length, uint32_t timeout);
|
||||
|
||||
bool NRF24L01P_txStandBy(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_txStandByTimeout(NRF24L01P_t *NRF, uint32_t timeout, bool start_tx);
|
||||
|
||||
bool NRF24L01P_writeAckPayload(NRF24L01P_t *NRF, uint8_t pipe, const void *payload, uint8_t length);
|
||||
|
||||
void NRF24L01P_whatHappened(NRF24L01P_t *NRF, bool *tx_ok, bool *tx_fail, bool *rx_ready);
|
||||
|
||||
void NRF24L01P_startFastWrite(NRF24L01P_t *NRF, const void *payload, uint8_t length, const bool multicast, bool start_tx);
|
||||
|
||||
bool NRF24L01P_startWrite(NRF24L01P_t *NRF, const void *payload, uint8_t length, const bool multicast);
|
||||
|
||||
void NRF24L01P_reUseTX(NRF24L01P_t *NRF);
|
||||
|
||||
uint8_t NRF24L01P_flush_tx(NRF24L01P_t *NRF);
|
||||
|
||||
uint8_t NRF24L01P_flush_rx(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_testCarrier(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_testRPD(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_closeReadingPipe(NRF24L01P_t *NRF, uint8_t pipe);
|
||||
|
||||
void NRF24L01P_setAddressWidth(NRF24L01P_t *NRF, uint8_t a_width);
|
||||
|
||||
void NRF24L01P_setRetries(NRF24L01P_t *NRF, uint8_t delay, uint8_t count);
|
||||
|
||||
void NRF24L01P_setChannel(NRF24L01P_t *NRF, uint8_t channel);
|
||||
|
||||
uint8_t NRF24L01P_getChannel(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_setPayloadSize(NRF24L01P_t *NRF, uint8_t size);
|
||||
|
||||
uint8_t NRF24L01P_getPayloadSize(NRF24L01P_t *NRF);
|
||||
|
||||
uint8_t NRF24L01P_getDynamicPayloadSize(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_enableAckPayload(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_disableAckPayload(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_enableDynamicPayloads(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_disableDynamicPayloads(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_enableDynamicAck(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_isPVariant(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_setAutoAck(NRF24L01P_t *NRF, bool enable);
|
||||
|
||||
void NRF24L01P_setAutoAckPipe(NRF24L01P_t *NRF, uint8_t pipe, bool enable);
|
||||
|
||||
void NRF24L01P_setPALevel(NRF24L01P_t *NRF, rf24_pa_dbm_e level, bool lna_enable);
|
||||
|
||||
rf24_pa_dbm_e NRF24L01P_getPALevel(NRF24L01P_t *NRF);
|
||||
|
||||
uint8_t NRF24L01P_getARC(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_setDataRate(NRF24L01P_t *NRF, rf24_datarate_e data_rate);
|
||||
|
||||
rf24_datarate_e NRF24L01P_getDataRate(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_setCRCLength(NRF24L01P_t *NRF, rf24_crclength_e length);
|
||||
|
||||
rf24_crclength_e NRF24L01P_getCRCLength(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_disableCRC(NRF24L01P_t *NRF);
|
||||
|
||||
void NRF24L01P_maskIRQ(NRF24L01P_t *NRF, bool tx, bool fail, bool rx);
|
||||
|
||||
void NRF24L01P_startConstCarrier(NRF24L01P_t *NRF, rf24_pa_dbm_e level, uint8_t channel);
|
||||
|
||||
void NRF24L01P_stopConstCarrier(NRF24L01P_t *NRF);
|
||||
|
||||
bool NRF24L01P_isAckPayloadAvailable(NRF24L01P_t *NRF);
|
||||
|
||||
#endif //NRF24L01P_H
|
20
app/third_party/driver/NRF24L01P/NRF24L01P_hw_interface.h
vendored
Normal file
20
app/third_party/driver/NRF24L01P/NRF24L01P_hw_interface.h
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef NRF24L01P_HW_INTERFACE_H
|
||||
#define NRF24L01P_HW_INTERFACE_H
|
||||
|
||||
#include "wm_include.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "app_common.h"
|
||||
#include "nano_shell_interface.h"
|
||||
#include "app_utils.h"
|
||||
|
||||
#define debug_printf(...) shell_printf(__VA_ARGS__); shell_printf(NEW_LINE)
|
||||
|
||||
void delay_ms(uint32_t ms);
|
||||
|
||||
uint32_t elapsed_ms(void);
|
||||
|
||||
void CE_HIGH(void);
|
||||
|
||||
void CE_LOW(void);
|
||||
|
||||
#endif //NRF24L01P_HW_INTERFACE_H
|
21
app/third_party/nano-shell-master/LICENSE
vendored
Normal file
21
app/third_party/nano-shell-master/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Liber
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
18
app/third_party/nano-shell-master/Makefile
vendored
Normal file
18
app/third_party/nano-shell-master/Makefile
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
TOP_DIR = ../../..
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libnanoshell$(LIB_EXT)
|
||||
COMPONENTS_libnanoshell = command/libcommand$(LIB_EXT) \
|
||||
parse/libparse$(LIB_EXT) \
|
||||
readline/libreadline$(LIB_EXT) \
|
||||
shell_io/libshell_io$(LIB_EXT)
|
||||
endif
|
||||
|
||||
#DEFINES +=
|
||||
|
||||
sinclude $(TOP_DIR)/tools/w800/rules.mk
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
384
app/third_party/nano-shell-master/README.md
vendored
Normal file
384
app/third_party/nano-shell-master/README.md
vendored
Normal file
@ -0,0 +1,384 @@
|
||||
# Nano-Shell <!-- omit in toc -->
|
||||
|
||||
<img src="doc/pic/nano_shell_welcome.png" width=600>
|
||||
|
||||
## Contents <!-- omit in toc -->
|
||||
- [Hot Key Bind](#hot-key-bind)
|
||||
- [Add Your Command](#add-your-command)
|
||||
- [HOW:](#how)
|
||||
- [Example:](#example)
|
||||
- [Configuring](#configuring)
|
||||
- [readline configurations:](#readline-configurations)
|
||||
- [command configurations:](#command-configurations)
|
||||
- [shell configurations:](#shell-configurations)
|
||||
- [shell io configurations:](#shell-io-configurations)
|
||||
- [Porting nano-shell to your project](#porting-nano-shell-to-your-project)
|
||||
|
||||
---
|
||||
|
||||
Nano-Shell is a light but powerful shell designed for embedded systems.
|
||||
|
||||
- with or without an operating system;
|
||||
- `<main loop mode>` or `<react mode>`;
|
||||
- highly configurable;
|
||||
- powerful: command line editing, history record, multi-line input, hot key bind, etc...
|
||||
- memory friendly: **NO** malloc and free;
|
||||
- light (build with arm-none-eabi-gcc 7.3.1 20180622, -O3):
|
||||
| | .text<sup>(1)</sup> | .rodata | .bss<sup>(2)</sup> | .data |
|
||||
|:------------------------------------------:|:------:|:-------:|:-----:|:-----:|
|
||||
| main loop mode,<br/>all configurations on | 2.5KB | 1.03KB | 852B | 8B |
|
||||
| main loop mode,<br/>all configurations off<sup>(3)</sup> | 616B | 600B | 180B | 0B |
|
||||
| react mode,<br/>all configurations on | 2.52KB | 1.03KB | 852B | 8B |
|
||||
| react mode,<br/>all configurations off<sup>(3)</sup> | 608B | 600B | 180B | 0B |
|
||||
|
||||
> 1: include built-in `help` command.
|
||||
>
|
||||
> 2: include `input buffer`(default 128Bytes) and `hisroty record buffer`(defaut 650Bytes(5*(128+2)))
|
||||
>
|
||||
> 3: except `CONFIG_SHELL_CMD_BUILTIN_HELP`.
|
||||
|
||||
---
|
||||
|
||||
## Hot Key Bind
|
||||
|
||||
nano-shell has internally bound these hotkeys:
|
||||
|
||||
| HOT KEY | ASCII/ANSI-Escape Code<br/>(Xterm, VT100) | Function |
|
||||
|---------|------------------------|----------|
|
||||
| Ctrl-A | 1 | Home<br/>Move curosr to the start of line.|
|
||||
| Ctrl-E | 5 | End<br/>Move curosr to the end of line.|
|
||||
| Ctrl-P | 16 | Up arrow(-->)<br/>Move cursor right one char.|
|
||||
| Ctrl-N | 14 | Down arrow(-->)<br/>Move cursor right one char.|
|
||||
| Ctrl-B | 2 | Left arrow(<--)<br/>Move cursor left one char.|
|
||||
| Ctrl-F | 6 | Right arrow(-->)<br/>Move cursor right one char.|
|
||||
| Ctrl-D | 4 | Delete<br/>Delete the character under the cursor.|
|
||||
| Ctrl-K | 11 | Erase forward<br/>Clears all characters from the cursor position to the end of the line.|
|
||||
| Ctrl-U | 21 | Erase backword<br/>Clears all characters from the cursor position to the start of the line..|
|
||||
| Ctrl-C | 3 | Kill the line.|
|
||||
| Home | Esc[H | Move curosr to the beginning of line.|
|
||||
| End | Esc[F | Move curosr to the end of line.|
|
||||
| Up Arrow | Esc[A | Get the previous history. |
|
||||
| Down Arrow | Esc[B | Get the next history. |
|
||||
| Left Arrow | Esc[D | Left arrow(<--)<br/>Move cursor left one char. |
|
||||
| Right Arrow | Esc[C | Right arrow(-->)<br/>Move cursor right one char.|
|
||||
| Delete | Esc[3~ | Delete the character under the cursor.|
|
||||
|
||||
---
|
||||
|
||||
## Add Your Command
|
||||
|
||||
### HOW:
|
||||
|
||||
Commands are added to nano-shell by creating a new command structure.
|
||||
|
||||
This is done by first including `command/command.h`, then using the `NANO_SHELL_ADD_CMD()` macro to fill in a `shell_cmd_t` struct.
|
||||
|
||||
``` c
|
||||
NANO_SHELL_ADD_CMD(_name, _func, _brief, _help)
|
||||
```
|
||||
`_name`: name of the command. Note: **THIS IS NOT** a string.
|
||||
|
||||
`_func`: function pointer: `(*cmd)(const shell_cmd_t *, int, int, char *const[])`.
|
||||
|
||||
`_brief`: brief summaries of the command. This is a string.
|
||||
|
||||
`_help`: detailed help information of the command. This is a string.
|
||||
|
||||
Commands with sub-commands can easily be created with a combination of `NANO_SHELL_DEFINE_SUBCMDS`,
|
||||
`NANO_SHELL_SUBCMD_ENTRY` and `NANO_SHELL_ADD_CMD`. See examples for more details.
|
||||
|
||||
### Example 1: Simple command:
|
||||
|
||||
```c
|
||||
int _do_demo(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
for (int i=0; i<argc; i++) {
|
||||
shell_printf(" [DEMO] ARGV[%d]: %s\r\n", i, argv[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
NANO_SHELL_ADD_CMD(demo,
|
||||
_do_demo,
|
||||
"a command demo",
|
||||
" It's detailed help information of demo command\r\n");
|
||||
```
|
||||
|
||||
Run `demo` in terminal:
|
||||
|
||||
<img src="doc/pic/command_demo.png" width=600>
|
||||
|
||||
Run `help` and `help demo` in terminal:
|
||||
|
||||
<img src="doc/pic/help_demo.png" width=600>
|
||||
|
||||
### Example 2: Command with sub-commands:
|
||||
|
||||
It is possible to create commands with sub-commands. More nested command can also be created.
|
||||
|
||||
```c
|
||||
/* Create a bunch of commands to be run as a demo */
|
||||
int _top_command_fallback_fct(const shell_cmd_t* pCmdt, int argc, char* const argv[])
|
||||
{
|
||||
if(argc > 1) {
|
||||
shell_printf(" '%s' is not a subcommand of %s\r\n", argv[1], argv[0]);
|
||||
}
|
||||
else {
|
||||
shell_printf(" Hey, there is subcommands here, type '%s help' for more info\r\n", argv[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int _do_subcommand1(const shell_cmd_t* pCmdt, int argc, char* const argv[]) {
|
||||
shell_puts(" This is sub-command 1\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _do_subsubcommand1(const shell_cmd_t* pCmdt, int argc, char* const argv[]) {
|
||||
shell_puts(" This is sub-sub-command 1\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _do_subsubcommand2(const shell_cmd_t* pCmdt, int argc, char* const argv[]) {
|
||||
shell_puts(" This is sub-sub-command 2\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sub-Sub commands group
|
||||
NANO_SHELL_DEFINE_SUBCMDS(subcommand2_group,
|
||||
NULL,
|
||||
NANO_SHELL_SUBCMD_ENTRY(subsubcommand1,
|
||||
_do_subsubcommand1,
|
||||
"first sub-sub-command",
|
||||
""),
|
||||
NANO_SHELL_SUBCMD_ENTRY(subsubcommand2,
|
||||
_do_subsubcommand2,
|
||||
"second sub-sub-command",
|
||||
""));
|
||||
|
||||
|
||||
// Sub commands group
|
||||
NANO_SHELL_DEFINE_SUBCMDS(top_command_group,
|
||||
_top_command_fallback_fct,
|
||||
NANO_SHELL_SUBCMD_ENTRY(subcommand1,
|
||||
_do_subcommand1,
|
||||
"first subcommand",
|
||||
""),
|
||||
NANO_SHELL_SUBCMD_ENTRY(subcommand2,
|
||||
NANO_SHELL_SUBCMDS_FCT(subcommand2_group),
|
||||
"second subcommand with sub-sub commands",
|
||||
""));
|
||||
|
||||
// Command with sub commands
|
||||
NANO_SHELL_ADD_CMD(top_command,
|
||||
NANO_SHELL_SUBCMDS_FCT(top_command_group),
|
||||
"A command with subcommand",
|
||||
" This command have 2 sub-commands and one sub-sub-command\r\n");
|
||||
|
||||
```
|
||||
|
||||
In a terminal, you get:
|
||||
<img src="doc/pic/subcommand_demo.png" width=600>
|
||||
|
||||
---
|
||||
|
||||
## Configuring
|
||||
|
||||
@file: [`shell_config.h`](/shell_config.h)
|
||||
|
||||
### readline configurations:
|
||||
|
||||
- CONFIG_SHELL_INPUT_BUFFSIZE (127U)
|
||||
- default: `(127U)`
|
||||
- config the command line input buffer size (in byte).
|
||||
|
||||
- CONFIG_SHELL_LINE_EDITING
|
||||
- default: `1(enabled)`
|
||||
- set this to `0` will disable command line editing.
|
||||
|
||||
- CONFIG_SHELL_KEY_SEQ_BIND
|
||||
- default: `1(enabled)`
|
||||
- set this to `0` will disable ANSI-Escape-Sequence. nano-shell will not be able to detect Home/End/Delete/Arrow keys. Doesn't affect Ctrl-P, Ctrl-N, etc...
|
||||
|
||||
- CONFIG_SHELL_MULTI_LINE
|
||||
- default: `1(enabled)`
|
||||
- use Backslash('\\') for line continuation when enabled, set this to `0` will disable line continuation.
|
||||
- line continuation example:<br/><img src="doc/pic/line_continuation.png" width=600> <br/>
|
||||
|
||||
- CONFIG_SHELL_HIST_MIN_RECORD
|
||||
- default: `(5U)`
|
||||
- set this to `0` will disable history record.
|
||||
- nano-shell will take `CONFIG_SHELL_HIST_MIN_RECORD*(2+CONFIG_SHELL_INPUT_BUFFSIZE)` bytes to record **At Least** `CONFIG_SHELL_HIST_MIN_RECORD` histroys. The max history records depends on the average length of the input.
|
||||
|
||||
### command configurations:
|
||||
|
||||
- CONFIG_SHELL_CMD_BRIEF_USAGE
|
||||
- default: `1(enabled)`
|
||||
- command structure `shell_cmd_t` has a pointer point to "brief usage information of the command", set this to `0` will remove it.
|
||||
|
||||
- CONFIG_SHELL_CMD_LONG_HELP
|
||||
- default: `1(enabled)`
|
||||
- command structure `shell_cmd_t` has a pointer point to "detailed help information of the command", set this to `0` will remove it.
|
||||
|
||||
- CONFIG_SHELL_CMD_BUILTIN_HELP
|
||||
- default: `1(enabled)`
|
||||
- nano-shell provides a built-in `help` command, set this to `0` will remove the deault `help` command.
|
||||
|
||||
- CONFIG_SHELL_CMD_MAX_ARGC
|
||||
- default: `(10U)`
|
||||
- config the max number of arguments, must be no less than 1.
|
||||
|
||||
### shell configurations:
|
||||
|
||||
- CONFIG_SHELL_PROMPT
|
||||
- default: `"Nano-Shell >> "`
|
||||
- config the shell promot that will displayed at the start of line. If you don't need it, set this to `NULL` or `""`.
|
||||
|
||||
|
||||
### shell io configurations:
|
||||
|
||||
- CONFIG_SHELL_PRINTF_BUFFER_SIZE
|
||||
- default: `(128U)`
|
||||
- config the buffer size of `shell_printf()`.
|
||||
|
||||
---
|
||||
|
||||
## Porting nano-shell to your project
|
||||
|
||||
### 1. add nano-shell root path to your project include path. <!-- omit in toc -->
|
||||
|
||||
### 2. implement these functions([`@file shell_io.h`](/shell_io/shell_io.h)) in your project: <!-- omit in toc -->
|
||||
|
||||
this file may help: [`/shell_io/shell_io.c`](/shell_io/shell_io.c).
|
||||
```c
|
||||
/**
|
||||
* @brief send a chararcter...
|
||||
*
|
||||
*/
|
||||
extern void shell_putc(char ch);
|
||||
|
||||
|
||||
/**
|
||||
* @brief send string...
|
||||
*
|
||||
*/
|
||||
extern void shell_puts(const char *str);
|
||||
|
||||
|
||||
/**
|
||||
* @brief printf() for nano-shell
|
||||
*
|
||||
*/
|
||||
extern int shell_printf(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
|
||||
/**
|
||||
* @brief: Get next character available from stream.
|
||||
*
|
||||
* @param ch: Return the character in `ch` if there was...
|
||||
* @return: Result is non-zero if there was a character, or 0 if there wasn't.
|
||||
*
|
||||
*/
|
||||
extern int shell_getc(char *ch);
|
||||
```
|
||||
|
||||
Note:
|
||||
- `int shell_getc(char *ch)` is **NOT USED** in `<react mode>`
|
||||
- If you run nano-shell in `<main loop mode>`, to avoid losing characters, you'd better use a low layer receive fifo.
|
||||
|
||||
Take uart for example, you can detect incoming data using interrupts and then store each received character in a first-in-first-out (FIFO) buffer:
|
||||
```c
|
||||
void your_uart_interrupt_handler(void)
|
||||
{
|
||||
/* your uart receive code */
|
||||
char ch = uart_get_char();
|
||||
|
||||
/* store character in fifo */
|
||||
fifo_push(ch);
|
||||
}
|
||||
```
|
||||
|
||||
then `shell_getc(char *ch)` may be:
|
||||
```c
|
||||
int shell_getc(char *ch)
|
||||
{
|
||||
if (fifo_empty()) { // if no character in fifo,
|
||||
return 0; // return false
|
||||
}
|
||||
|
||||
*ch = fifo_pop(); // fifo is not empty, get a character from fifo.
|
||||
return 1; // return true
|
||||
}
|
||||
```
|
||||
I write a simple and lock free fifo based on ring buffer in [`@file: /shell_io/static_fifo.h`](/shell_io/static_fifo.h), maybe helpful...
|
||||
|
||||
### 3. then modify the configuration file: [`shell_config.h`](/shell_config.h) <!-- omit in toc -->
|
||||
|
||||
### 4. according to your system, you can: <!-- omit in toc -->
|
||||
|
||||
#### 4.1 without os, main loop mode: <!-- omit in toc -->
|
||||
|
||||
```c
|
||||
#include "nano_shell.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* system init code... */
|
||||
|
||||
/* nano-shell infinite loop. */
|
||||
nano_shell_loop(NULL);
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2 without os, react mode(non-block): <!-- omit in toc -->
|
||||
|
||||
you can use it in interrupt, take UART for example:
|
||||
|
||||
```c
|
||||
void your_uart_interrupt_handler (void)
|
||||
{
|
||||
/* your uart receive code */
|
||||
char ch = uart_get_char();
|
||||
|
||||
/* nano-shell isr interface */
|
||||
nano_shell_react(ch);
|
||||
}
|
||||
```
|
||||
|
||||
Note:
|
||||
- `nano_shell_react()` is non-blocked (unless there was an infinite loop in your command function), you can call it when get a new character.
|
||||
- ~~It is recommended to disable some configurations in `shell_config.h` if it was called in interrupt.~~
|
||||
|
||||
#### 4.3 with os, take freertos for example: <!-- omit in toc -->
|
||||
|
||||
```c
|
||||
#include "nano_shell.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* system init code... */
|
||||
|
||||
/* create nano_shell task */
|
||||
TaskHandle_t shellTaskHandle = NULL;
|
||||
xTaskCreate(nano_shell_loop, "shellTask", <stack_size>, NULL,
|
||||
<task_priority>, &shellTaskHandle);
|
||||
|
||||
/* start rtos task scheduler */
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
```
|
||||
|
||||
Note:
|
||||
- When determining the stack size for nano-shell, you should consider the memory occupied by commands added in nano-shell.
|
||||
|
||||
### 5. define nano_shell section in your linker script file: <!-- omit in toc -->
|
||||
|
||||
add these 5 lines to your linker script file:
|
||||
```ld
|
||||
.nano_shell : {
|
||||
. = ALIGN(4);
|
||||
KEEP (*(SORT(.nano_shell*)))
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
```
|
||||
|
||||
### 6. build, flash and try it. <!-- omit in toc -->
|
13
app/third_party/nano-shell-master/command/Makefile
vendored
Normal file
13
app/third_party/nano-shell-master/command/Makefile
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
TOP_DIR = ../../../..
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libcommand$(LIB_EXT)
|
||||
endif
|
||||
|
||||
#DEFINES +=
|
||||
|
||||
sinclude $(TOP_DIR)/tools/w800/rules.mk
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
102
app/third_party/nano-shell-master/command/cmd_help.c
vendored
Normal file
102
app/third_party/nano-shell-master/command/cmd_help.c
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file cmd_help.c
|
||||
* @author Liber (lvlebin@outlook.com), Cédric CARRÉE (beg0@free.fr)
|
||||
* @brief nano-shell build in command: help
|
||||
* @version 1.0
|
||||
* @date 2020-03-25
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "command.h"
|
||||
#include "shell_io/shell_io.h"
|
||||
|
||||
#include "shell_config.h"
|
||||
|
||||
/****************************** build in command: help ******************************/
|
||||
#if CONFIG_SHELL_CMD_BUILTIN_HELP
|
||||
|
||||
static void shell_print_cmd_list(const shell_cmd_t* start, unsigned int count)
|
||||
{
|
||||
const shell_cmd_t* tmp = start;
|
||||
while (count) {
|
||||
#if CONFIG_SHELL_CMD_BRIEF_USAGE
|
||||
shell_printf(" %s: %s\r\n", tmp->name, tmp->brief_usage);
|
||||
#else
|
||||
shell_printf(" %s\r\n", tmp->name);
|
||||
#endif
|
||||
count--;
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
static void shell_print_cmd_help(const char *cmd_name,
|
||||
const shell_cmd_t* start, unsigned int count)
|
||||
{
|
||||
#if CONFIG_SHELL_CMD_LONG_HELP
|
||||
const shell_cmd_t *tmp = shell_find_cmd(cmd_name, start, count);
|
||||
|
||||
if (tmp) {
|
||||
#if CONFIG_SHELL_CMD_BRIEF_USAGE
|
||||
shell_printf("%s: %s\r\n", cmd_name, tmp->brief_usage);
|
||||
#else
|
||||
shell_printf("%s:\r\n", cmd_name);
|
||||
#endif
|
||||
|
||||
// use puts() instead of printf() to avoid printf buffer overflow
|
||||
shell_puts(tmp->help);
|
||||
} else {
|
||||
shell_printf("%s: command not found.\r\n", cmd_name);
|
||||
}
|
||||
#endif /* CONFIG_SHELL_CMD_LONG_HELP */
|
||||
}
|
||||
|
||||
|
||||
int shell_cmd_help(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||
{
|
||||
const shell_cmd_t *start = _shell_entry_start(shell_cmd_t);
|
||||
unsigned int count = _shell_entry_count(shell_cmd_t);
|
||||
return shell_help_generic(argc, argv,
|
||||
"nano-shell, version 1.0.0.",
|
||||
start, count);
|
||||
}
|
||||
|
||||
int shell_help_generic(int argc, char *const argv[],
|
||||
const char* preamble,
|
||||
const shell_cmd_t* start, unsigned int count)
|
||||
{
|
||||
if (argc == 1) {
|
||||
shell_puts(preamble);
|
||||
shell_puts("\r\n"
|
||||
#if CONFIG_SHELL_CMD_LONG_HELP
|
||||
"Type `help name' to find out more about the function `name'.\r\n"
|
||||
#endif
|
||||
"\r\n");
|
||||
shell_print_cmd_list(start, count);
|
||||
shell_puts("\r\n");
|
||||
}
|
||||
#if CONFIG_SHELL_CMD_LONG_HELP
|
||||
else {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
shell_print_cmd_help(argv[i], start, count);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SHELL_CMD_LONG_HELP */
|
||||
return 0;
|
||||
}
|
||||
|
||||
NANO_SHELL_ADD_CMD(help,
|
||||
shell_cmd_help,
|
||||
"help [pattern ...]",
|
||||
|
||||
" Print information about builtin commands.\r\n"
|
||||
"\r\n"
|
||||
" If PATTERN is specified, gives detailed help on all commands\r\n"
|
||||
" matching PATTERN, otherwise print the list of all available commands.\r\n"
|
||||
"\r\n"
|
||||
" Arguments:\r\n"
|
||||
" PATTERN: specifiying the help topic\r\n");
|
||||
|
||||
#endif /* CONFIG_SHELL_CMD_BUILTIN_HELP */
|
80
app/third_party/nano-shell-master/command/command.c
vendored
Normal file
80
app/third_party/nano-shell-master/command/command.c
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @file command.c
|
||||
* @author Liber (lvlebin@outlook.com), Cédric CARRÉE (beg0@free.fr)
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2020-03-24
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "shell_io/shell_io.h"
|
||||
#include "command.h"
|
||||
|
||||
const shell_cmd_t *shell_find_top_cmd(const char *cmd_name)
|
||||
{
|
||||
const shell_cmd_t *start = _shell_entry_start(shell_cmd_t);
|
||||
unsigned int count = _shell_entry_count(shell_cmd_t);
|
||||
return shell_find_cmd(cmd_name, start, count);
|
||||
}
|
||||
|
||||
const shell_cmd_t *shell_find_cmd(const char *cmd_name, const shell_cmd_t* start, unsigned int count)
|
||||
{
|
||||
const shell_cmd_t *tmp = start;
|
||||
|
||||
if (cmd_name == NULL || start == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (count) {
|
||||
if (strcmp(cmd_name, tmp->name) == 0) {
|
||||
return tmp;
|
||||
}
|
||||
count--;
|
||||
tmp++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int shell_run_cmd(int argc, char *const argv[])
|
||||
{
|
||||
if (argc > 0) {
|
||||
const shell_cmd_t *pCmdt = shell_find_top_cmd(argv[0]);
|
||||
|
||||
if (pCmdt) {
|
||||
return pCmdt->cmd(pCmdt, argc, argv);
|
||||
}
|
||||
|
||||
shell_printf(" %s: command not found.\r\n", argv[0]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int shell_run_subcmd_implem(const shell_cmd_t* pCmdt,
|
||||
int argc, char* const argv[],
|
||||
shell_cmd_cb_t fallback_fct,
|
||||
const shell_cmd_t* subcommands, unsigned int subcommands_count)
|
||||
{
|
||||
if (argc > 1) {
|
||||
const shell_cmd_t* pSubCmdt = shell_find_cmd(argv[1], subcommands, subcommands_count);
|
||||
|
||||
if (pSubCmdt) {
|
||||
return pSubCmdt->cmd(pSubCmdt, argc - 1, argv + 1);
|
||||
}
|
||||
else if(fallback_fct) {
|
||||
return fallback_fct(pCmdt, argc, argv);
|
||||
}
|
||||
else {
|
||||
shell_printf(" %s: sub-command not found.\r\n", argv[1]);
|
||||
}
|
||||
}
|
||||
else if(fallback_fct) {
|
||||
return fallback_fct(pCmdt, argc, argv);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
249
app/third_party/nano-shell-master/command/command.h
vendored
Normal file
249
app/third_party/nano-shell-master/command/command.h
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
/**
|
||||
* @file command.h
|
||||
* @author Liber (lvlebin@outlook.com), Cédric CARRÉE (beg0@free.fr)
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2020-03-23
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SHELL_COMMAND_H
|
||||
#define __NANO_SHELL_COMMAND_H
|
||||
|
||||
#include "shell_linker.h"
|
||||
|
||||
#include "shell_config.h"
|
||||
|
||||
// Forward delecation of shell command structure
|
||||
struct _shell_cmd_s;
|
||||
|
||||
/**
|
||||
* @brief this is the implementation function of the command.
|
||||
*
|
||||
* @param pCmdt: pointer of the structure.
|
||||
* @param argc: the count of arguments.
|
||||
* @param argv: argument vector.
|
||||
* @return 0 if succeed, else non-zero. (return value is not used in ver1.0)
|
||||
*
|
||||
* @note the command name is the first argument, argv[0], so argc is always at least 1.
|
||||
*/
|
||||
typedef int (*shell_cmd_cb_t)(const struct _shell_cmd_s *pCmdt, int argc, char *const argv[]);
|
||||
|
||||
// shell command structure
|
||||
typedef struct _shell_cmd_s {
|
||||
const char *name; // command name
|
||||
|
||||
shell_cmd_cb_t cmd; // Callback function to run the shell command
|
||||
|
||||
#if CONFIG_SHELL_CMD_BRIEF_USAGE
|
||||
const char *brief_usage; // brief usage of the command.
|
||||
#endif
|
||||
|
||||
#if CONFIG_SHELL_CMD_LONG_HELP
|
||||
const char *help; // detailed help information of the command.
|
||||
#endif
|
||||
} shell_cmd_t;
|
||||
|
||||
|
||||
// shell function structure
|
||||
typedef struct {
|
||||
const char *name; // function name
|
||||
|
||||
const int param_n; // number of parameters
|
||||
|
||||
int (*func)(); // function pointr.
|
||||
|
||||
#if CONFIG_SHELL_FUNC_BRIEF_USAGE
|
||||
const char *brief; // brief summaries of the command.
|
||||
#endif
|
||||
} shell_func_t;
|
||||
|
||||
|
||||
#if CONFIG_SHELL_CMD_BRIEF_USAGE
|
||||
#define _CMD_BRIEF(x) x,
|
||||
#else
|
||||
#define _CMD_BRIEF(x)
|
||||
#endif /* CONFIG_SHELL_CMD_BRIEF_USAGE */
|
||||
|
||||
#if CONFIG_SHELL_CMD_LONG_HELP
|
||||
#define _CMD_HELP(x) x,
|
||||
#else
|
||||
#define _CMD_HELP(x)
|
||||
#endif /* CONFIG_SHELL_CMD_LONG_HELP */
|
||||
|
||||
#if CONFIG_SHELL_FUNC_BRIEF_USAGE
|
||||
#define _FUNC_BRIEF(x) x,
|
||||
#else
|
||||
#define _FUNC_BRIEF(x)
|
||||
#endif /* CONFIG_SHELL_FUNC_BRIEF_USAGE */
|
||||
|
||||
|
||||
|
||||
#define _shell_cmd_complete(_name, _func, _brief, _help) \
|
||||
{ #_name, _func, _CMD_BRIEF(_brief) _CMD_HELP(_help) }
|
||||
|
||||
|
||||
#define _shell_func_complete(_name, _nparam, _func, _brief) \
|
||||
{ #_name, _nparam, _func, _FUNC_BRIEF(_brief) }
|
||||
|
||||
|
||||
/**
|
||||
* @brief add a command to nano-shell
|
||||
*
|
||||
* @_name: name of the command. Note: THIS IS NOT a string.
|
||||
* @_func: function pointer: (*cmd)(const shell_cmd_t *, int, int, char *const[]).
|
||||
* @_brief: brief summaries of the command. This is a string.
|
||||
* @_help: detailed help information of the command. This is a string.
|
||||
*/
|
||||
#define NANO_SHELL_ADD_CMD(_name, _func, _brief, _help) \
|
||||
_shell_entry_declare(shell_cmd_t, _name) = _shell_cmd_complete(_name, _func, _brief, _help)
|
||||
|
||||
|
||||
/**
|
||||
* @brief add a function to nano-shell.
|
||||
*
|
||||
* @_name: name of the function. Note: THIS IS NOT a string.
|
||||
* @_nparam: param num of the function.
|
||||
* @_func: pointer of the function.
|
||||
* @_brief: brief summaries of the function. This is a string.
|
||||
*/
|
||||
#define NANO_SHELL_ADD_FUNC(_name, _nparam, _func, _brief) \
|
||||
_shell_entry_declare(shell_func_t, _name) = _shell_func_complete(_name, _nparam, _func, _brief)
|
||||
|
||||
#if CONFIG_SHELL_CMD_BUILTIN_HELP
|
||||
#define _shell_help_subcmd_entry(_name) \
|
||||
NANO_SHELL_SUBCMD_ENTRY(help, _name ## _subcmd_help, \
|
||||
"help [pattern ...]", \
|
||||
" Print information about subcommands of " # _name ".\r\n" \
|
||||
"\r\n" \
|
||||
" If PATTERN is specified, gives detailed help on all commands\r\n" \
|
||||
" matching PATTERN, otherwise print the list of all available commands.\r\n" \
|
||||
"\r\n" \
|
||||
" Arguments:\r\n" \
|
||||
" PATTERN: specifiying the help topic\r\n"),
|
||||
#define _shell_help_subcmd_declare(_name) \
|
||||
static int _name ## _subcmd_help(const shell_cmd_t* pCmd, int argc, char* const argv[]);
|
||||
#define _shell_help_subcmd_define(_name) \
|
||||
static int _name ## _subcmd_help(const shell_cmd_t* pCmd, int argc, char* const argv[]) \
|
||||
{ \
|
||||
const unsigned int subcommands_count = sizeof(_name ## _subcommands)/sizeof(shell_cmd_t); \
|
||||
return shell_help_generic( \
|
||||
argc, argv, \
|
||||
"Help for " #_name, \
|
||||
_name ## _subcommands, subcommands_count); \
|
||||
}
|
||||
#else
|
||||
#define _shell_help_subcmd_entry(_name)
|
||||
#define _shell_help_subcmd_declare(_name)
|
||||
#define _shell_help_subcmd_define(_name)
|
||||
#endif /* CONFIG_SHELL_CMD_BUILTIN_HELP */
|
||||
|
||||
/**
|
||||
* @brief Add a sub command in a group of sub-command
|
||||
*
|
||||
* To be used as the last arguments of @ref NANO_SHELL_DEFINE_SUBCMDS()
|
||||
* The syntax is similar to @ref NANO_SHELL_ADD_CMD()
|
||||
*
|
||||
* @param _name: name of the command. Note: THIS IS NOT a string.
|
||||
* @param _func: function pointer: (*cmd)(const shell_cmd_t *, int, int, char *const[]).
|
||||
* @param _brief: brief summaries of the command. This is a string.
|
||||
* @param _help: detailed help information of the command. This is a string.
|
||||
*/
|
||||
#define NANO_SHELL_SUBCMD_ENTRY(_name, _func, _brief, _help) _shell_cmd_complete(_name, _func, _brief, _help)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the name of the function implementing a sub-command group in nano-shell
|
||||
*
|
||||
* @param _name name of the group of sub-commands
|
||||
*
|
||||
* @note this macro is to be used for the @c _func parameter of @ref NANO_SHELL_ADD_CMD() or @c _func parameter of @ref NANO_SHELL_SUBCMD_ENTRY()
|
||||
*/
|
||||
#define NANO_SHELL_SUBCMDS_FCT(_name) _name ## _shell_cmd
|
||||
|
||||
/**
|
||||
* @brief Define a group of sub-commands in nano-shell
|
||||
*
|
||||
* @param _name name of the group of sub-commands
|
||||
* @param fallback_fct: function that will be run if no subcommand can be found (either @c argc is 1 or argv[1] is not found in @c subcommand)
|
||||
* @param ... A list of @ref NANO_SHELL_SUBCMD_ENTRY() that define the list of sub-commands
|
||||
*/
|
||||
#define NANO_SHELL_DEFINE_SUBCMDS(_name, fallback_fct, ...) \
|
||||
_shell_help_subcmd_declare(_name) \
|
||||
static const shell_cmd_t _name ## _subcommands[] = { \
|
||||
_shell_help_subcmd_entry(_name) \
|
||||
__VA_ARGS__ }; \
|
||||
_shell_help_subcmd_define(_name) \
|
||||
int NANO_SHELL_SUBCMDS_FCT(_name)(const shell_cmd_t* pCmd, int argc, char* const argv[]) \
|
||||
{ \
|
||||
const unsigned int subcommands_count = sizeof(_name ## _subcommands)/sizeof(shell_cmd_t); \
|
||||
return shell_run_subcmd_implem(pCmd, argc, argv, \
|
||||
fallback_fct, _name ## _subcommands, subcommands_count); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find a shell command by name
|
||||
*
|
||||
* Find in the list of commandes registred by @ref NANO_SHELL_ADD_CMD().
|
||||
*
|
||||
* @param cmd_name name of the shell command to search
|
||||
* @return const shell_cmd_t*
|
||||
*/
|
||||
const shell_cmd_t *shell_find_top_cmd(const char *cmd_name);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Find a shell command by name in a specific list of commands
|
||||
*
|
||||
* @param cmd_name name of the shell command to search
|
||||
* @param cmds list of commands to search
|
||||
* @count number of entries in @c cmds
|
||||
* @return const shell_cmd_t*
|
||||
*/
|
||||
const shell_cmd_t *shell_find_cmd(const char *cmd_name, const shell_cmd_t* cmds, unsigned int count);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Run a shell command from a parsed line
|
||||
*
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @return int
|
||||
*/
|
||||
int shell_run_cmd(int argc, char *const argv[]);
|
||||
|
||||
/**
|
||||
* @brief Implementation function for @ref NANO_SHELL_ADD_CMD_WITH_SUB
|
||||
*
|
||||
* @param pCmdt: pointer of the structure.
|
||||
* @param argc: the count of arguments.
|
||||
* @param argv: argument vector.
|
||||
* @param fallback_fct: function that will be run if no subcommand can be found (either @c argc is 1 or argv[1] is not found in @c subcommand)
|
||||
* @param subcommands: a list of sub-commands
|
||||
* @param subcommands_count: number of entries in @c subcommands
|
||||
*
|
||||
* @return 0 if succeed, else non-zero. (return value is not used in ver1.0)
|
||||
*/
|
||||
int shell_run_subcmd_implem(const shell_cmd_t* pCmdt,
|
||||
int argc, char* const argv[],
|
||||
shell_cmd_cb_t fallback_fct,
|
||||
const shell_cmd_t* subcommands, unsigned int subcommands_count);
|
||||
|
||||
/**
|
||||
* @brief Implementation function for 'help' command (or sub-command)
|
||||
*
|
||||
* @param argc: the count of arguments.
|
||||
* @param argv: argument vector.
|
||||
* @param preamble: text that will appears before the list of commands
|
||||
* @param start first command in the list of commands that we want to display helps for
|
||||
* @param count number of command in the list of command
|
||||
*
|
||||
* @return 0 if succeed, else non-zero. (return value is not used in ver1.0)
|
||||
*/
|
||||
int shell_help_generic(int argc, char *const argv[],
|
||||
const char* preamble,
|
||||
const shell_cmd_t* start, unsigned int count);
|
||||
|
||||
#endif /* __NANO_SHELL_COMMAND_H */
|
62
app/third_party/nano-shell-master/command/shell_linker.h
vendored
Normal file
62
app/third_party/nano-shell-master/command/shell_linker.h
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @file command.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2020-03-23
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SHELL_LINKER_H
|
||||
#define __NANO_SHELL_LINKER_H
|
||||
|
||||
#define __align(x) __attribute__((aligned(x)))
|
||||
|
||||
/**
|
||||
* @brief array entry declare.
|
||||
* @_type: data type of the entry.
|
||||
* @_name: name of the entry.
|
||||
*/
|
||||
#define _shell_entry_declare(_type, _name) \
|
||||
static const _type nano_shell_##_type##_##_name __align(4) \
|
||||
__attribute__((used, section(".nano_shell_" #_type "_1_" #_name)))
|
||||
|
||||
|
||||
/**
|
||||
* @brief: get the pointer of first entry.
|
||||
* @_type: data type of the entry.
|
||||
*/
|
||||
#define _shell_entry_start(_type) \
|
||||
({ \
|
||||
static char start[0] __align(4) \
|
||||
__attribute__((unused, section(".nano_shell_" #_type "_0"))); \
|
||||
(_type *)&start; \
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* @brief: get the pointer after last entry.
|
||||
* @_type: data type of the entry.
|
||||
*/
|
||||
#define _shell_entry_end(_type) \
|
||||
({ \
|
||||
static char end[0] __align(4) \
|
||||
__attribute__((unused, section(".nano_shell_" #_type "_2"))); \
|
||||
(_type *)&end; \
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* @brief: get the number of elements.
|
||||
* @_type: data type of the entry.
|
||||
*/
|
||||
#define _shell_entry_count(_type) \
|
||||
({ \
|
||||
_type *start = _shell_entry_start(_type); \
|
||||
_type *end = _shell_entry_end(_type); \
|
||||
unsigned int count = end - start; \
|
||||
count; \
|
||||
})
|
||||
|
||||
|
||||
#endif /* __NANO_SHELL_LINKER_H */
|
BIN
app/third_party/nano-shell-master/doc/pic/command_demo.png
vendored
Normal file
BIN
app/third_party/nano-shell-master/doc/pic/command_demo.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
BIN
app/third_party/nano-shell-master/doc/pic/help_demo.png
vendored
Normal file
BIN
app/third_party/nano-shell-master/doc/pic/help_demo.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
BIN
app/third_party/nano-shell-master/doc/pic/line_continuation.png
vendored
Normal file
BIN
app/third_party/nano-shell-master/doc/pic/line_continuation.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
BIN
app/third_party/nano-shell-master/doc/pic/nano_shell_welcome.png
vendored
Normal file
BIN
app/third_party/nano-shell-master/doc/pic/nano_shell_welcome.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
BIN
app/third_party/nano-shell-master/doc/pic/subcommand_demo.png
vendored
Normal file
BIN
app/third_party/nano-shell-master/doc/pic/subcommand_demo.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
120
app/third_party/nano-shell-master/nano_shell.c
vendored
Normal file
120
app/third_party/nano-shell-master/nano_shell.c
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @file nano_shell.c
|
||||
* @author Liber (lvlebin@outlook.com), Cédric CARRÉE (beg0@free.fr)
|
||||
* @brief nano-shell: a light but powerful shell designed for embedded systems.
|
||||
* @version 1.0
|
||||
* @date 2020-03-27
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "nano_shell.h"
|
||||
#include "shell_io/shell_io.h"
|
||||
#include "command/command.h"
|
||||
#include "readline/readline.h"
|
||||
#include "parse/text_parse.h"
|
||||
|
||||
#include "shell_config.h"
|
||||
|
||||
#define NANO_SHELL_BUILD_VERDION "1.0"
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param argc: MUST be larger than 0
|
||||
* @param argv:
|
||||
* @return int
|
||||
*/
|
||||
int nano_shell_run_cmd(int argc, char *const argv[])
|
||||
{
|
||||
const shell_cmd_t *pCmdt = shell_find_top_cmd(argv[0]);
|
||||
|
||||
if (pCmdt) {
|
||||
return pCmdt->cmd(pCmdt, argc, argv);
|
||||
}
|
||||
shell_printf(" %s: command not found.\r\n", argv[0]);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#if (CONFIG_SHELL_CMD_MAX_ARGC < 1)
|
||||
#error "CONFIG_SHELL_CMD_MAX_ARGC must be no less than 1."
|
||||
#endif
|
||||
|
||||
void nano_shell_loop(void *argument)
|
||||
{
|
||||
static char *argv[CONFIG_SHELL_CMD_MAX_ARGC + 1];
|
||||
char *line;
|
||||
int argc;
|
||||
|
||||
shell_puts("\r\n"
|
||||
" _ _ ____ _ _ _\r\n"
|
||||
"| \\ | | __ _ _ __ ___ / ___|| |__ ___| | |\r\n"
|
||||
"| \\| |/ _` | '_ \\ / _ \\ \\___ \\| '_ \\ / _ \\ | |\r\n"
|
||||
"| |\\ | (_| | | | | (_) | ___) | | | | __/ | |\r\n"
|
||||
"|_| \\_|\\__,_|_| |_|\\___/ |____/|_| |_|\\___|_|_|\r\n"
|
||||
"\r\n"
|
||||
"Welcome to Nano-Shell "NANO_SHELL_BUILD_VERDION"\r\n"
|
||||
"\r\n"
|
||||
" * Build: "__DATE__" - "__TIME__"\r\n"
|
||||
" * Source: https://github.com/lebinlv/nano-shell\r\n"
|
||||
" * Copyright: (c) Liber 2020\r\n"
|
||||
"\r\n");
|
||||
|
||||
for (;;) {
|
||||
line = readline(CONFIG_SHELL_PROMPT);
|
||||
|
||||
argc = nano_shell_parse_line(line, argv, CONFIG_SHELL_CMD_MAX_ARGC + 1);
|
||||
|
||||
// shell_printf("[DEBUG] argc: %d\r\n", argc);
|
||||
// for (int i = 0; i < argc; i++) {
|
||||
// shell_printf("[DEBUG] ARGV[%d]: %s\r\n", i, argv[i]);
|
||||
// }
|
||||
|
||||
if (argc > CONFIG_SHELL_CMD_MAX_ARGC) {
|
||||
argc--;
|
||||
shell_printf("** WARNING: too many args (max: %d)! ", CONFIG_SHELL_CMD_MAX_ARGC);
|
||||
shell_printf("arguments after \"%s\" will be ignored. **\r\n", argv[argc - 1]);
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
nano_shell_run_cmd(argc, argv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nano_shell_react(char ch)
|
||||
{
|
||||
static char *argv[CONFIG_SHELL_CMD_MAX_ARGC + 1];
|
||||
int argc;
|
||||
|
||||
char *line = readline_react(ch);
|
||||
|
||||
if (line) {
|
||||
/**
|
||||
* in react mode, use if (* line) to avoid unnecessary process
|
||||
* to improve speed.
|
||||
*/
|
||||
if (*line) {
|
||||
argc = nano_shell_parse_line(line, argv, CONFIG_SHELL_CMD_MAX_ARGC + 1);
|
||||
|
||||
if (argc > CONFIG_SHELL_CMD_MAX_ARGC) {
|
||||
argc--;
|
||||
shell_printf("** WARNING: too many args (max: %d)! ", CONFIG_SHELL_CMD_MAX_ARGC);
|
||||
shell_printf("arguments after \"%s\" will be ignored. **\r\n", argv[argc - 1]);
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
nano_shell_run_cmd(argc, argv);
|
||||
}
|
||||
}
|
||||
|
||||
if (CONFIG_SHELL_PROMPT) {
|
||||
shell_puts(CONFIG_SHELL_PROMPT);
|
||||
}
|
||||
}
|
||||
}
|
34
app/third_party/nano-shell-master/nano_shell.h
vendored
Normal file
34
app/third_party/nano-shell-master/nano_shell.h
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @file nano_shell.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief nano-shell interface. include this file in your project.
|
||||
* @version 1.0
|
||||
* @date 2020-03-27
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __NANO_SHELL_H
|
||||
#define __NANO_SHELL_H
|
||||
|
||||
/**
|
||||
* @brief nano-shell infinite loop
|
||||
*
|
||||
* @param argument not used in ver1.0
|
||||
*/
|
||||
void nano_shell_loop(void *argument);
|
||||
|
||||
|
||||
/**
|
||||
* @brief nano-shell non-block interface, just react to the input character.
|
||||
* It is non-blocked (unless there is an infinite loop in your command function)
|
||||
* you can call it when get a new character.
|
||||
*
|
||||
* @param ch input character
|
||||
*/
|
||||
void nano_shell_react(char ch);
|
||||
|
||||
|
||||
#endif /*__NANO_SHELL_H */
|
13
app/third_party/nano-shell-master/parse/Makefile
vendored
Normal file
13
app/third_party/nano-shell-master/parse/Makefile
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
TOP_DIR = ../../../..
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libparse$(LIB_EXT)
|
||||
endif
|
||||
|
||||
#DEFINES +=
|
||||
|
||||
sinclude $(TOP_DIR)/tools/w800/rules.mk
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
54
app/third_party/nano-shell-master/parse/text_parse.c
vendored
Normal file
54
app/third_party/nano-shell-master/parse/text_parse.c
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file text_parse.c
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2020-03-28
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include "text_parse.h"
|
||||
|
||||
#define isblank(c) ((c) == ' ' || (c) == '\t')
|
||||
|
||||
|
||||
int nano_shell_parse_line(char *input, char *argv[], const int maxArgc)
|
||||
{
|
||||
char tmp;
|
||||
int nargc = 0;
|
||||
|
||||
while (nargc < maxArgc) {
|
||||
while (isblank(*input)) {
|
||||
input++;
|
||||
}
|
||||
if (*input == '\0') { // end of input
|
||||
argv[nargc] = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = *input;
|
||||
// single quotes ('') and double quotes ("")
|
||||
if (tmp == '\'' || tmp == '"') {
|
||||
argv[nargc] = ++input;
|
||||
while (*input && (*input != tmp)) {
|
||||
input++;
|
||||
}
|
||||
} else { // normal character
|
||||
argv[nargc] = input++;
|
||||
while (*input && !isblank(*input)) {
|
||||
input++;
|
||||
}
|
||||
}
|
||||
|
||||
nargc++;
|
||||
if (*input) {
|
||||
*input++ = '\0'; /* terminate current arg */
|
||||
}
|
||||
}
|
||||
|
||||
return nargc;
|
||||
}
|
27
app/third_party/nano-shell-master/parse/text_parse.h
vendored
Normal file
27
app/third_party/nano-shell-master/parse/text_parse.h
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @file text_parse.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2020-03-28
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __NANO_SHELL_TEXT_PARSE_H
|
||||
#define __NANO_SHELL_TEXT_PARSE_H
|
||||
|
||||
/**
|
||||
* @brief parse the line, doesn't support backslash('\') in ver1.0
|
||||
*
|
||||
* @param input: the line to be parsed.
|
||||
* @param argv:
|
||||
* @param maxArgc: max number of arguments.
|
||||
* @return int: the number of parsed arguments.
|
||||
*/
|
||||
int nano_shell_parse_line(char *input, char *argv[], const int maxArgc);
|
||||
|
||||
|
||||
#endif /* __NANO_SHELL_TEXT_PARSE_H */
|
13
app/third_party/nano-shell-master/readline/Makefile
vendored
Normal file
13
app/third_party/nano-shell-master/readline/Makefile
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
TOP_DIR = ../../../..
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libreadline$(LIB_EXT)
|
||||
endif
|
||||
|
||||
#DEFINES +=
|
||||
|
||||
sinclude $(TOP_DIR)/tools/w800/rules.mk
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
115
app/third_party/nano-shell-master/readline/history.c
vendored
Normal file
115
app/third_party/nano-shell-master/readline/history.c
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file history.c
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief history manager
|
||||
* @version 1.0
|
||||
* @date 2020-03-18
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "history.h"
|
||||
#include "shell_config.h"
|
||||
|
||||
#if CONFIG_SHELL_HIST_MIN_RECORD > 0
|
||||
|
||||
typedef unsigned char len_t;
|
||||
|
||||
/**
|
||||
memory view of the history buffer:
|
||||
|
||||
-------------------------------------------------------------------------------------------
|
||||
|length| string |length| *** |length| string |length| |
|
||||
|<---- 1st record ---->| *** |<---- record ---->| |
|
||||
^ ^ ^ ^
|
||||
&buffer[0] cursor tail buffer end
|
||||
(new record will be saved here)
|
||||
-------------------------------------------------------------------------------------------
|
||||
|
||||
Let the data type of `length` be `len_t`,
|
||||
then the value of length: length = strlen(string) + 1 + 2*sizeof(len_t)
|
||||
*/
|
||||
|
||||
#define TOTAL_BUFFER_SIZE \
|
||||
(CONFIG_SHELL_HIST_MIN_RECORD * (CONFIG_SHELL_INPUT_BUFFSIZE + 1 + 2 * sizeof(len_t)))
|
||||
|
||||
static char historyBuffer[TOTAL_BUFFER_SIZE]; // history buffer
|
||||
|
||||
#define HISTORY_BUFFER_BEGIN() (&historyBuffer[0])
|
||||
#define HISTORY_BUFFER_END() (&historyBuffer[TOTAL_BUFFER_SIZE])
|
||||
|
||||
#define GET_RECORD_SIZE(pRecord) ((len_t)(*((len_t *)(pRecord))))
|
||||
|
||||
static char *historyCursor = HISTORY_BUFFER_BEGIN();
|
||||
static char *historyTail = HISTORY_BUFFER_BEGIN(); // new record will be saved here
|
||||
|
||||
|
||||
char *rl_history_next(void)
|
||||
{
|
||||
if (historyCursor >= historyTail || // cursor point to the tail
|
||||
historyCursor + GET_RECORD_SIZE(historyCursor) >= historyTail // cursor point to the last one
|
||||
) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
historyCursor += GET_RECORD_SIZE(historyCursor);
|
||||
return historyCursor + sizeof(len_t);
|
||||
}
|
||||
|
||||
|
||||
char *rl_history_prev(void)
|
||||
{
|
||||
if (historyTail != HISTORY_BUFFER_BEGIN() && // buffer is not empty
|
||||
historyCursor > HISTORY_BUFFER_BEGIN() // cursor does not point to the first
|
||||
) {
|
||||
historyCursor -= GET_RECORD_SIZE(historyCursor - sizeof(len_t));
|
||||
return historyCursor + sizeof(len_t);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void rl_history_add(char *input)
|
||||
{
|
||||
size_t freeSpace = HISTORY_BUFFER_END() - historyTail;
|
||||
|
||||
len_t inputLength = strlen(input) + 1;
|
||||
len_t newRecordLength = inputLength + 2 * sizeof(len_t);
|
||||
|
||||
if (freeSpace < newRecordLength) {
|
||||
len_t tmpLength;
|
||||
char *tmpRecord = HISTORY_BUFFER_BEGIN();
|
||||
do {
|
||||
tmpLength = GET_RECORD_SIZE(tmpRecord);
|
||||
freeSpace += tmpLength;
|
||||
tmpRecord += tmpLength;
|
||||
} while (freeSpace < newRecordLength);
|
||||
|
||||
memmove(HISTORY_BUFFER_BEGIN(), tmpRecord, historyTail - tmpRecord);
|
||||
historyTail -= (tmpRecord - HISTORY_BUFFER_BEGIN());
|
||||
}
|
||||
|
||||
/* put the new record in the history buffer */
|
||||
*((len_t *)historyTail) = newRecordLength;
|
||||
memcpy(historyTail + sizeof(len_t), input, inputLength);
|
||||
historyTail += newRecordLength; // move tail to the end of the new record
|
||||
*((len_t *)(historyTail - sizeof(len_t))) = newRecordLength;
|
||||
|
||||
/* set cursor point to the end */
|
||||
historyCursor = historyTail;
|
||||
}
|
||||
|
||||
|
||||
void rl_history_rm_last(void)
|
||||
{
|
||||
if (historyTail > HISTORY_BUFFER_BEGIN()) {
|
||||
historyTail -= GET_RECORD_SIZE(historyTail - sizeof(len_t));
|
||||
historyCursor = historyTail;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SHELL_HIST_MIN_RECORD > 0 */
|
46
app/third_party/nano-shell-master/readline/history.h
vendored
Normal file
46
app/third_party/nano-shell-master/readline/history.h
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file history.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief history manage interface
|
||||
* @version 1.0
|
||||
* @date 2020-03-20
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SHELL_HISTORY_H
|
||||
#define __NANO_SHELL_HISTORY_H
|
||||
|
||||
|
||||
/**
|
||||
* @brief add a new record
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
void rl_history_add(char *input);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get next record
|
||||
*
|
||||
* @return char*
|
||||
*/
|
||||
char *rl_history_next(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get previous record
|
||||
*
|
||||
* @return char*
|
||||
*/
|
||||
char *rl_history_prev(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Remove last record
|
||||
*
|
||||
*/
|
||||
void rl_history_rm_last(void);
|
||||
|
||||
#endif /* __NANO_SHELL_HISTORY_H */
|
98
app/third_party/nano-shell-master/readline/key_seq.c
vendored
Normal file
98
app/third_party/nano-shell-master/readline/key_seq.c
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
* @file key_seq.c
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief ESC Control Sequence recognize and key-sequence-map.
|
||||
* @version 1.0
|
||||
* @date 2020-03-21
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SEHLL_KEY_SEQ_MAP_H
|
||||
#define __NANO_SHELL_KEY_SEQ_MAP_H
|
||||
|
||||
#include "key_seq.h"
|
||||
#include "shell_io/shell_io.h"
|
||||
|
||||
#include "shell_config.h"
|
||||
|
||||
extern void rl_get_pre_history(void); // `up arrow` or `Ctrl P`
|
||||
extern void rl_get_next_history(void); // `down arrow` or `Ctrl N`
|
||||
extern void rl_backward_cursor(void); // `right arrow` or `Ctrl F`
|
||||
extern void rl_forward_cursor(void); // `left arrow` or `Ctrl B`
|
||||
extern void rl_line_home(void); // `Home`
|
||||
extern void rl_line_end(void); // `End`
|
||||
extern void rl_delete(void); // `Delete`
|
||||
|
||||
#if CONFIG_SHELL_KEY_SEQ_BIND
|
||||
|
||||
const static key_seq_t key_seq_map[] = {
|
||||
#if CONFIG_SHELL_HIST_MIN_RECORD > 0
|
||||
{CONVERT_KEY_SEQ('\033', '[', 'A', 0), rl_get_pre_history}, // up arrow
|
||||
{CONVERT_KEY_SEQ('\033', '[', 'B', 0), rl_get_next_history}, // down arrow
|
||||
// {CONVERT_KEY_SEQ('\033', 'O', 'A', 0), rl_get_pre_history},
|
||||
// {CONVERT_KEY_SEQ('\033', 'O', 'B', 0), rl_get_next_history},
|
||||
|
||||
#endif /* CONFIG_SHELL_HIST_MIN_RECORD */
|
||||
|
||||
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
{CONVERT_KEY_SEQ('\033', '[', 'C', 0), rl_backward_cursor}, // right arrow
|
||||
{CONVERT_KEY_SEQ('\033', '[', 'D', 0), rl_forward_cursor}, // left arrow
|
||||
{CONVERT_KEY_SEQ('\033', '[', 'H', 0), rl_line_home}, // home
|
||||
{CONVERT_KEY_SEQ('\033', '[', 'F', 0), rl_line_end}, // end
|
||||
// {CONVERT_KEY_SEQ('\033', 'O', 'C', 0), rl_forward_cursor},
|
||||
// {CONVERT_KEY_SEQ('\033', 'O', 'D', 0), rl_backward_cursor},
|
||||
// {CONVERT_KEY_SEQ('\033', 'O', 'H', 0), rl_line_home},
|
||||
// {CONVERT_KEY_SEQ('\033', 'O', 'F', 0), rl_line_end},
|
||||
|
||||
{CONVERT_KEY_SEQ('\033', '[', '3', '~'), rl_delete}, // delete
|
||||
#endif /* CONFIG_SHELL_LINE_EDITING */
|
||||
|
||||
};
|
||||
|
||||
#define KEY_SEQ_MAP_SIZE (sizeof(key_seq_map) / sizeof(key_seq_t))
|
||||
|
||||
|
||||
extern int _rl_key_seq_len;
|
||||
|
||||
void rl_dispatch_seq(char ch)
|
||||
{
|
||||
static uint32_t key_seq_val, key_seq_mask;
|
||||
|
||||
uint32_t offset, miss_match, tmp_val;
|
||||
|
||||
_rl_key_seq_len++;
|
||||
|
||||
offset = ((uint32_t)(sizeof(uint32_t) - _rl_key_seq_len)) << 3; // (4-_rl_key_seq_len)*8
|
||||
key_seq_val |= (((uint32_t)ch) << offset);
|
||||
key_seq_mask |= (0xFF << offset);
|
||||
|
||||
miss_match = 1;
|
||||
for (int i = 0; i < KEY_SEQ_MAP_SIZE; i++) {
|
||||
tmp_val = key_seq_map[i].key_seq_val;
|
||||
if ((tmp_val & key_seq_mask) == key_seq_val) { // partial match
|
||||
if (key_seq_val == tmp_val) { // full match
|
||||
key_seq_val = 0;
|
||||
key_seq_mask = 0;
|
||||
_rl_key_seq_len = 0;
|
||||
|
||||
key_seq_map[i].key_func();
|
||||
return;
|
||||
}
|
||||
miss_match = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (miss_match) {
|
||||
key_seq_val = 0;
|
||||
key_seq_mask = 0;
|
||||
_rl_key_seq_len = 0;
|
||||
shell_putc('\a');
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SHELL_KEY_SEQ_BIND */
|
||||
|
||||
|
||||
#endif /* __NANO_SHELL_KEY_SEQ_MAP_H */
|
33
app/third_party/nano-shell-master/readline/key_seq.h
vendored
Normal file
33
app/third_party/nano-shell-master/readline/key_seq.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @file key_seq.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2020-03-21
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SHELL_KEY_SEQ_H
|
||||
#define __NANO_SHELL_KEY_SEQ_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint8_t u8;
|
||||
|
||||
#define CONVERT_KEY_SEQ(c1, c2, c3, c4) \
|
||||
((u32)((((u8)(c1)) << 24) | (((u8)(c2)) << 16) | (((u8)(c3)) << 8) | (((u8)(c4)) << 0)))
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 key_seq_val;
|
||||
void (*key_func)(void);
|
||||
} key_seq_t;
|
||||
|
||||
|
||||
void rl_dispatch_seq(char ch);
|
||||
|
||||
|
||||
#endif /* __NANO_SHELL_KEY_SEQ_H */
|
419
app/third_party/nano-shell-master/readline/readline.c
vendored
Normal file
419
app/third_party/nano-shell-master/readline/readline.c
vendored
Normal file
@ -0,0 +1,419 @@
|
||||
/**
|
||||
* @file readline.c
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief readline component of nano-shell
|
||||
* @version 1.0
|
||||
* @date 2020-03-21
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "readline.h"
|
||||
#include "shell_io/shell_io.h"
|
||||
#include "history.h"
|
||||
#include "key_seq.h"
|
||||
|
||||
#include "shell_config.h"
|
||||
|
||||
|
||||
#define CTL_CH(ch) ((ch) - 'A' + 1)
|
||||
#define U_SHELL_ALERT() shell_putc('\a')
|
||||
|
||||
// erase sequence, used to erase one character on screen.
|
||||
static const char _erase_seq[] = "\b \b";
|
||||
|
||||
// console input buffer
|
||||
static char _rl_line_buffer[CONFIG_SHELL_INPUT_BUFFSIZE + 1];
|
||||
|
||||
// non-zero means readline completed.
|
||||
static int _rl_done;
|
||||
|
||||
/**
|
||||
* The number of characters present in `_rl_line_buffer`.
|
||||
* 0 <= `_rl_end` <= `CONFIG_SHELL_INPUT_BUFFSIZE`
|
||||
* When `_rl_cursor` is at the end of the line, `_rl_cursor` and `_rl_end` are equal.
|
||||
* Note that the value of `_rl_line_buffer[_rl_end]` should be `\0` in any case.
|
||||
*/
|
||||
static int _rl_end;
|
||||
|
||||
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
// The offset of the current cursor position in `_rl_line_buffer`
|
||||
// 0 <= `_rl_cursor` <= `_rl_end`
|
||||
static int _rl_cursor;
|
||||
#endif /* CONFIG_SHELL_LINE_EDITING */
|
||||
|
||||
|
||||
#if CONFIG_SHELL_KEY_SEQ_BIND
|
||||
/* uesed by @file{key_seq.c} to recognize key sequences */
|
||||
int _rl_key_seq_len = 0;
|
||||
#endif
|
||||
|
||||
|
||||
void rl_end_input(void);
|
||||
|
||||
#if CONFIG_SHELL_MULTI_LINE
|
||||
static int _rl_home;
|
||||
|
||||
/**
|
||||
* @brief Judge whether the line should be continued
|
||||
*
|
||||
* @return int 1: continue.
|
||||
* 0: no continue, start a new line.
|
||||
*/
|
||||
int rl_should_continue()
|
||||
{
|
||||
// in version 1.0, only judged whether the last character is '\' or not
|
||||
return (_rl_end > _rl_home && _rl_line_buffer[_rl_end-1] == '\\');
|
||||
}
|
||||
|
||||
void rl_new_line()
|
||||
{
|
||||
if (rl_should_continue()) {
|
||||
_rl_line_buffer[--_rl_end] = '\0'; // overwrite the backslash('\')
|
||||
_rl_home = _rl_end;
|
||||
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
_rl_cursor = _rl_end; // update _rl_cursor if LINE_EDITING is enabled.
|
||||
#endif /* CONFIG_SHELL_LINE_EDITING */
|
||||
|
||||
shell_puts("\r\n> ");
|
||||
} else {
|
||||
rl_end_input();
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define _rl_home 0
|
||||
#define rl_new_line() rl_end_input()
|
||||
#endif /* CONFIG_SHELL_MULTI_LINE */
|
||||
|
||||
|
||||
void rl_end_input(void)
|
||||
{
|
||||
#if CONFIG_SHELL_HIST_MIN_RECORD > 0
|
||||
if (*_rl_line_buffer) {
|
||||
rl_history_add(_rl_line_buffer);
|
||||
}
|
||||
#endif /*CONFIG_SHELL_HIST_MIN_RECORD */
|
||||
|
||||
#if CONFIG_SHELL_MULTI_LINE
|
||||
_rl_home = 0;
|
||||
#endif /* CONFIG_SHELL_MULTI_LINE */
|
||||
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
_rl_cursor = 0;
|
||||
#endif /* CONFIG_SHELL_LINE_EDITING */
|
||||
|
||||
_rl_end = 0;
|
||||
_rl_done = 1;
|
||||
shell_puts("\r\n");
|
||||
}
|
||||
|
||||
// add one character to the buffer
|
||||
void rl_add_char(char ch)
|
||||
{
|
||||
if (_rl_end < CONFIG_SHELL_INPUT_BUFFSIZE && ch >= ' ') {
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
int len = _rl_end - _rl_cursor;
|
||||
|
||||
_rl_end++;
|
||||
_rl_line_buffer[_rl_end] = '\0';
|
||||
|
||||
memmove(&_rl_line_buffer[_rl_cursor + 1], &_rl_line_buffer[_rl_cursor], len);
|
||||
_rl_line_buffer[_rl_cursor] = ch;
|
||||
|
||||
shell_puts(&_rl_line_buffer[_rl_cursor++]);
|
||||
while (len > 0) {
|
||||
shell_putc('\b');
|
||||
len--;
|
||||
}
|
||||
#else
|
||||
shell_putc(ch);
|
||||
_rl_line_buffer[_rl_end++] = ch;
|
||||
_rl_line_buffer[_rl_end] = '\0';
|
||||
#endif /* CONFIG_SHELL_LINE_EDITING */
|
||||
} else {
|
||||
U_SHELL_ALERT();
|
||||
}
|
||||
}
|
||||
|
||||
// Rubout the character behind `_rl_cursor`(Backspace).
|
||||
void rl_rubout(void)
|
||||
{
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
if (_rl_cursor > _rl_home) {
|
||||
int len = _rl_end - (--_rl_cursor);
|
||||
_rl_end--;
|
||||
|
||||
memmove(&_rl_line_buffer[_rl_cursor], &_rl_line_buffer[_rl_cursor + 1], len);
|
||||
shell_putc('\b');
|
||||
shell_puts(&_rl_line_buffer[_rl_cursor]);
|
||||
shell_putc(' ');
|
||||
do {
|
||||
shell_putc('\b');
|
||||
len--;
|
||||
} while (len > 0);
|
||||
#else
|
||||
if (_rl_end > _rl_home) {
|
||||
_rl_end--;
|
||||
_rl_line_buffer[_rl_end] = '\0';
|
||||
shell_puts(_erase_seq);
|
||||
#endif /* CONFIG_SHELL_LINE_EDITING */
|
||||
} else {
|
||||
U_SHELL_ALERT();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if CONFIG_SHELL_HIST_MIN_RECORD > 0
|
||||
void rl_process_history(const char *history)
|
||||
{
|
||||
if (history) {
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
shell_puts(&_rl_line_buffer[_rl_cursor]); // move cursor to the end on screen.
|
||||
#endif
|
||||
|
||||
while (_rl_end > _rl_home) { // erase all on the screen.
|
||||
shell_puts(_erase_seq);
|
||||
_rl_end--;
|
||||
}
|
||||
|
||||
_rl_end = strlen(history) + _rl_home; // update _rl_end.
|
||||
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
_rl_cursor = _rl_end; // update _rl_cursor if LINE_EDITING is enabled.
|
||||
#endif
|
||||
|
||||
memcpy(_rl_line_buffer + _rl_home, history, _rl_end -_rl_home + 1);
|
||||
shell_puts(_rl_line_buffer + _rl_home); // display new text and move cursor to the end on screen.
|
||||
} else {
|
||||
U_SHELL_ALERT();
|
||||
}
|
||||
}
|
||||
|
||||
void rl_get_pre_history(void)
|
||||
{
|
||||
rl_process_history(rl_history_prev());
|
||||
}
|
||||
|
||||
void rl_get_next_history(void)
|
||||
{
|
||||
rl_process_history(rl_history_next());
|
||||
}
|
||||
#endif /* CONFIG_SHELL_HIST_MIN_RECORD > 0 */
|
||||
|
||||
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
// Delete the character under the cursor (Delete).
|
||||
void rl_delete(void)
|
||||
{
|
||||
if (_rl_cursor < _rl_end) {
|
||||
int len = _rl_end - _rl_cursor;
|
||||
_rl_end--;
|
||||
|
||||
memmove(&_rl_line_buffer[_rl_cursor], &_rl_line_buffer[_rl_cursor + 1], len);
|
||||
shell_puts(&_rl_line_buffer[_rl_cursor]);
|
||||
shell_putc(' ');
|
||||
do {
|
||||
shell_putc('\b');
|
||||
len--;
|
||||
} while (len > 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Move curosr to the beginning of line.
|
||||
void rl_line_home(void)
|
||||
{
|
||||
while (_rl_cursor > _rl_home) {
|
||||
shell_putc('\b');
|
||||
_rl_cursor--;
|
||||
}
|
||||
}
|
||||
|
||||
// Move cursor to the end of line.
|
||||
void rl_line_end(void)
|
||||
{
|
||||
shell_puts(_rl_line_buffer + _rl_cursor);
|
||||
_rl_cursor = _rl_end;
|
||||
}
|
||||
|
||||
// Move forward (left).
|
||||
void rl_forward_cursor(void)
|
||||
{
|
||||
if (_rl_cursor > _rl_home) {
|
||||
shell_putc('\b');
|
||||
_rl_cursor--;
|
||||
} else {
|
||||
U_SHELL_ALERT();
|
||||
}
|
||||
}
|
||||
|
||||
// Move backward (right).
|
||||
void rl_backward_cursor(void)
|
||||
{
|
||||
if (_rl_cursor < _rl_end) {
|
||||
shell_putc(_rl_line_buffer[_rl_cursor]);
|
||||
_rl_cursor++;
|
||||
} else {
|
||||
U_SHELL_ALERT();
|
||||
}
|
||||
}
|
||||
|
||||
// Erase from beginning of line to cursor.
|
||||
void rl_erase_all_backward(void)
|
||||
{
|
||||
if (_rl_cursor > _rl_home) {
|
||||
int len = _rl_end - _rl_cursor + 1;
|
||||
|
||||
shell_puts(&_rl_line_buffer[_rl_cursor]); // move cursor to the end on screen.
|
||||
while (_rl_end > _rl_home) { // erase all on the screen
|
||||
shell_puts(_erase_seq);
|
||||
_rl_end--;
|
||||
}
|
||||
|
||||
memmove(_rl_line_buffer + _rl_home, &_rl_line_buffer[_rl_cursor], len--); // new text.
|
||||
shell_puts(_rl_line_buffer + _rl_home); // display new text and move cursor to the end on screen.
|
||||
|
||||
_rl_cursor = _rl_home;
|
||||
_rl_end = len + _rl_home;
|
||||
while (len > 0) { // move cursor to the begin on the screen.
|
||||
shell_putc('\b');
|
||||
len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Erase from cursor to end of line.
|
||||
void rl_erase_all_forward(void)
|
||||
{
|
||||
shell_puts(&_rl_line_buffer[_rl_cursor]); // move cursor to the end on screen.
|
||||
while (_rl_end > _rl_cursor) {
|
||||
shell_puts(_erase_seq); // erase all right to _rl_cursor, and move screen cursor to _rl_cursor.
|
||||
_rl_end--;
|
||||
}
|
||||
_rl_line_buffer[_rl_end] = '\0';
|
||||
}
|
||||
#endif /* CONFIG_SHELL_LINE_EDITING */
|
||||
|
||||
|
||||
void rl_dispatch(char ch)
|
||||
{
|
||||
#if CONFIG_SHELL_KEY_SEQ_BIND
|
||||
if (_rl_key_seq_len) {
|
||||
rl_dispatch_seq(ch);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_SHELL_KEY_SEQ_BIND */
|
||||
|
||||
switch (ch) {
|
||||
case '\r': // CTL_CH('M')
|
||||
case '\n': // CTL_CH('J')
|
||||
rl_new_line();
|
||||
break;
|
||||
|
||||
case CTL_CH('C'):
|
||||
shell_puts("^C\r\n");
|
||||
*_rl_line_buffer = '\0';
|
||||
rl_end_input();
|
||||
break;
|
||||
|
||||
case 255:
|
||||
case 127:
|
||||
case 8: // backspace, CTL_CH('H')
|
||||
rl_rubout();
|
||||
break;
|
||||
|
||||
#if CONFIG_SHELL_KEY_SEQ_BIND
|
||||
case '\033': // ESC(\033)
|
||||
rl_dispatch_seq(ch);
|
||||
break;
|
||||
#endif /* CONFIG_SHELL_KEY_SEQ_BIND */
|
||||
|
||||
|
||||
#if CONFIG_SHELL_LINE_EDITING
|
||||
case CTL_CH('A'): // HOME
|
||||
rl_line_home();
|
||||
break;
|
||||
case CTL_CH('E'): // END
|
||||
rl_line_end();
|
||||
break;
|
||||
|
||||
case CTL_CH('B'): // <-- (left arrow)
|
||||
rl_forward_cursor();
|
||||
break;
|
||||
case CTL_CH('F'): // --> (right arrow)
|
||||
rl_backward_cursor();
|
||||
break;
|
||||
|
||||
|
||||
case CTL_CH('K'): // Delete all characters on the right side.
|
||||
rl_erase_all_forward();
|
||||
break;
|
||||
case CTL_CH('U'): // Delete all characters one the left side.
|
||||
rl_erase_all_backward();
|
||||
break;
|
||||
|
||||
case CTL_CH('D'): // DELETE
|
||||
rl_delete();
|
||||
break;
|
||||
|
||||
// case CTL_CH('X'):
|
||||
// case CTL_CH('O'):
|
||||
// break;
|
||||
#endif /* CONFIG_SHELL_LINE_EDITING */
|
||||
|
||||
|
||||
#if CONFIG_SHELL_HIST_MIN_RECORD > 0
|
||||
case CTL_CH('P'): // up arrow
|
||||
rl_get_pre_history();
|
||||
break;
|
||||
case CTL_CH('N'): // down arrow
|
||||
rl_get_next_history();
|
||||
break;
|
||||
#endif /* CONFIG_SHELL_HIST_MIN_RECORD > 0 */
|
||||
|
||||
default: // add current character to the buffer
|
||||
rl_add_char(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *readline(const char *promot)
|
||||
{
|
||||
char input;
|
||||
|
||||
if (promot) {
|
||||
shell_puts(promot);
|
||||
}
|
||||
|
||||
// clean last line.
|
||||
_rl_done = 0;
|
||||
*_rl_line_buffer = '\0';
|
||||
|
||||
// start read the new line.
|
||||
while (_rl_done == 0) {
|
||||
while (!shell_getc(&input)) {
|
||||
}
|
||||
|
||||
rl_dispatch(input);
|
||||
}
|
||||
|
||||
return _rl_line_buffer;
|
||||
}
|
||||
|
||||
|
||||
char *readline_react(char ch)
|
||||
{
|
||||
if (_rl_done) { // clean last line.
|
||||
_rl_done = 0;
|
||||
*_rl_line_buffer = '\0';
|
||||
}
|
||||
|
||||
rl_dispatch(ch);
|
||||
|
||||
return (_rl_done ? _rl_line_buffer : NULL);
|
||||
}
|
30
app/third_party/nano-shell-master/readline/readline.h
vendored
Normal file
30
app/third_party/nano-shell-master/readline/readline.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @file readline.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief readline interface
|
||||
* @version 1.0
|
||||
* @date 2020-03-21
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SHELL_READLINE_H
|
||||
#define __NANO_SHELL_READLINE_H
|
||||
|
||||
|
||||
// read a line of input. Prompt with PROMPT. A NULL PROMPT means none.
|
||||
char *readline(const char *promot);
|
||||
|
||||
|
||||
/**
|
||||
* @brief react to the input character `ch`.
|
||||
*
|
||||
* @param[in] ch: input character.
|
||||
* @return: NULL means the current line has not been completed (need more input).
|
||||
*
|
||||
*/
|
||||
char *readline_react(char ch);
|
||||
|
||||
|
||||
#endif /* __NANO_SHELL_READLINE_H */
|
64
app/third_party/nano-shell-master/shell_config.h
vendored
Normal file
64
app/third_party/nano-shell-master/shell_config.h
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @file shell_config.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief nano-shell configurations.
|
||||
* @version 1.0
|
||||
* @date 2020-03-18
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SHELL_CONFIG_H
|
||||
#define __NANO_SHELL_CONFIG_H
|
||||
|
||||
/******************************* readline configuration ****************************/
|
||||
|
||||
/* command line input buffer size(byte) */
|
||||
#define CONFIG_SHELL_INPUT_BUFFSIZE (256U)
|
||||
|
||||
/* set 1 to enable command line edit */
|
||||
#define CONFIG_SHELL_LINE_EDITING 1
|
||||
|
||||
/* ESC Control Sequence detect, such as Home, Delete, Arrow, etc. */
|
||||
#define CONFIG_SHELL_KEY_SEQ_BIND 1
|
||||
|
||||
/* set 1 to enable Backslash('\') for line continuation */
|
||||
#define CONFIG_SHELL_MULTI_LINE 1
|
||||
|
||||
|
||||
/**
|
||||
* set 0 to disable history record.
|
||||
*
|
||||
* nano-shell will take `CONFIG_SHELL_HIST_MIN_RECORD*(2+CONFIG_SHELL_INPUT_BUFFSIZE)` bytes to
|
||||
* record **at least** `CONFIG_SHELL_HIST_MIN_RECORD` histroys.
|
||||
* the maximum number of history records depends on the average length of the input.
|
||||
*/
|
||||
#define CONFIG_SHELL_HIST_MIN_RECORD (10U)
|
||||
|
||||
|
||||
/******************************* command configuration ****************************/
|
||||
|
||||
#define CONFIG_SHELL_FUNC_BRIEF_USAGE 1
|
||||
|
||||
#define CONFIG_SHELL_CMD_BRIEF_USAGE 1
|
||||
|
||||
#define CONFIG_SHELL_CMD_LONG_HELP 1
|
||||
|
||||
/* nano-shell provides a built-in help command, set 0 to disable it */
|
||||
#define CONFIG_SHELL_CMD_BUILTIN_HELP 1
|
||||
|
||||
/* config the max number of arguments, must be no less than 1. */
|
||||
#define CONFIG_SHELL_CMD_MAX_ARGC (10U)
|
||||
|
||||
|
||||
/******************************* shell io configuration ****************************/
|
||||
|
||||
/* config the buffer size (shell_printf()) */
|
||||
#define CONFIG_SHELL_PRINTF_BUFFER_SIZE 1024U
|
||||
|
||||
|
||||
/******************************* shell configuration ****************************/
|
||||
#define CONFIG_SHELL_PROMPT "Nano-Shell >> "
|
||||
|
||||
#endif /* __NANO_SHELL_CONFIG_H */
|
13
app/third_party/nano-shell-master/shell_io/Makefile
vendored
Normal file
13
app/third_party/nano-shell-master/shell_io/Makefile
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
TOP_DIR = ../../../..
|
||||
sinclude $(TOP_DIR)/tools/w800/conf.mk
|
||||
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libshell_io$(LIB_EXT)
|
||||
endif
|
||||
|
||||
#DEFINES +=
|
||||
|
||||
sinclude $(TOP_DIR)/tools/w800/rules.mk
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
80
app/third_party/nano-shell-master/shell_io/shell_io.c
vendored
Normal file
80
app/third_party/nano-shell-master/shell_io/shell_io.c
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @file shell_io.c
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief Example implementation of some functions in file "shell_io.h".
|
||||
* @version 1.0
|
||||
* @date 2020-03-24
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "shell_io.h"
|
||||
#include "shell_config.h"
|
||||
|
||||
/**
|
||||
* @brief This function should do the actual transmission of the character.
|
||||
* It can also be implemented by macro definition, for example:
|
||||
* ```
|
||||
* #define low_level_write_char(ch) \
|
||||
* do { \
|
||||
* uart_send_char(ch); \
|
||||
* } while(0)
|
||||
* ```
|
||||
*
|
||||
* @param ch the character to be transmitted.
|
||||
*/
|
||||
extern void low_level_write_char(char ch);
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif /* __weak */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
#if !(CONFIG_SHELL_PRINTF_BUFFER_SIZE > 0)
|
||||
#error "the value of CONFIG_SHELL_PRINTF_BUFFER_SIZE must be greater than 0!"
|
||||
#endif
|
||||
|
||||
|
||||
__weak int shell_printf(const char *format, ...)
|
||||
{
|
||||
static char shell_printf_buffer[CONFIG_SHELL_PRINTF_BUFFER_SIZE];
|
||||
|
||||
int length = 0;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
length = vsnprintf(shell_printf_buffer, CONFIG_SHELL_PRINTF_BUFFER_SIZE, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
low_level_write_char(shell_printf_buffer[i]);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
__weak void shell_puts(const char *str)
|
||||
{
|
||||
while (*str) {
|
||||
low_level_write_char(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__weak void shell_putc(char ch)
|
||||
{
|
||||
low_level_write_char(ch);
|
||||
}
|
69
app/third_party/nano-shell-master/shell_io/shell_io.h
vendored
Normal file
69
app/third_party/nano-shell-master/shell_io/shell_io.h
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @file shell_io.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief I/O interface
|
||||
* @version 1.0
|
||||
* @date 2020-03-17
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SHELL_IO_H
|
||||
#define __NANO_SHELL_IO_H
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
nano-shell uses these functions to get/send character from/to stream.
|
||||
You should implement these functions in your project.
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* @brief send a chararcter...
|
||||
*
|
||||
*/
|
||||
extern void shell_putc(char ch);
|
||||
|
||||
|
||||
/**
|
||||
* @brief send string...
|
||||
*
|
||||
*/
|
||||
extern void shell_puts(const char *str);
|
||||
|
||||
|
||||
/**
|
||||
* @brief printf() for nano-shell
|
||||
*
|
||||
*/
|
||||
extern int shell_printf(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get next character available from stream.
|
||||
* not used in <interrupt mode>.
|
||||
*
|
||||
* @param ch Return the character in `ch` if there was...
|
||||
* @return Result is non-zero if there was a character, or 0 if there wasn't.
|
||||
*
|
||||
* @note if you run nano-shell in <main loop mode>, to avoid losing characters, you'd better use a
|
||||
* low layer receive fifo. Take uart for example, you can detect incoming data using interrupts and
|
||||
* then store each received character in a first-in-first out (FIFO) buffer.
|
||||
*
|
||||
* then `shell_getc(char *ch)` may be like this:
|
||||
*
|
||||
* int shell_getc(char *ch)
|
||||
* {
|
||||
* if (fifo_empty()) { // if no character in fifo,
|
||||
* return 0; // return false
|
||||
* }
|
||||
*
|
||||
* *ch = fifo_pop(); // fifo is not empty, get it.
|
||||
* return 1; // return true
|
||||
* }
|
||||
*
|
||||
*/
|
||||
extern int shell_getc(char *ch);
|
||||
|
||||
|
||||
#endif /* __NANO_SHELL_IO_H */
|
104
app/third_party/nano-shell-master/shell_io/static_fifo.h
vendored
Normal file
104
app/third_party/nano-shell-master/shell_io/static_fifo.h
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
* @file fifo.h
|
||||
* @author Liber (lvlebin@outlook.com)
|
||||
* @brief simple fifo based on ring buffer
|
||||
* @version 1.0
|
||||
* @date 2020-03-24
|
||||
*
|
||||
* @copyright Copyright (c) Liber 2020
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NANO_SHELL_FIFO_H
|
||||
#define __NANO_SHELL_FIFO_H
|
||||
|
||||
/**
|
||||
* @brief: declare a STATIC fifo
|
||||
*
|
||||
* @name: name of the fifo, THIS IS NOT a string.
|
||||
* @size: MUST be a CONSTANT, and MUST be a POWER OF 2!!! such as 64, 128, 256, 512, etc ...
|
||||
* @size_type: data type of size, MUST be unsigned!!! such as, uint8_t, uint16_t, uint32_t, etc...
|
||||
* and max_value(size_type) >= size-1
|
||||
* @data_type: data type of element.
|
||||
*
|
||||
* @example:
|
||||
* 1). declare a char type fifo: static_fifo_declare(my_fifo, 256, unsigned char, char);
|
||||
* 2). add a char to the fifo: fifo_push(my_fifo, ch);
|
||||
* 3). get and remove a char: char ch = fifo_pop(my_fifo);
|
||||
*
|
||||
* 4). check manually and then get and remove a char:
|
||||
* char ch = 0;
|
||||
* if (is_fifo_empty(my_fifo)) {
|
||||
* ch = fifo_pop_unsafe(my_fifo);
|
||||
* }
|
||||
*
|
||||
* 5). get a char without remove: char ch = fifo_peek(my_fifo);
|
||||
* 6). get capacity of the fifo: size_t capacity = get_fifo_capacity(my_fifo);
|
||||
* 7). get size of the fifo: size_t size = get_fifo_size(my_fifo);
|
||||
*
|
||||
* @note: All operations on the same FIFO declared by `static_fifo_declare` must be in the same scope.
|
||||
*
|
||||
*/
|
||||
#define static_fifo_declare(name, size, size_type, data_type) \
|
||||
static struct { \
|
||||
size_type head; \
|
||||
size_type tail; \
|
||||
data_type buff[size]; \
|
||||
} _fifo_##name = { 0, 0, {0, } }; \
|
||||
static const size_type _fifo_size_##name = ((size)-1); // the actual available size is (size-1). use const type for gcc optimization
|
||||
|
||||
|
||||
#define get_fifo_capacity(name) (_fifo_size_##name)
|
||||
|
||||
#define get_fifo_size(name) ((unsigned int)(_fifo_##name.head - _fifo_##name.tail))
|
||||
|
||||
#define is_fifo_empty(name) (_fifo_##name.head == _fifo_##name.tail)
|
||||
|
||||
#define is_fifo_full(name) (_fifo_##name.head - _fifo_##name.tail >= _fifo_size_##name)
|
||||
|
||||
|
||||
/**
|
||||
* @brief: add a new element to the fifo. if the fifo is full, do nothing.
|
||||
*
|
||||
* @name: name of the fifo.
|
||||
* @data: the new element to be added.
|
||||
*/
|
||||
#define fifo_push(name, data) \
|
||||
do { \
|
||||
if (!is_fifo_full(name)) { \
|
||||
_fifo_##name.buff[_fifo_##name.head++ & _fifo_size_##name] = (data); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* @brief: Returns the last element in the fifo, without remove it.
|
||||
* If the fifo is empty, return 0.
|
||||
*
|
||||
* @name: name of the fifo.
|
||||
*
|
||||
*/
|
||||
#define fifo_peek(name) \
|
||||
(is_fifo_empty(name) ? 0 : _fifo_##name.buff[_fifo_##name.tail & _fifo_size_##name])
|
||||
|
||||
|
||||
/**
|
||||
* @brief: remove and return last element without checking if the fifo is empty.
|
||||
*
|
||||
* @name: name of the fifo
|
||||
*/
|
||||
#define fifo_pop_unsafe(name) \
|
||||
(_fifo_##name.buff[_fifo_##name.tail++ & _fifo_size_##name])
|
||||
|
||||
|
||||
/**
|
||||
* @brief: Remove and return last element in the fifo.
|
||||
* If the fifo is empty, return 0.
|
||||
*
|
||||
* @name: name of the fifo.
|
||||
*/
|
||||
#define fifo_pop(name) \
|
||||
(is_fifo_empty(name) ? 0 : _fifo_##name.buff[_fifo_##name.tail++ & _fifo_size_##name])
|
||||
|
||||
|
||||
#endif
|
6
app_include/app_common.h
Normal file
6
app_include/app_common.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef APP_COMMON_H
|
||||
#define APP_COMMON_H
|
||||
|
||||
#define NEW_LINE "\r\n"
|
||||
|
||||
#endif //APP_COMMON_H
|
6
app_include/nano_shell_interface.h
Normal file
6
app_include/nano_shell_interface.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef NANO_SHELL_INTERFACE_H
|
||||
#define NANO_SHELL_INTERFACE_H
|
||||
|
||||
extern int shell_printf(const char *format, ...);
|
||||
|
||||
#endif //NANO_SHELL_INTERFACE_H
|
BIN
bin/build/w800/lib/lib7816.a
Normal file
BIN
bin/build/w800/lib/lib7816.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/liba2dp.a
Normal file
BIN
bin/build/w800/lib/liba2dp.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libadc.a
Normal file
BIN
bin/build/w800/lib/libadc.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libag.a
Normal file
BIN
bin/build/w800/lib/libag.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libapi.a
Normal file
BIN
bin/build/w800/lib/libapi.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libapp.a
Normal file
BIN
bin/build/w800/lib/libapp.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libapp_br_edr.a
Normal file
BIN
bin/build/w800/lib/libapp_br_edr.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libapplib.a
Normal file
BIN
bin/build/w800/lib/libapplib.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libar.a
Normal file
BIN
bin/build/w800/lib/libar.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libav.a
Normal file
BIN
bin/build/w800/lib/libav.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libavct.a
Normal file
BIN
bin/build/w800/lib/libavct.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libavdt.a
Normal file
BIN
bin/build/w800/lib/libavdt.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libavrc.a
Normal file
BIN
bin/build/w800/lib/libavrc.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbleapp.a
Normal file
BIN
bin/build/w800/lib/libbleapp.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libblehost.a
Normal file
BIN
bin/build/w800/lib/libblehost.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbleuart.a
Normal file
BIN
bin/build/w800/lib/libbleuart.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbnep.a
Normal file
BIN
bin/build/w800/lib/libbnep.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbta.a
Normal file
BIN
bin/build/w800/lib/libbta.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbtapp.a
Normal file
BIN
bin/build/w800/lib/libbtapp.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbtcore.a
Normal file
BIN
bin/build/w800/lib/libbtcore.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbthcommon.a
Normal file
BIN
bin/build/w800/lib/libbthcommon.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbthost_br_edr.a
Normal file
BIN
bin/build/w800/lib/libbthost_br_edr.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbthsys.a
Normal file
BIN
bin/build/w800/lib/libbthsys.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbtif.a
Normal file
BIN
bin/build/w800/lib/libbtif.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbtm.a
Normal file
BIN
bin/build/w800/lib/libbtm.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libbtu.a
Normal file
BIN
bin/build/w800/lib/libbtu.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libcjson.a
Normal file
BIN
bin/build/w800/lib/libcjson.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libco.a
Normal file
BIN
bin/build/w800/lib/libco.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libcoap.a
Normal file
BIN
bin/build/w800/lib/libcoap.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libcommand.a
Normal file
BIN
bin/build/w800/lib/libcommand.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libconfig.a
Normal file
BIN
bin/build/w800/lib/libconfig.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libconsole.a
Normal file
BIN
bin/build/w800/lib/libconsole.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libcore.a
Normal file
BIN
bin/build/w800/lib/libcore.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libcpu.a
Normal file
BIN
bin/build/w800/lib/libcpu.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libcrypto.a
Normal file
BIN
bin/build/w800/lib/libcrypto.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libdecoder.a
Normal file
BIN
bin/build/w800/lib/libdecoder.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libdemo.a
Normal file
BIN
bin/build/w800/lib/libdemo.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libdhcpserver.a
Normal file
BIN
bin/build/w800/lib/libdhcpserver.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libdm.a
Normal file
BIN
bin/build/w800/lib/libdm.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libdma.a
Normal file
BIN
bin/build/w800/lib/libdma.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libdnsserver.a
Normal file
BIN
bin/build/w800/lib/libdnsserver.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libdrivers.a
Normal file
BIN
bin/build/w800/lib/libdrivers.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libefuse.a
Normal file
BIN
bin/build/w800/lib/libefuse.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libembdrv.a
Normal file
BIN
bin/build/w800/lib/libembdrv.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libencoder.a
Normal file
BIN
bin/build/w800/lib/libencoder.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libext.a
Normal file
BIN
bin/build/w800/lib/libext.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libfatfs.a
Normal file
BIN
bin/build/w800/lib/libfatfs.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libfcmd.a
Normal file
BIN
bin/build/w800/lib/libfcmd.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libflash.a
Normal file
BIN
bin/build/w800/lib/libflash.a
Normal file
Binary file not shown.
BIN
bin/build/w800/lib/libfwup.a
Normal file
BIN
bin/build/w800/lib/libfwup.a
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user