656fde2902
数据解析同意放入 func.c 中有parseTTData() 判断 更新parseTTData函数,添加对粘包数据的支持
423 lines
9.9 KiB
C
423 lines
9.9 KiB
C
|
||
|
||
#include <rtthread.h>
|
||
#define LOG_TAG "tool"
|
||
#define LOG_LVL LOG_LVL_DBG
|
||
#include <ulog.h>
|
||
//#include <cJSON.h>
|
||
#include <dfs_file.h>
|
||
#include <usrcfg.h>
|
||
|
||
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);
|