添加初始化时建立sd目录避免sd卡挂载失败的问题

自检功能测试ok
tools.c 添加部分基本函数
func.c 解析逻辑部分初步完成
This commit is contained in:
CSSC-WORK\murmur 2023-07-18 19:23:48 +08:00
parent b0571964e8
commit 851c1c2352
6 changed files with 536 additions and 13 deletions

View File

@ -11,6 +11,7 @@
#include <rtthread.h>
#include <usrcfg.h>
#include <ttmsg/ttmsg.h>
#include "func.h"
#define LOG_TAG "func"
#define LOG_LVL LOG_LVL_DBG
@ -49,27 +50,85 @@ int getCommMode()
/**
*
*/
extern int df(const char *path);
/**
* MB
* @param path指定磁盘挂载的路径
* @return MB
*/
static uint16_t getFreeSpace(const char *path)
{
long long cap;
struct statfs buffer;
int result = dfs_statfs(path ? path : "/", &buffer);
if (result != 0)
{
LOG_E("dfs_statfs failed.");
return 0;
}
cap = (uint16_t)((long long)buffer.f_bsize) * ((long long)buffer.f_bfree) / 1024LL / 1024LL ;//转换为MB
return cap;
}
void ddf()
{
LOG_D("free space of flash is %d MB.",getFreeSpace(NULL));
uint16_t rst = getFreeSpace("/sd");
LOG_D("free space of sd is %d MB.%02X,%02X",rst,rst>>8,rst&0xff);
}
MSH_CMD_EXPORT(ddf,getFreeSpace);
/**
*
* @return
*/
RT_WEAK int getPowerLevel(void)
{
return 0;
}
/**
*
* @param din
* @param len
* @return
*/
RT_WEAK int uploadData(uint8_t *din, size_t len)
{
return 0;
}
void sysSelfTest()
{
rt_uint8_t rst[]={0x5A, 0xA5, 0x32, 0x3E, 0x0A, 0x41, 0x00,0x06};
int p = sizeof(rst);
rt_uint8_t sysSta=1,xh,jh,commSpeed=0,powerLevel,storageCapacity;
rt_uint8_t rst[100]={0x5A, 0xA5, 0x32, 0x3E, 0x0A, 0x41};
int p = 6;
rt_uint8_t sysSta=1,xh=0,jh=0,commSpeed=0;
rst[p++]=0x00;
rst[p++]=0x09;
rst[p++] = sysSta;
rst[p++] = xh;
rst[p++] = jh;
rst[p++] = commSpeed;
rst[p++] = getPowerLevel();
rst[p++]=sysSta;
rst[p++]=xh;
rst[p++]=jh;
rst[p++]=commSpeed;
rst[p++]=getPowerLevel();
rst[p++]=getCapacityLevel();
//flash 剩餘空間
uint16_t cap = getFreeSpace("/");
rst[p++] = (uint8_t)(cap >> 8);
rst[p++] = (uint8_t)(cap & 0xff);
rst[p++]=0x00;//校验位
rst[p++]=0xED;//结束位
//SD卡剩餘空間
cap = getFreeSpace("/sd");
rst[p++] = (uint8_t)(cap >> 8);
rst[p++] = (uint8_t)(cap & 0xff);
rst[p++] = bccCRC(rst+2, p-1); ////校验位为1个字节采用异或运算从指令的第3个字节开始到奇偶校验位的前一个字节结束
rst[p++] = 0xED; //结束位
LOG_HEX("selfTestRes",16,rst,p);
//发送结果
uploadData(rst,p);
}
MSH_CMD_EXPORT(sysSelfTest,sysSelfTest);
//3.2.3日志记录
//日志功能由各函数通过LOG_D()实现
@ -248,3 +307,182 @@ void clearAllData()
/**
* @brief TT根据下发的指令执行对应的功能
*
* @param din
* @param len
*/
void ttRunCMD(uint8_t *din, size_t len)
{
int cmd=(din[4]<<8) + din[5];
switch (cmd)
{
case _CFG_COMM_MODE:
/* code */
break;
case _CMD_SELF_TEST:
break;
case _CFG_SELF_DESTRUCT:
break;
case _CMD_SELF_DESTRUCT:
break;
case _CFG_COMM_WINDOW:
break;
case _CMD_OPEN_WINDOW:
break;
case _CMD_CLOSE_WINDOW:
break;
case _CFG_LOCATION_ALERT:
break;
case _CMD_CLEAR_DATA:
break;
default:
LOG_W("未支持的指令。");
break;
}
}
//原计划将指令粗解析放在上位机考虑到上位机到位时间晚现放到MCU端
/**
* @brief 3S数据0x5AA50xED
*
* @param din
* @param count
*/
void parse3SData(uint8_t *din, size_t count)
{
uint8_t head[]={0x5a,0xA5};
//header[4] addr[2]  func[2]  len[2]  data[N]  fcrc[1] tail[1]
uint8_t rst = memcmp(din,head,sizeof(head[0]));
if (rst)
{
LOG_W("0x%02X%02X != 0x%5AA5,帧头不匹配",din[0],din[1]);
return;
}
if (din[count-2] != bccCRC(din+2,count-2-2))//校验位为1个字节采用异或运算从指令的第3个字节开始到奇偶校验位的前一个字节结束
{
LOG_W("0x%02X != 0x%02X,校验值不匹配",din[count-2] , bccCRC(din+2,count-2-2));
return;
}
if (din[count-1] != 0xED)
{
LOG_W("0x%02X != 0xED,帧尾不匹配",din[count-1]);
return;
}
uint8_t dout[200];
size_t len=0;
if (din[3] == ADDR_TT)//仅给TT的消息
{
ttRunCMD(din,len);
}
if (din[3] == ADDR_3S)//给3S的指令需要再加工返回数据可能也需要再加工
{
//
LOG_D("直接调用小彭的函数进行处理。");
// extern void xpParse(uint8_t *din, size_t len);
// xpParse(din,len);
//以下处理逻辑作废
//绝大部分数据均需要转换。详见《主要指令一览》
// int cmd = (din[4]<<8) + din[5]
// switch (cmd)
// {
// case _CMD_RTC_CHECK:
// case 0:
// /* 不转换 */
// break;
// default:
// //转换
// char rst[]="";
// bytes2str(din,count,16,"",rst);
// break;
// }
// //发送
}
}
/**
* @brief TT数据TT收到的指令必是单指令
*
* @param din
* @param len
*/
void parseTTData(uint8_t *din, size_t len)
{
uint8_t head[]={0x88,0xAA,0xBB,0x88, 0x00,0x01, 0x00,0x22, 0x70,0x21, 0x00,0xaa, 0x00, 0x27,0x22,0x22,0x22 };
//fstart[4] fnum[2]  bak[2]  ftype[2]  fdlen[2]  fcrc[1] ftccid[4]
uint8_t rst = memcmp(din,head,sizeof(head));
if (rst)
{
LOG_W("帧头不匹配");
return;
}
uint8_t id[30]="";
LOG_D("get new data: id=\"%s\", cur/all=[%d/%d]",bytes2str(din+17,7,10,"_",id),din[25],din[26]);
if (din[24] >> 7) // fcfg=数据类型。解析TT收到的数据时仅需解析“命令”“数据”传输是单向的。
{
LOG_W("浮标端仅接受指令,暂不支持数据。");
return;
}
uint8_t rawData[200];
uint8_t rawDataLen=len-27;
memcpy(rawData, din + 27, rawDataLen);
parse3SData(rawData,rawDataLen);
// switch (din[24] & 0x7F) // 识别指令的目标地址
// {
// case _ONLY_FOR_TT:
// ttRunCMD(rawData, len - 27);
// break;
// case _ONLY_FOR_3S:
// /* code */
// // 发送数据至3S
// break;
// case _FOR_BOTH:
// // 发送数据至3S
// // 等待返回数据
// // 打包
// // 上传
// break;
// default:
// LOG_W("未识别到指令的目标地址");
// break;
// }
}

