Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找硬故障源-C嵌入式ARM Cortex-M4 32b_C_Eclipse_Arm_Embedded_Cortex M - Fatal编程技术网

查找硬故障源-C嵌入式ARM Cortex-M4 32b

查找硬故障源-C嵌入式ARM Cortex-M4 32b,c,eclipse,arm,embedded,cortex-m,C,Eclipse,Arm,Embedded,Cortex M,我是C嵌入式的新手。调试用于图像摄像机跟踪的嵌入式系统我得到以下HardFaultHandler: Atolic调试会在此时停止它,而没有明显的特定错误指示 __weak void DefaultHardFaultHandle ( void ){ asm volatile( " tst lr,#4 \n" " ite eq \n" " mrseq r0,msp \n" " mrsne r0,psp \n" " mov r1,lr \n" " ldr r2,=HardwareFault

我是C嵌入式的新手。调试用于图像摄像机跟踪的嵌入式系统我得到以下HardFaultHandler:

Atolic调试会在此时停止它,而没有明显的特定错误指示

__weak void DefaultHardFaultHandle ( void ){
asm volatile(
 " tst lr,#4 \n"
 " ite eq \n"
 " mrseq r0,msp \n"
 " mrsne r0,psp \n"
 " mov r1,lr \n"
 " ldr r2,=HardwareFaultHandler_GetSP \n"
 " bx r2"
 );
我没有一堆内存位置,但是,如何根据这些位置得出哪行代码导致问题的结论? 这是代码的一部分,请帮助我:

uint8_t CameraImageTracker(uint8_t **edgeImage){
    ......

for (y = xRight.yStart; (y < height) && (exit == false); y++)
{
    xRight.yStart = y;

    int x = 0;
    for (x = 0; (x < width) && (exit == false); x++)
    {
        if (edgeImage[y][x] == grayScale)
        {
            xRight.xStart = x;
            xRight.yStart = y;

            CountPixelX(width, height, &xRight, edgeImage, grayScale);

            if (xRight.count > WhiteLinesPixMin)
            {
                exit = true;
            }
        }
    }

    WhiteLinesPixMin = xRight.count;
    WhiteLinesPixMax = (WhiteLinesPixMin + 5);

    if (exit == true)
    {
        exit = false;

        xLeft.xStart = xRight.xStart;
        xLeft.yStart = xRight.yStart;

        CountPixelXleft(width, height, &xLeft, edgeImage, WhiteLinesPixMax, grayScale);

        yLeft.xStart = xLeft.xEnd;
        yLeft.yStart = xLeft.yEnd;

        CountPixelY(width, height, &yLeft, edgeImage, grayScale);

        yRight.xStart = xRight.xEnd;
        yRight.yStart = xRight.yEnd;

        CountPixelY(width, height, &yRight, edgeImage, grayScale);

        ellipseCenter(&xRight, &yRight, &xLeft, &yLeft);

        exit = true;
    }
}
return 0;
uint8\u t摄像机图像跟踪器(uint8\u t**edgeImage){
......
对于(y=xRight.yStart;(yWhiteLinesPixMin)
{
退出=真;
}
}
}
WhiteLinesPixMin=xRight.count;
WhiteLinesPixMax=(WhiteLinesPixMin+5);
if(exit==true)
{
退出=假;
xLeft.xStart=xRight.xStart;
xLeft.yStart=xRight.yStart;
CountPixelXleft(宽度、高度和xLeft、边缘图像、白线SpiXmax、灰度);
yLeft.xStart=xLeft.xEnd;
yLeft.yStart=xLeft.yEnd;
CountPixelY(宽度、高度和宽度、边缘图像、灰度);
yRight.xStart=xRight.xEnd;
yRight.yStart=xRight.yEnd;
CountPixelY(宽度、高度和亮度、边缘图像、灰度);
椭圆中心(&xRight、&yRight、&xLeft和&yLeft);
退出=真;
}
}
返回0;

根据您发布的代码,我看不到您的硬故障源。但可以通过检查堆栈找到硬故障源。Cortex-M4在输入硬故障时应将旧寄存器值推送到堆栈上。在堆栈上,它应如下所示:

sp + 0x00 =  R0
sp + 0x04 =  R1
sp + 0x08 =  R2
sp + 0x0C =  R3
sp + 0x10 =  R12
sp + 0x14 =  LR
sp + 0x18 =  PC <- That is the one you need
sp + 0x1C =  xPSR 
sp + 0x20 =  end of the stack before hard fault 
sp+0x00=R0
sp+0x04=R1
sp+0x08=R2
sp+0x0C=R3
sp+0x10=R12
sp+0x14=LR

sp+0x18=PC CSFR以了解发生了什么。查看手册中位的含义。

根据您发布的代码,我看不到您的硬故障源。但是可以通过检查堆栈找到硬故障源。Cortex-M4应在输入硬故障时将旧寄存器值推送到堆栈上。在堆栈上,它应d看起来像这样:

sp + 0x00 =  R0
sp + 0x04 =  R1
sp + 0x08 =  R2
sp + 0x0C =  R3
sp + 0x10 =  R12
sp + 0x14 =  LR
sp + 0x18 =  PC <- That is the one you need
sp + 0x1C =  xPSR 
sp + 0x20 =  end of the stack before hard fault 
sp+0x00=R0
sp+0x04=R1
sp+0x08=R2
sp+0x0C=R3
sp+0x10=R12
sp+0x14=LR

sp+0x18=PC CSFR以了解发生了什么。请查看手册中的位的含义。

第一步是确定发生故障时的PC值。在“DefaultHardFaultHandle”中,请注意:

“mrseq r0,msp\n”
“mrsne r0,psp\n”
“mov r1,lr\n”
“ldr,=HardwareFaultHandler\u GetSP\n”
“bx r2”

前两条指令获得指向R0的正确SP(堆栈指针)。有两个SP,其中一个SP的使用取决于CPU模式(线程或处理程序模式)CPU出现故障时处于运行状态。最后两条指令跳转到新的例程HardwareFaultHandler_GetSP。换句话说,如果要为HardwareFaultHandler_GetSP编写C签名,它将如下所示:

sp + 0x00 =  R0
sp + 0x04 =  R1
sp + 0x08 =  R2
sp + 0x0C =  R3
sp + 0x10 =  R12
sp + 0x14 =  LR
sp + 0x18 =  PC <- That is the one you need
sp + 0x1C =  xPSR 
sp + 0x20 =  end of the stack before hard fault 
void HardwareFaultHandler_GetSP(uint32_t*sp)

您应该能够使用调试器深入查找发生故障的PC。例如,通过DefaultHardFaultHandle,一旦它将SP获取到R0,然后查看R0的值。假设它是0x20004000。然后使用内存窗口,查看地址0x20004000+0x18或0x20004018。该地址包含发生故障的PC

如果您经常这样做,使用我所写的函数签名,您可以修改HardwareFaultHandler_GetSP以显示“SP[6]”来获取PC


注意由于高速缓存的原因,PC可能会被一条或两条指令关闭。总线故障状态寄存器(或BFSR,地址0xE000ED29处可访问字节)中的不精确RR位(第2位)控制此行为。如果它打开,您可以在调试器中将其关闭(例如,当您在main()处中断时)或以编程方式。这会使您的程序运行较慢,但在发生故障时会显示准确的PC。

第一步是确定发生故障时的PC值。在“DefaultHardFaultHandle”中,请注意:

“mrseq r0,msp\n”
“mrsne r0,psp\n”
“mov r1,lr\n”
“ldr,=HardwareFaultHandler\u GetSP\n”
“bx r2”

前两条指令获得指向R0的正确SP(堆栈指针)。有两个SP,其中一个SP的使用取决于CPU模式(线程或处理程序模式)CPU出现故障时处于运行状态。最后两条指令跳转到新的例程HardwareFaultHandler_GetSP。换句话说,如果要为HardwareFaultHandler_GetSP编写C签名,它将如下所示:

sp + 0x00 =  R0
sp + 0x04 =  R1
sp + 0x08 =  R2
sp + 0x0C =  R3
sp + 0x10 =  R12
sp + 0x14 =  LR
sp + 0x18 =  PC <- That is the one you need
sp + 0x1C =  xPSR 
sp + 0x20 =  end of the stack before hard fault 
void HardwareFaultHandler_GetSP(uint32_t*sp)

您应该能够使用调试器深入查找发生故障的PC。例如,通过DefaultHardFaultHandle,一旦它将SP获取到R0,然后查看R0的值。假设它是0x20004000。然后使用内存窗口,查看地址0x20004000+0x18或0x20004018。该地址包含发生故障的PC

如果您经常这样做,使用我所写的函数签名,您可以修改HardwareFaultHandler_GetSP以显示“SP[6]”来获取PC


注意由于高速缓存的原因,PC可能会被一条或两条指令关闭。总线故障状态寄存器(或BFSR,地址0xE000ED29处可访问字节)中的不精确RR位(第2位)控制此行为。如果它打开,您可以在调试器中将其关闭(例如,当您在main()处中断时)或以编程方式。这会使您的程序运行较慢,但在出现故障时会显示准确的PC。

为什么标记eclipse?可能是OP使用的IDE。因此,当您注释掉此代码或使用其他调试技术以缩小