添加初始化时建立sd目录避免sd卡挂载失败的问题
自检功能测试ok tools.c 添加部分基本函数 func.c 解析逻辑部分初步完成
This commit is contained in:
parent
b0571964e8
commit
851c1c2352
@ -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数据,以0x5AA5开头0xED结尾。
|
||||
*
|
||||
* @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
79
applications/func/func.h
Normal 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_ */
|
@ -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,显示版本号);
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user