79
applications/func/func.h Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-07-18 murmur the first version
*/
#ifndef APPLICATIONS_FUNC_FUNC_H_
#define APPLICATIONS_FUNC_FUNC_H_
enum {
_ONLY_FOR_TT=0,
_ONLY_FOR_3S,
_FOR_BOTH,
}sub_mode;
#ifdef ENUM
enum
{
// CFG 代表更新配置
// CMD 代表执行相关功能
_CFG_COMM_MODE, // 配置工作方式
_CMD_SELF_TEST, // 执行自检
_CFG_SELF_DESTRUCT, // 设置自毁开关
_CMD_SELF_DESTRUCT, // 执行自毁
_CFG_COMM_WINDOW, // 配置开窗
_CMD_OPEN_WINDOW, // 执行手动开窗
_CMD_CLOSE_WINDOW, // 执行手动关窗
_CFG_LOCATION_ALERT, // 配置位置告警
_CMD_CLEAR_DATA, // 执行清空数据
_CMD_RETRY_DATA,
} cmd;
#endif
//define function
// CFG 代表更新配置
// CMD 代表执行相关功能
#define _CFG_COMM_MODE 0x00 // 配置工作方式
#define _CMD_SELF_TEST 0x01 // 执行自检
#define _CFG_SELF_DESTRUCT 0x0A21 // 设置自毁开关
#define _CMD_SELF_DESTRUCT 0x02 // 执行自毁
#define _CFG_COMM_WINDOW 0x03 // 配置开窗
#define _CMD_OPEN_WINDOW 0x0B11 // 执行手动开窗
#define _CMD_CLOSE_WINDOW 0x1905 // 执行手动关窗
#define _CFG_LOCATION_ALERT 0x04// 配置位置告警
#define _CMD_CLEAR_DATA 0x05 // 执行清空数据
#define _CMD_RETRY_DATA 0x06 //
#define _CFG_UPDATE_CFG 0x7001
//3S
#define _CMD_DEPTH_REQUEST 0x0601
#define _CMD_RTC_CHECK 0x410F
//
#define ADDR_ANJI 0x32 //0x42?
#define ADDR_TT 0x41
#define ADDR_3S 0x3E
#endif /* APPLICATIONS_FUNC_FUNC_H_ */

