【问题标题】:malloc crashes embedded systemmalloc 使嵌入式系统崩溃
【发布时间】:2015-07-15 04:00:11
【问题描述】:

我正在尝试在皮质 M4 核上乘以任意大小的矩阵。我确实需要一个malloc... 但我不明白为什么在第一次通话时它起作用,而在第二次通话时它不再起作用。它只是跳转到默认的中断处理程序 FaultISR。

特此反汇编代码:

执行BL命令失败

函数调用:

multiplyMatrices( &transFRotMatrix[0][0],3, 3, &sunMeasurements[0][0], 3, 1, *orbitalSunVector); //Works fine

multiplyMatrices( &firstRotMatrix[0][0],3, 3, &orbitalTMFV[0][0], 3, 1, *inertialTMFV); //doesn t work fine

代码:

void multiplyMatrices(float *transposedMatrix, int height1, int width1, float *iSunVector,int height2, int width2, float *orbitalSunVector)
{

    int y=0;
    int x = 0;
    int row=0;
    int column =0;
    int k=0;
    int k2=0;
    float result = 0;
    float *output2=NULL;

    int i=0;
    int j=0;

    i=0;
    k=0;
    k2 = 0;


    if(width1 != height2)
    {
        //printf("unmatching matrices, error.\n\n");
        return;
    }

    output2 = malloc(height1 * width2 * sizeof(float)); //<---- jumps o FaultISR


    while(k<width1) //aantal rijen 1ste matrix
    {
        for(j=0;j<height2;j++) //aantal rijen 2de matrix
        {
            result += (*((transposedMatrix+k*width1)+j)) * (*((iSunVector+j*width2)+k2));  //1ste var:aantal kolommen 2de matrix  --2de variabele na de plus = aantal kolommen 2de matrix
            //printf("%f * %f\t + ", (*((transposedMatrix+k*width1)+j)), (*((iSunVector+j*width2)+k2)));
        }

         output2[row* width1 + column] = result;

        k2++;
        x++;
        column++;

        if(x==width2) //aantal kolommen 2de Matrix
        {
            k2=0;
            x=0;
            column=0;
            row++;
            y++;
            k++;
        }
        result = 0;

    }

    //tussenresultaat
    for(i=0;i<height1;i++)
    {
        for(j=0;j<width2;j++)
        {
             orbitalSunVector[j * height1 + i] = output2[i* width1 + j]; //output2[i][j];

        }
    }

    free(output2);
}

【问题讨论】:

  • height1width2 的值是多少?也许你的内存不足?也许你写的超出了(或其他一些)分配的内存?
  • 不应失败,除非堆栈和堆没有正确设置,即使 height1 和 width2 太大,它也应该返回 NULL(如果它们的乘积为负数,情况相同)
  • 你可以在函数调用中看到这些变量的值
  • 所以你要分配3 * 3 * sizeof(float)为什么你不能这样做,例如float output[9]?
  • 因为这不是动态的,并且不适用于任何大小的矩阵

标签: c matrix malloc cortex-m


【解决方案1】:

您是否在代码的其他地方使用printf

This page 建议堆大小从 0x400 开始,即十进制 1024:

建议从一个合理的堆大小开始,比如 0x400,当 动态分配有限(如代码中的 printf() 调用), 并根据应用程序按需增加。

您今天有 512 个,如果可能的话,您至少可以尝试将其翻倍,根据 TI 的建议,看看这会将您带向何方。

This 是一个相关问题。如果您没有即时查看堆分配的工具,请尝试在启动时手动填充堆(memcpy 它使用已知值,例如 ASCII '#==#'、0xDEADBEEF 或任何可识别的值),然后运行到你通常崩溃之前,并在内存窗口中观察堆的内容。我最好的猜测是您会发现堆已满。

还请查看在 FaultISR 中是否可以看到错误标志寄存器。通常有什么地方告诉你为什么你来这里。

我不确定 TI 对 malloc 的实现,但它们可能会保存错误值。我不会打赌那个,因为在这种情况下它可能会返回 NULL,而不是崩溃。

【讨论】:

    【解决方案2】:

    由于索引计算不正确,您在两个循环中都溢出了 output2 矩阵。你有:

    output2[row*width1 + column] = result;
    ...
    orbitalSunVector[j*height1 + i] = output2[i*width1 + j];
    

    但你应该在这两种情况下都使用width2,因为最终矩阵的大小是width2 * height1(因为它是分配的):

    output2[row*width2 + column] = result;
    ...
    orbitalSunVector[j*height1 + i] = output2[i*width2 + j];
    

    我没有检查您的任何其他索引,但我会用一些已知案例测试该函数,以确保它输出正确的结果。如果您进行了更多调试并检查了数组索引,应该很容易发现。

    请注意,它第一次对您有效但第二次无效的原因是由于未定义的行为 (UB)。一旦你写到output2 的末尾,你就会调用UB,任何事情都可能发生。对你来说,它恰好在第二次调用时显示为错误。对我来说,它在第一次通话时发生了故障。如果你真的不走运,它可能永远不会出错,只是默默地破坏数据。

    【讨论】:

    • 我改了,但不幸的是,这并没有解决我的问题,我错了
    • 如果您同意此处建议的更改,请相应地更新您问题中的代码。
    • @rudolf 那么你很可能在其他地方也溢出了另一个缓冲区。 (例如,检查 orbitalSunVector 是否与代码假设的一样大)。但请注意,即使这里的函数发生崩溃,可能是由于堆损坏,错误也可能是在其他地方引起的。
    • @rudolf 我还要说@uesp 感觉您的索引有问题,我也有这种感觉。你有相当多的变量,名称不是很具描述性。 kk2xrowcolumn,目前还不清楚这些是什么,以及它们适用于哪些矩阵或维度。我打算重构你的函数,但这确实是你应该自己做的事情,例如从将 1xN 乘以 Nx1 向量乘法到一个单独的函数开始,也许。
    猜你喜欢
    • 2016-12-31
    • 2016-03-28
    • 2014-04-20
    • 2012-03-09
    • 2019-10-31
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多