小mi粥的米 2024-09-23 09:42 采纳率: 62.5%
浏览 5

为什么写数据函数中语句“INTFIFO[ax] = (unsigned long long)Ptr->Data;”报错:写入缓存区溢出?

//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_ */


  • 写回答

1条回答 默认 最新

  • 月下独码 Java领域新星创作者 2024-09-23 09:50
    关注
    1. 问题分析
      • 报错“写入缓存区溢出”意味着在执行INTFIFO[ax]=(unsigned long long)Ptr - > Data;语句时,ax的值可能超出了INTFIFO数组的有效索引范围。
      • INT_FIFO_Write函数中,ax的计算方式为ax=(INT_FIFO_Reg.Top_Ptr + 1)&0x03FF;,如果没有正确地处理边界情况或者在后续计算中出现错误,就可能导致越界访问。
      • 另外,从代码逻辑看,Ptr->Data的类型转换和赋值操作也可能存在问题。
    2. 修改方案
      • 检查索引计算
        • 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是否大于等于这个固定大小。
      • 整体逻辑调整
        • for循环中对INTFIFO数组进行写入操作时,需要确保索引计算正确。当前代码中的INTFIFO[ax * ARR_SIZE + i]=(unsigned long long)Ptr->Data[i];看起来有些复杂且可能存在错误。如果Ptr->Data是一个简单的unsigned long long类型,可能不需要这样的循环。如果Ptr->Data是一个数组,需要重新审视整个写入逻辑。例如,如果Ptr->Data是一个包含ARR_SIZEunsigned 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;
          }
          

    注意,以上答案源自微信小程序“超时代智能助手”,仅供参考,实用性请自行斟酌

    评论

报告相同问题?

问题事件

  • 修改了问题 9月23日
  • 修改了问题 9月23日
  • 修改了问题 9月23日
  • 创建了问题 9月23日

悬赏问题

  • ¥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如何向数据库中添加自动生成的字段数据。