Перейти к содержанию
    

Hard Fault Exception на кортексе м3

Вот только не надо передёргивать! Тут есть история и всегда можно посмотреть о чём и когда шла речь.

Во-первых - вызов перегруженного члена класса не может осуществляться BL, а только командами BLX; BX; LDR PC, ...; (возможно ещё TBB/TBH) - почитайте

последние сообщения тут, чтобы понять почему.

Ох, ну что же вы такой упёртый-то. Ну давайте почитаем.

Вот исходное сообщение, с которого всё началось (выделение жирным - моё):

Выпадаю в Hard Fault Exception. описал обработчик, получил вывод

[skip]

LR = 0x8002c09

PC = 0x20001498

Вот мой ответ:

Посмотрите команду, которая находится перед 0x8002c08, возможно дело в ней.

juvf посмотрел:

перед 0x8002c09 такой код

 

LDR R1, [R1]
LDR R1,[R1, #0x8]
BLX R1
CMP R0,#0

[skip]

падает в перегруженном операторе --

 

if(--(*(MyClass*)p) )

{

}

Видите, всё именно так, как я описал. В регистре LR - адрес, следующий после адреса проблемного вызова. То есть, по сути, мы уже нашли место возникновения проблемы:

Команда BLX R1 должна прыгать на код вашего перегруженного оператора, а вместо этого прыгает в ОЗУ. Да, похоже, что память портится.

 

И тут, как чёрт из табакерки, выскочили вы, и начали умничать. Я бы уже давно перестал отвечать на ваши петушиные наскоки, но всё надеялся, что вы перечитаете тему, переосмыслите и признаете свою неправоту. Однако теперь вижу, что это бесполезно. Думаю, что в этом ответе я предельно чётко подытожил описание проблемы и её решение. Надеюсь, это поможет кому-то, кто будет читать эту тему потом. Что касаемо дальнейшей дискуссии с вами, то я не вижу в ней никакого смысла.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

stm32L052 падает в HF

 

пытаюсь сделать обработчик HF и вывести содержимое регистров.

 

вставляю в обработчик

  asm volatile (
        "TST LR, #4             \n "
        "ITE EQ                  \n"
        "MRSEQ R0, MSP        \n"
        "MRSNE R0, PSP         \n"
        "B hardfault_handler    "
    );

- не компилиться. пишет

Updating build tree...

stm32l0xx_it.c  
Error[Og006]: Error in inline assembly: "Error[401]: Operand syntax error" ...\Src\stm32l0xx_it.c 107 
Error[Og006]: Error in inline assembly: "Error[438]: This instruction is not available in the selected cpu/core" ...\Src\stm32l0xx_it.c 108 
Error while running C/C++ Compiler

на строчку "TST LR, #4" и "ITE EQ". Погуглив гдето на форумах было задето, что возможно это из-за того, что препроцессор в режиме Thumb. Но как его на ARM переключить? Собираю в ИАРе сгенерированный проект из куба. в настройках выбран Thumb и выбор режима ARM или Thumb заблокирован. Как можно отловить HF?

post-49045-1490887640_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Error[Og006]: Error in inline assembly: "Error[401]: Operand syntax error" ...\Src\stm32l0xx_it.c 107

Error[Og006]: Error in inline assembly: "Error[438]: This instruction is not available in the selected cpu/core" ...\Src\stm32l0xx_it.c 108

Это Cortex-M0(+)/Cortex-M1. У них нет инструкции ITE. Для них надо вот так:

void HardFault_Handler(void)
{
    asm volatile (
        "    MOV R0, LR              \n"
        "    CMP R0, #4              \n"
        "    BNE hf_psp%=            \n"

        "hf_msp%=:                  \n"
        "    MRS R0, MSP             \n"
        "    B hard_fault_handler    \n"

        "hf_psp%=:                  \n"
        "    MRS R0, PSP              \n"
        "    B hard_fault_handler    \n"
        :                    // no output
        : [param]"r" (0)     // dummy param
        :                    // no clobbers
    );
}

(Это для gcc, для IAR-а сами подправьте).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

препроцессор в режиме Thumb.

Препроцессор только в одном режиме может работать - в режиме си.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Препроцессор только в одном режиме может работать - в режиме си.

опечатался, процессор

 

 

Это Cortex-M0(+)/Cortex-M1. У них нет инструкции ITE.
Спасибо АНТОХА!!! В очередной раз выручил.

 

для иара (кубовски проект) в файле stm32l0xx_it.c нужно в юзеркод вставить так

/* USER CODE BEGIN 0 */
void hard_fault_handler (unsigned int * hardfault_args)
{
    unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;

stacked_r0 = ((unsigned long) hardfault_args[0]);
stacked_r1 = ((unsigned long) hardfault_args[1]);
stacked_r2 = ((unsigned long) hardfault_args[2]);
stacked_r3 = ((unsigned long) hardfault_args[3]);

stacked_r12 = ((unsigned long) hardfault_args[4]);
stacked_lr = ((unsigned long) hardfault_args[5]);
stacked_pc = ((unsigned long) hardfault_args[6]);
stacked_psr = ((unsigned long) hardfault_args[7]);

printf ("[Hard fault handler]\n");
printf ("R0 = 0x%x\n", stacked_r0);
printf ("R1 = 0x%x\n", stacked_r1);
printf ("R2 = 0x%x\n", stacked_r2);
printf ("R3 = 0x%x\n", stacked_r3);
printf ("R12 = 0x%x\n", stacked_r12);
printf ("LR = 0x%x\n", stacked_lr);
printf ("PC = 0x%x\n", stacked_pc);
printf ("PSR = 0x%x\n\n", stacked_psr);
printf ("Execute code from 0x%x\n\n", stacked_pc);
printf ("See command befor 0x%x\n\n", stacked_lr);
for(;;);
}
/* USER CODE END 0 */

...

void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */
  
   asm volatile (
        "    MOV R0, LR              \n"
        "    CMP R0, #4              \n"
        "    BNE hf_psp            \n"

        "hf_msp:                  \n"
        "    MRS R0, MSP             \n"
        "    B hard_fault_handler    \n"

        "hf_psp:                  \n"
        "    MRS R0, PSP              \n"
        "    B hard_fault_handler    \n"
        :                    // no output
        : [param]"r" (0)     // dummy param
        :                    // no clobbers
    );

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN HardFault_IRQn 1 */

  /* USER CODE END HardFault_IRQn 1 */
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что, на брейкпойнте в точке входа в HF и под JTAGом, нельзя посмотреть содержимое регистров без портянки из printf-ов?

Просто интересуюсь…

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно. Только, когда ошибка появляется в рабочем приборе, вдалеке от отладчика, вот тогда нужно пересылать информацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"…в рабочем приборе, вдалеке от отладчика…"

Тогда тут то, чем зебра заканчивается… дистанционно добавлять в прошивку диагностику HF :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что, на брейкпойнте в точке входа в HF и под JTAGом, нельзя посмотреть содержимое регистров без портянки из printf-ов?

Просто интересуюсь…

По мойму нельзя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"…в рабочем приборе, вдалеке от отладчика…"

Тогда тут то, чем зебра заканчивается… дистанционно добавлять в прошивку диагностику HF :(

Программа выдала симптомы, а диагноз выполняет и лечение назначает программист, глядя в исходник сотворенного.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По мойму нельзя.

Можно. Более того есть смысл оформить обработчик так:

void Default_Handler(void) 
{
volatile int i = 1;
  while (i) 
  {
  }
}

Тогда можно переменную i в отладчике поменять на 0 и пройтись до выхода из HardFault, выйдет как раз в место его возникновения, бывает очень удобно. Можно конечно адрес из стека вытащить, но так проще, удобней, нагляднее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно. Только, когда ошибка появляется в рабочем приборе, вдалеке от отладчика, вот тогда нужно пересылать информацию.

Все HF следует отлавливать еще на этапе отладки и прогона на месте, иначе грош-цена такому коду.

А вот для фиксации различных событий и т. п. следует использовать самописный или готовый журнал событий, который писать на внешнюю или внутр. флэшку.

В этом случае можно спокойно проанализировать записи в журнале за некий период работы, просто переслав разработчику соотв. файл журнала событий.

Для этого никуда ездить не нужно.

Если есть доступ в сеть, то можно научить девайс писать журнал сразу наружу, да хоть на "облако" ))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда можно переменную i в отладчике поменять на 0 и пройтись до выхода из HardFault, выйдет как раз в место его возникновения, бывает очень удобно. Можно конечно адрес из стека вытащить, но так проще, удобней, нагляднее.

У Cortex есть неточные ошибки с памятью (Imprecise Bus Fault). Так Вы их место не найдёте. А через регистры - найдёте.

Да и очень неудобно каждый раз вспоминать где какой стек, лучше иметь готовый код.

Не зря же даже в винде подобный обработчик сделали с регистрами и стеком (синий экран). Вот у меня как раз подобный для Cortex есть ;)

 

Все HF следует отлавливать еще на этапе отладки и прогона на месте, иначе грош-цена такому коду.

А вот для фиксации различных событий и т. п. следует использовать самописный или готовый журнал событий, который писать на внешнюю или внутр. флэшку.

Это конечно всё хорошо и правильно. Но на практике почему-то случаются такие ошибки (в том числе и HF), которые проявляются почему-то только у заказчика :laughing:

Вот тут-то фиксация в журнал спасает (а особенно - в энергонезависимый).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...