第一次提交

This commit is contained in:
2025-10-04 16:06:55 +08:00
commit 2acba0caf0
58 changed files with 11679 additions and 0 deletions

493
app/app_param_manage.c Normal file
View File

@@ -0,0 +1,493 @@
#include "app_config.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
#include "app_param_manage.h"
#define E2_RESERVE_COUNT 0x20 //增加IP地址 修改为0x20 20250110
// 待发送的参数请求信号
UnParamRequest un_param_request1 ;
UnParamRequest un_param_request2;
RequestContext request_send ;
RequestContext request_context ;
uint8_t read_write_e2_finished = 0;
// 定义全局信号实例,读写信号现在包括 offset 和 size
ParamSignal param_signal = {
.param_ptr = NULL, // 参数指针初始化为 NULL
.type = READ_OPERATION, // 操作类型设置为读操作
.offset = 0, // 整个数据块的偏移
.size = sizeof(param_manager.arr) // 整个数据块的大小
};
// 全局变量:初始化参数名称结构体
ParamNames param_names = {
#define X(name) .name = #name,
PARAM_LIST
#undef X
};
UnParamManager param_manager ;
static uint8_t is_param_initialized = 0;
// 打印所有参数的名称和值, 每行 4 个参数
void printParams()
{
unsigned int param_count = 0;
#define X(name) \
printf("%-8s: %-8.2f", param_names.name, param_manager.bit_data.name); \
param_count++; \
if (param_count % 4 == 0) { \
printf("\n"); \
} else { \
printf(" "); \
}
PARAM_LIST
#undef X
// 如果最后一行不足 4 个参数, 打印换行
if (param_count % 4 != 0)
{
printf("\n");
}
}
void writeByte24c02(uint16_t addr, uint8_t data)
{
if(0 != wrbyte_24c02(addr,data))
{
printf("E2PROM write error!\n");
}
}
uint8_t readByte24c02(uint16_t addr)
{
return rdbyte_24c02(addr);
}
// 定义一个通用的 EEPROM 访问函数
uint8_t accessEeprom(size_t offset, void *data, size_t size, OperationType type)
{
if (data == NULL || size == 0)
{
return 1; // 返回错误状态,表示无效的参数
}
uint8_t *byte_data = (uint8_t *)data; // 将 void* 转换为 uint8_t*,方便逐字节操作
size_t index;
if (type == WRITE_OPERATION)
{
// 写入操作
for (index = 0; index < size; index++)
{
writeByte24c02((uint16_t)(offset + index + E2_RESERVE_COUNT), byte_data[index]);
udelay(4000);//写入一个字节延时4ms
}
// 校验
for (index = 0; index < size; index++)
{
if (readByte24c02((uint16_t)(offset + index + E2_RESERVE_COUNT)) != byte_data[index])
{
return 2; // 返回错误状态,表示写入验证失败
}
}
}
else
{
// 读取操作
for (index = 0; index < size; index++)
{
byte_data[index] = readByte24c02((uint16_t)(offset + index + E2_RESERVE_COUNT));
}
}
return 0; // 返回状态,表示成功
}
void handleParamOp(void *data)
{
ParamSignal *signal = (ParamSignal *)data;
if (signal->param_ptr == NULL)
{
// 操作整个参数管理器
if (accessEeprom(0, param_manager.arr, sizeof(param_manager.arr), signal->type) == 0)
{
read_write_e2_finished = 1;
publishMessage(&read_write_e2_finished, 1); // 读写成功
}
else
{
read_write_e2_finished = 2;
publishMessage(&read_write_e2_finished, 1); // 读写失败
}
}
else
{
// 根据信号中的偏移和大小操作单个参数
if (accessEeprom(signal->offset, signal->param_ptr, signal->size, signal->type) == 0)
{
read_write_e2_finished = 1;
publishMessage(&read_write_e2_finished, 1); // 读写成功
}
else
{
read_write_e2_finished = 2;
publishMessage(&read_write_e2_finished, 1); // 读写失败
}
}
}
uint8_t calculateCRC(const uint8_t* data, uint32_t length) {
uint8_t crc = 0;
for (uint32_t i = 0; i < length; ++i) {
crc += data[i]; // 简单的校验和,按字节累加
}
return crc;
}
float readParameter(const char *param_name) {
float float_value = 0;
unsigned int offset = 0;
#define X(name) \
if (strcmp(param_name, param_names.name) == 0) { \
accessEeprom(offset, &param_manager.bit_data.name,sizeof(param_manager.bit_data.name), READ_OPERATION);\
memcpy(&float_value, &param_manager.bit_data.name, sizeof(param_manager.bit_data.name)); \
return float_value; \
} \
offset += 4;
PARAM_LIST
#undef X
printf("Parameter not found: %s\n", param_name);
return 0;
}
void writeParameter(const char *param_name, const uint8_t *data) {
unsigned int offset = 0;
#define X(name) \
if (strcmp(param_name, param_names.name) == 0) { \
memcpy(&param_manager.bit_data.name, data, sizeof(param_manager.bit_data.name)); \
accessEeprom(offset, &param_manager.bit_data.name,sizeof(param_manager.bit_data.name), WRITE_OPERATION);\
return; \
} \
offset += 4;
PARAM_LIST
#undef X
printf("Parameter not found: %s\n", param_name);
}
void sendParamRequestResponse(UnParamRequest *paramRequest, uint32_t sender_ip, uint16_t sender_port, uint8_t isWriteOperation) {
// 准备响应帧
paramRequest->bit_data.frame_header = 0xFF80;
paramRequest->bit_data.frame_type = 0x002B;
paramRequest->bit_data.frame_length = sizeof(StrParamRequest);
paramRequest->bit_data.accumulated = 0;
paramRequest->bit_data.request_id = isWriteOperation ? 98 : 99;
paramRequest->bit_data.crc = calculateCRC(paramRequest->arr, sizeof(paramRequest->arr) - 1);
request_send.param_request = paramRequest;
request_send.sender_ip = sender_ip;
request_send.sender_port = sender_port;
// 发送信号从UDP发送
publishMessage(&request_send, 1);
}
void processReadAllParams(UnParamRequest *paramRequest, uint32_t sender_ip, uint16_t sender_port) {
uint8_t allParams[256][4]; // Size based on E2 size
unsigned int i = 0;
float param_value;
uint8_t exceeded_max = 0; // 新增标志变量
// 清零 paramRequest
memset(paramRequest, 0, sizeof(UnParamRequest));
accessEeprom(0, param_manager.arr, sizeof(param_manager.arr), READ_OPERATION);
printf("Sending parameter data:\n");
#define X(name) \
if (!exceeded_max) { \
if (i < 256) { \
strncpy((char *)paramRequest->bit_data.param_name[i], #name, sizeof(paramRequest->bit_data.param_name[i]) - 1); \
paramRequest->bit_data.param_name[i][sizeof(paramRequest->bit_data.param_name[i]) - 1] = '\0'; \
memcpy(allParams[i], &param_manager.bit_data.name, sizeof(param_manager.bit_data.name)); \
memcpy(&param_value, allParams[i], sizeof(float)); \
printf("Parameter name: %-20s Value: %f\n", #name, param_value); \
i++; \
} else { \
printf("Warning: Exceeded maximum number of parameters\n"); \
exceeded_max = 1; \
} \
}
PARAM_LIST
#undef X
// Pack all parameter data into paramRequest
memcpy(paramRequest->bit_data.data, allParams, sizeof(allParams));
printf("Total parameters sent: %d\n", i);
// Send response
sendParamRequestResponse(paramRequest, sender_ip, sender_port, 0);
}
void processWriteRequestFrame(UnParamRequest *paramRequest, uint32_t sender_ip, uint16_t sender_port) {
float value;
printf("Processing write request.\n");
// 先发送信号,然后从结构体读数
for (int i = 0; i < 256; ++i) {
if (strlen((char *)paramRequest->bit_data.param_name[i]) > 0) {
writeParameter(paramRequest->bit_data.param_name[i], paramRequest->bit_data.data[i]);
printf("paramRequest->bit_data.param_name[i]:%s \n",paramRequest->bit_data.param_name[i]);
memcpy(&value, paramRequest->bit_data.data[i], sizeof(float));
printf("paramRequest->bit_data.data[i]:%f \n", value);
}
}
// 发送响应,发送所有参数
processReadAllParams(paramRequest, sender_ip, sender_port);
}
void processReadRequestFrame(UnParamRequest *paramRequest, uint32_t sender_ip, uint16_t sender_port) {
printf("Processing read request.\n");
// 先备份原始请求数据
UnParamRequest originalRequest;
memcpy(&originalRequest, paramRequest, sizeof(UnParamRequest));
// 清零响应数据
memset(paramRequest, 0, sizeof(UnParamRequest));
// 处理客户端请求的参数
for (int i = 0; i < 256; ++i) {
if (strlen((char *)originalRequest.bit_data.param_name[i]) > 0) {
// 复制参数名到响应
strcpy((char *)paramRequest->bit_data.param_name[i],
(char *)originalRequest.bit_data.param_name[i]);
// 读取参数值
float readData = readParameter(originalRequest.bit_data.param_name[i]);
memcpy(paramRequest->bit_data.data[i], &readData, sizeof(float));
printf("Read parameter: %s = %f\n",
originalRequest.bit_data.param_name[i], readData);
}
}
// 发送响应 - 直接传递 paramRequest
sendParamRequestResponse(paramRequest, sender_ip, sender_port, 0);
}
void OnParamSignal(void *data)
{
RequestContext *signal = (RequestContext *)data;
uint8_t *datagram = (uint8_t *)signal->param_request->arr;
uint16_t request_id = ((uint16_t)datagram[7] << 8) | (uint16_t)datagram[8];// 大端模式
// 调试输出
printf("Received request ID: 0x%04X\n", request_id);
// 计算CRC
uint8_t calculatedCrc = calculateCRC(datagram, sizeof(UnParamRequest) - 1);
uint8_t receivedCrc = datagram[sizeof(UnParamRequest) - 1];
// 比较CRC
if (calculatedCrc != receivedCrc)
{
printf("CRC check failed, discarding data\n");
printf("Calculated CRC: 0x%02X, Received CRC: 0x%02X\n", calculatedCrc, receivedCrc);
return;
}
printf("CRC check passed\n");
if (request_id == 100)
{ // 读请求
processReadRequestFrame(signal->param_request, signal->sender_ip, signal->sender_port);
}
else if (request_id == 101)
{ // 写请求
processWriteRequestFrame(signal->param_request, signal->sender_ip, signal->sender_port);
}
else if (request_id == 102)
{ // 读取所有参数
processReadAllParams(signal->param_request, signal->sender_ip, signal->sender_port);
}
else
{
printf("Unknown request ID.\n");
return;
}
}
float getParam(const char *param_name)
{
// 检查是否已初始化
if (!is_param_initialized)
{
printf("Parameters not initialized, reinitializing\n");
accessEeprom(0, param_manager.arr, sizeof(param_manager.arr), READ_OPERATION);//Read all parameters from E2
is_param_initialized = 1; // Mark as initialized
printParams();
return 0.0f;
}
// 检查参数名是否为空
if (param_name == NULL)
{
printf("Error: Parameter name is empty\n");
return 0.0f;
}
// 遍历所有参数
#define X(name) \
if (strcmp(param_name, #name) == 0) \
{ \
return param_manager.bit_data.name; \
}
PARAM_LIST
#undef X
// 如果没有找到匹配的参数名
printf("Error: Parameter %s not found\n", param_name);
return 0.0f;
}
// setParam 函数
uint8_t setParam(const char *param_name, float value)
{
// 检查参数名是否为空
if (param_name == NULL)
{
printf("Error: Parameter name is empty\n");
return 2; // 返回错误码
}
// 参数名和值写入EEPROM先转成字节数组
uint8_t data[sizeof(float)];
memcpy(data, &value, sizeof(float));
writeParameter(param_name, data);
// 更新参数
#define X(name) \
if (strcmp(param_name, #name) == 0) \
{ \
memcpy(&param_manager.bit_data.name, data, sizeof(param_manager.bit_data.name)); \
}
PARAM_LIST
#undef X
return 0;
}
void paramAppInit(void)
{
// 初始化全局变量
memset(&un_param_request1, 0, sizeof(UnParamRequest));
memset(&un_param_request2, 0, sizeof(UnParamRequest));
// 正确初始化 RequestContext 结构体
request_send.param_request = &un_param_request1;
request_send.sender_ip = 0;
request_send.sender_port = 0;
request_context.param_request = &un_param_request2;
request_context.sender_ip = 0;
request_context.sender_port = 0;
// 上电读取所有参数
memset(param_manager.arr, 0, sizeof(param_manager.arr));
accessEeprom(0, param_manager.arr, sizeof(param_manager.arr), READ_OPERATION);
// whl_bas 轮胎直径<单位m>
// max_rpm 最大转速<单位rpm/min>
// whl_dia 轴距<单位m>
// max_acc 最大加速度
// spd_kp 遥控速度P
// spd_ki 遥控速度I
// spd_kd 遥控速度D
// spd_il 遥控速度积分限制
// spd_ol 遥控速度PID输出限制
// crv_kp 遥控转弯P
// crv_ki 遥控转弯I
// crv_kd 遥控转弯D
// crv_il 遥控转弯积分限制
// crv_ol 遥控转弯PID输出限制
// brk_on 刹车刹紧时间 单位ms
// brk_off 刹车释放时间 单位ms
// maxTorq 最大扭矩 单位n*m
// feedPwr 最大馈电功率 单位w
// dispPwr 最大放电功率 单位w
// VehMass 车重 单位kg
// gRatio 减速比
// prCTime 预充电时间 单位s
// brk_pos 刹车位置
// pwr_sta 电源状态
// high_sw 高压开关状态
// stop_sw 急停开关状态
// lightSt 灯光状态
// pwr_btn 电源开关状态
// sleepTm 休眠时间 单位min
// wakeTm 唤醒时间 单位min
// Ospd_kp 自主速度P
// Ospd_ki 自主速度I
// Ospd_kd 自主速度D
// Ospd_il 自主速度积分限制
// Ospd_ol 自主速度PID输出限制
// Ocrv_kp 自主转弯P
// Ocrv_ki 自主转弯I
// Ocrv_kd 自主转弯D
// Ocrv_il 自主转弯积分限制
// Ocrv_ol 自主转弯PID输出限制
// minTorq 输出扭矩死区 单位n*m
// brk_rev 刹车方向
// mot_kp 同侧扭矩P参数
// mot_ki 同侧扭矩I参数
// mot_kd 同侧扭矩d参数
// mot_il 同侧扭矩积分限制
// mot_ol 同侧扭矩输出限制
// diff_sp 同侧扭矩速度差阈值
// test 初始化测试参数
// 订阅信号
subscribe(&param_signal, handleParamOp);
subscribe(&request_context, OnParamSignal);// 接收到上位机读写参数信号
printParams();//打印所有参数
is_param_initialized = 1; // 标记初始化完成
printf("paramAPP init OK! %d\n",getCurrentTime());
}