//int_fifo.h文件
#ifndef INT_FIFO_H_
#define INT_FIFO_H_
#define INT_FIFO_Write_Err 0xD5020000 //输出FIFO已经写满
#define INT_FIFO_Read_Bottom_Err 0xD5020001 //输出FIFO已经写满
struct INT_OUTPUT_FIFO {
unsigned short Dead_Ptr; // 指向数据死区指针,在 FIFO 头指针与尾指针之间
unsigned short Top_Ptr; // fifo 头指针,写入 FIFO
unsigned short Bottom_Ptr; // fifo 尾指针,读取 FIFO
unsigned short Free; // FIFO空余容量
unsigned short Use; // FIFO使用容量
unsigned short Pause_Ptr;
unsigned short Bak2;
unsigned short Bak3;
};
struct OUT_INT_REG{
unsigned long long Data;
};
int INT_FIFO_Write(struct OUT_INT_REG *Ptr);
int INT_FIFO_Read_BottomPtr(unsigned long long *Ptr);
#endif /* INT_FIFO_H_ */
//pause.h文件
#ifndef PAUSE_H
#define PAUSE_H
#define INT_FIFO_USE 800
#define FIFO_SIZE 1024
#define Vmax 1000
#define Amax 1.0
#define MAX_SIZE 1000
#define ARR_SIZE 1736
#define CH_SIZE 32
#define Limit_SIZE 1000
#define Trigger_usage 33
#define change_speed_zero_esp 0.0000001
#define main_Amax_zero_error 0x01
#define main_ff_zero_error 0x01
#define pause_plan_and_interpolation_pause_T_zero_error 0x01
#define pause_plan_and_interpolation_Exceed_maximum_quantity_error 0x01
#define Data_processing_is_not_complete_error 0x01
typedef struct {
double pause_first_coefficient;
double pause_last_coefficient;
double delta_coefficient;
double pause_t;
int end_flag;
double pause_T;
double pause_F;
double pause_totol_F;
double pause_cur_pos;
double pause_next_pos;
double pause_hold;
int pause_n;
int pause_x;
} PauseRegType;
void Calculate_hold(int n);
int pause_plan_and_interpolation();
#endif // PAUSE_H
//test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <int_fifo.h>
#include <pause.h>
double joint_hold;
double joint_data;
double input_data;
double data[ARR_SIZE];
int joint_count;
unsigned long long INTFIFO[1024];
OUT_INT_REG fifo;
unsigned long long* Fifo = (unsigned long long*) & input_data;
INT_OUTPUT_FIFO INT_FIFO_Reg;
PauseRegType PauseReg = { 0 };
int jump_count = 1, n = 0;
int main()
{
//初始化
int err = 0;
int totol_num = 1;
int data_count = 0;
int int_fifo_data_end = 0;
int data_num = 1;
double dis[MAX_SIZE] = { 0 };
double vel[FIFO_SIZE] = { 0 };
double OUTPUT_DATA[FIFO_SIZE] = { 0 };
//打开文件
int dig[ARR_SIZE] = { 0 }; //小数位数
int count = 0, x = 0;
FILE* fp;//
fp = fopen("D:\\Code01\\Project2\\Project2\\data.txt", "r");//fp = fopen("D:\\data.txt", "r");
if (!fp)
{
printf("File open fail!\n");
return 1;
}
char* buffer = (char*)malloc(CH_SIZE * sizeof(char));
if (buffer == NULL)
{
printf("缓存分配失败\n");
fclose(fp);
return 1;
}
memset(buffer, 0, CH_SIZE * sizeof(char));
while (1) {
if (fscanf(fp, "%s", buffer) == 1)
{
if (sscanf_s(buffer, "%lf", &data[count], CH_SIZE) == 1)
{
char* ptr2 = strchr(buffer, 'e'); //+1.23400e-03 ptr2=8
if (ptr2)
{ // 如果是科学计数法,提取出整数部分,根据符号位计算小数位
ptr2++;
sscanf_s(ptr2, "%d", &x);
if (*ptr2 == '-')
x += 4;
else
x += 3;
}
else
x = 0;
dig[count] = (int)(strlen(buffer) - 4 - x);
if (dig[count] <= 0) dig[count] = 1;// 如果是 1 位或 2 位的整数,输出 1 位小数位
//printf("%.*f\n", dig[count] , data[count]);
count++;
if (count >= Limit_SIZE || count >= ARR_SIZE) break;
//数据读取超过 1000 则退出,或超过数组data[]大小也须退出
}
memset(buffer, 0, CH_SIZE * sizeof(char));
}
else
break;
}
fclose(fp);
free(buffer);
//写数据
INT_FIFO_Reg.Use = 0;
if (INT_FIFO_Reg.Use < INT_FIFO_USE)
{
int NUM = INT_FIFO_USE - INT_FIFO_Reg.Use;
for (int i = 0; i < NUM; i++)
{
if (data_num > ARR_SIZE)
{
break;
}
INT_FIFO_Reg.Use = INT_FIFO_Write(&fifo); //写入 INTFIFO;
//写入无效
data_num++;
}
}
//读数据
//INT_FIFO_Reg.Use = INT_FIFO_Read_BottomPtr(Fifo); //*Ptr
//joint_data = pause_plan_and_interpolation();
INT_FIFO_Reg.Use = INT_FIFO_Read_BottomPtr(Fifo); //读到intputdtata
joint_data = pause_plan_and_interpolation();
//判断是否用完一个数据
while (PauseReg.pause_totol_F >= (double)(PauseReg.pause_n + n - PauseReg.pause_x))
{
INT_FIFO_Reg.Use = INT_FIFO_Read_BottomPtr(Fifo); //读到intputdtata
// 结束段触发信号
if (INT_FIFO_Reg.Use <= 33)
{
int_fifo_data_end = 1;
}
// 数据初始化 全局速度修改
if (jump_count == 1)
{
PauseReg.pause_first_coefficient = 0.8;
PauseReg.pause_last_coefficient = 0;
PauseReg.pause_F = PauseReg.pause_first_coefficient;
PauseReg.pause_x = 1;
PauseReg.pause_n = 0;
PauseReg.pause_totol_F = 0;
PauseReg.pause_cur_pos = 0;//input_data[0];
PauseReg.pause_next_pos = 0;// input_data[0];
PauseReg.pause_t = 0;
PauseReg.pause_T = 0;
}
// 正常变速指令处理
PauseReg.pause_first_coefficient = PauseReg.pause_F;
srand((unsigned int)time(NULL)); // 初始化随机数生成器
PauseReg.pause_last_coefficient = (double)(rand() / (RAND_MAX + 1.0) * 100.0) / 100; // 生成0\~1之间的随机数并保留
PauseReg.end_flag = 0;
double Tmax = (double)(Vmax / Amax);
if (Amax < change_speed_zero_esp)
{
err = main_Amax_zero_error;
return err;
}
double delta_k = fabs(PauseReg.pause_first_coefficient - PauseReg.pause_last_coefficient);
PauseReg.pause_T = Tmax * delta_k;
joint_data = pause_plan_and_interpolation();
//printf("%lf", joint_data);
jump_count++;
//结束段停止处理
if (int_fifo_data_end == 1)
{
// PauseRegType PauseReg = { 0 };
PauseReg.pause_first_coefficient = PauseReg.pause_F;
PauseReg.pause_last_coefficient = 0;
PauseReg.end_flag = 1;
double D = 2 * (32 + 1 - PauseReg.pause_totol_F + floor(PauseReg.pause_totol_F));
double ff = (double)(PauseReg.pause_first_coefficient - pow(PauseReg.pause_first_coefficient, 2) / (PauseReg.pause_first_coefficient + D));
PauseReg.pause_T = (double)(D / ff);
if (ff < change_speed_zero_esp)
{
err = main_ff_zero_error;
return err;
}
joint_data = pause_plan_and_interpolation();
//printf("%lf", joint_data);
jump_count++;
}
return joint_data;
}
}
//写入数据函数
int INT_FIFO_Write(struct OUT_INT_REG* Ptr)
{
unsigned short ax, bx; //ax=ptr
unsigned short n;
//int m = 0;
//int k = 0;
// 检查 FIFO 是否已满
if ((INT_FIFO_Reg.Top_Ptr + 1) % 1024 == INT_FIFO_Reg.Bottom_Ptr) {
printf("Error: FIFO is full before writing.\n");
return INT_FIFO_Write_Err;
}
//检查指针
printf("Before Write: Top = %d, Bottom = %d, Use = %d\n", INT_FIFO_Reg.Top_Ptr, INT_FIFO_Reg.Bottom_Ptr, INT_FIFO_Reg.Use);
//OS_ENTER_CRITICAL(); //禁止中断
n = 32;//取死指针32ms数据
if (INT_FIFO_Reg.Free == 0)//其他正在操作未加入,公用信号量
{
//OS_EXIT_CRITICAL(); //取消禁止中断
return INT_FIFO_Write_Err;
}
ax = (INT_FIFO_Reg.Top_Ptr + 1) & 0x03FF;
if (ax >= 1024) {
// 处理错误情况,例如返回错误码或者调整指针
return INT_FIFO_Write_Err;
}
if (ax == 0)
{
ax = 1024;
}
if (ax == INT_FIFO_Reg.Bottom_Ptr) //FIFO写满
{
//OS_EXIT_CRITICAL(); //取消禁止中断
return INT_FIFO_Write_Err;
}
Ptr->Data = (unsigned long long)data[m++];
INTFIFO[ax] = (unsigned long long)Ptr->Data;
INT_FIFO_Reg.Top_Ptr = ax; // 更新 Top_Ptr
// 计算 FIFO 使用量
if (INT_FIFO_Reg.Top_Ptr > INT_FIFO_Reg.Bottom_Ptr) // 计算 FIFO 使用量
{
INT_FIFO_Reg.Use = INT_FIFO_Reg.Top_Ptr - INT_FIFO_Reg.Bottom_Ptr + 1;
}
else
{
INT_FIFO_Reg.Use = 1024 - (INT_FIFO_Reg.Bottom_Ptr - INT_FIFO_Reg.Top_Ptr) + 1;
}
INT_FIFO_Reg.Free = 1024 - INT_FIFO_Reg.Use; // 计算 FIFO 空余量
bx = (INT_FIFO_Reg.Bottom_Ptr + n) & 0x03FF;
if (bx == 0)
{
bx = 1024;
}
if (INT_FIFO_Reg.Dead_Ptr != bx)
{
INT_FIFO_Reg.Dead_Ptr = (INT_FIFO_Reg.Dead_Ptr + 1) & 0x03FF;
}
//OS_EXIT_CRITICAL(); //取消禁止中断
return INT_FIFO_Reg.Use;
}
//读数据函数
int INT_FIFO_Read_BottomPtr(unsigned long long* Ptr)
{
unsigned short ax, bx, m;
printf("Before Read: Top = %d, Bottom = %d, Use = %d\n", INT_FIFO_Reg.Top_Ptr, INT_FIFO_Reg.Bottom_Ptr, INT_FIFO_Reg.Use);
bx = (INT_FIFO_Reg.Top_Ptr + 1) & 0x03FF;
if (bx == 0)
{
bx = 1024;
}
if ((INT_FIFO_Reg.Bottom_Ptr != bx) || (INT_FIFO_Reg.Use == 1024))
{
ax = INT_FIFO_Reg.Bottom_Ptr;
if (ax == 0)
{
ax = 1024;
}
*Ptr = INTFIFO[ax];
if (INT_FIFO_Reg.Bottom_Ptr != INT_FIFO_Reg.Top_Ptr)
{
INT_FIFO_Reg.Bottom_Ptr = (INT_FIFO_Reg.Bottom_Ptr + 1) & 0x03FF; // 对 Bottom_Ptr 指针加1
}
if (INT_FIFO_Reg.Dead_Ptr != INT_FIFO_Reg.Top_Ptr)
{
INT_FIFO_Reg.Dead_Ptr = (INT_FIFO_Reg.Dead_Ptr + 1) & 0x03FF; // 对 Dead_Ptr 指针加1
}
if (INT_FIFO_Reg.Top_Ptr >= INT_FIFO_Reg.Bottom_Ptr) // 计算 FIFO 使用量
{
INT_FIFO_Reg.Use = INT_FIFO_Reg.Top_Ptr - INT_FIFO_Reg.Bottom_Ptr + 1;
}
else
{
INT_FIFO_Reg.Use = 1024 - (INT_FIFO_Reg.Bottom_Ptr - INT_FIFO_Reg.Top_Ptr) + 1;
}
INT_FIFO_Reg.Free = 1024 - INT_FIFO_Reg.Use; // 计算 FIFO 空余量
return INT_FIFO_Reg.Use;
}
else
{
return INT_FIFO_Read_Bottom_Err;
}
}
// pause_plan_and_interpolation()函数略
#endif /* INT_FIFO_H_ */
为什么写数据函数中语句“INTFIFO[ax] = (unsigned long long)Ptr->Data;”报错:写入缓存区溢出?
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
1条回答 默认 最新
关注 - 问题分析
- 报错“写入缓存区溢出”意味着在执行
INTFIFO[ax]=(unsigned long long)Ptr - > Data;
语句时,ax
的值可能超出了INTFIFO
数组的有效索引范围。 - 在
INT_FIFO_Write
函数中,ax
的计算方式为ax=(INT_FIFO_Reg.Top_Ptr + 1)&0x03FF;
,如果没有正确地处理边界情况或者在后续计算中出现错误,就可能导致越界访问。 - 另外,从代码逻辑看,
Ptr->Data
的类型转换和赋值操作也可能存在问题。
- 报错“写入缓存区溢出”意味着在执行
- 修改方案
- 检查索引计算
- 在
INT_FIFO_Write
函数中,确保ax
的计算结果在INTFIFO
数组的有效索引范围内。目前ax
的计算是ax=(INT_FIFO_Reg.Top_Ptr + 1)&0x03FF;
,如果INT_FIFO_Reg.Top_Ptr
的值接近INTFIFO
数组的大小,加上1后可能会超出范围。可以添加一个额外的检查来确保ax
不超过INTFIFO
的大小。例如:ax=(INT_FIFO_Reg.Top_Ptr + 1)&0x03FF; if(ax >= sizeof(INTFIFO)/sizeof(INTFIFO[0])) { // 处理错误情况,例如返回错误码或者调整指针 return -1; }
- 在
- 数据类型和赋值检查
- 对于
INTFIFO[ax]=(unsigned long long)Ptr - > Data;
语句,需要确保Ptr->Data
的数据类型与INTFIFO
数组元素的类型匹配。如果Ptr->Data
是一个数组或者结构体的成员,可能需要调整赋值方式。例如,如果Ptr->Data
是一个数组,而你只想赋值数组的第一个元素,可以修改为:INTFIFO[ax]=(unsigned long long)Ptr->Data[0];
- 对于
- FIFO容量检查
- 在写入数据之前,除了检查FIFO是否已满(当前代码已经有部分检查),还需要确保有足够的空间来存储即将写入的数据。例如,如果要写入的数据大小是固定的,可以在写入之前检查
INT_FIFO_Reg.Free
是否大于等于这个固定大小。
- 在写入数据之前,除了检查FIFO是否已满(当前代码已经有部分检查),还需要确保有足够的空间来存储即将写入的数据。例如,如果要写入的数据大小是固定的,可以在写入之前检查
- 整体逻辑调整
- 在
for
循环中对INTFIFO
数组进行写入操作时,需要确保索引计算正确。当前代码中的INTFIFO[ax * ARR_SIZE + i]=(unsigned long long)Ptr->Data[i];
看起来有些复杂且可能存在错误。如果Ptr->Data
是一个简单的unsigned long long
类型,可能不需要这样的循环。如果Ptr->Data
是一个数组,需要重新审视整个写入逻辑。例如,如果Ptr->Data
是一个包含ARR_SIZE
个unsigned long long
元素的数组,并且要将其全部写入INTFIFO
,可以这样修改:// 假设INTFIFO足够大来容纳所有数据 if(INT_FIFO_Reg.Free >= ARR_SIZE) { for (int i = 0; i < ARR_SIZE; i++) { ax=(INT_FIFO_Reg.Top_Ptr + i + 1)&0x03FF; if(ax >= sizeof(INTFIFO)/sizeof(INTFIFO[0])) { // 处理错误情况,例如返回错误码或者调整指针 return -1; } INTFIFO[ax]=(unsigned long long)Ptr->Data[i]; } INT_FIFO_Reg.Top_Ptr=(INT_FIFO_Reg.Top_Ptr + ARR_SIZE)&0x03FF; // 更新其他相关的FIFO状态变量,如Use和Free INT_FIFO_Reg.Use += ARR_SIZE; INT_FIFO_Reg.Free -= ARR_SIZE; } else { // 处理FIFO空间不足的情况,例如返回错误码 return -1; }
- 在
- 检查索引计算
注意,以上答案源自微信小程序“超时代智能助手”,仅供参考,实用性请自行斟酌
解决 无用评论 打赏 举报- 问题分析
悬赏问题
- ¥15 ansys fluent计算闪退
- ¥15 有关wireshark抓包的问题
- ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
- ¥15 向数据表用newid方式插入GUID问题
- ¥15 multisim电路设计
- ¥20 用keil,写代码解决两个问题,用库函数
- ¥50 ID中开关量采样信号通道、以及程序流程的设计
- ¥15 U-Mamba/nnunetv2固定随机数种子
- ¥15 vba使用jmail发送邮件正文里面怎么加图片
- ¥15 vb6.0如何向数据库中添加自动生成的字段数据。