You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
968 lines
28 KiB
C
968 lines
28 KiB
C
/******************************************************************************
|
|
* file Core/Src/cli.c
|
|
* author YuLiang
|
|
* version 1.0.0
|
|
* date 10-Jun-2022
|
|
* brief This file provides all the cli related operation functions.
|
|
******************************************************************************
|
|
* Attention
|
|
*
|
|
* <h2><center>© COPYRIGHT(c) 2022 LandPower</center></h2>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* 3. Neither the name of WTOE nor the names of its contributors may be used to
|
|
* endorse or promote products derived from this software without specific
|
|
* prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
******************************************************************************/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
|
|
#include "main.h"
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "cmsis_os.h"
|
|
#include "usart.h"
|
|
#include "tim.h"
|
|
#include "rtc.h"
|
|
|
|
#include "common.h"
|
|
#include "dev_config.h"
|
|
#include "FreeRTOS_CLI.h"
|
|
#include "cli.h"
|
|
#include "flash_if.h"
|
|
#include "wireless.h"
|
|
#include "ADC_collect.h"
|
|
#include "RS485_debug.h"
|
|
#include "flash_log.h"
|
|
#include "dau.h"
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
/* cli buffer 长度定义. */
|
|
#define CLI_OUTPUT_SIZE 4096
|
|
#define CLI_CMD_SIZE 256
|
|
/* cli 等待超时时间. */
|
|
#define CLI_TIMEOUT 300000
|
|
/* 可查询任务最大长度. */
|
|
#define MAX_TASK_NUM 16
|
|
/* 无效 cli 数据. */
|
|
#define CLI_DATA_INVALID 0xca
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* cli 状态机 flag 号. */
|
|
typedef enum
|
|
{
|
|
CLI_FLAG_PASSWORD = 0, // 表示cli是否输入了密码.
|
|
} CLI_FLAG_E;
|
|
|
|
/* cli 发包缓冲. */
|
|
typedef struct
|
|
{
|
|
char buf[CLI_OUTPUT_SIZE];
|
|
uint16_t index;
|
|
} cli_output_buf_t;
|
|
|
|
/* cli 全局结构体. */
|
|
typedef struct
|
|
{
|
|
uint32_t flag;
|
|
osMutexId_t mutex;
|
|
cli_output_buf_t output_buf;
|
|
char cmd[CLI_CMD_SIZE];
|
|
} cli_machine_t;
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
usart_buf_t cli_buf;
|
|
static cli_machine_t cli_machine; // cli 全局结构体.
|
|
//static TaskStatus_t cli_tasks_status[MAX_TASK_NUM]; // task 任务监测数组.
|
|
static char cli_param_erro[] = "Incorrect command parameter(s).\r\n";
|
|
static char cli_rv_ok[] ="ok.\r\n";
|
|
/* cli 互斥锁属性结构体. */
|
|
static const osMutexAttr_t cli_mutex_attr =
|
|
{
|
|
.name = "cli"
|
|
};
|
|
UART_HandleTypeDef *cli_uart = &huart4;
|
|
|
|
extern uint8_t yl_test;
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
static BaseType_t _cli_adc_auto(const char *string);
|
|
static BaseType_t _cli_dbg_mode(const char *string);
|
|
static BaseType_t _cli_default(const char *string);
|
|
static BaseType_t _cli_eny_mode(const char *string);
|
|
static BaseType_t _cli_host(const char *string);
|
|
static BaseType_t _cli_id(const char *string);
|
|
static BaseType_t _cli_password(const char *string);
|
|
static BaseType_t _cli_reset(const char *string);
|
|
static BaseType_t _cli_save(const char *string);
|
|
static BaseType_t _cli_show(const char *string);
|
|
static BaseType_t _cli_test(const char *string);
|
|
static BaseType_t _cli_work_mode(const char *string);
|
|
|
|
#if LD_DEBUG
|
|
static BaseType_t _cli_debug(const char *string);
|
|
static const char *debug_str[DBG_M_COUNT] =
|
|
{
|
|
"adc",
|
|
"4g",
|
|
"sen",
|
|
"dbg",
|
|
"dau",
|
|
"dau_txrx"
|
|
"gps"
|
|
};
|
|
static const CLI_Command_Definition_t cmd_debug = {"debug", _cli_debug, 2};
|
|
#endif
|
|
static const CLI_Command_Definition_t cmd_adc_auto = {"adc-auto", _cli_adc_auto, 1};
|
|
static const CLI_Command_Definition_t cmd_dbg_mode = {"dbg-mode", _cli_dbg_mode, 1};
|
|
static const CLI_Command_Definition_t cmd_default = {"default", _cli_default, 1};
|
|
static const CLI_Command_Definition_t cmd_eny_mode = {"eny-mode", _cli_eny_mode, 1};
|
|
static const CLI_Command_Definition_t cmd_host = {"host", _cli_host, 1};
|
|
static const CLI_Command_Definition_t cmd_id = {"id", _cli_id, 1};
|
|
static const CLI_Command_Definition_t cmd_pw = {"passwd", _cli_password, 1};
|
|
static const CLI_Command_Definition_t cmd_reset = {"reset", _cli_reset, 1};
|
|
static const CLI_Command_Definition_t cmd_save = {"save", _cli_save, 1};
|
|
static const CLI_Command_Definition_t cmd_show = {"show", _cli_show, 2};
|
|
static const CLI_Command_Definition_t cmd_test = {"test", _cli_test, 1};
|
|
static const CLI_Command_Definition_t cmd_work_mode = {"work-mode", _cli_work_mode, 1};
|
|
|
|
/* Internal functions --------------------------------------------------------*/
|
|
/* cli获取互斥锁. */
|
|
static void _cli_mutex_lock(void)
|
|
{
|
|
osMutexAcquire(cli_machine.mutex, osWaitForever);
|
|
}
|
|
|
|
/* cli释放互斥锁. */
|
|
static void _cli_mutex_unlock(void)
|
|
{
|
|
osMutexRelease(cli_machine.mutex);
|
|
}
|
|
|
|
#if LD_DEBUG
|
|
static uint8_t _cli_string_for_num(const char *string,BaseType_t param_len)
|
|
{
|
|
uint8_t debug_idx = 0xff;
|
|
|
|
for(uint8_t idx = 0; idx < DBG_M_COUNT; idx++)
|
|
{
|
|
if (0 == memcmp(string, debug_str[idx], param_len))
|
|
{
|
|
debug_idx = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return debug_idx;
|
|
}
|
|
|
|
static void _cli_debug_process(uint8_t cmd, const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
BaseType_t param_len = 0;
|
|
uint8_t data = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 2, ¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
if (DBG_CMD_OFF == cmd)
|
|
cmd = DBG_CMD_OFF_ALL;
|
|
else
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
data =_cli_string_for_num(param, param_len);
|
|
if (0xff == data)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (dbg_cmd_hander(cmd, data) != HAL_OK)
|
|
return;
|
|
|
|
vty_print(cli_rv_ok);
|
|
}
|
|
|
|
/* 命令行debug接口. */
|
|
static BaseType_t _cli_debug(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
uint8_t i = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
switch(param[0])
|
|
{
|
|
/* 开debug. */
|
|
case 'e':
|
|
_cli_debug_process(DBG_CMD_ON, string);
|
|
break;
|
|
/* 关debug. */
|
|
case 'd':
|
|
_cli_debug_process(DBG_CMD_OFF, string);
|
|
break;
|
|
/* 帮助信息. */
|
|
case 'h':
|
|
vty_print("debug <cmd> [data]:\r\n <cmd>: e-enable | d-disable\r\n");
|
|
vty_print(" [data]:");
|
|
for(i = 0; i < DBG_M_COUNT; i++)
|
|
vty_print(" %s |", debug_str[i]);
|
|
vty_print("\r\n");
|
|
vty_print("Enable or disable debug module.\r\n");
|
|
return pdFALSE;
|
|
|
|
default:
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
return pdFALSE;
|
|
}
|
|
#endif
|
|
|
|
/* 自动校准. */
|
|
static BaseType_t _cli_adc_auto(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
uint32_t bitmap = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
if (0 == strncmp(param, "h", param_len))
|
|
{
|
|
vty_print("adc-auto <bitmap>\r\n ADC auto adjust.\r\n");
|
|
return pdFALSE;
|
|
}
|
|
|
|
if (sscanf(param, "%x", &bitmap) <= 0)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
debug_adj_auto(bitmap);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 配置 debug 模式. */
|
|
static BaseType_t _cli_dbg_mode(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint32_t reset_delay = 2;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
switch(param[0])
|
|
{
|
|
/* CLI 模式. */
|
|
case 'c':
|
|
dev_config_flag_set(DEV_FLAG_CLI);
|
|
break;
|
|
/* 可视化模式. */
|
|
case 'p':
|
|
dev_config_flag_unset(DEV_FLAG_CLI);
|
|
break;
|
|
/* 帮助信息. */
|
|
case 'h':
|
|
vty_print("dbg-mode <mode>\r\n <mode>: cli | pc\r\n Entry debug mode.\r\n");
|
|
return pdFALSE;
|
|
|
|
default:
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
flash_log_write(FLASH_LOG_TYPE_INFO, "Change debug mode system reset!\r\n");
|
|
common_sys_set(COM_SYS_SAVE_CONFIG, 0);
|
|
common_sys_set(COM_SYS_RESET, (void*)&reset_delay);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 恢复出厂设置.. */
|
|
static BaseType_t _cli_default(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (param != NULL)
|
|
{
|
|
if (param[0] != 'h')
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
else
|
|
{
|
|
vty_print("default\r\n Set config to default.\r\n");
|
|
return pdFALSE;
|
|
}
|
|
}
|
|
|
|
dev_config_defaults_set();
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 配置电源工作模式. */
|
|
static BaseType_t _cli_eny_mode(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
switch(param[0])
|
|
{
|
|
/* 智能模式. */
|
|
case 'a':
|
|
dev_config.energy_mode = ADC_ENERGY_AUTO;
|
|
break;
|
|
/* 正常模式. */
|
|
case 'n':
|
|
dev_config.energy_mode = ADC_ENERGY_NORMAL;
|
|
break;
|
|
/* 节能模式. */
|
|
case 's':
|
|
dev_config.energy_mode = ADC_ENERGY_SLEEP;
|
|
break;
|
|
/* 帮助信息. */
|
|
case 'h':
|
|
vty_print("eny-mode <mode>\r\n <mode>: auto | normal | sleep\r\n Entry energy mode.\r\n");
|
|
return pdFALSE;
|
|
|
|
default:
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
common_sys_set(COM_SYS_SAVE_CONFIG, 0);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 设置主机名. */
|
|
static BaseType_t _cli_host(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
if (0 == strncmp(param, "h", param_len))
|
|
{
|
|
vty_print("host <name>\r\n Set host name.\r\n");
|
|
return pdFALSE;
|
|
}
|
|
|
|
dev_config_host_name_set((uint8_t*)param);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 设置设备 id. */
|
|
static BaseType_t _cli_id(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
uint32_t id = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
if (0 == strncmp(param, "h", param_len))
|
|
{
|
|
vty_print("id <ID>\r\n Set device id.\r\n");
|
|
return pdFALSE;
|
|
}
|
|
|
|
if (sscanf(param, "%x", &id) <= 0)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
dev_info_id_set(id);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 设置 cli 密码. */
|
|
static BaseType_t _cli_password(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
if (0 == strncmp(param, "h", param_len))
|
|
{
|
|
vty_print("passwd <password>\r\n Set cli password.\r\n");
|
|
return pdFALSE;
|
|
}
|
|
|
|
dev_config_password_set((uint8_t*)param);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 设备软复位. */
|
|
static BaseType_t _cli_reset(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
uint32_t reset_delay = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if ('h' == param[0])
|
|
{
|
|
vty_print("reset [iap]\r\n Reset system.\r\n");
|
|
return pdFALSE;
|
|
}
|
|
else if('i' == param[0])
|
|
{
|
|
dev_record_reset_type_set(RESET_IAP);
|
|
common_sys_set(COM_SYS_SAVE_RECORD, 0);
|
|
}
|
|
|
|
flash_log_write(FLASH_LOG_TYPE_INFO, "Cli system reset!\r\n");
|
|
common_sys_set(COM_SYS_RESET, (void*)&reset_delay);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 配置保存命令. */
|
|
BaseType_t _cli_save(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
if (0 == strncmp(param, "h", param_len))
|
|
vty_print("save <config | info | record>\r\n Save info or config.\r\n");
|
|
else if (0 == strncmp(param, "info", param_len))
|
|
common_sys_set(COM_SYS_SAVE_INFO, 0);
|
|
else if (0 == strncmp(param, "config", param_len))
|
|
common_sys_set(COM_SYS_SAVE_CONFIG, 0);
|
|
else if (0 == strncmp(param, "record", param_len))
|
|
common_sys_set(COM_SYS_SAVE_RECORD, 0);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 打印版本信息. */
|
|
static BaseType_t _cli_show(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
if (0 == strncmp(param, "h", param_len))
|
|
{
|
|
vty_print("show <cmd> [param]:\r\n");
|
|
vty_print(" <cmd>: info | sen | ADC | ADCi | ADCv | ADCj | mode | wave | wl | position\r\n");
|
|
vty_print(" Show info.\r\n");
|
|
}
|
|
else if(0 == strncmp(param, "ADCi", param_len))
|
|
{
|
|
ADC_show();
|
|
}
|
|
else if(0 == strncmp(param, "csg", param_len))
|
|
{
|
|
dev_csg_print();
|
|
}
|
|
else if(0 == strncmp(param, "data", param_len))
|
|
{
|
|
fd_show(20);
|
|
}
|
|
else if(0 == strncmp(param, "dau", param_len))
|
|
{
|
|
dau_show();
|
|
}
|
|
else if(0 == strncmp(param, "info", param_len))
|
|
{
|
|
dev_info_print();
|
|
}
|
|
else if(0 == strncmp(param, "log", param_len))
|
|
{
|
|
flash_log_show(20);
|
|
}
|
|
else if(0 == strncmp(param, "mode", param_len))
|
|
{
|
|
vty_print("Debug mode: %s\r\n", IS_MONITOR_BIT_SET(dev_config.flag, DEV_FLAG_CLI) ? "CLI" : "PC");
|
|
vty_print("Work mode: %s\r\n", IS_MONITOR_BIT_SET(dev_config.flag, DEV_FLAG_ADJ) ? "ADJ" : "NORMAL");
|
|
vty_print("Work mode: %s\r\n", IS_MONITOR_BIT_SET(dev_config.flag, DEV_FLAG_FACTORY) ? "FACTORY" : "NORMAL");
|
|
vty_print("Normal sleep: %d\r\n", dev_config.normal_sleep);
|
|
vty_print("Force sleep up: %d\r\n", st_data.force_sleep_up);
|
|
vty_print("BAT charge: %d\r\n", HAL_GPIO_ReadPin(BAT_CHECK_GPIO_Port, BAT_CHECK_Pin));
|
|
vty_print("Collect interval: %dmin\r\n", dev_config.collect_interval);
|
|
vty_print("Collect threshold: %dA\r\n", dev_config.threshold);
|
|
vty_print("Defect threshold: %dmV\r\n", dev_config.wave_threshold);
|
|
vty_print("Fault threshold: %dA\r\n", dev_config.fault_threshold);
|
|
vty_print("Keepalive: %dms\r\n", dev_config.keepalive);
|
|
vty_print("Mian cable: %d\r\n", dev_config.main_cable);
|
|
vty_print("Voltage col: %d\r\n", dev_config.is_voltage_col);
|
|
vty_print("Temp col: %d\r\n", dev_config.is_temp_col);
|
|
vty_print("Wave col: %d\r\n", dev_config.is_wave_col);
|
|
}
|
|
else if(0 == strncmp(param, "state", param_len))
|
|
{
|
|
st_show(20);
|
|
}
|
|
else if(0 == strncmp(param, "wl", param_len))
|
|
{
|
|
wl_show();
|
|
}
|
|
else
|
|
{
|
|
vty_print(cli_param_erro);
|
|
}
|
|
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 测试函数. */
|
|
static BaseType_t _cli_test(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (param != NULL)
|
|
{
|
|
if (param[0] != 'h')
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
else
|
|
{
|
|
vty_print("test\r\n Test.\r\n");
|
|
return pdFALSE;
|
|
}
|
|
}
|
|
|
|
//flash_log_write(FLASH_LOG_TYPE_ERROR, "test%d\r\n", 1);
|
|
//flash_log_write(FLASH_LOG_TYPE_WARNING, "test%d\r\n", 2);
|
|
//flash_log_write(FLASH_LOG_TYPE_NOTIFY, "test%d\r\n", 3);
|
|
//flash_log_write(FLASH_LOG_TYPE_INFO, "test%d\r\n", 4);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 工作模式配置命令. */
|
|
static BaseType_t _cli_work_mode(const char *string)
|
|
{
|
|
const char *param = NULL;
|
|
uint32_t reset_delay = 2;
|
|
uint8_t param_len = 0;
|
|
|
|
param = FreeRTOS_CLIGetParameter(string, 1, (BaseType_t *)¶m_len);
|
|
if (NULL == param)
|
|
{
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
switch(param[0])
|
|
{
|
|
case 'w':
|
|
dev_config_flag_unset(DEV_FLAG_ADJ);
|
|
dev_config_flag_unset(DEV_FLAG_FACTORY);
|
|
break;
|
|
case 'a':
|
|
dev_config_flag_set(DEV_FLAG_ADJ);
|
|
dev_config_flag_unset(DEV_FLAG_FACTORY);
|
|
break;
|
|
case 'f':
|
|
dev_config_flag_unset(DEV_FLAG_ADJ);
|
|
dev_config_flag_set(DEV_FLAG_FACTORY);
|
|
break;
|
|
/* 帮助信息. */
|
|
case 'h':
|
|
vty_print("work-mode <mode>\r\n <mode>: w-work | a-adj | f-factory\r\n Select work mode.\r\n");
|
|
return pdFALSE;
|
|
|
|
default:
|
|
vty_print(cli_param_erro);
|
|
return pdFALSE;
|
|
}
|
|
|
|
flash_log_write(FLASH_LOG_TYPE_INFO, "Change work mode system reset!\r\n");
|
|
common_sys_set(COM_SYS_SAVE_CONFIG, 0);
|
|
common_sys_set(COM_SYS_RESET, (void*)&reset_delay);
|
|
|
|
vty_print(cli_rv_ok);
|
|
return pdFALSE;
|
|
}
|
|
|
|
/* 命令行等待一个字符串. */
|
|
static HAL_StatusTypeDef _cli_wait_string(char *string, uint16_t size, uint32_t timeout)
|
|
{
|
|
uint32_t tickstart = HAL_GetTick();
|
|
uint32_t notify_value = 0xff;
|
|
uint16_t index = 0;
|
|
uint8_t key = 0;
|
|
uint8_t cmd_index = 0;
|
|
|
|
while(1)
|
|
{
|
|
/* 判断超时. */
|
|
if (timeout != portMAX_DELAY
|
|
&& (HAL_GetTick() - tickstart) > timeout)
|
|
{
|
|
string[0] = '\0';
|
|
HAL_UART_AbortReceive(cli_uart);
|
|
return HAL_TIMEOUT;
|
|
}
|
|
|
|
/* 启动串口中断. */
|
|
if (HAL_OK == HAL_UARTEx_ReceiveToIdle_DMA(cli_uart, cli_buf.buf, USART_BUF_SIZE))
|
|
{
|
|
cli_buf.end = 0;
|
|
cli_buf.is_half = FALSE;
|
|
}
|
|
|
|
common_watchdog_set(COM_WDG_CLI);
|
|
|
|
/* 等待收包完成. */
|
|
notify_value = ulTaskNotifyTake(pdTRUE, 10000);
|
|
if (0 == notify_value)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/* 命令过长. */
|
|
if (cli_buf.end >= USART_BUF_SIZE)
|
|
{
|
|
cmd_index = 0;
|
|
string[0] = '\0';
|
|
continue;
|
|
}
|
|
|
|
/* 收到数据,刷新tick. */
|
|
tickstart = HAL_GetTick();
|
|
|
|
for(index = 0; index < cli_buf.end; index++)
|
|
{
|
|
key = cli_buf.buf[index];
|
|
if ('\r' == key || '\n' == key)
|
|
{
|
|
/* 字符串结束. */
|
|
HAL_UART_AbortReceive(cli_uart);
|
|
string[cmd_index] = 0;
|
|
vty_print("\r\n");
|
|
return HAL_OK;
|
|
}
|
|
else if((KEY_BACK == key) || (KEY_DEL == key))
|
|
{
|
|
/* Backspace was pressed. Erase the last character in the string. */
|
|
if (cmd_index > 0)
|
|
{
|
|
cmd_index--;
|
|
string[cmd_index] = '\0';
|
|
vty_print("%c%c%c", KEY_BACK, ' ', KEY_BACK);
|
|
}
|
|
}
|
|
else if((key >= ' ') && (key <= '~'))
|
|
{
|
|
/* A character was entered. Add it to the string entered so far. */
|
|
if (cmd_index < size - 1)
|
|
{
|
|
string[cmd_index] = key;
|
|
if (!IS_MONITOR_BIT_SET(cli_machine.flag, CLI_FLAG_PASSWORD))
|
|
vty_print("*");
|
|
else
|
|
vty_print("%c", key);
|
|
cmd_index++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* cli处理函数. */
|
|
static void _cli_process(void)
|
|
{
|
|
BaseType_t rv = 0;
|
|
|
|
for(;;)
|
|
{
|
|
/* 获取命令字符串. */
|
|
if (_cli_wait_string(cli_machine.cmd, CLI_CMD_SIZE, CLI_TIMEOUT) != HAL_OK)
|
|
{
|
|
vty_print("\r\nCli is timeout.\r\n");
|
|
return;
|
|
}
|
|
|
|
/* 处理命令. */
|
|
do
|
|
{
|
|
rv = FreeRTOS_CLIProcessCommand(cli_machine.cmd);
|
|
} while(rv != pdFALSE);
|
|
FreeRTOS_CLIPrintPrefix((char*)dev_config.host);
|
|
}
|
|
}
|
|
|
|
/* 命令行系统相关初始化. */
|
|
static void _cli_start(void)
|
|
{
|
|
/* 命令注册. */
|
|
#if LD_DEBUG
|
|
FreeRTOS_CLIRegisterCommand(&cmd_debug, CLI_NODE_COMMON);
|
|
#endif
|
|
FreeRTOS_CLIRegisterCommand(&cmd_adc_auto, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_dbg_mode, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_default, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_eny_mode, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_host, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_id, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_pw, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_reset, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_save, CLI_NODE_CONFIG);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_show, CLI_NODE_COMMON);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_test, CLI_NODE_COMMON);
|
|
FreeRTOS_CLIRegisterCommand(&cmd_work_mode, CLI_NODE_CONFIG);
|
|
|
|
for(;;)
|
|
{
|
|
/* 提示输入密码. */
|
|
vty_print("Password: ");
|
|
|
|
/* 等待输入密码. */
|
|
_cli_wait_string(cli_machine.cmd, CLI_CMD_SIZE, portMAX_DELAY);
|
|
if (0 == strncmp((char*)dev_config.password, cli_machine.cmd, DEV_PASSWORD_LEN - 1))
|
|
{
|
|
FreeRTOS_CLIPrintPrefix((char*)dev_config.host);
|
|
MONITOR_BITMAP_SET(cli_machine.flag, CLI_FLAG_PASSWORD);
|
|
_cli_process();
|
|
MONITOR_BITMAP_RESET(cli_machine.flag, CLI_FLAG_PASSWORD);
|
|
}
|
|
else
|
|
vty_print("Password not match!!!\r\n");
|
|
}
|
|
}
|
|
|
|
/* 命令行系统相关初始化. */
|
|
void _cli_init(void)
|
|
{
|
|
/* 初始化互斥锁. */
|
|
cli_machine.mutex = osMutexNew(&cli_mutex_attr);
|
|
/* 致命错误,此处不应该被运行,记录错误log,打印错误信息. */
|
|
if (NULL == cli_machine.mutex)
|
|
ERROR_PRINT(-1);
|
|
}
|
|
|
|
/* Interface functions -------------------------------------------------------*/
|
|
/* 命令行线程开始函数. */
|
|
void cli_start(void const * argument)
|
|
{
|
|
/******** START INIT ********/
|
|
/* 以下代码是freeRTOS启动后第一个运行的任务,因为优先级最高,且最早创建.所以需要在freeRTOS启动后再初始化
|
|
* 的地方统一放在下面这段地方. */
|
|
/* crc32 初始化. */
|
|
crc32_table_init();
|
|
/* 命令行系统相关初始化. */
|
|
_cli_init();
|
|
/* spi flash 初始化. */
|
|
spi_flash_init();
|
|
FLASH_If_Init();
|
|
/* 配置系统初始化. */
|
|
dev_config_init();
|
|
dev_config_flag_set(DEV_FLAG_CLI);
|
|
//dev_config_flag_unset(DEV_FLAG_CLI);
|
|
dev_config.keepalive = 300000;
|
|
flash_log_init();
|
|
st_init();
|
|
/* 公共监控任务初始化. */
|
|
common_sys_init();
|
|
/* 默认开启的 debug. */
|
|
//dbg_cmd_hander(DBG_CMD_ON, DBG_M_DAU);
|
|
//dbg_cmd_hander(DBG_CMD_ON, DBG_M_GPS);
|
|
dbg_cmd_hander(DBG_CMD_ON, DBG_M_4G);
|
|
/* 初始化 ADC 采样任务. */
|
|
ADC_init();
|
|
/* 初始化 DAU 任务. */
|
|
dau_init();
|
|
/* 初始化无线通讯任务. */
|
|
if (!IS_MONITOR_BIT_SET(dev_config.flag, DEV_FLAG_ADJ)
|
|
&& !IS_MONITOR_BIT_SET(dev_config.flag, DEV_FLAG_FACTORY))
|
|
{
|
|
wl_init();
|
|
}
|
|
|
|
/* 在这个标志置位前vty_print是原地循环等待,置位后变为任务调度. */
|
|
MONITOR_BITMAP_SET(system_init_flag, SYS_INIT_OS);
|
|
flash_log_write(FLASH_LOG_TYPE_INFO, "System start!\r\n");
|
|
/********* END INIT *********/
|
|
|
|
if (IS_MONITOR_BIT_SET(dev_config.flag, DEV_FLAG_CLI))
|
|
{
|
|
/* 使用命令行调试. */
|
|
_cli_start();
|
|
}
|
|
else
|
|
{
|
|
/* 使用 PC 调试软件调试. */
|
|
debug_start();
|
|
}
|
|
}
|
|
|
|
/* description: 将cli需要发送的数据存入缓存.
|
|
* param: 无.
|
|
* return: 无. */
|
|
void cli_usart_data_buf_send(char *format, va_list ap)
|
|
{
|
|
cli_output_buf_t *buf = &cli_machine.output_buf;
|
|
uint16_t index = 0;
|
|
int16_t num = 0;
|
|
|
|
/* 串口为中断发送,在没有发送完前不能写数据. */
|
|
while(HAL_UART_STATE_BUSY_TX == cli_uart->gState)
|
|
osThreadYield();
|
|
|
|
_cli_mutex_lock();
|
|
|
|
index = buf->index;
|
|
if ((num = vsnprintf(&buf->buf[index], CLI_OUTPUT_SIZE - index, format, ap)) < 0)
|
|
{
|
|
_cli_mutex_unlock();
|
|
return;
|
|
}
|
|
|
|
if ((index + num) >= CLI_OUTPUT_SIZE)
|
|
buf->index = CLI_OUTPUT_SIZE - 1;
|
|
else
|
|
buf->index = index + num;
|
|
|
|
_cli_mutex_unlock();
|
|
}
|
|
|
|
/* description: 在操作系统没有启动的情况下发送cli数据.
|
|
* param: 无.
|
|
* return: 无. */
|
|
void cli_usart_data_buf_send_without_os(char *format, va_list ap)
|
|
{
|
|
cli_output_buf_t *buf = &cli_machine.output_buf;
|
|
|
|
while(HAL_UART_STATE_BUSY_TX == cli_uart->gState)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (vsnprintf(buf->buf, CLI_OUTPUT_SIZE, format, ap) > 0)
|
|
{
|
|
HAL_UART_Transmit_IT(cli_uart, (uint8_t*)buf->buf, strlen(buf->buf));
|
|
}
|
|
}
|
|
|
|
/* description: 将cli缓存数据通过串口发送出去.
|
|
* param: 无.
|
|
* return: 无. */
|
|
void cli_data_buf_send_hw(void)
|
|
{
|
|
cli_output_buf_t *buf = &cli_machine.output_buf;
|
|
|
|
if (HAL_UART_STATE_BUSY_TX == cli_uart->gState)
|
|
return;
|
|
|
|
_cli_mutex_lock();
|
|
if (buf->index > 0)
|
|
{
|
|
HAL_UART_Transmit_IT(cli_uart, (uint8_t*)buf->buf, buf->index);
|
|
buf->index = 0;
|
|
}
|
|
_cli_mutex_unlock();
|
|
}
|
|
/******************* (C) COPYRIGHT LandPower ***** END OF FILE ****************/
|