查找硬故障源-C嵌入式ARM Cortex-M4 32b
我是C嵌入式的新手。调试用于图像摄像机跟踪的嵌入式系统我得到以下HardFaultHandler: Atolic调试会在此时停止它,而没有明显的特定错误指示查找硬故障源-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
__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。因此,当您注释掉此代码或使用其他调试技术以缩小