2017-02-03 4 views
0

У меня есть HardFault при выполнении моей программы. Я нашел десятки способов получить ценность ПК, но я использую Keil uVision 5, и никто из них не работал.Cortex M0 HardFault_Handler и получение адреса ошибки

Насколько я знаю, я не в контексте многозадачности, а PSP содержит 0xFFFFFFF1, поэтому добавление 24 к нему приведет к переполнению.

Вот что мне удалось получить работу (как, он компилирует и выполнить):

enum { r0, r1, r2, r3, r12, lr, pc, psr}; 

extern "C" void HardFault_Handler() 
{ 
    uint32_t *stack; 
    __ASM volatile("MRS stack, MSP"); 

    stack += 0x20; 

    pc = stack[pc]; 
    psr = stack[psr]; 
    __ASM volatile("BKPT #01"); 
} 

Обратите внимание на «+ = 0x20», который находится здесь, чтобы компенсировать функции стека C.

Всякий раз, когда я читаю значение ПК, оно равно 0. У кого-нибудь есть рабочий код для этого?

В противном случае, вот как я это делаю вручную:

  • Поставьте точку останова на HardFault_Handler (исходной)
  • Когда он ломается, выглядят МПВ
  • Добавить 24 к его стоимости.
  • Дамп памяти по этому адресу. И вот оно, 0x00000000.

Что я делаю неправильно?

ответ

0

Несколько проблем с кодом

uint32_t *stack; 
__ASM volatile("MRS stack, MSP"); 

MRS поддерживает регистр только адресатам. Ваш ассемблер migt будет достаточно умным, чтобы сначала перенести его во временный регистр, но я бы хотел, чтобы с него был сгенерирован машинный код.

Если вы используете какую-то систему многозадачности, она может использовать PSP вместо MSP. См. Связанный код ниже о том, как это можно отличить.

pc = stack[pc]; 
psr = stack[psr]; 

Он использует предыдущие значения pc и psr в качестве индекса. Должно быть

pc = stack[6]; 
psr = stack[7]; 

Всякий раз, когда я прочитал значение ПК, это 0.

Ваша программа может фактически прыгнули на адрес 0 (например, через нулевой указатель на функцию), пытался выполнить значение найденный там, который, вероятно, был недействительной инструкцией, а начальным значением SP из таблицы векторов и был ошибочным. Этот код

void (*f)(void) = 0; 
f(); 

делает именно то, что я вижу 0x00000000 со смещением 24.

ли кто-нибудь есть рабочий код для этого?

This works for me. Обратите внимание на код выбора между PSP и МПВ, а директива __attribute__((naked)).Вы можете попытаться найти какой-то эквивалент для своего компилятора, чтобы компилятор вообще не выделял фрейм стека.

+0

Спасибо, я добавил некоторую точность и недостающий код. Мой компилятор/ассемблер фактически не поддерживает «MRS R0, MSP», однако результат моего «MRS stack, MSP» тот же. Это меня очень сильно ограничивает, он, похоже, не понимает никакого регистра. До сих пор я не нашел эквивалентов __attribute __ ((голый)), которые будут работать с компилятором, но в любом случае вы подтвердили, что это в целом правильно. И большое спасибо за подсказку нулевого указателя, не подумал об этом, может быть недостающим обратным вызовом ... – user1532080

+0

Основываясь на вашем ответе, я взглянул на значение LR, помещенное в стек. Он указывает на правильное местоположение, поэтому я думаю, что это так, спасибо! – user1532080

Смежные вопросы