9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
390 lines
13 KiB
C
390 lines
13 KiB
C
#include "publicdata/publicdata.h"
|
||
#include "app_init/app_init.h"
|
||
#include <string.h>
|
||
|
||
/**
|
||
* ************************************************************************
|
||
* @brief - 全局应用函数接口文件--用于汇总所有公共函数
|
||
*
|
||
* @author jiankalka
|
||
* @date 2025-09-12
|
||
* ************************************************************************
|
||
*/
|
||
|
||
const char *success = "success";
|
||
const char *failure = "failure";
|
||
|
||
#if 1 //数据校验函数
|
||
//CRC校验驱动表
|
||
const U8_T aucCRCHi[] = {
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||
0x00, 0xC1, 0x81, 0x40
|
||
};
|
||
|
||
const U8_T aucCRCLo[] = {
|
||
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
|
||
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
|
||
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
|
||
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
|
||
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
|
||
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
|
||
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
|
||
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
|
||
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
|
||
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
|
||
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
|
||
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
|
||
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
|
||
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
|
||
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
|
||
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
|
||
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
|
||
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
|
||
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
|
||
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
||
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
|
||
0x41, 0x81, 0x80, 0x40
|
||
};
|
||
|
||
//计算累加和校验
|
||
U16_T u16_crc_checksum(U8_T *p, U16_T u16_len)
|
||
{
|
||
U16_T i;
|
||
U16_T u16_sum = 0;
|
||
|
||
for (i=0; i<u16_len; i++)
|
||
u16_sum += *(p+i);
|
||
|
||
return u16_sum;
|
||
}
|
||
//modbus crc16校验函数
|
||
U16_T u16_modbus_crc16( U8_T * pucFrame, U16_T usLen )
|
||
{
|
||
U8_T ucCRCHi = 0xFF;
|
||
U8_T ucCRCLo = 0xFF;
|
||
int iIndex;
|
||
|
||
while( usLen-- )
|
||
{
|
||
iIndex = ucCRCLo ^ *( pucFrame++ );
|
||
ucCRCLo = ( U8_T )( ucCRCHi ^ aucCRCHi[iIndex] );
|
||
ucCRCHi = aucCRCLo[iIndex];
|
||
}
|
||
|
||
return ( U16_T )( ucCRCHi << 8 | ucCRCLo );
|
||
}
|
||
U8_T u8_calculate_bcc(U8_T *pu8_data, U16_T u16_len) //BCC异或校验
|
||
{
|
||
U32_T i;
|
||
U8_T u8_ret = 0;
|
||
|
||
for (i=0; i<u16_len; i++)
|
||
u8_ret ^= *pu8_data++;
|
||
|
||
return u8_ret;
|
||
}
|
||
#endif
|
||
|
||
#if 1 //时间戳、时间数据计算函数
|
||
/**
|
||
* @brief 获取系统运行总毫秒数(从启动开始)
|
||
* @return uint64_t 当前毫秒数(自动处理32位tick溢出)
|
||
*/
|
||
uint64_t u64_get_current_millis(void) {
|
||
static uint32_t overflow_count = 0;
|
||
static TickType_t last_tick = 0;
|
||
|
||
// 进入临界区保护静态变量
|
||
taskENTER_CRITICAL();
|
||
TickType_t current_tick = xTaskGetTickCount();
|
||
|
||
// 检测tick计数器溢出(0xFFFFFFFF → 0)
|
||
if (current_tick < last_tick) {
|
||
overflow_count++;
|
||
}
|
||
last_tick = current_tick;
|
||
taskEXIT_CRITICAL();
|
||
|
||
// 计算总毫秒数 = (溢出次数 * 周期毫秒) + 当前tick转换的毫秒
|
||
const uint64_t period_ms = ((uint64_t)0xFFFFFFFF * 1000) / configTICK_RATE_HZ;
|
||
uint64_t current_ms = (uint64_t)current_tick * 1000 / configTICK_RATE_HZ;
|
||
|
||
return (overflow_count * period_ms) + current_ms;
|
||
}
|
||
|
||
/**
|
||
* @brief 计算当前时间与上次时间的毫秒数差值(自动处理64位溢出)
|
||
* @param last_millis 上次记录的时间戳(毫秒)
|
||
* @return uint64_t 距离上次时间的毫秒数差值(总是正数)
|
||
*/
|
||
uint64_t u64_safe_millis_since(uint64_t last_millis) {
|
||
uint64_t current_millis = u64_get_current_millis();
|
||
|
||
// 处理毫秒计数器自增特性(时间不会回退)
|
||
if (current_millis >= last_millis) {
|
||
return current_millis - last_millis;
|
||
} else {
|
||
// 发生错误时返回0(如传入未来时间或时间重置)
|
||
return 0;
|
||
}
|
||
}
|
||
/**
|
||
* @brief 获取系统运行总秒数(从启动开始)
|
||
* @return uint32_t 当前秒数(自动处理32位tick溢出)
|
||
*/
|
||
uint32_t get_current_seconds(void) {
|
||
return (uint32_t)(u64_get_current_millis() / 1000);
|
||
}
|
||
|
||
/**
|
||
* @brief 计算当前时间与上次时间的秒数差值(无符号,自动处理溢出)
|
||
* @param last_sec 上次记录的时间戳(秒)
|
||
* @return uint32_t 距离上次时间的秒数差值(总是正数)
|
||
*/
|
||
uint32_t u32_safe_seconds_since(uint32_t last_sec) {
|
||
// 获取当前秒数(基于系统tick,含溢出处理)
|
||
uint32_t current_sec = get_current_seconds(); // 使用前文定义的get_current_seconds()
|
||
|
||
// 计算差值(自动处理32位溢出)
|
||
return (current_sec >= last_sec) ? (current_sec - last_sec) :
|
||
(0xFFFFFFFF - last_sec + current_sec + 1);
|
||
}
|
||
|
||
#endif
|
||
|
||
#if 1 //数据进制转换函数-BCD转换
|
||
// 十进制转BCD
|
||
uint8_t dec_to_bcd(uint8_t dec) {
|
||
return ((dec / 10) << 4) | (dec % 10);
|
||
}
|
||
|
||
// BCD转十进制
|
||
uint8_t bcd_to_dec(uint8_t bcd) {
|
||
return ((bcd >> 4) * 10) + (bcd & 0x0F);
|
||
}
|
||
|
||
/**
|
||
* @brief 将BCD码转换为ASCII字符串
|
||
* @param bcd_data BCD码数据数组
|
||
* @param bcd_len BCD数据长度(字节数)
|
||
* @param ascii_str 输出ASCII字符串缓冲区
|
||
* @param ascii_buf_len 输出缓冲区大小 要大于bcd_len*2+1
|
||
* @return 成功返回0,失败返回-1
|
||
*/
|
||
int bcd_to_ascii(const U8_T *bcd_data, U8_T bcd_len,
|
||
char *ascii_str, U8_T ascii_buf_len)
|
||
{
|
||
if (bcd_data == NULL || ascii_str == NULL) {
|
||
return -1;
|
||
}
|
||
|
||
// 确保缓冲区足够大(每个BCD字节可以转换为2个ASCII字符)
|
||
if (ascii_buf_len < bcd_len * 2 + 1) {
|
||
return -1;
|
||
}
|
||
|
||
int i, j = 0;
|
||
|
||
for (i = 0; i < bcd_len; i++) {
|
||
// 提取高4位和低4位BCD码
|
||
U8_T high_nibble = (bcd_data[i] >> 4) & 0x0F;
|
||
U8_T low_nibble = bcd_data[i] & 0x0F;
|
||
|
||
// 转换为ASCII字符
|
||
if (high_nibble < 10) {
|
||
ascii_str[j++] = high_nibble + '0'; // 数字0-9
|
||
} else if (high_nibble == 0x0A) {
|
||
ascii_str[j++] = 'A'; // 可选的十六进制表示
|
||
} else if (high_nibble == 0x0B) {
|
||
ascii_str[j++] = 'B';
|
||
} else if (high_nibble == 0x0C) {
|
||
ascii_str[j++] = 'C';
|
||
} else if (high_nibble == 0x0D) {
|
||
ascii_str[j++] = 'D';
|
||
} else if (high_nibble == 0x0E) {
|
||
ascii_str[j++] = 'E';
|
||
} else if (high_nibble == 0x0F) {
|
||
ascii_str[j++] = 'F';
|
||
}
|
||
|
||
if (low_nibble < 10) {
|
||
ascii_str[j++] = low_nibble + '0';
|
||
} else if (low_nibble == 0x0A) {
|
||
ascii_str[j++] = 'A';
|
||
} else if (low_nibble == 0x0B) {
|
||
ascii_str[j++] = 'B';
|
||
} else if (low_nibble == 0x0C) {
|
||
ascii_str[j++] = 'C';
|
||
} else if (low_nibble == 0x0D) {
|
||
ascii_str[j++] = 'D';
|
||
} else if (low_nibble == 0x0E) {
|
||
ascii_str[j++] = 'E';
|
||
} else if (low_nibble == 0x0F) {
|
||
ascii_str[j++] = 'F';
|
||
}
|
||
}
|
||
|
||
ascii_str[j] = '\0'; // 字符串结束符
|
||
return 0;
|
||
}
|
||
#endif
|
||
|
||
#if 1 //系统重启
|
||
|
||
void v_sys_reboot()
|
||
{
|
||
printf("sys reboot\r\n");
|
||
mSleep(2000);
|
||
//重启
|
||
|
||
__set_FAULTMASK(1); //关闭所有中断
|
||
NVIC_SystemReset(); //复位函数
|
||
}
|
||
#endif
|
||
|
||
#if 1 //Base64编码解码函数
|
||
|
||
/**
|
||
* @brief BASE64编码函数
|
||
* @param input 二进制数据输入
|
||
* @param input_len 输入数据长度
|
||
* @param output 输出缓冲区(Base64字符串)
|
||
* @param output_size 输出缓冲区大小
|
||
* @return 编码后的字符串长度,-1表示错误
|
||
*/
|
||
int base64_encode(const uint8_t *input, uint32_t input_len,
|
||
char *output, uint32_t output_size)
|
||
{
|
||
static const char base64_table[] =
|
||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||
|
||
if (input == NULL || output == NULL || output_size == 0) {
|
||
return -1;
|
||
}
|
||
|
||
uint32_t i = 0, j = 0;
|
||
uint32_t output_len = ((input_len + 2) / 3) * 4; /* Base64编码后的长度 */
|
||
|
||
if (output_len + 1 > output_size) {
|
||
return -1;
|
||
}
|
||
|
||
while (i < input_len) {
|
||
uint32_t octet_a = i < input_len ? input[i++] : 0;
|
||
uint32_t octet_b = i < input_len ? input[i++] : 0;
|
||
uint32_t octet_c = i < input_len ? input[i++] : 0;
|
||
|
||
uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;
|
||
|
||
output[j++] = base64_table[(triple >> 18) & 0x3F];
|
||
output[j++] = base64_table[(triple >> 12) & 0x3F];
|
||
output[j++] = base64_table[(triple >> 6) & 0x3F];
|
||
output[j++] = base64_table[triple & 0x3F];
|
||
}
|
||
|
||
/* 添加填充字符 */
|
||
if (input_len % 3 == 1) {
|
||
output[j - 2] = '=';
|
||
output[j - 1] = '=';
|
||
} else if (input_len % 3 == 2) {
|
||
output[j - 1] = '=';
|
||
}
|
||
|
||
output[j] = '\0';
|
||
return j;
|
||
}
|
||
|
||
/**
|
||
* @brief BASE64解码函数
|
||
* @param input Base64编码字符串输入
|
||
* @param output 输出缓冲区(二进制数据)
|
||
* @param output_size 输出缓冲区大小
|
||
* @return 解码后的数据长度,-1表示错误
|
||
*/
|
||
int base64_decode(const char *input, uint8_t *output, uint32_t output_size)
|
||
{
|
||
static const int8_t base64_reverse_table[] = {
|
||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
|
||
};
|
||
|
||
if (input == NULL || output == NULL || output_size == 0) {
|
||
return -1;
|
||
}
|
||
|
||
uint32_t input_len = strlen(input);
|
||
uint32_t i = 0, j = 0;
|
||
uint32_t output_len = (input_len * 3) / 4; /* 最大可能的输出长度 */
|
||
|
||
if (output_len > output_size) {
|
||
return -1;
|
||
}
|
||
|
||
/* 跳过末尾的填充字符 */
|
||
while (input_len > 0 && input[input_len - 1] == '=') {
|
||
input_len--;
|
||
}
|
||
|
||
/* 解码过程 */
|
||
while (i < input_len) {
|
||
int8_t sextet_a = (i < input_len) ? base64_reverse_table[(uint8_t)input[i++]] : -1;
|
||
int8_t sextet_b = (i < input_len) ? base64_reverse_table[(uint8_t)input[i++]] : -1;
|
||
int8_t sextet_c = (i < input_len) ? base64_reverse_table[(uint8_t)input[i++]] : -1;
|
||
int8_t sextet_d = (i < input_len) ? base64_reverse_table[(uint8_t)input[i++]] : -1;
|
||
|
||
if (sextet_a == -1 || sextet_b == -1) {
|
||
return -1; /* 无效的Base64字符 */
|
||
}
|
||
|
||
uint32_t triple = (sextet_a << 18) | (sextet_b << 12);
|
||
|
||
if (sextet_c != -1) {
|
||
triple |= sextet_c << 6;
|
||
}
|
||
|
||
if (sextet_d != -1) {
|
||
triple |= sextet_d;
|
||
}
|
||
|
||
output[j++] = (triple >> 16) & 0xFF;
|
||
|
||
if (sextet_c != -1) {
|
||
output[j++] = (triple >> 8) & 0xFF;
|
||
}
|
||
|
||
if (sextet_d != -1) {
|
||
output[j++] = triple & 0xFF;
|
||
}
|
||
}
|
||
|
||
return j;
|
||
}
|
||
|
||
#endif /* Base64编码解码函数 */
|