Поиск источника неисправности - встроенный в C ARM Cortex-M4 32b - PullRequest
1 голос
/ 03 мая 2019

Я новичок в Си. Отладка встроенной системы для слежения за изображениями камеры, я получаю следующее HardFaultHandler:

Отладка Atollic останавливает его на этом этапе без видимых указаний на конкретные ошибки.

__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;

Ответы [ 2 ]

3 голосов
/ 03 мая 2019

По коду, который вы опубликовали, я не вижу источник вашего хардбоута.Но источник проблемы может быть найден путем проверки стека.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 

Но учтите, что если вы сделали какие-то забавные вещи, ПК может указывать на неправильное место или на что-либо еще, особенно если ваша неполадка вызвана не вашей программой, аDMA, MPU или что-то в этом роде.

РЕДАКТИРОВАТЬ: Забудьте упомянуть: вы должны сначала заглянуть в SCB-> CSFR, чтобы понять, что произошло.Посмотрите в справочнике, что означают эти биты.

1 голос
/ 03 мая 2019

Первый шаг - определить, какое значение имеет ПК в случае неисправности.В вашем «DefaultHardFaultHandle» обратите внимание:

" mrseq r0,msp \n" " mrsne r0,psp \n" " mov r1,lr \n" " ldr ,=HardwareFaultHandler_GetSP \n" " bx r2"

Первые две инструкции получают правильный SP (указатель стека) на R0.Существует два SP, и один используемый зависит от режима ЦП (режим потока или обработчика), в котором ЦП находится в случае сбоя.Последние две инструкции переходят к новой подпрограмме HardwareFaultHandler_GetSP.Другими словами, если бы вы написали сигнатуру C для HardwareFaultHandler_GetSP, это выглядело бы так:

void HardwareFaultHandler_GetSP (uint32_t * sp);

Вы должны бытьвозможность детализировать с помощью отладчика, чтобы найти неисправный ПК.например, переходя через DefaultHardFaultHandle, как только он получает SP в R0, затем посмотрите на значение R0.Допустим, это 0x20004000.Затем используйте окно памяти, посмотрите на адрес 0x20004000 + 0x18 или 0x20004018.Он содержит ПК, на котором он выходит из строя.

Если вы делаете это часто, используя подпись функции, как я написал, вы можете изменить HardwareFaultHandler_GetSP, чтобы отобразить «SP [6]» для получения ПК.

ПРИМЕЧАНИЕ ПК может быть отключен по одной или двум инструкциям из-за кэширования.Бит IMPRECISERR (бит 2) в регистре состояния BusFault (или BFSR, доступный по байту по адресу 0xE000ED29) контролирует это поведение.Если он включен, вы можете отключить его в отладчике (например, когда вы прерываете main ()) или программно.Это замедляет работу вашей программы, но при сбое показывает точный ПК.

...