/****************************************************************************** 版权所有: 文件名称: sys_api.c 文件版本: 01.01 创建作者: xxxxxx 创建日期: 2022-09o 功能说明: 系统接口 其它说明: 修改记录: *******************************************************************************/ #include "head.h" extern int timespec_to_rtchms(struct timespec ts, struct rtc_time_t *p_rtc, int is_round); /*********************************************************************** 函数名称:parseEnvInfo 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-10-31 函数说明:解析环境变量信息 参数说明:*env_buf:环境变量buf首地址 type_char:环境变量类型字符 *ver:解析环境变量信息得到的版本信息首地址 返 回 值:true:解析成功 false:解析失败 ***********************************************************************/ static bool parseEnvInfo(char *env_buf, char type_char, VERSION *ver) { u8 dat; bool ret = false; int i, str_len, tab = 0; str_len = strlen(env_buf); for (i = 0; i < str_len; i++) { if (env_buf[i] == type_char) { tab = i; } else if (env_buf[i] == 'V' && i == (tab + 1)) { tab = i; ret = true; continue; } if (!ret) continue; if (i == (tab + 1)) { dat = atoi(&env_buf[i]); } if (env_buf[i] == '.') { if (dat) { ver->majorVer = dat; tab = i; } } else if (ver->majorVer && dat) { ver->minorVer = dat; break; } } return ret; } /*********************************************************************** 函数名称:GetUBootVer 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-09-30 函数说明:获取U-Boot版本号 参数说明:none 返 回 值:版本号对象的首地址 NULL:为获取失败 ***********************************************************************/ VERSION *GetUBootVer(void) { char *pboot; bool ret = false; const char uboot_char = 'U'; static VERSION g_uBootVer = {0}; pboot = env_get_info(ENV_U_BOOT); if (pboot == NULL) { rt_printf("warning:Get system u-boot version failure!\r\n"); return NULL; } ret = parseEnvInfo(pboot, uboot_char, &g_uBootVer); if (!ret) { rt_printf("warning:Get system u-boot version failure!\r\n"); return NULL; } if (!g_uBootVer.minorVer && !g_uBootVer.majorVer) { rt_printf("warning:Get system u-boot version failure!\r\n"); return NULL; } rt_printf("Current system u-boot version number:V%02d.%03d\r\n", g_uBootVer.majorVer, g_uBootVer.minorVer); return &g_uBootVer; } /*********************************************************************** 函数名称:GetKernelVer 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-09-30 函数说明:获取内核版本号 参数说明:none 返 回 值:版本号对象的首地址 NULL:为获取失败 ***********************************************************************/ VERSION *GetKernelVer(void) { char *pker; bool ret = false; const char kernel_char = 'K'; static VERSION g_kernelVer = {0}; pker = env_get_info(ENV_KERNEL); if (pker == NULL) { rt_printf("warning:Get system kernel version failure!\r\n"); return NULL; } ret = parseEnvInfo(pker, kernel_char, &g_kernelVer); if (!ret) { rt_printf("warning:Get system kernel version failure!\r\n"); return NULL; } if (!g_kernelVer.minorVer && !g_kernelVer.majorVer) { rt_printf("warning:Get system kernel version failure!\r\n"); return NULL; } rt_printf("Current system kernel version number:V%02d.%03d\r\n", g_kernelVer.majorVer, g_kernelVer.minorVer); return &g_kernelVer; } /*********************************************************************** 函数名称:GetRootFileSysVer 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-10-31 函数说明:获取文件系统版本号 参数说明:none 返 回 值:版本号对象的首地址 NULL:为获取失败 ***********************************************************************/ VERSION *GetRootFileSysVer(void) { char *proot; bool ret = false; const char file_sys_char = 'R'; static VERSION g_fileSysVer = {0}; proot = env_get_info(ENV_ROOT_FS); if (proot == NULL) { rt_printf("warning:Get system file system version failure!\r\n"); return NULL; } ret = parseEnvInfo(proot, file_sys_char, &g_fileSysVer); if (!ret) { rt_printf("warning:Get system file system version failure!\r\n"); return NULL; } if (!g_fileSysVer.minorVer && !g_fileSysVer.majorVer) { rt_printf("warning:Get system file system version failure!\r\n"); return NULL; } rt_printf("Current system file system version number:V%02d.%03d\r\n", g_fileSysVer.majorVer, g_fileSysVer.minorVer); return &g_fileSysVer; } /*********************************************************************** 函数名称:CheckSysProgramVer 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-09-30 函数说明:检查系统程序版本 参数说明:none 返 回 值:0:版本号合法 非0:版本号非法 ***********************************************************************/ int CheckSysProgramVer(void) { int ver_num; // 版本号 VERSION *ver; ver = GetUBootVer(); if (ver == NULL) return -1; ver_num = ver->majorVer * 256 + ver->minorVer; if (ver_num < UBOOT_VER_BASE) { rt_printf("warning:Current system u-boot version is low, please upgrade for the u-boot to version higher than or equal V01.%03d\r\n", UBOOT_VER_BASE % 256); return -2; } ver = GetKernelVer(); if (ver == NULL) return -3; ver_num = ver->majorVer * 256 + ver->minorVer; if (ver_num < KERNEL_VER_BASE) { rt_printf("warning:Current system kernel version is low, please upgrade for the kernel to version higher than or equal V01.%03d\r\n", KERNEL_VER_BASE % 256); return -4; } ver = GetRootFileSysVer(); if (ver == NULL) return -5; ver_num = ver->majorVer * 256 + ver->minorVer; if (ver_num < ROOT_FILE_SYS_VER_BASE) { rt_printf("warning:Current system file system version is low, please upgrade for the file system to version higher than or equal V01.%03d\r\n", ROOT_FILE_SYS_VER_BASE % 256); return -6; } return 0; } /*********************************************************************** 函数名称:find_par_cval_param 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-09 函数说明:查找遥参参数 参数说明:addr:遥参地址 返 回 值: 遥参参数实体首地址(获取失败返回NULL指针) ***********************************************************************/ static SET_PARAID *find_par_cval_param(WORD addr) { int i; SET_PARAID *pt; for (i = 0; i < ParaIDNum; i++) { pt = &tParaID[i]; if (pt->parId != addr) continue; return pt; } return NULL; } /*********************************************************************** 函数名称:set_par_value 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-09 函数说明:修改遥参值 参数说明:addr:遥参地址 value:写入的值 返 回 值: 0:修改成功 非0:修改失败 ***********************************************************************/ int set_par_value(WORD addr, float value) { const SET_PARAID *pt; SET_VALUE *psetbuf, *pparabuf, *pcstbuf; pt = find_par_cval_param(addr); if (pt == NULL) { rt_printf("%s:地址0x%x在遥参点表里查找失败!\r\n", __func__, addr); return -1; } switch (pt->group_type) { case SETGROUP_TYPE_BH: case SETGROUP_TYPE_PUB: psetbuf = rt_malloc(SET_NUMBER * 4); if (!psetbuf) { return -2; } if (!ReadSet(m_runsection, (void *)psetbuf)) // 读定值 { GetDefSet((float *)psetbuf); } if (pt->group_type == SETGROUP_TYPE_PUB) { psetbuf[pt->setno].ff = value; } else { psetbuf[PUB_SET_NUMBER + pt->setno].ff = value; } if (SaveSet(m_runsection, (void *)psetbuf)) { soe_record_opt(EV_SET_OK, 0); MakeRunSet(false); rt_err_clr(ERR_CODE_SET, 0); } else { soe_record_opt(EV_SET_FAIL, 0); } rt_free(psetbuf); break; case SETGROUP_TYPE_PARA: pparabuf = rt_malloc(EQUIP_PARA_NUMBER * 4); if (!pparabuf) { return -3; } if (!ReadPara((void *)pparabuf, EEP_EQUIP_PARA_ADDR, EQUIP_PARA_NUMBER, &tEquipParaTable[0])) { GetDefPara((void *)pparabuf, EQUIP_PARA_NUMBER, &tEquipParaTable[0]); } if (tEquipParaTable[pt->setno].wType == SETTYPE_IP) pparabuf[pt->setno].tt = (DWORD)value; else pparabuf[pt->setno].ff = value; if (SavePara((void *)pparabuf, EEP_EQUIP_PARA_ADDR, EQUIP_PARA_NUMBER, &tEquipParaTable[0])) { soe_record_opt(EV_EQUPARA_OK, 0); MakeRunPara(false, false); rt_err_clr(ERR_CODE_EQU_PARA, 0); } else { soe_record_opt(EV_EQUPARA_FAIL, 0); } rt_free(pparabuf); break; case SETGROUP_TYPE_CSTSET: pcstbuf = rt_malloc(CSTSET_NUMBER * 4); if (!pcstbuf) { return -4; } if (!ReadPara((void *)pcstbuf, EEP_CSTSET_ADDR, CSTSET_NUMBER, &tCstSetTable[0])) { GetDefPara((void *)pcstbuf, CSTSET_NUMBER, &tCstSetTable[0]); } pcstbuf[pt->setno].ff = value; if (SavePara((void *)pcstbuf, EEP_CSTSET_ADDR, CSTSET_NUMBER, &tCstSetTable[0])) { soe_record_opt(EV_CSTSET_OK, 0); MakeRunSet(false); rt_err_clr(ERR_CODE_SET_IN, 0); } else { soe_record_opt(EV_CSTSET_FAIL, 0); } rt_free(pcstbuf); break; default: return -5; } return 0; } /*********************************************************************** 函数名称:get_par_nane 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-09 函数说明:获取遥参描述 参数说明:addr:遥参的地址 返 回 值: 获取的遥参描述首地址(获取失败返回NULL指针) ***********************************************************************/ char *get_par_nane(WORD addr) { char *name = NULL; const SET_PARAID *pt = find_par_cval_param(addr); if (pt == NULL) { rt_printf("%s:地址0x%x在遥参点表里查找失败!\r\n", __func__, addr); return NULL; } switch (pt->group_type) { case SETGROUP_TYPE_BH: name = (char *)tSwSetTable[pt->setno].szName; break; case SETGROUP_TYPE_PUB: name = (char *)tPubSetTable[pt->setno].szName; break; case SETGROUP_TYPE_PARA: name = (char *)tEquipParaTable[pt->setno].szName; break; case SETGROUP_TYPE_CSTSET: name = (char *)tCstSetTable[pt->setno].szName; break; default: break; } return name; } /*********************************************************************** 函数名称:get_par_nane 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-09 函数说明:获取遥参描述 参数说明:addr:遥参的地址 返 回 值: 获取的遥参描述首地址(获取失败返回NULL指针) ***********************************************************************/ int get_par_value_str(WORD addr, char *buf, const int buf_len) { int str_len; DWORD u32_val; SET_VALUE tmp_val; const SET_PARAID *pt; char tmp_buf[128] = {0}; const TSETTABLE *table; struct timespec ts = {0}; struct rtc_time_t time = {0}; SET_VALUE *psetbuf, *pparabuf, *pcstbuf; if (buf == NULL) return -1; pt = find_par_cval_param(addr); if (pt == NULL) { rt_printf("%s:地址0x%x在遥参点表里查找失败!\r\n", __func__, addr); return -2; } switch (pt->group_type) { case SETGROUP_TYPE_BH: case SETGROUP_TYPE_PUB: psetbuf = rt_malloc(SET_NUMBER * 4); if (!psetbuf) { return -3; } if (!ReadSet(m_runsection, (void *)psetbuf)) { GetDefSet((float *)psetbuf); } if (pt->group_type == SETGROUP_TYPE_PUB) { table = &tPubSetTable[pt->setno]; tmp_val.ff = psetbuf[pt->setno].ff; } else { table = &tSwSetTable[pt->setno]; tmp_val.ff = psetbuf[PUB_SET_NUMBER + pt->setno].ff; } rt_free(psetbuf); break; case SETGROUP_TYPE_PARA: pparabuf = rt_malloc(EQUIP_PARA_NUMBER * 4); if (!pparabuf) { return -4; } if (!ReadPara((void *)pparabuf, EEP_EQUIP_PARA_ADDR, EQUIP_PARA_NUMBER, &tEquipParaTable[0])) { GetDefPara((void *)pparabuf, EQUIP_PARA_NUMBER, &tEquipParaTable[0]); } table = &tEquipParaTable[pt->setno]; tmp_val.ff = pparabuf[pt->setno].ff; rt_free(pparabuf); break; case SETGROUP_TYPE_CSTSET: pcstbuf = rt_malloc(CSTSET_NUMBER * 4); if (!pcstbuf) { return -5; } if (!ReadPara((void *)pcstbuf, EEP_CSTSET_ADDR, CSTSET_NUMBER, &tCstSetTable[0])) { GetDefPara((void *)pcstbuf, CSTSET_NUMBER, &tCstSetTable[0]); } table = &tCstSetTable[pt->setno]; tmp_val.ff = pcstbuf[pt->setno].ff; rt_free(pcstbuf); break; default: return -6; } u32_val = (DWORD)tmp_val.ff; switch (table->wType) { case SETTYPE_LIST: str_len = sprintf(tmp_buf, "%s", table->list[u32_val].str); break; case SETTYPE_IP: str_len = sprintf(tmp_buf, "%d.%d.%d.%d", (tmp_val.tt >> 24) & 0xFF, (tmp_val.tt >> 16) & 0xFF, (tmp_val.tt >> 8) & 0xFF, tmp_val.tt & 0xFF); break; case SETTYPE_YMD: ts.tv_sec = tmp_val.tt; timespec_to_rtc(ts, &time, 1); str_len = sprintf(tmp_buf, "%04d-%02d-%02d", 2000 + time.year, time.month, time.day); break; case SETTYPE_HMS: ts.tv_sec = tmp_val.tt; timespec_to_rtchms(ts, &time, 1); str_len = sprintf(tmp_buf, "%02d:%02d:%02d", time.hour, time.min, time.ms % 1000); break; default: str_len = sprintf(tmp_buf, "%.3f", tmp_val.ff); strcat(tmp_buf, SetUints[table->wUnit]); str_len += strlen(SetUints[table->wUnit]); break; } if (str_len > buf_len) { str_len = buf_len; } memcpy(buf, tmp_buf, str_len); return str_len; } /*********************************************************************** 函数名称:get_plc_yx_nane 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-09 函数说明:获取遥信描述 参数说明:addr:遥信地址 *buf:缓存遥信描述的首地址 buf_len:缓存区的字节数 返 回 值: 获取遥信描述的长度 ***********************************************************************/ int get_plc_yx_nane(WORD addr, char *buf, const int buf_len) { int index; int name_len; char name[128] = {0}; if (buf == NULL) return 0; index = tbl_cp2index(addr); if (index < 0) { return 0; } tbl_getname(RES_TYPE_YX, index, name); name_len = strlen(name); if (name_len > buf_len) { name_len = buf_len; } memcpy(buf, name, name_len); return name_len; } /*********************************************************************** 函数名称:get_plc_yx_val 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-09 函数说明:获取遥信值 参数说明:addr:遥信地址 返 回 值: 获取遥信的遥信值(正常值:0、1、2 其他:获取失败) ***********************************************************************/ int get_plc_yx_val(WORD addr) { int val, index; index = tbl_cp2index(addr); if (index < 0) return -1; val = tbl_get_yx(index, 0); return val; } /*********************************************************************** 函数名称:set_plc_yk 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-09 函数说明:控制遥控开出 参数说明:addr:遥控地址 cmd:命令码 1:合 0:分 返 回 值: 0:遥控成功 非0:遥控失败 ***********************************************************************/ int set_plc_yk(WORD addr, int cmd) { int i, ret; int yk_cmd; for (i = 0; i < g_table_head->do_num; i++) { if (addr != g_do_table[i].cp) { continue; } if (cmd == 0) { yk_cmd = YK_VAL_TZ; } else if (cmd == 1) { yk_cmd = YK_VAL_HZ; } else { return -1; // 遥控命令码错误 } ret = RemoteCtrl(YK_TYPE_SEL, i, yk_cmd, MASTER_MAINTAIN); // 预置 if (ret == 0) return RemoteCtrl(YK_TYPE_EXE, i, yk_cmd, MASTER_MAINTAIN); // 执行 else return ret; } return -255; // 遥控地址错误 } /*********************************************************************** 函数名称:get_led_name 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-10 函数说明:获取LED描述 参数说明:slot:板卡号 addr:LED地址 返 回 值: led描述的长度 0:失败 ***********************************************************************/ char *get_led_name(int slot, int addr) { char *name; struct led_config *pt; if (slot >= EQU_SLOT_NUM_MAX) return NULL; pt = &g_led_slot[slot]; if (addr >= pt->num || pt->sn[addr].no == LED_NULL) return NULL; if (pt->sn[addr].sw) // 开关的 { int index = pt->sn[addr].no % SW_LED_NUM; name = (char *)g_sw_led_name[index]; } else // 公共的 { if (pt->sn[addr].no >= PUB_LED_NUM) return NULL; name = (char *)g_pub_led_name[pt->sn[addr].no]; } return name; } /*********************************************************************** 函数名称:get_led_value 函数版本:01.01 创建作者:xxxxxx 创建日期:2022-11-10 函数说明:获取LED状态值 参数说明:slot:板卡号 addr:led地址 返 回 值: 0灭 1快闪 2慢闪 3常亮 其他:错误 ***********************************************************************/ int get_led_value(int slot, int addr) { int status; struct led_config *pt; if (slot >= EQU_SLOT_NUM_MAX) return -1; pt = &g_led_slot[slot]; if (addr >= pt->num) return -2; if (pt->sn[addr].sw >= (SWITCH_NUM_MAX + 1) || pt->sn[addr].no == LED_NULL || pt->sn[addr].no >= SW_LED_NUM) return -3; status = g_led_stu[pt->sn[addr].sw][pt->sn[addr].no]; return status; } int rt_gunzip(char *filename) { int ret; char *argv[] = {"/bin/gunzip", "-f", filename, NULL}; char *envp[] = {NULL}; ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); rt_printf("rt_gunzip=%d,%s\r\n\r\n", ret, filename); return ret; } int rt_bunzip2(char *filename) { int ret; char *argv[] = {"/usr/bin/bunzip2", "-f", filename, NULL}; char *envp[] = {NULL}; ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); rt_printf("rt_bunzip2=%d,%s\r\n\r\n", ret, filename); return ret; } int rt_untar_a(char *filename) { int ret = -1; if (strstr(filename, ".gz")) { ret = rt_gunzip(filename); } else if (strstr(filename, ".bz2")) { ret = rt_bunzip2(filename); } return ret; }