View File

@ -127,7 +127,7 @@ MSH_CMD_EXPORT(rt_hw_stm32_eth_init, 初始化网络。);
void show_version(void)
{
rt_kprintf("SW Version: %s\n","1.3");
rt_kprintf("SW Version: %s\n","1.41");
}
MSH_CMD_EXPORT(show_version,);

View File

@ -155,6 +155,198 @@ void tm2str(int argc, char **argv)
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);
}
strncpy(str,rst,strlen(rst)-strlen(sep));//去掉末尾的连接符
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;
}
void sDemo()
{

View File

@ -50,6 +50,7 @@ void w25q128_mount(void)
if(dev != RT_NULL) {
if(dfs_mount("W25Q128", "/", "elm", 0, 0) == 0){
// rt_kprintf("spi_flash mount to spi!\n");
mkdir("sd",0);
} else {
rt_kprintf("spi_flash mount to spi failed!\n");
}
@ -59,6 +60,9 @@ void w25q128_mount(void)
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(w25q128_mount);
//1.41版本之前挂载并未出现问题。
//1.41版出现flash能挂载而sd卡正确识别后却不能挂载的问题
//后发现是SD卡的挂载目录"sd"丢失,原因未知。
void sdmnt_init(void)

View File

@ -9,6 +9,11 @@
"ver": "v1.7.15",
"name": "CJSON"
},
{
"path": "/packages/system/enhanced-kservice/rt_vsnprintf_full",
"ver": "latest",
"name": "RT_VSNPRINTF_FULL"
},
{
"path": "/packages/system/syswatch",
"ver": "latest",
@ -19,6 +24,11 @@
"ver": "latest",
"name": "MININI"
},
{
"path": "/packages/misc/samples/peripheral_samples",
"ver": "latest",
"name": "PERIPHERAL_SAMPLES"
},
{
"path": "/packages/misc/fastlz",
"ver": "v1.0.1",