TT12-MCU/applications/ttmsg/ttmsg.c

545 lines
15 KiB
C
Raw Normal View History

2023-05-18 00:58:26 +00:00
/*
*
*
* Esc!1 @2 #3 $4 %5 ^6 &7 *8 (9 )0 _- += |\ `~
*
* Tab Q W E R T Y U I O P {[ }] BS
*
* Ctrl A S D F G H J K L : ;" '│ Enter ││
*
* Shift Z X C V B N M < ,> .? /Shift Fn
*
* Fn Alt Space Alt Win HHKB
*
*
*/
/*
* @Author: murmur test@test.com
* @Date: 2023-05-05 10:07:30
* @LastEditors: murmur test@test.com
* @LastEditTime: 2023-05-11 16:34:31
* @FilePath: \TT12-MCU\applications\ttmsg\ttmsg.c
* @Description:
*
* Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
2023-05-18 00:58:26 +00:00
*/
// #include <dfs_file.h>
2023-05-11 03:33:47 +00:00
#define LOG_TAG "ttmsg"
#define LOG_LVL LOG_LVL_DBG
2023-05-11 03:33:47 +00:00
#include <ulog.h>
#include "ttmsg.h"
#include <board.h>
2023-05-11 03:33:47 +00:00
/**
* @brief
*
* @param str
* @param deli
* @param out
* @return size_t
*/
#ifdef USE_STRTOK
2023-05-18 00:58:26 +00:00
static size_t split(const char *str, const char *deli, char (*out)[STR_LEN_MAX])
2023-05-11 03:33:47 +00:00
{
char buf[50];
strcpy(buf, str); // strtok会修改字符串
char *token = strtok(buf, deli);
char *rst[STR_LEN_MAX];
size_t i = 0;
while (token)
{
rst[i++] = token;
token = strtok(NULL, deli);
}
// 更新out
for (size_t ii = 0; ii < i; ii++)
{
// out[ii] = id[ii];
strcpy(out[ii], rst[ii]);
}
return i;
2023-05-11 03:33:47 +00:00
}
#else
// strtok_r版本
static size_t split(const char *str, const char *delim, rt_uint8_t (*out)[STR_LEN_MAX])
{
char buf[50];
strcpy(buf, str); // strtok会修改字符串
char *token = NULL;
char *saveptr = NULL;
char *rst[STR_LEN_MAX];
int idx = 0;
token = strtok_r(buf, delim, &saveptr);
while (token)
{
// LOG_D("---%s---",token);
rst[idx++] = token;
token = strtok_r(NULL, delim, &saveptr);
}
// 更新out
for (size_t ii = 0; ii < idx; ii++)
{
// out[ii] = id[ii];
strcpy(out[ii], rst[ii]);
}
return idx;
}
#endif
2023-05-11 03:33:47 +00:00
/**
* @brief ID
*
* @param fin
* @param out
* @return size_t ID长度
*/
static size_t getID(const char *str, rt_uint8_t *out)
2023-05-11 03:33:47 +00:00
{
char id[10][STR_LEN_MAX] = {};
// 分割路径
size_t len = split(str, "/", id);
2023-05-11 03:33:47 +00:00
// 分割后缀
// LOG_D("file is %s",id[len-1]);
len = split(id[len - 1], ".", id);
2023-05-11 03:33:47 +00:00
// 分割时间
// LOG_D("file name is %s",id[0]);
len = split(id[0], "_", id);
2023-05-11 03:33:47 +00:00
unsigned char tmp[len];
for (size_t i = 0; i < len; i++)
2023-05-11 03:33:47 +00:00
{
unsigned int v = atoi(id[i]);
2023-05-11 03:33:47 +00:00
// 去除代表20的2000
if (v > 0xff)
{
v = v - 2000;
}
2023-05-11 03:33:47 +00:00
tmp[i] = v;
}
LOG_HEX("file ID",16,tmp,len);
memcpy(out, tmp, len);
return len;
2023-05-11 03:33:47 +00:00
}
/**
2023-05-18 00:58:26 +00:00
* @brief MSG
* @param *tpl MSG结构体
* @param fin ID
2023-05-11 03:33:47 +00:00
* @param flag
2023-05-18 00:58:26 +00:00
* @return 0
2023-05-11 03:33:47 +00:00
*/
rt_uint8_t packInit(MSG *tpl, const rt_uint8_t *fin, rt_uint8_t flag)
2023-05-11 03:33:47 +00:00
{
// memset(tpl, 0, sizeof(MSG)); // 分配空间
// 模板
MSG msgs_tpl = {
.fstart = {0x88, 0xAA, 0xBB, 0x88},
.fnum = {0x00, 0x01},
.fbak = {0x00, 0x02},
.ftype = {
0x70, 0x21},
.fdlen = {0x00, 0x00},
.ftccid = {0x37, 0x32, 0x32, 0x32},
.fcfg = flag,
2023-05-11 03:33:47 +00:00
};
rt_memcpy(tpl, &msgs_tpl, sizeof(MSG));
2023-05-11 03:33:47 +00:00
size_t len = getID(fin, tpl->findex);
if (len != 7)
{
LOG_E("file name %s format error", fin);
return RT_ERROR;
2023-05-11 03:33:47 +00:00
}
2023-05-18 00:58:26 +00:00
return RT_EOK;
2023-05-11 03:33:47 +00:00
}
/**
* @description: MSG帧格式拼接din数据后输出到dout
* @param *p_msg MSG格式配置文件
2023-05-11 03:33:47 +00:00
* @param {rt_uint8_t} *din
* @param {rt_uint8_t} len
* @param {rt_uint8_t} *dout
2023-05-11 03:33:47 +00:00
* @return {*}
*/
2023-05-18 00:58:26 +00:00
rt_uint8_t packMsg(MSG *p_msg, rt_uint8_t *din, rt_uint8_t len, rt_uint8_t *dout)
2023-05-11 03:33:47 +00:00
{
rt_uint8_t fralen = sizeof(MSG) + len; // len of current frame
2023-05-11 03:33:47 +00:00
// 计算各字段
p_msg->fdlen[0] = 0; // 单包长度必不会超过0xFF故高字节始终为0
p_msg->fdlen[1] = fralen - 13; // 总长度-帧头长度
2023-05-18 00:58:26 +00:00
// memcpy(p_msg->findex,id,6);
2023-05-11 03:33:47 +00:00
// 将待发数据传入帧数据
rt_memcpy(p_msg->fdata, din, len);
2023-05-11 03:33:47 +00:00
2023-05-18 00:58:26 +00:00
// 将打包后帧数据传入buff
rt_memcpy(dout, p_msg, fralen);
2023-05-11 03:33:47 +00:00
return fralen;
}
/**
* @description: din按指定长度w分割MSG帧格式拼接
* @param *cfg MSG格式配置文件
* @param {rt_uint8_t} *din
* @param {rt_uint8_t} len
* @param {rt_uint8_t} w
* @param {rt_uint8_t} *dout
* @return {*}
*/
rt_uint8_t packMsgs(MSG *cfg, rt_uint8_t *din, size_t len, rt_uint8_t w, rt_uint8_t (*dout)[200], rt_uint8_t *arrlen)
{
if (!(w > 0)) // 无效长度
{
w = len;
}
rt_uint8_t row = (len / w) + (len % w > 0 ? 1 : 0);
LOG_I("ROW = %d",row);
// rt_uint8_t packdata[row][200]; // 打包后数据
rt_uint8_t tlen[row]; // 打包后数据各维长度
// static rt_uint8_t index = 0;
// rt_uint8_t in[len];
// memcpy(in,din,len);
cfg->fallpiece[0]=row;
rt_uint8_t tmplen = 0;
size_t var=0;
for (rt_uint8_t index = 0; index< row;index++)
{
// rt_uint8_t tmplen = w; // 当前待打包数据的长度
tmplen = (len - var) > w ? w : (len - var); // 判断最后一包数据的长度
cfg->fcurpiece[0] = index+1;
rt_uint8_t col = packMsg(cfg, din+var, tmplen, dout[index]);
arrlen[index] = col;
// index++;
var += w;
LOG_D("index/row-var-tmplen");
LOG_D("%5d/%3d-%3d-%6d",index,row,var,tmplen);
LOG_HEX("per msg",27,dout[index],col);
// LOG_D("--------");
rt_thread_mdelay(100);
}
// for (size_t i = 0; i < row; i++)
// {
// memcpy(dout[i], packdata[i], tlen[i]);
// }
// memcpy(arrlen, tlen, row);
// LOG_D("--addr is %d",din);
return row;
}
size_t demo (uint8_t *din)
{
size_t s= 1024*10;
rt_uint8_t *buf = rt_malloc(s);
if (buf!=RT_NULL) {
LOG_D("mem ok, addr is %d",buf);
LOG_D("addr is %d",rt_memset(buf, 0xab, s));
}
else {
LOG_E("no mem.");
}
for (size_t var = 0; var < s; ++ var) {
rt_memcpy(buf+var, din+var, 1);
}
LOG_HEX("buf",16,buf,100);
// LOG_D("addr is %d",din);
if (buf) {
rt_free(buf);
}
return 1;
}
2023-05-18 00:58:26 +00:00
/**
*
* @param *cfg MSG格式配置文件
2023-05-18 00:58:26 +00:00
* @param fin
* @param flag
2023-05-18 00:58:26 +00:00
* @param dout
* @param arrlen
2023-05-18 00:58:26 +00:00
* @return
*/
rt_uint8_t pack_File(const char *fin, rt_uint8_t flag, const rt_uint8_t (*dout)[200], rt_uint8_t *arrLen)
2023-05-11 03:33:47 +00:00
{
static MSG cfg;
rt_memset(&cfg, 0, sizeof(MSG)); // 分配空间
rt_uint8_t rst = packInit(&cfg, fin, flag);
if (rst != RT_EOK)
{
return 0;
}
int fd_in = -1; //, fd_out = -1;
2023-05-11 03:33:47 +00:00
static size_t file_size = 0;
// rt_uint8_t *buffer = RT_NULL;
size_t flen = 150; // 每包数据初始长度,最大不超过 FRAME_DATA_LEN_MAX
rt_uint8_t len = 0;
2023-05-11 03:33:47 +00:00
fd_in = open(fin, O_RDONLY, 0);
if (fd_in < 0)
{
LOG_E("open the input file : %s error!\n", fin);
close(fd_in);
return len;
2023-05-11 03:33:47 +00:00
}
file_size = lseek(fd_in, 0, SEEK_END);
LOG_I("file size is %d bytes.",file_size);
2023-05-11 03:33:47 +00:00
lseek(fd_in, 0, SEEK_SET);
rt_uint8_t *buffer=RT_NULL ;
buffer = rt_malloc(file_size);
if (buffer == RT_NULL) {
LOG_E("No memory for read %s.",fin);
return 0;
2023-05-11 03:33:47 +00:00
}
read(fd_in, buffer, file_size);
close(fd_in);
// 粗略调整每包大小
if (file_size > FRAME_DATA_LEN_MAX) {
while (file_size % flen < flen / 1.2 && flen < FRAME_DATA_LEN_MAX) // 阈值约83%
2023-05-11 03:33:47 +00:00
{
flen += 1;
}
if (file_size % flen < flen / 1.2)
{ // 到达限制仍不符合要求
flen = 150;
while (file_size % flen < flen / 2.5 && flen < FRAME_DATA_LEN_MAX) // 调整阈值为40%
{
flen += 1;
}
}
}
else {
flen = file_size;
2023-05-11 03:33:47 +00:00
}
LOG_I("len of data per pack is %d Bytes.",flen);
LOG_I("cnt of packages is %d",(file_size / flen) + (file_size % flen > 0 ? 1 : 0));
len = packMsgs(&cfg, buffer, file_size, flen, dout, arrLen);
if (fd_in >= 0)
2023-05-11 03:33:47 +00:00
{
close(fd_in);
2023-05-11 03:33:47 +00:00
}
if (buffer!=RT_NULL)
{
LOG_D("try to free buf.");
rt_free(buffer);
LOG_D("free buf done.");
}
// LOG_D("%p--%p",dout,arrLen);
2023-05-11 03:33:47 +00:00
return len;
2023-05-11 03:33:47 +00:00
}
static char d[40][200];
static char s[40];
// static rt_uint8_t *buffer = RT_NULL;
// static MSG cfg;
static int pf_thread_entry(void* parameter)
{
char *f = (char *) parameter;
// static char d[5][200];
// static char s[5];
rt_uint8_t *buffer = RT_NULL;
static MSG cfg;
static rt_uint8_t len=0;
// len = pack_File(f, 0, d, s);
#define DEMO
#ifdef DEMO
{
//
rt_memset(&cfg, 0, sizeof(MSG)); // 分配空间
rt_uint8_t rst = packInit(&cfg, f, 0);
if (rst != RT_EOK)
{
return 0;
}
int fd_in = -1; //, fd_out = -1;
static size_t file_size = 0;
// rt_uint8_t *buffer = RT_NULL;
static size_t flen = 150; // 每包数据初始长度,最大不超过 FRAME_DATA_LEN_MAX
// rt_uint8_t len = 0;
fd_in = open(f, O_RDONLY, 0);
if (fd_in < 0)
{
LOG_E("open the input file : %s error!\n", f);
close(fd_in);
return len;
}
file_size = lseek(fd_in, 0, SEEK_END);
LOG_I("file size is %d bytes.", file_size);
lseek(fd_in, 0, SEEK_SET);
// static rt_uint8_t *buffer = RT_NULL;
buffer = rt_malloc(file_size);
if (buffer == RT_NULL)
{
LOG_E("No memory for read %s.", f);
return 0;
}
read(fd_in, buffer, file_size);
// LOG_HEX()
close(fd_in);
// 粗略调整每包大小
if (file_size > (size_t)FRAME_DATA_LEN_MAX)
{
while (file_size % flen < flen / 1.2 && flen < FRAME_DATA_LEN_MAX) // 阈值约83%
{
flen += 1;
}
if (file_size % flen < flen / 1.2)
{ // 到达限制仍不符合要求
flen = 150;
while (file_size % flen < flen / 2.5 && flen < FRAME_DATA_LEN_MAX) // 调整阈值为40%
{
flen += 1;
}
}
}
else
{
flen = file_size;
}
LOG_I("flen is %d",flen);
// s[0] = packMsg(&cfg, buffer, flen, d[0]);
len = packMsgs(&cfg, buffer, file_size, flen, d, s);
if (fd_in >= 0)
{
close(fd_in);
}
if (buffer != RT_NULL)
{
LOG_D("try to free buf.");
rt_free(buffer);
LOG_D("free buf done.");
}
}
#endif
rt_kprintf("len is %d\n", len);
if (len)
{
for (size_t var = 0; var < len; var++)
{
LOG_D("i = %d",var);
LOG_HEX("d", 27, d[var], s[var]);
}
LOG_I("Done.");
}
return RT_EOK;
2023-05-11 03:33:47 +00:00
}
static int pmsg(int argc, char **argv)
{
if (argc == 2)
{
static char c[STR_LEN_MAX];
strcpy(c, argv[1]);
/* 创建线程 */
rt_thread_t thread = rt_thread_create("pmsg", pf_thread_entry, (void *) c, 1024 * 20, 25, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
// rt_kprintf("done");
}
else
{
LOG_E("thread 'pmsg' create failure.");
return RT_ERROR;
}
}
else
{
rt_kprintf("Usage:\n");
rt_kprintf("pmsg [input_file] pack \"input_file\" \n");
}
return 0;
}
#include <finsh.h>
2023-05-11 03:33:47 +00:00
MSH_CMD_EXPORT(pmsg, );
void pwTT_thread_entry(void *parameter)
{
// LOG_I("--%s--",parameter);
if (parameter == NULL) {
int f = rt_pin_read(TT_EN);
rt_pin_write(TT_EN, !f);
LOG_I("set TT %s",!f?"ON":"OFF");
}
else
{
rt_bool_t flag = (rt_bool_t)parameter;
rt_pin_write(TT_EN, flag);
LOG_I("set TT %s",flag?"ON":"OFF");
}
}
static int swTT(int argc, char **argv)
{
int f = NULL;//不带参数时argv[1]为NULL
if (argc == 2)
{
f = atoi(argv[1]);
}
/* 创建线程 */
rt_thread_t thread = rt_thread_create("sw_TT", pwTT_thread_entry, (void *) f, 1024 * 1, 25, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
LOG_E("thread 'sw_TT' create failure.");
return RT_ERROR;
}
}
MSH_CMD_EXPORT(swTT, TT电源);