TT12-MCU/applications/ttmsg/ttmsg.c
murmur 9b76e1fbe8 添加流程文件
添加主逻辑函数
待完善ttgetinfo 文件
2023-06-01 17:10:00 +08:00

558 lines
15 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* ┌─────────────────────────────────────────────────────────────┐
* │┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐│
* ││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.
*/
// #include <dfs_file.h>
#define LOG_TAG "ttmsg"
#define LOG_LVL LOG_LVL_INFO
#include <ulog.h>
#include "ttmsg.h"
#include <board.h>
#include <ttTR.h>
#include <cfg.h>
/**
* @brief 按指定分隔符分割字符串
*
* @param str 待分割字符串
* @param deli 分隔符
* @param out 输出字符串数组
* @return size_t 分割后字符串个数
*/
#ifdef USE_STRTOK
static size_t split(const char *str, const char *deli, char (*out)[STR_LEN_MAX])
{
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;
}
#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
/**
* @brief 从文件名字符串提取ID
*
* @param fin 文件名,支持路径
* @param out 提取结果
* @return size_t ID长度
*/
static size_t getID(const char *str, rt_uint8_t *out)
{
char id[10][STR_LEN_MAX] = {};
// 分割路径
size_t len = split(str, "/", id);
// 分割后缀
// LOG_D("file is %s",id[len-1]);
len = split(id[len - 1], ".", id);
// 分割时间
// LOG_D("file name is %s",id[0]);
len = split(id[0], "_", id);
unsigned char tmp[len];
for (size_t i = 0; i < len; i++)
{
unsigned int v = atoi(id[i]);
// 去除代表20的2000
if (v > 0xff)
{
v = v - 2000;
}
tmp[i] = v;
}
LOG_HEX("file ID",16,tmp,len);
memcpy(out, tmp, len);
return len;
}
/**
* @brief 根据配置初始化MSG
* @param *tpl MSG结构体
* @param fin 文件名由时间戳和随机码组成作为数据包唯一ID
* @param flag 参数配置,如信息类型、压缩方式、加密方式等
* @return 成功返回0
*/
rt_uint8_t packInit(MSG *tpl, const rt_uint8_t *fin, rt_uint8_t flag)
{
// 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,
};
rt_memcpy(tpl, &msgs_tpl, sizeof(MSG));
size_t len = getID(fin, tpl->findex);
if (len != 7)
{
LOG_E("file name %s format error", fin);
return RT_ERROR;
}
return RT_EOK;
}
/**
* @description: 按MSG帧格式拼接din数据后输出到dout
* @param *p_msg MSG格式配置文件
* @param {rt_uint8_t} *din 待打包数据
* @param {rt_uint8_t} len 待打包数据长度
* @param {rt_uint8_t} *dout 打包后数据
* @return {*} 打包后数据总长度
*/
rt_uint8_t packMsg(MSG *p_msg, rt_uint8_t *din, rt_uint8_t len, rt_uint8_t *dout)
{
rt_uint8_t fralen = sizeof(MSG) + len; // len of current frame
// 计算各字段
p_msg->fdlen[0] = 0; // 单包长度必不会超过0xFF故高字节始终为0
p_msg->fdlen[1] = fralen - 13; // 总长度-帧头长度
// memcpy(p_msg->findex,id,6);
// 将待发数据传入帧数据
rt_memcpy(p_msg->fdata, din, len);
// 将打包后帧数据传入buff
rt_memcpy(dout, p_msg, fralen);
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;
}
/**
* 将指定文件按帧协议进行切片打包,返回二维数组
* @param *cfg MSG格式配置文件
* @param fin 待打包文件名
* @param flag 配置信息
* @param dout 打包后二维数组
* @param arrlen 打包后二维数组各维数组的长度
* @return
*/
rt_uint8_t pack_File(const char *fin, rt_uint8_t flag, const rt_uint8_t (*dout)[200], rt_uint8_t *arrLen)
{
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;
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;
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;
}
file_size = lseek(fd_in, 0, SEEK_END);
LOG_I("file size is %d bytes.",file_size);
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;
}
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%
{
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("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)
{
close(fd_in);
}
if (buffer!=RT_NULL)
{
LOG_D("try to free buf.");
rt_free(buffer);
LOG_D("free buf done.");
}
// LOG_D("%p--%p",dout,arrLen);
return len;
}
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++)
{
// sendMsg(d[var], s[var]);
LOG_D("i = %d",var);
LOG_HEX("d", 27, d[var], s[var]);
}
LOG_I("Done.");
}
return RT_EOK;
}
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>
MSH_CMD_EXPORT(pmsg, );
/**
* 天通上电
* @param parameter
*/
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);
}
else
{
rt_bool_t flag = (rt_bool_t) parameter;
rt_pin_write(TT_EN, flag);
}
if (rt_pin_read(TT_EN))
{
LOG_I("set TT %s", "ON");
add_val("swCnt");//更新统计值
}
else
{
LOG_I("set TT %s", "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 * 2, 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电源);