/****************************************************************************** * 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("Energy mode: %d\r\n", ADC_ctrl.energy_mode); 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 ****************/