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 ****************/
 |