/******************************************************************************
* 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
*
*
© COPYRIGHT(c) 2022 LandPower
*
* 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
#include
#include
#include
#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 "RS485_sensor.h"
#include "ADC_collect.h"
#include "RS485_debug.h"
#include "recording_wave.h"
#include "flash_log.h"
#include "position.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_sen_id(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",
"wave",
"position"
};
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_sen_id = {"sen-id", _cli_sen_id, 8};
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 [data]:\r\n : 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 \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 \r\n : 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 \r\n : 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 \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 \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 \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 \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;
}
/* 设置传感器 id. */
static BaseType_t _cli_sen_id(const char *string)
{
const char *param = NULL;
uint8_t param_len = 0;
uint8_t i = 0;
uint32_t id = 0;
for(i = 0; i < SENSOR_SUM; i++)
{
param = FreeRTOS_CLIGetParameter(string, i + 1, (BaseType_t *)¶m_len);
if (NULL == param)
{
vty_print(cli_param_erro);
return pdFALSE;
}
if (0 == strncmp(param, "h", param_len))
{
vty_print("sen-id \r\n");
vty_print(" Set sensor id.\r\n");
return pdFALSE;
}
else
{
if (sscanf(param, "%d", &id) <= 0)
{
vty_print(cli_param_erro);
return pdFALSE;
}
dev_config.sensor_id[i] = id;
}
}
vty_print(cli_rv_ok);
return pdFALSE;
}
/* 打印版本信息. */
static BaseType_t _cli_show(const char *string)
{
const char *param = NULL;
uint8_t param_len = 0;
uint32_t temp = 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 [param]:\r\n");
vty_print(" : info | sen | ADC | ADCi | ADCv | ADCj | mode | wave | wl | position\r\n");
vty_print(" Show info.\r\n");
}
else if(0 == strncmp(param, "ADC", param_len))
{
ADC_show();
}
else if(0 == strncmp(param, "ADCi", param_len))
{
ADCi_show();
}
else if(0 == strncmp(param, "ADCv", param_len))
{
param = FreeRTOS_CLIGetParameter(string, 2, (BaseType_t *)¶m_len);
if (NULL == param)
{
vty_print(cli_param_erro);
return pdFALSE;
}
if (sscanf(param, "%d", &temp) != 1)
{
vty_print(cli_param_erro);
return pdFALSE;
}
ADC_value_show(temp);
}
else if(0 == strncmp(param, "ADCj", param_len))
{
param = FreeRTOS_CLIGetParameter(string, 2, (BaseType_t *)¶m_len);
if (NULL == param)
{
ADC_adj_show();
return pdFALSE;
}
if (sscanf(param, "%d", &temp) != 1)
{
vty_print(cli_param_erro);
return pdFALSE;
}
ADC_adj_show_ch(temp);
}
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, "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: %d min\r\n", dev_config.collect_interval);
vty_print("Collect threshold: %d A\r\n", dev_config.threshold);
vty_print("Wave interval: %d hour\r\n", dev_config.wave_interval);
vty_print("Wave threshold: %d mV\r\n", dev_config.wave_threshold);
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, "sen", param_len))
{
sensor_show();
}
else if(0 == strncmp(param, "state", param_len))
{
st_show(20);
}
else if(0 == strncmp(param, "wave", param_len))
{
wave_show();
}
else if(0 == strncmp(param, "wl", param_len))
{
wl_show();
}
else if(0 == strncmp(param, "position", param_len))
{
position_show(20);
}
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);
#if 1
uint8_t i = 0;
st_data.wave_time = 0;
st_data.wave_start = TRUE;
st_data.wave_up_start = TRUE;
st_data.wave_index = 0;
for(i = 0; i < WAVE_SUM; i++)
{
st_data.wave_max[i] = 0;
}
st_write(&st_data);
uint32_t reset_delay = 2;
common_sys_set(COM_SYS_RESET, (void*)&reset_delay);
#endif
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 \r\n : 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_sen_id, 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_os(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_os();
/* spi flash 初始化. */
spi_flash_init_os();
FLASH_If_Init();
/* 配置系统初始化. */
dev_config_init_os();
dev_config_init();
flash_log_init();
st_init();
/* 公共监控任务初始化. */
common_sys_init_os();
/* 默认开启的 debug. */
dbg_cmd_hander(DBG_CMD_ON, DBG_M_4G);
//dbg_cmd_hander(DBG_CMD_ON, DBG_M_RS485_SEN);
//dbg_cmd_hander(DBG_CMD_ON, DBG_M_WAVE);
/* 初始化 ADC 采样任务. */
ADC_init_os();
/* 初始化高频录波任务. */
wave_init_os();
if (!IS_MONITOR_BIT_SET(dev_config.flag, DEV_FLAG_ADJ)
&& !IS_MONITOR_BIT_SET(dev_config.flag, DEV_FLAG_FACTORY))
{
/* 4G 通讯任务.*/
wl_init_os();
}
/* 在这个标志置位前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_GPIO_WritePin(RS485_DBG_EN_GPIO_Port, RS485_DBG_EN_Pin, GPIO_PIN_SET);
HAL_UART_Transmit_DMA(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_GPIO_WritePin(RS485_DBG_EN_GPIO_Port, RS485_DBG_EN_Pin, GPIO_PIN_SET);
HAL_UART_Transmit_DMA(cli_uart, (uint8_t*)buf->buf, buf->index);
buf->index = 0;
}
_cli_mutex_unlock();
}
/******************* (C) COPYRIGHT LandPower ***** END OF FILE ****************/