#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; //typedef struct //{ // int sendInterval; // int maxTTWaitTime; // int maxTTRetryCnt; // int minTTPeriCnt; // int minTTsinal; //} SYS_CFG; #define _CFGALL #ifdef _CFGALL SYS_CFG scfg={ .sendInterval =60, .maxTTWaitTime = 4, .maxTTRetryCnt = 3, .minTTPeriCnt=5, .minTTsinal=5, }; /** * 更新全局参数 */ 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"); } 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("------Start------\n"); 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); uint8_t tmp[]={tm->tm_year-100, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,tm->tm_sec}; 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; } void tm2str(int argc, char **argv) { char s[30]; time2Str(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; } void sDemo() { // extern struct rt_event sw_check;//软件条件 // rt_event_send(&sw_check, FILE_IS_OK); void upSWflag(void); upSWflag(); } MSH_CMD_EXPORT(sDemo,喂文件数据); /** * 关闭网口,去初始化,释放内存 */ RT_WEAK void rt_hw_stm32_eth_deinit() { } MSH_CMD_EXPORT(rt_hw_stm32_eth_deinit, 去初始化网络。); void TTisReady(void) { rt_sem_release(TTReady); } void sysInit() { // pwTT_thread_entry("1");//开机 TTReady = rt_sem_create("TTisReady", 0, RT_IPC_FLAG_PRIO); cfgUpdate = rt_sem_create("cfgUpdate", 0, RT_IPC_FLAG_PRIO); rt_sem_release(cfgUpdate);//上电更新值 // rt_hw_stm32_eth_init();//激活网口 // LOG_D("sysInit"); } INIT_APP_EXPORT(sysInit); INIT_APP_EXPORT(updatecfg);