#include #define LOG_TAG "tool" #define LOG_LVL LOG_LVL_DBG #include //#include #include #include // //rt_sem_t TTReady= RT_NULL;//天通具备发送状态后 rt_sem_release(TTReady); //rt_sem_t cfgUpdate = RT_NULL; // // // //#define _CFGALL //#ifdef _CFGALL // //SYS_CFG scfg={ // .sendInterval =60, // .maxTTWaitTime = 4, // .maxTTRetryCnt = 3, // .minTTPeriCnt=5, // .minTTsinal=5, // .timeout=5; //}; // // // ///** // * 更新全局参数 // */ //static void updatecfg(void) //{ ////因为不知原因,采用事件集独立更新配置出错,无精力深查 ////独立响应单个参数更新事件,程序上更复杂也没特别必要 ////现采用事件通知、统一全部重新加载 // while(1) // { // if(rt_sem_take(cfgUpdate, RT_WAITING_FOREVER) == RT_EOK) // { // scfg.maxTTWaitTime = get_cfg("maxTTWaitTime"); // scfg.maxTTRetryCnt = get_cfg("maxTTRetryCnt"); // scfg.minTTPeriCnt = get_cfg("minTTPeriCnt"); // scfg.minTTsinal = get_cfg("minTTsinal"); // scfg.timeout = get_cfg("timeout"); // } // LOG_D("cfg updated."); // } //} // ////INIT_APP_EXPORT(updatecfg); //#endif /** * 以HEX显示文件内容 */ void hexFile_thread_entry(void* parameter) { int fd_in = -1; int block_size = 0; char *fin = (char *)parameter; fd_in = open(fin, O_RDONLY, 0); if (fd_in < 0) { LOG_E("[hex] open the input file : %s error.", fin); return RT_ERROR; } size_t file_size = lseek(fd_in, 0, SEEK_END); lseek(fd_in, 0, SEEK_SET); rt_uint8_t *buffer = RT_NULL; #define READ_BUFFER_SIZE 512 buffer = (rt_uint8_t *) malloc(READ_BUFFER_SIZE); rt_kprintf("\n------Start------\n"); LOG_D("size = %d bytes.",file_size); for (size_t i = 0; i < file_size; i += READ_BUFFER_SIZE) { if ((file_size - i) < READ_BUFFER_SIZE) { block_size = file_size - i; } else { block_size = READ_BUFFER_SIZE; } memset(buffer, 0x00, READ_BUFFER_SIZE); read(fd_in, buffer, block_size); LOG_HEX("hex_file",27,buffer,block_size); } rt_free(buffer); close(fd_in); rt_kprintf("------Done.------\n"); } void hexFile(int argc, char **argv) { if (argc == 2) { static char f[30]; rt_strcpy(f,argv[1]); /* 创建线程 */ rt_thread_t thread = rt_thread_create("hex_file", hexFile_thread_entry, (void *) f, 1024 * 2, 25, 10); /* 创建成功则启动线程 */ if (thread != RT_NULL) { rt_thread_startup(thread); } else { LOG_E("thread 'hex_file' create failure."); return RT_ERROR; } } } MSH_CMD_EXPORT(hexFile,以HEX方式显示文件内容); int time2Byte(uint8_t * t) { static time_t now; static struct tm *tm, tm_tmp; now = time(RT_NULL); tm = localtime_r(&now, &tm_tmp); srand((unsigned)now); uint8_t rnd=(uint8_t)rand()%99; uint8_t tmp[]={tm->tm_year-100, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,rnd}; memcpy(t,tmp,sizeof(tmp)); return sizeof(tmp); } char *bytes2str(uint8_t *din, size_t count, int radix, char *sep, char *str); /** * 将当前时间转为字符串 * @param str 字符串buffer * @return 字符串长度 */ char *time2Str(char *str) { uint8_t t[10]; size_t len=time2Byte(t); bytes2str(t, len, 10, "_", str); len = strlen(str); str[len]='\0'; return str; } char *date2Str(char *str) { uint8_t t[10]; size_t len=time2Byte(t); bytes2str(t, len, 10, "_", str); // len = strlen(str); str[11]='\0'; return str; } char *getTimestmp(char *str) { uint8_t t[10]; size_t len=time2Byte(t); str[0]='\0'; strcat(str,"20"); bytes2str(t, len, 10, "-", str+2); str[10]=' '; len = strlen(str); str[len]='\0'; return str; } void tm2str(int argc, char **argv) { char s[30]; time2Str(s); LOG_I("result is %s",s); getTimestmp(s); LOG_I("result is %s",s); } MSH_CMD_EXPORT(tm2str,时间转换为字符串) /** * @brief 将整型数据转换为字符串,支持负数。windows环境下的itoa(= integer to alphanumeric)源码。 * * @param num 待转换数据 * @param str 指向转换结果字符串的指针 * @param radix 进制 * @return char* */ char *int2str(int num, char *str, int radix) { char index[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 索引表 unsigned unum; // 存放要转换的整数的绝对值,转换的整数可能是负数 int i = 0, j, k; // i用来指示设置字符串相应位,转换之后i其实就是字符串的长度;转换后顺序是逆序的,有正负的情况,k用来指示调整顺序的开始位置;j用来指示调整顺序时的交换。 // 获取要转换的整数的绝对值 if (radix == 10 && num < 0) // 要转换成十进制数并且是负数 { unum = (unsigned)-num; // 将num的绝对值赋给unum str[i++] = '-'; // 在字符串最前面设置为'-'号,并且索引加1 } else unum = (unsigned)num; // 若是num为正,直接赋值给unum // 转换部分,注意转换后是逆序的 do { str[i++] = index[unum % (unsigned)radix]; // 取unum的最后一位,并设置为str对应位,指示索引加1 unum /= radix; // unum去掉最后一位 } while (unum); // 直至unum为0退出循环 str[i] = '\0'; // 在字符串最后添加'\0'字符,c语言字符串以'\0'结束。 // 将顺序调整过来 if (str[0] == '-') k = 1; // 如果是负数,符号不用调整,从符号后面开始调整 else k = 0; // 不是负数,全部都要调整 char temp; // 临时变量,交换两个值时用到 for (j = k; j <= (i - 1) / 2; j++) // 头尾一一对称交换,i其实就是字符串的长度,索引最大值比长度少1 { temp = str[j]; // 头部赋值给临时变量 str[j] = str[i - 1 + k - j]; // 尾部赋值给头部 str[i - 1 + k - j] = temp; // 将临时变量的值(其实就是之前的头部值)赋给尾部 } return str; // 返回转换后的字符串 } /** * @brief 将字节数组转换为字符串 * * @param din 待转换的数组 * @param count 待转换数组长度 * @param radix 指定进制 * @param sep 指定连接符 * @param str 转换结果 * @return char* 指向转换结果的指针 */ char *bytes2str(uint8_t *din, size_t count, int radix, char *sep, char *str) { char rst[512]="";//=malloc(512); for (size_t i = 0; i < count; i++) { char s[200]=""; // sprintf(s, tmp, din[i]); int2str(din[i],s,radix); // printf("str=%02X,s=%s,len=%d,p=%p\n", din[i], s, strlen(s), s); if (strlen(s) == 1) { strcat(rst,"0");//补充前导零 } strcat(rst, s); // strcat需要字符串尾 strcat(rst,sep); // printf("rst=%s,s=%s\n",rst,s); } int len = strlen(rst)-strlen(sep); strncpy(str,rst,len);//去掉末尾的连接符 str[len]='\0'; return str; } /** * @brief 将字符串按指定进制转换为字节数组,非法字符转换为0,如" AT5AA5"可转换为{0xA0,0x5A,0xA5} * * @param str 待转换字符串 * @param step 每次转换字符个数 * @param base 指定进制 * @param rst 转换结果 * @return size_t 转换结果的长度,包含失败的转换 */ size_t str2Byte(char *str, size_t step, int base, uint8_t *rst) { size_t len = strlen(str) / step; if (strlen(str)%2) { len +=1; } uint8_t b[200]; for (size_t i = 0; i < strlen(str); i = i + step) { char tmp[step]; strncpy(tmp, str + i, step); long d = strtol(tmp, NULL, base); b[i / step] = d; } memcpy(rst, b, len); return len; } /** * @brief 奇偶校验。实际采用的是XOR校验。文档中有出入。 * * @param din 待校验数组 * @param count 待校验数组长度 * @param isEven 偶校验还是奇校验 * @return uint8_t 校验结果 */ uint8_t parityCheck(uint8_t *din, size_t count, uint8_t isEven) { uint8_t rst = 0; if (isEven) { for (size_t i = 0; i < count; i++) { rst += GET_BIT_N_VAL((din), i); } return (rst & 0x1); } else { for (size_t i = 0; i < count; i++) { rst += rst + GET_BIT_N_VAL((din), i); } if (rst % 2 == 0) return 1; else return 0; } } /** * @brief 异或XOR校验 * * @param din 待校验数组 * @param count 待校验数组长度 * @return uint8_t 校验结果 */ uint8_t bccCRC(uint8_t *din, size_t count) { uint8_t rst = 0; // Initial value while(count--) { rst ^= *din++; } return rst; } /** * @brief 在指定数组中搜索目标数组 * * @param din 待搜索数组 * @param len 待搜索数组长度 * @param s 目标数组 * @param slen 搜索长度 * @param dout 搜索结果 * @return int 匹配个数 */ size_t isInByte(uint8_t *din, size_t len, uint8_t *s, size_t slen, uint8_t *dout) { size_t cnt = 0; uint8_t tmp[len]; for (size_t i = 0; i < len - slen+1; i++) { if (memcmp(din + i, s, slen) == 0) { tmp[cnt++] = i; i = i+slen-1; } } memcpy(dout,tmp,cnt); return cnt; } //static char cfname[60]=""; /** * 获取新缓存文件的文件名 * @param fin 指向文件名的数组 * @return */ char *getNewCacheFileName(char *fin) { char f[60]=""; char rootDir[22] = ROOT_PATH_DATA; mkdir(rootDir, 0); strcat(rootDir, "2023_07_19/"); //更新时戳 char ts[30] = ""; time2Str(ts); //更新文件夹 strncpy(rootDir + strlen(rootDir) - 9, ts, 8); mkdir(rootDir, 0); //更新文件名 f[0] = '\0'; strcat(f, rootDir); // strcpy(f,rootDir); strcat(f, "23_07_19_16_38_36_36.bin"); // LOG_D("need to creat new file"); strncpy(f + strlen(rootDir), ts, strlen(ts)); // strcpy(cfname,f); updateLstFile(f); strcpy(fin,f); return fin; } /** * 获取当前缓存文件的文件名 * @param fin 指向文件名的数组 * @return */ char *getLstCacheFileName(char *fin) { // if (strcmp(cfname,"") == 0) { // getNewCacheFileName(fin); // } char f[60]; if (!getLstFile(f)) { getNewCacheFileName(fin); } strcpy(fin,f); return fin; } void d_gcf() { char f[60]; LOG_D("--%s",getLstCacheFileName(f)); LOG_D("--%s",getNewCacheFileName(f)); } MSH_CMD_EXPORT(d_gcf,cache file); /** * 检测数组数据是ASCII还是还是BIN * @param din 待检测数组 * @param len 数组长度 * @return 1-ASCII,0-BIN */ int isDataASCII(uint8_t *din, size_t len) { int rst=0; for (size_t i = 0; i < len; i++) { if (!isprint(din[i])) { rst = 0; break; } if (i == len-1) { rst = 1; } } return rst; }