/****************************************************************************** 版权所有: 文件名称: Maintain.c 文件版本: 01.01 创建作者: xxxxxx 创建日期: 2013-03-05 功能说明: 装置维护管理 其它说明: 修改记录: */ /*------------------------------- 头文件 -------------------------------------- */ #include "head.h" /*------------------------------- 宏定义 -------------------------------------- */ #define MAINTAIN_TYPE 138 #define MAINTAIN_ACK 0X80 #define MAINTAIN_NAK 0X40 #define MAINTAIN_ERR_OK 0x00 #define MAINTAIN_ERR_NAME 0x01 #define MAINTAIN_ERR_TYPE 0x02 #define MAINTAIN_ERR_BUSY 0x03 #define MAINTAIN_ERR_ADDR 0x04 #define MAINTAIN_ERR_SIZE 0x05 #define MAINTAIN_ERR_CRC 0x06 #define MAINTAIN_ERR_SAVE 0x07 #define MAINTAIN_ERR_PHASE 0x08 #define MAINTAIN_ERR_MEM 0x09 #define MAINTAIN_ERR_STATE 0x0a #define MAINTAIN_ERR_OCODE 0X0B #define MAINTAIN_ERR_NCODE 0X0C #define MAINTAIN_ERR_NSLOT 0X0D #define MAINTAIN_ERR_TIME 0X0E #define MAINTAIN_ERR_SETNULL 0X0F #define MAINTAIN_ERR_SETERR 0X10 #define MAINTAIN_ERR_DATAL 0X11 //输入校正值太小 #define MAINTAIN_ERR_CHXS 0X12 //通道系数超范围 #define MAINTAIN_ERR_ANGLEL 0X13 //输入角度值太小 #define MAINTAIN_ERR_ANGLEH 0X14 //输入角度值太大 #define MAINTAIN_ERR_ANGLEXS 0X15 //角度系数超范围 #define MAINTAIN_ERR_XSSAVE 0X16 //系数保存错误 #define MAINTAIN_ERR_CODE 0X17 #define MAINTAIN_ERR_CMD 0X18 // 不支持的命令 #define MAINTAIN_ERR_FORMAT 0X19 // 格式错误 #define MAINTAIN_ERR_OTHER 0xff #define MAINTAIN_ATTR_UP 0X01 #define MAINTAIN_ATTR_DOWN 0X02 #define BOARD_NUMBER 12 //最大支持板卡个数 /*------------------------------ 类型结构 ------------------------------------- */ enum mState { MS_IDLE = 0, // 空闲状态 MS_REQUEST, // 维护请求 MS_END, // 维护结束 MS_UPDATE, // 文件更新命令 MS_EQUINF, // 查看装置信息 MS_BOARDINF, // 查看板卡信息 MS_TEST_DO, // 开出测试 MS_TEST_DI, // 开入值刷新 MS_TEST_LED, // LED测试 MS_SAMPLE, // 零漂值刷新 MS_ADJUST, // 采样校准 MS_TEST_REMOTE, // 远动测试 MS_RECORD, // 手动启动录波 MS_MEASURE, // 测量值刷新 MS_TIME_DIS, // 时间刷新 MS_TIME_SET, // 对时 MS_FLAG_DIS, // 标志刷新 MS_BAT_MANAGE, // 电池管理 MS_CLEAR_SOE, // 清除SOE MS_SET_CODE, // 修改密码 MS_KEEP_ALIVE, // 心跳命令 MS_BOARD_VERSION, // 主板版本 MS_DIDO_AUTO_TEST, // 开入开出自动测试 MS_BOARD_DI, // 板卡遥信 MS_RESOURCE_THAN, // 资源表文件比对 MS_BOARD_MEASURE, // 板卡测量值刷新 MS_BOARD_CALIBRATION, // 板卡校准系数上传 MS_DEFAULT_CALIBRATION, // 恢复默认校准系数 MS_SAMPLE_CALIBRATION, // 整机采样校准 MS_DEFAULT, // 恢复出厂设置 MS_UZTEMP_MEASURE, // 直流、温度刷新 MS_ADJUST_UZL, // 直流校准 MS_SAMPLE_TEST, // 采样通道测试 MS_KRKC_TEST, // 开入开出测试 MS_LCD_TEST, // LCD测试 MS_RESET_TEST, // 装置复位 MS_CFGINF, // 配置信息查看 MS_ERRINF, // 故障信息查看 MS_GETIP, // 获取网口及对应IP MS_GET_GPRS_INFO, // 得到GPRS信息 MS_FZXS_UD, // 辐值系数上传下载 MS_AC_CFG, // 采样板单板通道配置 MS_DC_FACTOR, // 直流校准系数 MS_WAVE_OK, // 录波完成 MS_FILE_ISUPDATE, // 文件是否更新 MS_COMM_TEST, // 串口测试 MS_PASSWORD, // 密码及权限确认 MS_INSTU, // 内部状态查看 MS_RCD_NAME, // 录波文件名称获取 MS_RMT_PAIR, // 遥控器配对 MS_BOARDINF2, // 查看板卡信息 MS_SET_MTPWD, // 设置维护工具密码 MS_MT_PWD, // 维护工具密码及权限确认 MS_CLOSE_PORT, // 关闭维护端口服务 MS_AUTH, // 装置授权管理 MS_YD_REFRESH, // 远动遥信遥测刷新 MS_FACTORY_SETUP, //出厂设置 #if defined(CPU_AM335X) MS_APP_BAK_START, //启动app分区备份 58 MS_APP_BAK_RESULT, //查询app分区备份结果 59 #endif }; struct maintain { enum mState state; s32 file_index; u16 file_type; }; //板卡类型 enum { BOARD_MASTER=0, //主板 BOARD_AUX, //辅助功能板 BOARD_DI_30, //DI板:30个 BOARD_DI_72, //DI板:72个 BOARD_DO, //DO板 BOARD_AI_UI, //AI板:电压3个,电流9个 BOARD_AI_I, //AI板:电流12个 BOARD_POWER, //电源板 BOARD_DISP, //显示板 }; //采样板类型 enum { AC_4U12I=1, AC_4U9I, AC_1U12I, AC_6U4I, AC_4U4I, ACTYPE_NUM, }; //板卡信息格式 struct board_inf { BYTE bytype; //板卡类型 BYTE bystatus; //板卡状态 BYTE byCRC[2]; //程序CRC校验 BYTE byVer[4]; //程序版本 }; struct ac_test_type { char * name; u16 normal_data; short normal_angle; }; struct ac_test_board { int type; int num; const struct ac_test_type *data; }; #define FILELIST_FILE_VERSION 0X01010101 //文件列表版本 #define MTPWD_FILE_VERSION 0X01010101 //文件版本 /*------------------------------ 全局变量 ------------------------------------- */ // 维护接入方式,是串口还是网络,如果是串口,不能打开网络端口 bool g_mt_rs232; struct maintain g_maintain = {0}; struct maintain_def g_mtbuf; struct prog_up g_prog_up; static const char * mt_init_pwd = "gh123456@"; // 维护工具默认密码 static char mt_pwd[17]; extern struct timespec g_sys_time; u8 dido_buf[128]; uint32_t alive_us0 = 0,alive_us1 = 0; uint32_t rmttest_us0 = 0,rmttest_us1 = 0; const struct ac_test_type g_dtu_ac4u12i_desc[17] = { {"Ua", 100, 0}, {"Ub", 100, -120}, {"Uc", 100, 120}, {"US", 100, 120}, {"Ia1", 5, 0}, {"Ib1", 5, -120}, {"Ic1", 5, 120}, {"Ia2", 5, 0}, {"Ib2", 5, -120}, {"Ic2", 5, 120}, {"Ia3", 5, 0}, {"Ib3", 5, -120}, {"Ic3", 5, 120}, {"Ia4", 5, 0}, {"Ib4", 5, -120}, {"Ic4", 5, 120}, {"F", 50, 0}, }; #define AC_DTU_4U12I_NUM (sizeof(g_dtu_ac4u12i_desc)/sizeof(g_dtu_ac4u12i_desc[0])) const struct ac_test_type g_dtu_ac4u9i_desc[17] = { {"Ua", 100, 0}, {"Ub", 100, -120}, {"Uc", 100, 120}, {"US", 100, 120}, {"Ia1", 5, 0}, {"Ib1", 5, -120}, {"Ic1", 5, 120}, {"Ia2", 5, 0}, {"Ib2", 5, -120}, {"Ic2", 5, 120}, {"Ia3", 5, 0}, {"Ib3", 5, -120}, {"Ic3", 5, 120}, {"+12V", 12, 0}, {"-12V", -12, 0}, {"+05V", 5, 0}, {"F", 50, 0}, }; #define AC_DTU_4U9I_NUM (sizeof(g_dtu_ac4u9i_desc)/sizeof(g_dtu_ac4u9i_desc[0])) const struct ac_test_type g_dtu_ac1u12i_desc[17] = { {"US1", 100, 0}, {"Ia1", 5, 0}, {"Ib1", 5, -120}, {"Ic1", 5, 120}, {"Ia2", 5, 0}, {"Ib2", 5, -120}, {"Ic2", 5, 120}, {"Ia3", 5, 0}, {"Ib3", 5, -120}, {"Ic3", 5, 120}, {"Ia4", 5, 0}, {"Ib4", 5, -120}, {"Ic4", 5, 120}, {"+12V", 12, 0}, {"-12V", -12, 0}, {"+05V", 5, 0}, {"F", 50, 0}, }; #define AC_DTU_1U12I_NUM (sizeof(g_dtu_ac1u12i_desc)/sizeof(g_dtu_ac1u12i_desc[0])) const struct ac_test_type g_ftu_4u4i_desc[9] = { {"UA", 100, 0}, {"UB", 100, -120}, {"UC", 100, 120}, {"U0", 100, 120}, {"IA", 5, 0}, {"IB", 5, -120}, {"IC", 5, 120}, {"I0", 5, 120}, {"F", 50, 0}, }; #define AC_FTU_4U4I_NUM (sizeof(g_ftu_4u4i_desc)/sizeof(g_ftu_4u4i_desc[0])) struct ac_test_board g_ac_test_board[] = { {AC_4U12I,AC_DTU_4U9I_NUM,g_dtu_ac4u12i_desc}, {AC_4U9I,AC_DTU_4U9I_NUM,g_dtu_ac4u9i_desc}, {AC_1U12I,AC_DTU_1U12I_NUM,g_dtu_ac1u12i_desc}, {AC_4U4I,AC_FTU_4U4I_NUM,g_ftu_4u4i_desc}, }; #define AC_TEST_BOARD_NUM (sizeof(g_ac_test_board)/sizeof(g_ac_test_board[0])) /*------------------------------ 函数声明 ------------------------------------- */ static void _maintain_state_reset(void); static void _maintain_echo(struct maintain_def *pt, u8 *cmd_buf, u8 cmd_len); static void _maintain_recv_rst(struct maintain_def *pt); static void _maintain_send(void); static int _maintain_comm(struct maintain_def *pt, unsigned char *buf, int len); static int _trans_file_comm(struct maintain_def *pt, u8 *buf, int len); static int _maintain_pwd_createfile(u8 *pwd); static int _maintain_pwd_readfile(void); extern BYTE g_LedNo; extern struct down_program_comm g_down_program; // 面板升级 int IEC101_TransFile(IEC101_DEF *pt, unsigned char *buf, int len); /*------------------------------ 外部函数 ------------------------------------- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性. */ /************************************************************************** 函数名称:MainTain_Init 函数版本:1.00 作者: 创建日期:2013.03.28 函数功能说明:维护命令初始化 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void MainTain_Init(void) { int i; memset(&g_mtbuf, 0, sizeof(struct maintain_def)); alive_us0 = ustimer_get_origin(); alive_us1 = ustimer_get_origin(); i = _maintain_pwd_readfile(); if (i != 0) { u8 j, tmp_pwd[16]; memset(&mt_pwd, ' ', 16); memcpy(&mt_pwd, mt_init_pwd, strlen(mt_init_pwd)); for (j = 0; j < 16; j++) { tmp_pwd[j] = ~mt_pwd[j]; } _maintain_pwd_createfile(tmp_pwd); rt_printf("维护工具密码文件错误: %d\r\n", i); } } /************************************************************************** 函数名称:Maintain_Applay 函数版本:1.00 作者: 创建日期:2013.03.28 函数功能说明:维护命令链路数据处理 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void Maintain_Applay(void) { struct maintain_def *pt = &g_mtbuf; BYTE *pd; u8 AddByte = 0; // 如果有僵死的维护线程,回收。 net_maintain_zombie(); if (bMaintain) { alive_us1 = ustimer_get_origin(); // noted by sunxi: 目前维护工具为每30秒发1条心跳,如果漏1条,就已经是60秒了。 // 这样很容易出问题,应该是发3条心跳,1条都没有收到才被认为有问题才合理。100秒可有3条心跳了。 if (alive_us1 - alive_us0 > 100 * USTIMER_SEC) // 100秒循环检查 { bMaintain = false; } } if (g_run_stu.bToolRmtTest) { rmttest_us1 = ustimer_get_origin(); if (rmttest_us1 - rmttest_us0 > 600UL * USTIMER_SEC) // 10分钟自动退出远动测试模式 { g_run_stu.bToolRmtTest = false; } } if (pt->bData) // 有接收到的数据 { if (!g_mtbuf.hmi_mode) { g_file_save = 0; } pt->bData = false; if (pt->recvbuf[0] == 0x10) pd = &pt->recvbuf[1]; // 短帧 else if (pt->recvbuf[0] == 0x68) pd = &pt->recvbuf[4]; // 长帧 else return; // rt_printf("Maintain_Recv buf= %x %x %x %x %x %x %x %x %x %x %x %x\r\n", pd[0],pd[1],pd[2],pd[3],pd[4],pd[5],pd[6],pd[7],pd[8],pd[9],pd[10],pd[11]); pt->dValidTime = dTCounter; switch ((pd[0] & 0x0f)) { case 3: // 请求/确认 case 4: // 请求/无应答 switch (pd[2]) // 类型标识判断 { case 138: // 维护命令管理模块 _maintain_comm(pt, &pd[2 + AddByte], pt->recvbuf[1] - (2 + AddByte)); break; case 137: // 下载上传文件 _trans_file_comm(pt, &pd[2 + AddByte], pt->recvbuf[1] - (2 + AddByte)); break; } break; } // 类型判断结束 _maintain_send(); } else // 无有效数据接收,平衡式101处理自动发送数据 { if (pt->bSend) return; // 正在发送数据,不处理 if (dTCounter - pt->dValidTime > T_1s * 10) // 6秒后,未收到应答报文 { pt->dValidTime = dTCounter; if (++pt->byRetryTimes > 2) // 重发三次后,重新初始化 { pt->bSend = false; } else { // 需重新组织发送 _maintain_send(); } } return; // 发送,未收到数据,返回 } } /************************************************************************** 函数名称:Maintain_Manage 函数版本:1.00 作者: 创建日期:2013.03.28 函数功能说明:维护命令处理 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ int Maintain_Manage(u8 *buf, u32 len, u8 *cmd_buf) { u8 cmd_len = 0; u16 i; char name[256]; #if defined(CPU_AM335X) u32 llen; u8 *lbuf; u8 result = 0; struct file *pfile; loff_t pos; char *cmd_ls[] = {"/usr/sbin/app_backup.sh", NULL, NULL, NULL}; #endif cmd_buf[0] = MAINTAIN_TYPE; cmd_buf[1] = buf[1]; alive_us0 = ustimer_get_origin(); switch (buf[1]) { case MS_REQUEST: // 维护请求 _maintain_state_reset(); sprintf(cmd_buf + 2, szTool); sprintf(cmd_buf + 21, VER_TIME "CRC:%04XH", m_CodeCrc); cmd_len = strlen(cmd_buf + 2) + 1 + 2; #if 0 for (i=0; i<19; i++) //检查版本号 { if (buf[2+i] != szTool[i]) { cmd_buf[1] |= MAINTAIN_NAK; break; } } #endif bMaintain = true; cmd_buf[1] |= MAINTAIN_ACK; g_maintain.state = MS_REQUEST; break; case MS_END: // 维护结束 bMaintain = false; if (g_run_stu.bToolRmtTest) { g_run_stu.bToolRmtTest = false; } // 如果是重复报文,继续肯定应答。 if (g_maintain.state == MS_END) { cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; break; } // 判断是否需要复位 if (buf[2] == 1) // 0:不复位;1:复位 { } // 一切正常,肯定应答 cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; // 复位全部状态后,设置状态为MS_END,继续应答重发确认帧。 _maintain_state_reset(); g_maintain.state = MS_END; break; case MS_UPDATE: { u16 file_type; char from_file_name[64]; char to_file_name[64]; memcpy(cmd_buf + 2, buf + 2, 25); // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[25] = MAINTAIN_ERR_PHASE; cmd_len = 26; break; } // 检查文件名 g_maintain.file_index = file_check(buf + 3, ATTR_DOWN); if (g_maintain.file_index < 0) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[25] = MAINTAIN_ERR_NAME; cmd_len = 26; break; } if (buf[25]) { // 子板升级 if (g_maintain.file_type == FILETYPE_CHILDPRO) { #if defined(BSP_CAN_ENABLE) extern struct program_comm g_program; if ((g_program.comm == 0) && (g_prog_up.bit_echo == 0)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[25] = MAINTAIN_ERR_OTHER; cmd_len = 26; break; } else { cmd_buf[26] = g_prog_up.framesum; cmd_buf[27] = g_prog_up.framesum >> 8; cmd_buf[28] = g_prog_up.frameno; cmd_buf[29] = g_prog_up.frameno >> 8; cmd_buf[30] = g_prog_up.bit_prog; cmd_buf[31] = g_prog_up.bit_prog >> 8; cmd_buf[32] = g_prog_up.bit_echo; cmd_buf[33] = g_prog_up.bit_echo >> 8; cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 34; } #endif } else if (g_maintain.file_type == FILETYPE_F308_HMI) { if ((g_down_program.comm == 0) && (g_down_program.bit_echo == 0)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[25] = MAINTAIN_ERR_OTHER; cmd_len = 26; break; } else { cmd_buf[26] = g_down_program.framenum; cmd_buf[27] = g_down_program.framenum >> 8; cmd_buf[28] = g_down_program.frameno; cmd_buf[29] = g_down_program.frameno >> 8; cmd_buf[30] = g_down_program.bit_prog; cmd_buf[31] = g_down_program.bit_prog >> 8; cmd_buf[32] = g_down_program.bit_echo; cmd_buf[33] = g_down_program.bit_echo >> 8; cmd_buf[1] |= MAINTAIN_ACK; // rt_printf("[frameno=%d, %d]\n", g_down_program.frameno,g_down_program.framenum); cmd_len = 34; } } break; } memcpy(&g_maintain.file_type, buf + 23, 2); #ifndef MODE_LITTLE_ENDIAN swap16(&g_maintain.file_type); #endif file_type = file_check_type(buf + 3, ATTR_DOWN); // 文件校验,并进行移动、删除动作.注意GPRS相关文件作特殊处理 if (g_file_save) { g_file_save = 0; } else if (g_maintain.file_type == file_type) { if (file_check_info(g_maintain.file_index) == 0) { char log_buf[128] = {0}; uint32_t us0 = ustimer_get_origin(); watchdog_feed_mainloop_50s(); sprintf(to_file_name, "%s%s", g_file_item[g_maintain.file_index].file_dir, g_file_item[g_maintain.file_index].file_name); sprintf(from_file_name, "%s%s", "/tmp/", g_file_item[g_maintain.file_index].file_name); rt_file_mv(from_file_name, to_file_name); rt_printf("rt_file_mv:us=%d.\r\n", ustimer_get_duration(us0) / USTIMER_US); sprintf(name, "%s%s%s", "文件更新", g_file_item[g_maintain.file_index].file_dir, g_file_item[g_maintain.file_index].file_name); log_str_time(LOG_OPERATE, name, 0, 1); sprintf(log_buf, "%s updated", g_file_item[g_maintain.file_index].file_name); load_hs_log_rcd(TYPE_SW_UPDATE, true, NULL, log_buf, 1); } else { sprintf(from_file_name, "%s%s", "/tmp/", g_file_item[g_maintain.file_index].file_name); rt_file_del(from_file_name); if (g_maintain.file_type == FILETYPE_SET) { set_create_data_file(); } cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[25] = MAINTAIN_ERR_CRC; cmd_len = 26; break; } } if (g_maintain.file_type == FILETYPE_SET) { int ret = 0; ret = set_save_data_file(g_maintain.file_index); if (ret != 0) { cmd_buf[1] |= MAINTAIN_NAK; if (ret < 0) { cmd_buf[25] = MAINTAIN_ERR_CRC; } else if (ret & 0x07) { cmd_buf[25] = MAINTAIN_ERR_SETNULL; } else if (ret & 0x70) { cmd_buf[25] = MAINTAIN_ERR_SETERR; } cmd_len = 26; break; } } #ifdef FUN_GPRS // modfiy for xxxxxx 20220706 GPRS没有使用。 else if (g_maintain.file_type == FILETYPE_INNERGPRS) { // extern void gprs_net_update_gprsini(void); // gprs_net_update_gprsini(); // 不作任何处理.GPRS模块自己会复位. extern int g_update_gprs_driver; if (strcmp(g_file_item[g_maintain.file_index].file_name, FILE_NAME_GPRSDRIVER) == 0) { g_update_gprs_driver = 1; // 置更新标志 } } #endif else if (g_maintain.file_type == FILETYPE_CHILDPRO) { #if defined(BSP_CAN_ENABLE) if (init_file_program(buf[2], g_maintain.file_index) != 0) // 文件读取校验有误 { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[25] = MAINTAIN_ERR_CRC; cmd_len = 26; rt_file_del("/tmp/DTU-DIDO.elf.bin"); break; } else { cmd_buf[25] = 1; } #endif } else if (g_maintain.file_type == FILETYPE_F308_HMI) { if (init_down_program(g_maintain.file_index) != 0) // 文件读取校验有误 { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[25] = MAINTAIN_ERR_CRC; cmd_len = 26; rt_file_del("/tmp/F308_HMI.bin"); break; } else { cmd_buf[25] = 1; } } cmd_buf[1] |= MAINTAIN_ACK; if (cmd_buf[25]) { // 子板升级 if (g_maintain.file_type == FILETYPE_CHILDPRO) { cmd_buf[26] = g_prog_up.framesum; cmd_buf[27] = g_prog_up.framesum >> 8; cmd_buf[28] = g_prog_up.frameno; cmd_buf[29] = g_prog_up.frameno >> 8; cmd_buf[30] = g_prog_up.bit_prog; cmd_buf[31] = g_prog_up.bit_prog >> 8; cmd_buf[32] = g_prog_up.bit_echo; cmd_buf[33] = g_prog_up.bit_echo >> 8; cmd_len = 34; } else if (g_maintain.file_type == FILETYPE_F308_HMI) { cmd_buf[26] = g_down_program.framenum; cmd_buf[27] = g_down_program.framenum >> 8; cmd_buf[28] = g_down_program.frameno; cmd_buf[29] = g_down_program.frameno >> 8; cmd_buf[30] = g_down_program.bit_prog; cmd_buf[31] = g_down_program.bit_prog >> 8; cmd_buf[32] = g_down_program.bit_echo; cmd_buf[33] = g_down_program.bit_echo >> 8; cmd_len = 34; } break; } else { cmd_len = 26; } } break; case MS_EQUINF: // 查看装置信息 cmd_len = set_get_fixed_args_sz(buf[2], cmd_buf + 2, 240); cmd_len += 2; cmd_buf[1] |= MAINTAIN_ACK; break; case MS_BOARDINF: case MS_BOARDINF2: { // 查看板卡信息 #define BOARD_INF_MAX_SLOT 11 int slot_num = 0, slot_begin = 0; int b_info_size; if (buf[1] == MS_BOARDINF) { slot_num = g_equ_config->equ_slot_num > BOARD_INF_MAX_SLOT ? BOARD_INF_MAX_SLOT : g_equ_config->equ_slot_num; slot_begin = 0; } else if (g_equ_config->equ_slot_num > BOARD_INF_MAX_SLOT) { slot_num = g_equ_config->equ_slot_num - BOARD_INF_MAX_SLOT; slot_begin = BOARD_INF_MAX_SLOT; } else { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OTHER; cmd_len = 3; break; } cmd_len = 2; b_info_size = 21; for (i = 0; i < slot_num; i++) { cmd_buf[2 + i * b_info_size] = g_board_info[slot_begin + i].type; cmd_buf[3 + i * b_info_size] = g_board_info[slot_begin + i].status; cmd_buf[4 + i * b_info_size] = g_board_info[slot_begin + i].errcode; cmd_buf[5 + i * b_info_size] = g_board_info[slot_begin + i].crc; cmd_buf[6 + i * b_info_size] = g_board_info[slot_begin + i].crc >> 8; cmd_buf[7 + i * b_info_size] = g_board_info[slot_begin + i].version; cmd_buf[8 + i * b_info_size] = g_board_info[slot_begin + i].version >> 8; cmd_buf[9 + i * b_info_size] = g_board_info[slot_begin + i].version >> 16; cmd_buf[10 + i * b_info_size] = g_board_info[slot_begin + i].version >> 24; cmd_buf[11 + i * b_info_size] = g_board_info[slot_begin + i].update_time.tv_sec; cmd_buf[12 + i * b_info_size] = g_board_info[slot_begin + i].update_time.tv_sec >> 8; cmd_buf[13 + i * b_info_size] = g_board_info[slot_begin + i].update_time.tv_sec >> 16; cmd_buf[14 + i * b_info_size] = g_board_info[slot_begin + i].update_time.tv_sec >> 24; cmd_buf[15 + i * b_info_size] = g_board_info[slot_begin + i].update_time.tv_nsec; cmd_buf[16 + i * b_info_size] = g_board_info[slot_begin + i].update_time.tv_nsec >> 8; cmd_buf[17 + i * b_info_size] = g_board_info[slot_begin + i].update_time.tv_nsec >> 16; cmd_buf[18 + i * b_info_size] = g_board_info[slot_begin + i].update_time.tv_nsec >> 24; cmd_buf[19 + i * b_info_size] = g_board_info[slot_begin + i].can_bus; cmd_buf[20 + i * b_info_size] = g_board_info[slot_begin + i].can_bus >> 8; cmd_buf[21 + i * b_info_size] = g_board_info[slot_begin + i].is_check; cmd_buf[22 + i * b_info_size] = g_board_info[slot_begin + i].is_check >> 8; cmd_len += b_info_size; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_TEST_DO: // 开出测试 // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } bMaintain_test = true; dido_single_test(buf[2], buf[3]); bMaintain_test = false; cmd_buf[2] = buf[2]; cmd_buf[3] = buf[3]; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 4; break; case MS_TEST_DI: { // 开入值刷新 int sw; sw = buf[2]; cmd_buf[2] = sw; if (sw == 0) { int i; long flag = 0; long value = 0; long flag2 = 0; long value2 = 0; for (i = 0; i < PUB_DI_NUM; i++) { if ((short)g_sw_pub.di_cfg_index[i] != INDEX_INVALLID) // 此遥信有配置 { struct equ_config_di *ecd = &g_equ_config_di[g_sw_pub.di_cfg_index[i]]; if (i < 32) { if (dido_di_is_on(ecd->slot, ecd->index)) { value |= (1 << i); } flag |= (1 << i); } else { if (dido_di_is_on(ecd->slot, ecd->index)) { value2 |= (1 << (i - 32)); } flag2 |= (1 << (i - 32)); } } } cmd_buf[3] = flag; cmd_buf[4] = (flag >> 8); cmd_buf[5] = (flag >> 16); cmd_buf[6] = (flag >> 24); cmd_buf[7] = value; cmd_buf[8] = (value >> 8); cmd_buf[9] = (value >> 16); cmd_buf[10] = (value >> 24); cmd_len = 11; if (PUB_DI_NUM > 32) { cmd_buf[11] = flag2; cmd_buf[12] = (flag2 >> 8); cmd_buf[13] = (flag2 >> 16); cmd_buf[14] = (flag2 >> 24); cmd_buf[15] = value2; cmd_buf[16] = (value2 >> 8); cmd_buf[17] = (value2 >> 16); cmd_buf[18] = (value2 >> 24); cmd_len = 19; } } else if (sw <= SWITCH_NUM_MAX) { int i; long flag = 0; long value = 0; long flag2 = 0; long value2 = 0; sw--; for (i = 0; i < SW_DI_NUM; i++) { if ((short)g_sw[sw].di_cfg_index[i] != INDEX_INVALLID) // 此遥信有配置 { struct equ_config_di *ecd = &g_equ_config_di[g_sw[sw].di_cfg_index[i]]; if (i < 32) { if (dido_di_is_on(ecd->slot, ecd->index)) { value |= (1 << i); } flag |= (1 << i); } else { if (dido_di_is_on(ecd->slot, ecd->index)) { value2 |= (1 << (i - 32)); } flag2 |= (1 << (i - 32)); } } } cmd_buf[3] = flag; cmd_buf[4] = (flag >> 8); cmd_buf[5] = (flag >> 16); cmd_buf[6] = (flag >> 24); cmd_buf[7] = value; cmd_buf[8] = (value >> 8); cmd_buf[9] = (value >> 16); cmd_buf[10] = (value >> 24); cmd_len = 11; if (SW_DI_NUM > 32) { cmd_buf[11] = flag2; cmd_buf[12] = (flag2 >> 8); cmd_buf[13] = (flag2 >> 16); cmd_buf[14] = (flag2 >> 24); cmd_buf[15] = value2; cmd_buf[16] = (value2 >> 8); cmd_buf[17] = (value2 >> 16); cmd_buf[18] = (value2 >> 24); cmd_len = 19; } } else { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_NSLOT; cmd_len = 3; break; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_TEST_LED: { // LED测试 // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } // 显示面板LED测试 if (buf[2] == 0) { add_led_test(TEST_LED); } // 辅助板LED测试 else if (buf[2] == 1) { g_led_aux_test_st = 1; } // 状态板LED测试 else if (buf[2] == 2) { g_led_aux_test_st = 1; } cmd_buf[2] = buf[2]; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 3; } break; case MS_SAMPLE: { // 零漂值刷新 u8 slot, i; short data; #ifdef CPU_FUXI int samcnt = ((g_adc_dots_data_count / ADC_REC_SAMPLE_RATE) & CFG_ADC_DOTS_MASK); #else int samcnt = ((g_adc_dots_count - 1) & CFG_ADC_DOTS_MASK); #endif cmd_buf[2] = buf[2]; slot = buf[2]; if ((slot >= 16) || !(g_board_info[slot].type == BOARD_TYPE_AC || g_board_info[slot].type == BOARD_TYPE_FUXI_AC) // 零漂 ) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_NSLOT; cmd_len = 3; break; } for (i = 0; i < EQU_SLOT_AC_CHN; i++) { data = g_adc_dots[equ_get_ac_channel(slot, i)][samcnt]; cmd_buf[i * 2 + 3] = (data); cmd_buf[i * 2 + 4] = (data) >> 8; } cmd_len = EQU_SLOT_AC_CHN * 2; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len += 3; } break; case MS_ADJUST: { // 采样校准 // 检查阶段 int ret; if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } ret = sw_auto_adjust(-1); switch (ret) { case 0: cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; break; case -1: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_DATAL; cmd_len = 3; break; case -2: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_CHXS; cmd_len = 3; break; case -3: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_ANGLEL; cmd_len = 3; break; case -4: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_ANGLEH; cmd_len = 3; break; case -5: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_ANGLEXS; cmd_len = 3; break; case -6: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_XSSAVE; cmd_len = 3; break; } if (ret == 0) { log_str_time(LOG_OPERATE, "工具交流校准成功", 0, 0); } else { log_str_time(LOG_OPERATE, "工具交流校准失败", 0, 0); } } break; case MS_TEST_REMOTE: { // 远动测试 // 检查阶段 if (g_maintain.state != MS_REQUEST) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } cmd_buf[2] = buf[2]; if (buf[2] == 0x01) { send_rmt_yc(buf); // 遥测 } else if (buf[2] == 0x06) // 电度 { send_rmt_dd(buf); // 遥测 } else if (buf[2] == 0x05) { int ret; char *szErr; ret = send_rmt_yk(buf); // 遥控 if (ret != 0) { szErr = RmtCtrl_Err(ret); // 发送ACK cmd_buf[1] |= MAINTAIN_NAK; strcpy(&cmd_buf[3], szErr); cmd_len = 3 + strlen(szErr) + 1; break; } } else if (buf[2] == 0x02 || buf[2] == 0x04) // xj 2019-10-18 解决远动测试发送遥测时,遥信也突发上送 { send_rmt_yx(buf); // 遥信 } rmttest_us0 = ustimer_get_origin(); g_run_stu.bToolRmtTest = true; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 3; } break; case MS_RECORD: { // 手动启动录波 int waves; struct rtc_time_t tm; struct timespec ts; memcpy(cmd_buf + 2, buf + 2, 4); waves = (int)buf[2] | (int)buf[3] << 8 | (int)buf[4] << 16 | (int)buf[5] << 24; // zwg 此处有BUG,维护工具未发时间 // 得到当前时刻。 clk_time_get(&ts); timespec_to_rtc(ts, &tm, 0); rt_printf("当前时间: %04d-%02d-%02d %02d:%02d:%02d:%09d!\r\n", tm.year + 2000, tm.month, tm.day, tm.hour, tm.min, tm.ms / 1000, ts.tv_nsec); rcd_start(SWITCH_NUM_MAX, RECORD_TYPE_SD, waves); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 6; } break; case MS_MEASURE: { // 测量值刷新 #define YC_NUM_PER_FRAME (250 / 9) int sw, frame, cnt; sw = buf[2] & 0x1f; frame = (buf[2] >> 5) & 0x07; cnt = 0; if (sw == 0) { long val, ang; int pCal = 0; for (i = frame * YC_NUM_PER_FRAME; i < PUB_AC_NUM_ALL; i++) { val = g_sw_pub.ac_in[i]; if (i < PUB_AC_NUM) { ang = g_ui[i].p; if (g_ui[i].chn_index != CFG_ADC_CHANNEL_ZERO) { pCal = 0x1; } else if (g_ui[i].ui_base_make != -1) { pCal = 0x2; } else { pCal = 0x4; } } else { ang = ANGEL_INVALID; pCal = 0x2; } if (g_unit[g_pub_ac_desc[i].unit].zero > 0 && _AbsL(val) < g_unit[g_pub_ac_desc[i].unit].zero && pRunSet->bTT_RET_ZERO) { val = 0; ang = ANGEL_INVALID; } cmd_buf[3 + cnt * 9] = pCal; cmd_buf[3 + cnt * 9 + 1] = val; cmd_buf[3 + cnt * 9 + 2] = (val >> 8); cmd_buf[3 + cnt * 9 + 3] = (val >> 16); cmd_buf[3 + cnt * 9 + 4] = (val >> 24); cmd_buf[3 + cnt * 9 + 5] = ang; cmd_buf[3 + cnt * 9 + 6] = (ang >> 8); cmd_buf[3 + cnt * 9 + 7] = (ang >> 16); cmd_buf[3 + cnt * 9 + 8] = (ang >> 24); cnt++; if (cnt == YC_NUM_PER_FRAME) { frame++; break; } } } else if (sw <= EQU_SLOT_NUM_MAX) { int index_begin; index_begin = UI_SW_INDEX_BEGIN(sw - 1); for (i = frame * YC_NUM_PER_FRAME; i < SW_AC_NUM_ALL; i++) { long val, ang; int pCal = 0; val = g_sw[sw - 1].ac_in[i]; if (i < SW_AC_NUM) { ang = g_ui[index_begin + i].p; if (g_ui[index_begin + i].chn_index != CFG_ADC_CHANNEL_ZERO) { pCal = 0x1; } else if (g_ui[index_begin + i].ui_base_make != -1) { pCal = 0x2; } else { pCal = 0x4; } } else { pCal = 0x2; ang = ANGEL_INVALID; } if (g_unit[g_sw_ac_desc[i].unit].zero > 0 && _AbsL(val) < g_unit[g_sw_ac_desc[i].unit].zero && pRunSet->bTT_RET_ZERO) { val = 0; ang = ANGEL_INVALID; } if (g_sw_ac_desc[i].unit == UNIT_GE) val *= 65536; cmd_buf[3 + cnt * 9] = pCal; cmd_buf[3 + cnt * 9 + 1] = val; cmd_buf[3 + cnt * 9 + 2] = (val >> 8); cmd_buf[3 + cnt * 9 + 3] = (val >> 16); cmd_buf[3 + cnt * 9 + 4] = (val >> 24); cmd_buf[3 + cnt * 9 + 5] = ang; cmd_buf[3 + cnt * 9 + 6] = (ang >> 8); cmd_buf[3 + cnt * 9 + 7] = (ang >> 16); cmd_buf[3 + cnt * 9 + 8] = (ang >> 24); cnt++; if (cnt == YC_NUM_PER_FRAME) { frame++; break; } } } cmd_len = cnt * 9; cmd_len += 3; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_buf[2] = sw; // | frame; } break; case MS_TIME_DIS: { // 时间刷新 struct rtc_time_t t_rtc; struct timespec ts; #ifndef MODE_LITTLE_ENDIAN u8 tmp = 0; #endif // 得到系统时间 clk_time_get(&ts); timespec_to_rtc(ts, &t_rtc, 1); memcpy(cmd_buf + 2, &t_rtc, 8); #ifndef MODE_LITTLE_ENDIAN tmp = cmd_buf[2]; cmd_buf[2] = cmd_buf[3]; cmd_buf[3] = tmp; tmp = cmd_buf[8]; cmd_buf[8] = cmd_buf[9]; cmd_buf[9] = tmp; #endif // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 10; } break; case MS_TIME_SET: { // 时间设置 struct rtc_time_t t_rtc; #ifndef MODE_LITTLE_ENDIAN u8 tmp = 0; #endif memcpy(cmd_buf + 2, buf + 2, 8); #ifndef MODE_LITTLE_ENDIAN tmp = buf[2]; buf[2] = buf[3]; buf[3] = tmp; tmp = buf[8]; buf[8] = buf[9]; buf[9] = tmp; #endif memcpy(&t_rtc, buf + 2, 8); // 设置系统时间 if (sys_time_set(&t_rtc) != 0) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_TIME; cmd_len = 3; break; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 10; log_str_time(LOG_OPERATE, "工具设置时间", 0, 0); } break; case MS_FLAG_DIS: // 标志刷新 // 得到所需上传标志 cmd_buf[2] = 1; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; break; case MS_BAT_MANAGE: // 电源管理 if (buf[2] == 1) { bat_active(1); } if (buf[3] == 1) { bat_act_off(1); } memcpy(cmd_buf + 2, buf + 2, 2); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 4; break; case MS_CLEAR_SOE: // 清除事件 if (buf[2]) // 清除操作记录 { soe_clear_opt(); soe_record_opt(EV_CLEAR_OPE, 0); } if (buf[3]) // 清除事件记录 { soe_clear_ev(); soe_record_opt(EV_CLEAR_SOE, 0); } memcpy(cmd_buf + 2, buf + 2, 2); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 4; break; case MS_SET_CODE: { // 设置密码 u16 old_password, new_password; old_password = buf[2] | (buf[3] << 8); new_password = buf[4] | (buf[5] << 8); if ((old_password != tRunPara.wPassword) && (old_password != PASS_WORD)) { old_password = 0; cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OCODE; // 旧密码错误 cmd_len = 3; break; } if (new_password == INTER_PASSWORD) { new_password = 0; old_password = 0; cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_NCODE; // 新密码无效 cmd_len = 3; break; } // SavePassword(new_password); tRunPara.wPassword = ReadPassword(); log_str_time(LOG_OPERATE, "工具设置用户密码", 0, 0); memcpy(cmd_buf + 2, buf + 2, 4); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 6; } break; case MS_KEEP_ALIVE: { alive_us0 = ustimer_get_origin(); cmd_len = 2; } break; case MS_BOARD_VERSION: { // 主板版本 int flag, no = 0; struct board_info *bi; bi = g_board_info; flag = buf[2]; cmd_buf[2] = flag; switch (flag) { case 0: no = ENV_U_BOOT; break; case 1: no = ENV_KERNEL; break; case 2: no = ENV_ROOT_FS; break; case 3: sprintf(cmd_buf + 3, "APP VERSION:SV%02d.%03d %s", VER_NUM / 1000, VER_NUM % 1000, VER_TIME); cmd_len = strlen(cmd_buf + 3) + 3; break; #ifdef CPU_FUXI // fuxi 增加裸核版本信息 case 4: sprintf(cmd_buf + 3, "LuoHe VERSION:V%d.%02d %s CRC=%X", LuoHe_version.ver / 100, LuoHe_version.ver % 100, LuoHe_version.time, LuoHe_version.v_crc); cmd_len = strlen(cmd_buf + 3) + 3; break; #endif default: cmd_len = 3; break; } if (flag < 3) { sprintf(cmd_buf + 3, "%s", env_get_info(no)); cmd_len = strlen(env_get_info(no)) + 3; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_DIDO_AUTO_TEST: { // 开入开出自动测试 char tmpbuf[16]; // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } bMaintain_test = true; switch (buf[2]) { case 0: // 自动检测板卡测试 #if defined(BSP_CAN_ENABLE) tmpbuf[0] = 1; tmpbuf[1] = 3; tmpbuf[2] = 1; tmpbuf[3] = 4; tmpbuf[4] = 2; tmpbuf[5] = 5; tmpbuf[6] = 2; tmpbuf[7] = 6; dido_auto_test(tmpbuf, 3); cmd_buf[6] = 3; #else tmpbuf[0] = 1; // DO板卡 tmpbuf[1] = 1; // DI板卡 dido_auto_test(tmpbuf, 1); cmd_buf[6] = 1; #endif break; case 1: // 开出板卡测试 case 2: // 开入板卡测试 tmpbuf[0] = 1; tmpbuf[1] = 3; dido_auto_test(tmpbuf, 1); cmd_buf[6] = 1; break; case 3: // 辅助板测试 tmpbuf[0] = 5; tmpbuf[1] = 5; dido_auto_test(tmpbuf, 1); cmd_buf[6] = 1; break; case 4: // 综合板测试 tmpbuf[0] = 4; tmpbuf[1] = 6; dido_auto_test(tmpbuf, 1); cmd_buf[6] = 1; break; case 5: // 开入60板测试 tmpbuf[0] = 1; tmpbuf[1] = 3; tmpbuf[2] = 2; tmpbuf[3] = 3; dido_auto_test(tmpbuf, 2); cmd_buf[6] = 2; break; default: break; } bMaintain_test = false; cmd_buf[2] = 0; #if defined(BSP_CAN_ENABLE) { extern struct rt_stat g_stat_do_delay; extern struct rt_stat g_stat_di_delay; if (g_stat_do_delay.max > 1000000) { cmd_buf[2] |= 0x01; } if (g_stat_di_delay.max > (20000000 + 20000000)) { cmd_buf[2] |= 0x02; } } #endif cmd_buf[3] = 0; cmd_buf[4] = 0; cmd_buf[5] = 0; memcpy(cmd_buf + 7, dido_buf, cmd_buf[6] * 14); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = cmd_buf[6] * 14 + 4 + 3; } break; case MS_BOARD_DI: { // 板卡遥信 int slot; slot = buf[2]; cmd_buf[2] = slot; { int i; long flag1 = 0; long value1 = 0; long flag2 = 0; long value2 = 0; int di_num; di_num = equ_get_di_num(slot); for (i = 0; i < di_num; i++) { if (i < 32) flag1 |= (1 << i); else flag2 |= (1 << (i - 32)); if (dido_di_is_on(slot, i)) { if (i < 32) value1 |= (1 << i); else value2 |= (1 << (i - 32)); } else { if (i < 32) value1 &= ~(1 << i); else value2 &= ~(1 << (i - 32)); } } cmd_buf[3] = flag1; cmd_buf[4] = (flag1 >> 8); cmd_buf[5] = (flag1 >> 16); cmd_buf[6] = (flag1 >> 24); cmd_buf[7] = (flag2 >> 0); cmd_buf[8] = (flag2 >> 8); cmd_buf[9] = (flag2 >> 16); cmd_buf[10] = (flag2 >> 24); cmd_buf[11] = value1; cmd_buf[12] = (value1 >> 8); cmd_buf[13] = (value1 >> 16); cmd_buf[14] = (value1 >> 24); cmd_buf[15] = (value2 >> 0); cmd_buf[16] = (value2 >> 8); cmd_buf[17] = (value2 >> 16); cmd_buf[18] = (value2 >> 24); } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 19; } break; case MS_RESOURCE_THAN: { memcpy(cmd_buf + 2, buf + 2, 22); // 定值描述文件 if (strcmp(buf + 2, FILE_NAME_SET_DESC) == 0) { cmd_buf[22] = setdesc_contrast.version; cmd_buf[23] = (setdesc_contrast.version >> 8); cmd_buf[24] = (setdesc_contrast.version >> 16); cmd_buf[25] = (setdesc_contrast.version >> 24); cmd_buf[26] = setdesc_contrast.signature; cmd_buf[27] = (setdesc_contrast.signature >> 8); cmd_buf[28] = (setdesc_contrast.signature >> 16); cmd_buf[29] = (setdesc_contrast.signature >> 24); cmd_buf[30] = setdesc_contrast.length; cmd_buf[31] = (setdesc_contrast.length >> 8); cmd_buf[32] = (setdesc_contrast.length >> 16); cmd_buf[33] = (setdesc_contrast.length >> 24); cmd_buf[34] = setdesc_contrast.crc; cmd_buf[35] = (setdesc_contrast.crc >> 8); } // 资源描述文件 else if (strcmp(buf + 2, FILE_NAME_RSC) == 0) { cmd_buf[22] = rsc_contrast.version; cmd_buf[23] = (rsc_contrast.version >> 8); cmd_buf[24] = (rsc_contrast.version >> 16); cmd_buf[25] = (rsc_contrast.version >> 24); cmd_buf[26] = rsc_contrast.signature; cmd_buf[27] = (rsc_contrast.signature >> 8); cmd_buf[28] = (rsc_contrast.signature >> 16); cmd_buf[29] = (rsc_contrast.signature >> 24); cmd_buf[30] = rsc_contrast.length; cmd_buf[31] = (rsc_contrast.length >> 8); cmd_buf[32] = (rsc_contrast.length >> 16); cmd_buf[33] = (rsc_contrast.length >> 24); cmd_buf[34] = rsc_contrast.crc; cmd_buf[35] = (rsc_contrast.crc >> 8); } // 通道配置文件 else if (strcmp(buf + 2, FILE_NAME_EQU_CFG) == 0) { cmd_buf[22] = g_equ_contrast.version; cmd_buf[23] = (g_equ_contrast.version >> 8); cmd_buf[24] = (g_equ_contrast.version >> 16); cmd_buf[25] = (g_equ_contrast.version >> 24); cmd_buf[26] = g_equ_contrast.signature; cmd_buf[27] = (g_equ_contrast.signature >> 8); cmd_buf[28] = (g_equ_contrast.signature >> 16); cmd_buf[29] = (g_equ_contrast.signature >> 24); cmd_buf[30] = g_equ_contrast.length; cmd_buf[31] = (g_equ_contrast.length >> 8); cmd_buf[32] = (g_equ_contrast.length >> 16); cmd_buf[33] = (g_equ_contrast.length >> 24); cmd_buf[34] = g_equ_contrast.crc; cmd_buf[35] = (g_equ_contrast.crc >> 8); } else { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[22] = MAINTAIN_ERR_PHASE; cmd_len = 23; break; } cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 36; } break; case MS_BOARD_MEASURE: { // 板卡测量值刷新 int slot, chn; slot = buf[2]; cmd_buf[2] = slot; if ((slot >= 16) || !(g_board_info[slot].type == BOARD_TYPE_AC || g_board_info[slot].type == BOARD_TYPE_FUXI_AC) // 有零漂 ) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_NSLOT; cmd_len = 3; break; } chn = g_board_res[g_board_info[slot].type].ac_num; for (i = 0; i < chn; i++) { long val, ang; int chn_index, j; chn_index = equ_get_ac_channel(slot, i); for (j = 0; j < UI_NUM; j++) { if (g_ui[j].chn_index == chn_index) { break; } } if (chn_index >= 0 && j != UI_NUM) { val = g_ui[j].e; ang = g_ui[j].p; } else { val = 0; ang = 0; } cmd_buf[3 + i * 8] = val; cmd_buf[3 + i * 8 + 1] = (val >> 8); cmd_buf[3 + i * 8 + 2] = (val >> 16); cmd_buf[3 + i * 8 + 3] = (val >> 24); cmd_buf[3 + i * 8 + 4] = ang; cmd_buf[3 + i * 8 + 5] = (ang >> 8); cmd_buf[3 + i * 8 + 6] = (ang >> 16); cmd_buf[3 + i * 8 + 7] = (ang >> 24); } { long val = 0; val = g_sw_pub.ac_in[PUB_AC_IN_F1]; cmd_buf[3 + i * 8 + 0] = val; cmd_buf[3 + i * 8 + 1] = (val >> 8); cmd_buf[3 + i * 8 + 2] = (val >> 16); cmd_buf[3 + i * 8 + 3] = (val >> 24); } cmd_len = 8 * (chn + 1); cmd_len += 3; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_BOARD_CALIBRATION: { // 板卡校准系数上传 int board; s32 factor; struct ac_slot_factor asf; board = buf[2]; cmd_buf[2] = board; if ((board >= 16) || !(g_board_info[board].type == BOARD_TYPE_AC || g_board_info[board].type == BOARD_TYPE_FUXI_AC) // 零漂 ) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_NSLOT; cmd_len = 3; break; } if (factor_read(board, &asf) != 0) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OTHER; cmd_len = 3; break; } for (i = 0; i < EQU_SLOT_AC_CHN; i++) { factor = (s32)rt_round(asf.factor_e_c[i] * Q16_BASE); // 幅值系数 cmd_buf[3 + i * 8 + 0] = factor; cmd_buf[3 + i * 8 + 1] = (factor >> 8); cmd_buf[3 + i * 8 + 2] = (factor >> 16); cmd_buf[3 + i * 8 + 3] = (factor >> 24); factor = (s32)rt_round(asf.factor_p_c[i] * Q16_BASE); // 角度系数 cmd_buf[3 + i * 8 + 4] = factor; cmd_buf[3 + i * 8 + 5] = (factor >> 8); cmd_buf[3 + i * 8 + 6] = (factor >> 16); cmd_buf[3 + i * 8 + 7] = (factor >> 24); } cmd_len = 8 * EQU_SLOT_AC_CHN; cmd_len += 3; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_DEFAULT_CALIBRATION: { // 恢复默认校准系数 // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } factor_restore_default(); log_str_time(LOG_OPERATE, "工具恢复默认校准系数", 0, 0); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; } break; case MS_SAMPLE_CALIBRATION: { // 整机采样校准 int ret; // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } ret = sw_auto_adjust(-1); switch (ret) { case 0: cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; break; case -1: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_DATAL; cmd_len = 3; break; case -2: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_CHXS; cmd_len = 3; break; case -3: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_ANGLEL; cmd_len = 3; break; case -4: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_ANGLEH; cmd_len = 3; break; case -5: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_ANGLEXS; cmd_len = 3; break; case -6: cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_XSSAVE; cmd_len = 3; break; } if (ret == 0) { log_str_time(LOG_OPERATE, "工具交流校准成功", 0, 0); } else { log_str_time(LOG_OPERATE, "工具交流校准失败", 0, 0); } } break; case MS_DEFAULT: { // 恢复出厂设置 // 检查阶段 if ((g_maintain.state != MS_REQUEST) || ((!bMaintain))) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } init_default_equip_set(1); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; log_str_time(LOG_OPERATE, "工具恢复出厂设置", 0, 0); } break; case MS_UZTEMP_MEASURE: { // 直流电压温度刷新 long val; for (i = PUB_AC_IN_UZ1; i < PUB_AC_NUM_ALL; i++) { val = g_sw_pub.ac_in[i]; if (_AbsL(val) < g_unit[g_pub_ac_desc[i].unit].zero && pRunSet->bTT_RET_ZERO) { val = 0; } cmd_buf[2 + (i - PUB_AC_IN_UZ1) * 4] = val; cmd_buf[2 + (i - PUB_AC_IN_UZ1) * 4 + 1] = (val >> 8); cmd_buf[2 + (i - PUB_AC_IN_UZ1) * 4 + 2] = (val >> 16); cmd_buf[2 + (i - PUB_AC_IN_UZ1) * 4 + 3] = (val >> 24); } cmd_len = 4 * 3; cmd_len += 3; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_ADJUST_UZL: { // 直流校准 // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } cmd_buf[2] = buf[2]; if (cmd_buf[2] == 0x01) { sw_adjust_dc_0(); } else if (cmd_buf[2] == 0x02) { sw_adjust_dc_1(); } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; log_str_time(LOG_OPERATE, "工具直流校准", 0, 0); } break; case MS_SAMPLE_TEST: { float val = 0, base_v = -1.0, base_i = -1.0; u32 check_result[2] = {0, 0}; float accuracy[6] = {0.1, -0.1, 0.2, -0.2, 0.01, -0.01}; u8 sw; // 检查电压 for (i = 0; i < PUB_AC_NUM; i++) { if (g_ui[i].chn_index == CFG_ADC_CHANNEL_ZERO) { continue; } // 确定基准 if (base_v < 0) { val = ((float)g_ui[i].e / 65536 - 100.0) / 100.0 * 100; if ((val < accuracy[0]) && (val > accuracy[1])) { base_v = 100.0; } else { val = ((float)g_ui[i].e / 65536 - 57.735) / 57.735 * 100; if ((val < accuracy[0]) && (val > accuracy[1])) { base_v = 57.735; } } } // 检查精度 val = ((float)g_ui[i].e / 65536 - base_v) / base_v * 100; if ((val > accuracy[0]) || (val < accuracy[1])) { check_result[0] |= 0x01; // 电压超精度 } } // 检查频率 val = g_sw_pub.ac_in[PUB_AC_IN_F1]; val = ((float)val / 65536 - 50.0) / 100.0 * 100; if ((val > accuracy[4]) || (val < accuracy[5])) { check_result[0] |= 0x02; // 频率超精度 } for (sw = 0; sw < g_sw_num; sw++) { float dat = 0; int cnt; // 检查电流 cnt = 0; for (i = 0; i < SW_AC_NUM; i++) { if (g_ui[UI_SW_INDEX(sw, i)].chn_index == CFG_ADC_CHANNEL_ZERO) { cnt++; continue; } // 确定基准 if (base_i < 0) { val = ((float)g_ui[UI_SW_INDEX(sw, i)].e / 65536 - 5.0) / 5.0 * 100; if ((val < accuracy[0]) && (val > accuracy[1])) { base_i = 5.0; } else { val = ((float)g_ui[UI_SW_INDEX(sw, i)].e / 65536 - 3.0) / 3.0 * 100; if ((val < accuracy[0]) && (val > accuracy[1])) { base_i = 3.0; } } rt_printf("base_i=%f.\r\n", base_i); } val = ((float)g_ui[UI_SW_INDEX(sw, i)].e / 65536 - base_i) / base_i * 100; if ((val > accuracy[0]) || (val < accuracy[1])) { // 0x01,开关电流超精度 check_result[1] |= 0x01 << (sw * 2); break; } } // 整个开关没有配置,置0x03标志 if (cnt == SW_AC_NUM) { check_result[1] |= 0x03 << (sw * 2); continue; } // 如果精度有问题,不再检测P、Q. if (i != SW_AC_NUM) { continue; } // 开始检查功率 dat = base_v * base_i * 3; if (g_ui[PUB_AC_UA1].chn_index == CFG_ADC_CHANNEL_ZERO) { // 二表法 dat /= 1.732; } // 检查P val = ((float)g_sw[sw].ac_in[SW_AC_IN_P] / 65536 - dat) / dat * 100; if ((val > accuracy[2]) || (val < accuracy[3])) { // 0x02,开关功率超精度 check_result[1] |= 0x02 << (sw * 2); } // 检查Q val = ((float)g_sw[sw].ac_in[SW_AC_IN_Q] / 65536 - 0.0) / dat * 100; if ((val > accuracy[2]) || (val < accuracy[3])) { // 0x02,开关功率超精度 check_result[1] |= 0x02 << (sw * 2); } } cmd_buf[2 + 0] = check_result[0]; cmd_buf[2 + 1] = (check_result[0] >> 8); cmd_buf[2 + 2] = (check_result[0] >> 16); cmd_buf[2 + 3] = (check_result[0] >> 24); cmd_buf[2 + 4] = check_result[1]; cmd_buf[2 + 5] = (check_result[1] >> 8); cmd_buf[2 + 6] = (check_result[1] >> 16); cmd_buf[2 + 7] = (check_result[1] >> 24); cmd_len = 10; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_KRKC_TEST: { // 开入开出自动测试 extern struct rt_stat g_stat_do_delay; extern struct rt_stat g_stat_di_delay; u8 buf_test[24]; // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } memset(buf_test, 0, sizeof(buf_test)); memcpy(buf_test, buf + 3, buf[2] * 2); dido_auto_test(buf_test, buf[2]); cmd_buf[2] = 0; if (g_stat_do_delay.max > 1000000) { cmd_buf[2] |= 0x01; } if (g_stat_di_delay.max > (5000000 + 20000000)) { cmd_buf[2] |= 0x02; } cmd_buf[3] = 0; cmd_buf[4] = 0; cmd_buf[5] = 0; cmd_buf[6] = buf[2]; memcpy(cmd_buf + 7, dido_buf, 42); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = buf[2] * 14 + 4 + 3; } break; case MS_LCD_TEST: { // LCD测试 // 检查阶段 if ((g_maintain.state != MS_REQUEST) || (!bMaintain)) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_PHASE; cmd_len = 3; break; } add_led_test(TEST_LED); add_led_test(TEST_LCD); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; } break; case MS_RESET_TEST: { // 复位 cmd_buf[2] = buf[2]; switch (cmd_buf[2]) { case 0x1: rt_printf("装置复位\r\n"); watchdog_reset_cpu(2); // 装置复位 break; case 0x2: rt_printf("子板复位\r\n"); break; case 0x4: rt_printf("应用复位\r\n"); // env_restart(); //主板复位 watchdog_reset_cpu(2); // 装置复位 break; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; } break; case MS_CFGINF: { // 配置信息查看 cmd_buf[2] = 6; sprintf(cmd_buf + 3 + 24 * 0, "装置资源文件:%04XH", g_crc_rsc); sprintf(cmd_buf + 3 + 24 * 1, "板卡资源文件:%04XH", g_crc_brd_res); sprintf(cmd_buf + 3 + 24 * 2, "通道配置文件:%04XH", g_crc_equ_cfg); sprintf(cmd_buf + 3 + 24 * 3, "转发点表文件:%04XH", g_crc_rectable); sprintf(cmd_buf + 3 + 24 * 4, "定值描述文件:%04XH", g_crc_set_desc); sprintf(cmd_buf + 3 + 24 * 5, "定值数据文件:%04XH", g_crc_set_data); cmd_len = 3 + 24 * 6; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_ERRINF: { // 故障信息查看 u8 num = 0; if (rt_err_count()) { cmd_buf[2] = rt_err_count(); for (i = 0; i < ERR_CODE_NUM; i++) { if (rt_err_test(i)) { num++; if (num > 9) { break; } sprintf(cmd_buf + 3 + (num - 1) * 20, rt_err_msg(i)); } } } else { cmd_buf[2] = 0; } cmd_len = 3 + 20 * 10; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_GETIP: { // 获取网口及对应IP int net; char ipbuf[32]; cmd_buf[2] = 0; for (net = 0; net < g_net_num; net++) { // 如果接口不正常,不初始化 if (rt_if_ip_get(net, ipbuf) != 0) { cmd_buf[3 + net * 5] = 0; continue; } cmd_buf[2] = net + 1; cmd_buf[3 + net * 5] = 1; Swap_32(ipbuf); memcpy(cmd_buf + 4 + net * 5, ipbuf, 4); } cmd_len = 3 + 5 * IEC104_TOTAL_SOCKETS; // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_GET_GPRS_INFO: { int i, num; cmd_buf[2] = buf[2]; if (cmd_buf[2] == 1) { // 发送查询子命令 IEC101_PH_GprsInfo(); cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 3; } else if (cmd_buf[2] == 2) { // 接收查询子命令1 gprs_get_info(); num = g_gprs_info_num < 10 ? g_gprs_info_num : 10; cmd_buf[3] = num; for (i = 0; i < num; i++) { strcpy(cmd_buf + 4 + i * 20, strGprsInf[i]); } cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 4 + num * 20; } else if (cmd_buf[2] == 3) { // 接收查询子命令2 num = g_gprs_info_num < 10 ? 0 : (g_gprs_info_num - 10); cmd_buf[3] = num; for (i = 0; i < num; i++) { strcpy(cmd_buf + 4 + i * 20, strGprsInf[i + 10]); } cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 4 + num * 20; } else { // 不支持的子命令 cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[3] = MAINTAIN_ERR_OTHER; cmd_len = 4; } } break; case MS_FZXS_UD: { int board; s32 factor; struct ac_slot_factor asf; cmd_buf[2] = buf[2]; board = buf[3]; cmd_buf[3] = board; if ((board >= 16) || !(g_board_info[board].type == BOARD_TYPE_AC || g_board_info[board].type == BOARD_TYPE_FUXI_AC) // 有零漂 ) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[4] = MAINTAIN_ERR_NSLOT; cmd_len = 5; break; } if (factor_read(board, &asf) != 0) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[4] = MAINTAIN_ERR_OTHER; cmd_len = 5; break; } if (cmd_buf[2] == 1) // 上传 { for (i = 0; i < EQU_SLOT_AC_CHN; i++) { factor = (s32)rt_round(asf.factor_e_c[i] * Q16_BASE); // 幅值系数 cmd_buf[4 + i * 8 + 0] = factor; cmd_buf[4 + i * 8 + 1] = (factor >> 8); cmd_buf[4 + i * 8 + 2] = (factor >> 16); cmd_buf[4 + i * 8 + 3] = (factor >> 24); factor = (s32)rt_round(asf.factor_p_c[i] * Q16_BASE); // 角度系数 cmd_buf[4 + i * 8 + 4] = factor; cmd_buf[4 + i * 8 + 5] = (factor >> 8); cmd_buf[4 + i * 8 + 6] = (factor >> 16); cmd_buf[4 + i * 8 + 7] = (factor >> 24); } cmd_len = 8 * EQU_SLOT_AC_CHN; cmd_len += 4; } else if (cmd_buf[2] == 2) // 下载 { union { float ff; u8 bb[4]; } ff; for (i = 0; i < EQU_SLOT_AC_CHN; i++) { CopySwap(ff.bb, &buf[4 + i * 8 + 0], 4, false); asf.factor_e_c[i] = ff.ff / Q16_BASE; CopySwap(ff.bb, &buf[4 + i * 8 + 4], 4, false); asf.factor_p_c[i] = ff.ff / Q16_BASE; } if (factor_write_board(board, &asf) != 0) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[4] = MAINTAIN_ERR_OTHER; cmd_len = 5; break; } cmd_len = 4; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_AC_CFG: { int i, j; cmd_buf[2] = buf[2]; for (i = 0; i < AC_TEST_BOARD_NUM; i++) { if (g_ac_test_board[i].type == cmd_buf[2]) { break; } } if (i == AC_TEST_BOARD_NUM) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[4] = MAINTAIN_ERR_NSLOT; cmd_len = 5; break; } else { char name[10]; for (j = 0; j < g_ac_test_board[i].num; j++) { strncpy(name, g_ac_test_board[i].data[j].name, 4); memcpy(&cmd_buf[3 + 8 * j + 0], name, 4); cmd_buf[3 + 8 * j + 4] = g_ac_test_board[i].data[j].normal_data; cmd_buf[3 + 8 * j + 5] = g_ac_test_board[i].data[j].normal_data >> 8; cmd_buf[3 + 8 * j + 6] = g_ac_test_board[i].data[j].normal_angle; cmd_buf[3 + 8 * j + 7] = g_ac_test_board[i].data[j].normal_angle >> 8; } } cmd_len = 8 * g_ac_test_board[i].num; cmd_len += 4; } break; case MS_DC_FACTOR: { s32 factor; u8 *p; cmd_buf[2] = buf[2]; cmd_len = 3; if (cmd_buf[2] == 1) // 上传 { for (i = 0; i < DC_NUM; i++) { factor = (s32)rt_round(g_dcfactor_save[i].dc_h * Q16_BASE); // 直流H系数 cmd_buf[3 + i * 8 + 0] = factor; cmd_buf[3 + i * 8 + 1] = (factor >> 8); cmd_buf[3 + i * 8 + 2] = (factor >> 16); cmd_buf[3 + i * 8 + 3] = (factor >> 24); factor = (s32)rt_round(g_dcfactor_save[i].dc_l * Q16_BASE); // 直流L系数 cmd_buf[3 + i * 8 + 4] = factor; cmd_buf[3 + i * 8 + 5] = (factor >> 8); cmd_buf[3 + i * 8 + 6] = (factor >> 16); cmd_buf[3 + i * 8 + 7] = (factor >> 24); } cmd_buf[3 + DC_NUM * 8 + 0] = g_dcfactor_save[0].adjust_set; cmd_buf[3 + DC_NUM * 8 + 1] = g_dcfactor_save[1].adjust_set; memcpy(&cmd_buf[3 + DC_NUM * 8 + 2], g_auth_id, 8); // 装置flash_id memcpy(&cmd_buf[3 + DC_NUM * 8 + 2 + 8], g_dcfactor_id, 8); // 存储flash_id // 上传校准温度 p = (u8 *)&g_dc_temp; cmd_buf[3 + DC_NUM * 8 + 2 + 16] = p[3]; cmd_buf[3 + DC_NUM * 8 + 2 + 17] = p[2]; cmd_buf[3 + DC_NUM * 8 + 2 + 18] = p[1]; cmd_buf[3 + DC_NUM * 8 + 2 + 19] = p[0]; cmd_len = 8 * 2 + 2 + 8 * 2 + 4; cmd_len += 3; cmd_buf[1] |= MAINTAIN_ACK; break; } else if (cmd_buf[2] == 2) // 下载 { union { float ff; u8 bb[4]; } ff; float dc_h, dc_l; u8 id[8]; struct dc_factor_save factor[2]; memcpy(factor, g_dcfactor_save, sizeof(g_dcfactor_save)); for (i = 0; i < DC_NUM; i++) { CopySwap(ff.bb, &buf[3 + i * 8 + 0], 4, false); dc_h = ff.ff / Q16_BASE; CopySwap(ff.bb, &buf[3 + i * 8 + 4], 4, false); dc_l = ff.ff / Q16_BASE; if (factor[i].dc_h != dc_h) { factor[i].dc_h = dc_h; factor[i].adjust_set = DC_SETDATA; } if (factor[i].dc_l != dc_l) { factor[i].dc_l = dc_l; factor[i].adjust_set = DC_SETDATA; } } memcpy(id, g_auth_id, 8); if (dcfactor_createfile(&id[0], (u8 *)&factor) != 0) { rt_printf("直流系数文件保存失败.\r\n"); cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[3] = MAINTAIN_ERR_OTHER; cmd_len = 4; break; } log_str_time(LOG_OPERATE, "工具直流系数修改", 0, 0); cmd_len = 3; cmd_buf[1] |= MAINTAIN_ACK; break; } else if (cmd_buf[2] == 3) // 恢复默认值 { if (dcfactor_restore_default() != 0) { rt_printf("直流系数恢复默认值失败.\r\n"); cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[3] = MAINTAIN_ERR_OTHER; cmd_len = 4; break; } cmd_len = 3; cmd_buf[1] |= MAINTAIN_ACK; break; } // 不支持的直流系数命令 rt_printf("不支持的直流系数命令:cmd_buf[2]=%d.\r\n", cmd_buf[2]); cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[3] = MAINTAIN_ERR_OTHER; break; } break; case MS_WAVE_OK: { if (rcd_check_ok(SWITCH_NUM_MAX) != 1) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OTHER; cmd_len = 3; break; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; } break; case MS_FILE_ISUPDATE: { int file_index = 0; u32 file_time = 0; u16 file_type = 0; // 复制文件名 memcpy(cmd_buf + 2, buf + 2, 20); // 检查文件名 file_index = file_check(buf + 2, ATTR_UP); if (file_index < 0) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[22] = MAINTAIN_ERR_NAME; cmd_len = 23; break; } // 获取文件当前时间 file_time = file_change_time(file_index); if ((short)file_time == -1) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[22] = MAINTAIN_ERR_NAME; cmd_len = 23; break; } // 如果是首次上传,暂存文件时间 if (buf[22]) { g_file_time[file_index].st_mtime = file_time; if (file_type == FILETYPE_LOG_APP) { file_index = log_file_check(buf + 2); g_logfile_update[file_index] = 0; } cmd_buf[22] = 0; } else { // 非首次上传,比对文件时间,并上传文件是否修改状态 cmd_buf[22] = 0; if (g_file_time[file_index].st_mtime != file_time) { cmd_buf[22] = 1; } else if (file_type == FILETYPE_LOG_APP) { file_index = log_file_check(buf + 2); if (g_logfile_update[file_index]) { cmd_buf[22] = 1; } } } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 23; } break; case MS_COMM_TEST: { u8 j; // 启动测试 uart_test_begin = 1; // 串口测试 uart_232_485_test(&buf[2]); // 停止测试 uart_test_begin = 0; memset(&cmd_buf[2], 0, 6); // RS232_1, RS232_2 cmd_buf[2] = 0x7; for (j = 0; j < 2; j++) { if (uart_test_flag[j][0]) { cmd_buf[3] |= 0x1 << j; } if (uart_test_flag[j][1]) { cmd_buf[4] |= 0x1 << j; } } cmd_buf[3] |= 0x1 << 2; // 串口3 自动满足 cmd_buf[4] |= 0x1 << 2; // RS485_1,RS485_2,RS485_3 cmd_buf[5] = 0x7; for (j = 0; j < 3; j++) { if (uart_test_flag[j + 3][0]) { cmd_buf[6] |= 0x1 << j; } if (uart_test_flag[j + 3][1]) { cmd_buf[7] |= 0x1 << j; } } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 8; } break; case MS_INSTU: { int i; u32 data; cmd_buf[2] = INSTU_NUM; for (i = 0; i < INSTU_NUM; i++) { data = *g_instu_desc[i].fstdata; cmd_buf[3 + i * 4] = data; cmd_buf[4 + i * 4] = (data >> 8); cmd_buf[5 + i * 4] = (data >> 16); cmd_buf[6 + i * 4] = (data >> 24); } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = INSTU_NUM * 4 + 3; } break; case MS_RCD_NAME: { static char name[9 * 64]; int i = 0, j; struct stat s; static int sum = 0, num = 0, cur = 0; // 首次查询 if (buf[2] == 0) { memset(name, 0, 9 * 64); // 检查文件是否存在 if (sys_newstat("/tmp/rec_wave.dat", &s) == 0) { memcpy(name, "/tmp/rec_wave.dat", strlen("/tmp/rec_wave.dat")); i = 1; } num = rcd_get_list_name(); if (num > 8) { num = 8; } for (j = 0; j < num; j++) { memcpy(&name[(i + j) * 64], "/app/data/rec_wave/", strlen("/app/data/rec_wave/")); memcpy(&name[(i + j) * 64 + strlen("/app/data/rec_wave/")], wave_name[j], 35); } if (num) { num += i; sum = num; } else { num = 0; sum = i; } cur = 0; } else { cur += 3; } // 总条数 cmd_buf[2] = sum; if (num > 3) { cmd_buf[3] = 1; memcpy(cmd_buf + 4, &name[cur * 64], 3 * 64); num -= 3; cmd_len += 3 * 64; } else { cmd_buf[3] = 0; memcpy(cmd_buf + 4, &name[cur * 64], (sum - cur) * 64); cmd_len += (sum - cur) * 64; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len += 4; } break; case MS_RMT_PAIR: { // 遥控器配对 memcpy(cmd_buf + 2, buf + 2, 2); if (cmd_buf[2]) { add_rmt_pair(RMT_PAIR); log_str_time(LOG_OPERATE, "工具遥控器配对", 0, 0); } if (cmd_buf[3]) { add_rmt_pair(RMT_CLRPAIR); log_str_time(LOG_OPERATE, "工具遥控器配对清除", 0, 0); } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 4; } break; case MS_SET_MTPWD: { // 设置密码 u8 pwd[16]; int i, check = 0, str = 0, data = 0; // 此处需将密码解密 for (i = 0; i < 16; i++) { pwd[i] = ~buf[2 + i]; } // 校验旧密码 check = memcmp(pwd, mt_pwd, 16); if (check != 0) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OCODE; cmd_len = 3; // break; } // 此处需将密码解密 for (i = 0; i < 16; i++) { pwd[i] = ~buf[18 + i]; } // 校验新密码是否符合规则 for (i = 0; i < 16; i++) { // 密码中有数字 if ((pwd[i] >= 0x30) && (pwd[i] < 0x3A)) { data = 1; } else { str = 1; } } if (!data || !str) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_NCODE; // 新密码无效 cmd_len = 3; break; } // 更新密码 memcpy(&mt_pwd, pwd, 16); // 保存加密后的新密码 _maintain_pwd_createfile(&buf[18]); log_str_time(LOG_OPERATE, "工具设置维护工具密码", 0, 0); memcpy(cmd_buf + 2, buf + 2, 32); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 34; } break; case MS_PASSWORD: // 不支持旧密码认证,直接否定确认 cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_CODE; cmd_len = 3; break; case MS_MT_PWD: { int i, check = 0; u8 pwd[16]; // 此处需将密码解密 for (i = 0; i < 16; i++) { pwd[i] = ~buf[2 + i]; } check = memcmp(pwd, mt_pwd, 16); if (check != 0) { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_CODE; cmd_len = 3; // print_mem("pwd0:",mt_pwd,16); // print_mem("pwd1:",pwd,16); break; } // 密码校验通过,打开相关的维护端口 { char log[128]; sprintf(log, "%s登录!", &buf[2 + 16]); log_str_time(LOG_OPERATE, log, 0, 0); rt_printf("%s\r\n", log); } if (g_mt_rs232 == 0) { net_debug_init(); open_inet_port(); } memcpy(cmd_buf + 2, buf + 2, 16); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 18; } break; case MS_CLOSE_PORT: { // 关闭端口服务,仅保留6008维护端口 net_debug_exit(); close_inet_port(); rt_printf("网络维护端口关闭.\r\n"); // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; } break; case MS_AUTH: { cmd_buf[2] = buf[2]; // 上传ID if (cmd_buf[2] == 1) { auth_get_encrypt_id(&cmd_buf[3], 32); print_mem(" id:", &cmd_buf[3], 24); cmd_len = 3 + 32; } // 下载license else if (cmd_buf[2] == 2) { auth_save(&buf[3], AUTH_LICENSE_LEN); cmd_len = 3; } // 从授权机获取授权 else if (cmd_buf[2] == 3) { int ret; ret = auth_license(&buf[3], (struct rtc_time_t *)&buf[3 + 32], &cmd_buf[3]); if (ret != 0) { rt_printf("auth_license error:ret=%d.\r\n", ret); cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OTHER; cmd_len = 3; break; } cmd_len = 3 + AUTH_LICENSE_LEN; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_YD_REFRESH: { u16 begin, num; // 将子命令和开始值复制到返回命令中 memcpy(&cmd_buf[2], &buf[2], 3); // 得到开始值和个数 Swap_16_memcpy((BYTE *)&begin, &buf[3]); // modify for am335x xxxxxx Swap_16_memcpy((BYTE *)&num, &buf[5]); // modify for am335x xxxxxx // 遥信 if (cmd_buf[2] == 1) { num = tbl_yd_yx(begin, num, cmd_buf + 7); if (num > 0) { Swap_16_memcpy(&cmd_buf[5], (BYTE *)&num); // modify for am335x xxxxxx cmd_len = 3 + 4 + (num + 3) / 4; } else { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OTHER; cmd_len = 3; break; } } // 遥测 else if (cmd_buf[2] == 2) { num = tbl_yd_yc(begin, num, cmd_buf + 7); if (num > 0) { Swap_16_memcpy(&cmd_buf[5], (BYTE *)&num); // modify for am335x xxxxxx cmd_len = 3 + 4 + num * 9; } else { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OTHER; cmd_len = 3; break; } } // 电度 else if (cmd_buf[2] == 3) { num = tbl_yd_dd(begin, num, cmd_buf + 7); if (num > 0) { Swap_16_memcpy(&cmd_buf[5], (BYTE *)&num); // modify for am335x xxxxxx cmd_len = 3 + 4 + num * 9; } else { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OTHER; cmd_len = 3; break; } } else { cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_OTHER; cmd_len = 3; break; } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; case MS_FACTORY_SETUP: { u8 mac[6]; cmd_buf[2] = buf[2]; // 装置ID码 if (buf[2] == 1) { if (strlen(&buf[3]) == 24) { env_setenv("pid", &buf[3]); rt_printf("pid=%s\r\n", &buf[3]); cmd_len = 3; } else { cmd_buf[3] = MAINTAIN_ERR_FORMAT; cmd_len = 4; cmd_buf[1] |= MAINTAIN_NAK; break; } } // 网络1MAC else if (buf[2] == 2) { if (rt_if_sz2mac(&buf[3], mac) == 0) { env_setenv("net1mac", &buf[3]); rt_printf("net1mac=%s\r\n", &buf[3]); cmd_len = 3; } else { cmd_buf[3] = MAINTAIN_ERR_FORMAT; cmd_len = 4; cmd_buf[1] |= MAINTAIN_NAK; break; } } // 网络2MAC else if (buf[2] == 3) { if (rt_if_sz2mac(&buf[3], mac) == 0) { env_setenv("net2mac", &buf[3]); rt_printf("net2mac=%s\r\n", &buf[3]); cmd_len = 3; } else { cmd_buf[3] = MAINTAIN_ERR_FORMAT; cmd_len = 4; cmd_buf[1] |= MAINTAIN_NAK; break; } } // 发送ACK cmd_buf[1] |= MAINTAIN_ACK; } break; #if defined(CPU_AM335X) case MS_APP_BAK_START: rt_printf("maintain: 启动app分区备份.\r\n"); // 下面备份工作需要大约5秒,耗时有点长,先喂狗 watchdog_feed_mainloop(); // 1. 删除临时文件/tmp/backup_flag rt_file_del("/tmp/backup_flag"); // 2. 调用启动备份脚本(函数) call_usermodehelper("/usr/sbin/app_backup.sh", cmd_ls, NULL, UMH_WAIT_PROC); watchdog_feed_mainloop(); // 3. 回复 cmd_buf[1] |= MAINTAIN_ACK; cmd_len = 2; break; case MS_APP_BAK_RESULT: // 1. 检测临时文件/tmp/backup_flag是否存在? // 打开文件 pfile = rt_file_open("/tmp/backup_flag", O_RDONLY, 0); if (IS_ERR(pfile)) { rt_printf("maintain: 临时文件/tmp/backup_flag不存在.\r\n"); // 1.1 不存在 cmd_buf[1] |= MAINTAIN_ACK; cmd_buf[2] = 2; // 备份中 cmd_len = 3; break; } // 得到文件长度 rt_file_llseek(pfile, 0, SEEK_END); llen = pfile->f_pos; rt_file_llseek(pfile, 0, SEEK_SET); // 分配内存 lbuf = rt_malloc(llen); if ((lbuf) == NULL) { rt_file_close(pfile, 0); break; } // 读出内容 pos = 0; if (rt_file_read(pfile, lbuf, llen, &pos) != llen) { rt_file_close(pfile, 0); rt_free(lbuf); break; } // 关闭文件 rt_file_close(pfile, 0); result = lbuf[0]; rt_free(lbuf); // 1.2 存在 if (result == '1') { rt_printf("maintain: app分区备份成功.\r\n"); // 2 读取文件/tmp/backup_flag内容,成功值是1,备份失败值是 0 // 成功 cmd_buf[1] |= MAINTAIN_ACK; cmd_buf[2] = 1; // 成功 cmd_len = 3; } else { rt_printf("maintain: app分区备份失败.\r\n"); // 失败 cmd_buf[1] |= MAINTAIN_ACK; cmd_buf[2] = 0; // 失败 cmd_len = 3; } break; #endif default: rt_printf("Maintain_Manage:不支持的命令(%d)\r\n", buf[1]); _maintain_state_reset(); cmd_buf[1] |= MAINTAIN_NAK; cmd_buf[2] = MAINTAIN_ERR_CMD; cmd_len = 3; break; } return cmd_len; } void Maintain_uart_send(void) { struct maintain_def *pt = &g_mtbuf; int len; u8 buf_tx[256]; memset(buf_tx, 0, sizeof(buf_tx)); pt->bData = false; len = pt->recvbuf[1] + 6; // 68 L L 68 + data + crc + END memcpy(buf_tx, pt->recvbuf, len - 1); buf_tx[len] = 0x80; buf_tx[len] |= (PDA_BOARD << 3); buf_tx[len] |= MAIN_BOARD; Add_Uart_Frame(PDA_BOARD, len, buf_tx); } void Maintain_Board_Recv(int len, BYTE *para) { struct maintain_def *pt = &g_mtbuf; if (pt->bData) { _maintain_recv_rst(pt); return; } pt->nRecvLenth = len; memcpy(pt->recvbuf, para, len); pt->bData = true; pt->hmi_mode = true; // print_mem("PCRX:",g_mtbuf.recvbuf,len); mainloop_wakeup(); } /************************************************************************** 函数名称:_maintain_recv 函数版本:1.00 作者: 创建日期:2013.03.29 函数功能说明:6008端口数据接受判断,只判断是否满足报文格式 输入参数: 输出参数:有完整帧接受,返回1,否则返回 0 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ void Maintain_Recv(u8 byRevData) { struct maintain_def *pt = &g_mtbuf; pt->recvbuf[pt->nRecvCounter++] = byRevData; // pt->dTRecvPiece=dTCounter; //接收字符时的时刻,在大循环中判断,是否需要复归 switch (pt->nTypeCounter) { case 0: if (byRevData == 0x68) { pt->nTypeCounter = 1; } else if (byRevData == 0x10) { pt->nTypeCounter = 4; pt->nRecvLenth = 2; } else { _maintain_recv_rst(pt); } break; case 1: pt->nTypeCounter = 2; pt->nRecvLenth = byRevData; // 长帧长度 if (pt->nRecvLenth > IEC101_RECVBUF_MAX) { _maintain_recv_rst(pt); } break; case 2: if (pt->nRecvLenth == byRevData) { pt->nTypeCounter = 3; } else { _maintain_recv_rst(pt); } break; case 3: if (byRevData == 0x68) { pt->nTypeCounter = 4; } else { _maintain_recv_rst(pt); } break; case 4: // 控制域 pt->sum = byRevData; pt->nTypeCounter = 5; break; case 5: // 目标地址 pt->sum += byRevData; pt->nRecvCnt = 0; pt->nTypeCounter = 6; if (pt->nRecvLenth == 2) // 短帧 pt->nTypeCounter = 7; break; case 6: // 有效数据 //有效数据 if (++pt->nRecvCnt >= pt->nRecvLenth - 2) { pt->nTypeCounter = 7; } pt->sum += byRevData; break; case 7: // 校验和 pt->recvsum = byRevData; pt->nTypeCounter = 8; break; case 8: // 结束符 _maintain_recv_rst(pt); if (byRevData == 0x16) // 校验结束字符,报文接收完毕, { if (pt->sum != pt->recvsum) { return; } else { pt->bData = true; // 唤醒主循环 mainloop_wakeup(); } return; } break; default: _maintain_recv_rst(pt); break; } // 类型校验结束 return; } /****************************************************************************** 函数名称: filelist_getlen 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2015-2-13 函数说明: 获取文件列表长度 参数说明: fname:文件列表名 返回值: 文件列表长度 修改记录: */ static unsigned int filelist_getlen(struct file_item *file_list) { int len = 0; int i = 0; int fd = 0; char file_name[64]; // 遍历文件列表 for (i = 0; i < FILE_LIST_NUM; i++) { memset(file_name, 0, 64); // 组合文件路径和文件名 sprintf(file_name, "%s%s", file_list[i].file_dir, file_list[i].file_name); // 打开文件 fd = sys_open(file_name, O_RDONLY, 0); // 打不开表示文件不存在 if (fd < 0) continue; // 计算长度 len += strlen(file_name) + 2; // 关闭文件 sys_close(fd); } return len; } /****************************************************************************** 函数名称: filelist_memcpy 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2015-2-13 函数说明: 拷贝文件列表内容到目的地址 参数说明: dst: 目的地址 fname:文件列表名 返回值: 文件列表长度 修改记录: */ static void filelist_memcpy(char *dst, struct file_item *file_list) { int len = 0; int i = 0; int fd = 0; char file_name[64]; // 遍历文件列表 for (i = 0; i < FILE_LIST_NUM; i++) { memset(file_name, 0, 64); // 组合文件路径和文件名 sprintf(file_name, "%s%s", file_list[i].file_dir, file_list[i].file_name); // 在系统中打开对应文件 fd = sys_open(file_name, O_RDONLY, 0); // 打不开表示文件不存在 if (fd < 0) continue; // 如果文件不需要放入文件列表,关闭文件并退出 if ((file_list[i].file_attr & ATTR_UP) == 0) { sys_close(fd); continue; } if ((strcmp(file_name, file_list[i].file_dir) == 0) && (strlen(file_name) == strlen(file_list[i].file_dir))) { continue; } // 文件名拷贝,并添加回车 len = strlen(file_name); memcpy(dst, file_name, len); dst = dst + len; memcpy(dst, "\r\n", 2); dst = dst + 2; // 关闭文件 sys_close(fd); } } /****************************************************************************** 函数名称: filelist_createfile 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2015-10-23 函数说明: 创建文件列表 参数说明: 无 返回值: 成功返回0. 修改记录: */ int filelist_createfile(void) { unsigned int addr, file_length; u16 crc; char *p; loff_t pos; struct file *pfile; struct cfg_file_head filelist_file; // 写文件头 memset(&filelist_file, 0, sizeof(filelist_file)); filelist_file.signature = SIG_FILELIST_FILE; filelist_file.version = FILELIST_FILE_VERSION; addr = FILE_ADDR_ALGIN(sizeof(filelist_file)); // 得到文件长度 file_length = addr + filelist_getlen(g_file_item); file_length = FILE_ADDR_ALGIN(file_length); // 分配并初始化空间 p = rt_malloc(file_length + 2); if (!p) { return -1; } memset(p, 0, file_length + 2); // 写入文件头 memcpy(p, (char *)&filelist_file, sizeof(filelist_file)); // 写文件列表 filelist_memcpy(p + addr, g_file_item); // 计算CRC crc = CrcStr(p, file_length); memcpy(p + file_length, &crc, 2); // 创建数据文件 pfile = rt_file_open("/tmp/file_list.bin", O_CREAT | O_RDWR, 0); if (IS_ERR(pfile)) { rt_free(p); return -2; } pos = 0; rt_file_write(pfile, p, file_length + 2, &pos); rt_file_close(pfile, 0); rt_free(p); return 0; } /*------------------------------ 内部函数 ------------------------------------- 内部函数以下划线‘_’开头,不需要检查参数的合法性. */ static void _maintain_state_reset(void) { g_maintain.state = MS_IDLE; } static void _maintain_echo(struct maintain_def *pt, u8 *cmd_buf, u8 cmd_len) // 确认帧 { u8 cnt, checksum, len; u8 *p; p = pt->sendbuf; // 101规约len域的值 +4=控制域、地址 、类型标识 、 文件命令 len = cmd_len + 2; // 报文帧长度 +6=报文头(4字节)校验和、结束符 p[0] = len + 6; // 帧头 p[1] = 0x68; // 报文头 p[2] = len; p[3] = len; p[4] = 0x68; p[5] = IEC101_ECHO_DATA; // 控制域 p[6] = 0x01; // 链路地址 // 命令 p = &pt->sendbuf[7]; // 调整位置 memcpy(p, cmd_buf, cmd_len); // 计算检验和 p = &pt->sendbuf[5]; checksum = 0; for (cnt = 0; cnt < len; cnt++) { checksum += *p++; } *p++ = checksum; // 帧尾 if (pt->hmi_mode) { *p++ = 0x80 | (MAIN_BOARD << 3) | MAINTAIN_BOARD; } else { *p++ = 0x16; } } /************************************************************************** 函数名称:IEC101_Recv_Rst 函数版本:1.00 作者: 创建日期:2008.9.1 函数功能说明:复归数据的接受 输入参数: 输出参数: 返回值: 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static void _maintain_recv_rst(struct maintain_def *pt) { pt->nTypeCounter = 0; pt->nRecvLenth = 0; pt->nRecvCounter = 0; } static int _maintain_comm(struct maintain_def *pt, u8 *buf, int len) { static u8 cmd_buf[256]; u8 cmd_len; g_mt_rs232 = 0; memset(cmd_buf, 0, sizeof(cmd_buf)); cmd_len = Maintain_Manage(buf, len, &cmd_buf[0]); // 按内部101格式组帧 _maintain_echo(pt, &cmd_buf[0], cmd_len); g_mtbuf.bSend = true; return 0; } static int _trans_file_comm(struct maintain_def *pt, u8 *buf, int len) { static u8 cmd_buf[256] = {0}; u8 cmd_len; cmd_len = com_trans_file(buf, len, &cmd_buf[0]); // 按内部101格式组帧 _maintain_echo(pt, &cmd_buf[0], cmd_len); g_mtbuf.bSend = true; return 0; } /************************************************************************** 函数名称:_maintain_Send 函数版本:1.00 作者: 创建日期:2013.03.28 函数功能说明:启动数据发送 输入参数: 输出参数:无 返回值: 函数扇入清单: ***************************************************************************/ static void _maintain_send(void) { u8 length; length = g_mtbuf.sendbuf[0]; if (g_mtbuf.bSend) { // print_mem("PCTX:",&g_mtbuf.sendbuf[1],length); if (!g_mtbuf.hmi_mode) { if (net_maintain_send(&g_mtbuf.sendbuf[1], length)) { g_mtbuf.bSend = FALSE; } } else { Add_Uart_Frame(PDA_BOARD, (int)g_mtbuf.sendbuf[0], &g_mtbuf.sendbuf[1]); g_mtbuf.bSend = FALSE; } } } /****************************************************************************** 函数名称: _maintain_pwd_createfile 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2015-10-23 函数说明: 创建直流系数文件 参数说明: 无 返回值: 成功返回0. 修改记录: */ static int _maintain_pwd_createfile(u8 *pwd) { unsigned int addr, file_length; u16 crc; char *p; loff_t pos; struct file *pfile; struct mtpwd_file_head_data mtpwd_file; // 写文件头 memset(&mtpwd_file, 0, sizeof(mtpwd_file)); mtpwd_file.cfh.signature = SIG_MTPWD_FILE; mtpwd_file.cfh.version = MTPWD_FILE_VERSION; memcpy(&mtpwd_file.pwd, pwd, 16); // 得到文件长度 addr = FILE_ADDR_ALGIN(sizeof(mtpwd_file)); file_length = FILE_ADDR_ALGIN(addr); // 分配并初始化空间 p = rt_malloc(file_length + 2); if (!p) { return -1; } memset(p, 0, file_length + 2); // 写入文件头 memcpy(p, (char *)&mtpwd_file, sizeof(mtpwd_file)); // 计算CRC crc = CrcStr(p, file_length); memcpy(p + file_length, &crc, 2); // 创建数据文件 pfile = rt_file_open("/app/data/mt_pwd.bin", O_CREAT | O_RDWR, 0); if (IS_ERR(pfile)) { rt_free(p); return -2; } pos = 0; rt_file_write(pfile, p, file_length + 2, &pos); rt_file_close(pfile, 0); rt_free(p); return 0; } /****************************************************************************** 函数名称: _maintain_pwd_readfile 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2015-10-23 函数说明: 读取直流系数文件 参数说明: 无 返回值: 成功返回0. 修改记录: */ static int _maintain_pwd_readfile(void) { u32 len; u16 crc; u8 *buf; loff_t pos; struct file *pfile; u8 i, pwd[16]; struct mtpwd_file_head_data *brh; // 创建并打开文件 pfile = rt_file_open("/app/data/mt_pwd.bin", O_RDWR, 0); if (IS_ERR(pfile)) { return -1; } // 得到文件长度 len = rt_file_getfile_size(pfile); if (len <= 0) { rt_file_close(pfile, 0); return -11; } // 分配内存 buf = rt_malloc(len); if ((buf) == NULL) { rt_file_close(pfile, 0); return -2; } // 读出内容 pos = 0; if (rt_file_read(pfile, buf, len, &pos) != len) { rt_file_close(pfile, 0); rt_free(buf); return -3; } // 关闭文件 rt_file_close(pfile, 0); // 检查CRC crc = CrcStr(buf, len - 2); if (crc != *(u16 *)(buf + len - 2)) { rt_free(buf); return -4; } // 检查文件签名 brh = (struct mtpwd_file_head_data *)buf; if (brh->cfh.signature != SIG_MTPWD_FILE) { rt_free(buf); return -5; } // 检查文件长度 if (len < sizeof(*brh) + 2) { rt_free(buf); return -7; } // 取出文件中存储内容 memcpy(&pwd, brh->pwd, 16); // 此处需将密码解密 for (i = 0; i < 16; i++) { mt_pwd[i] = ~pwd[i]; } rt_free(buf); return 0; } /*------------------------------ 测试函数 ------------------------------------- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数). */ int printf_maintian(void) { return 0; } /*------------------------------ 文件结束 ------------------------------------- */