реклама на сайте
подробности

 
 
5 страниц V  < 1 2 3 4 5 >  
Reply to this topicStart new topic
> Hard Fault Exception на кортексе м3, как узнать откуда прилезло
AHTOXA
сообщение Feb 28 2014, 04:36
Сообщение #31


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(jcxz @ Feb 28 2014, 08:32) *
Вот только не надо передёргивать! Тут есть история и всегда можно посмотреть о чём и когда шла речь.
Во-первых - вызов перегруженного члена класса не может осуществляться BL, а только командами BLX; BX; LDR PC, ...; (возможно ещё TBB/TBH) - почитайте
последние сообщения тут, чтобы понять почему.

Ох, ну что же вы такой упёртый-то. Ну давайте почитаем.
Вот исходное сообщение, с которого всё началось (выделение жирным - моё):
Цитата(juvf @ Feb 26 2014, 00:54) *
Выпадаю в Hard Fault Exception. описал обработчик, получил вывод
[skip]
LR = 0x8002c09
PC = 0x20001498

Вот мой ответ:
Цитата(AHTOXA @ Feb 26 2014, 17:30) *
Посмотрите команду, которая находится перед 0x8002c08, возможно дело в ней.

juvf посмотрел:
Цитата(juvf @ Feb 26 2014, 18:28) *
перед 0x8002c09 такой код

Код
LDR R1, [R1]
LDR R1,[R1, #0x8]
BLX R1
CMP R0,#0

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

if(--(*(MyClass*)p) )
{
}

Видите, всё именно так, как я описал. В регистре LR - адрес, следующий после адреса проблемного вызова. То есть, по сути, мы уже нашли место возникновения проблемы:
Цитата(AHTOXA @ Feb 26 2014, 18:54) *
Команда BLX R1 должна прыгать на код вашего перегруженного оператора, а вместо этого прыгает в ОЗУ. Да, похоже, что память портится.


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


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 28 2014, 05:59
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Я с вами тоже sm.gif
Go to the top of the page
 
+Quote Post
juvf
сообщение Feb 28 2014, 09:14
Сообщение #33


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Давайте жить дружно beer.gif
Go to the top of the page
 
+Quote Post
juvf
сообщение Mar 30 2017, 15:27
Сообщение #34


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



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?
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 30 2017, 16:10
Сообщение #35


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(juvf @ Mar 30 2017, 20:27) *
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-а сами подправьте).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 30 2017, 17:03
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(juvf @ Mar 30 2017, 17:27) *
препроцессор в режиме Thumb.

Препроцессор только в одном режиме может работать - в режиме си.
Go to the top of the page
 
+Quote Post
juvf
сообщение Mar 31 2017, 03:34
Сообщение #37


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(jcxz @ Mar 30 2017, 22:03) *
Препроцессор только в одном режиме может работать - в режиме си.

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


Цитата(AHTOXA @ Mar 30 2017, 21:10) *
Это 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 */
}
Go to the top of the page
 
+Quote Post
Obam
сообщение Mar 31 2017, 07:46
Сообщение #38


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



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


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 31 2017, 08:14
Сообщение #39


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Можно. Только, когда ошибка появляется в рабочем приборе, вдалеке от отладчика, вот тогда нужно пересылать информацию.
Go to the top of the page
 
+Quote Post
Obam
сообщение Mar 31 2017, 08:26
Сообщение #40


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



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


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
juvf
сообщение Mar 31 2017, 08:30
Сообщение #41


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(Obam @ Mar 31 2017, 12:46) *
А что, на брейкпойнте в точке входа в HF и под JTAGом, нельзя посмотреть содержимое регистров без портянки из printf-ов?
Просто интересуюсь…
По мойму нельзя.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 31 2017, 08:38
Сообщение #42


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Obam @ Mar 31 2017, 11:26) *
"…в рабочем приборе, вдалеке от отладчика…"
Тогда тут то, чем зебра заканчивается… дистанционно добавлять в прошивку диагностику HF sad.gif

Программа выдала симптомы, а диагноз выполняет и лечение назначает программист, глядя в исходник сотворенного.
Go to the top of the page
 
+Quote Post
Шаманъ
сообщение Mar 31 2017, 09:02
Сообщение #43


Знающий
****

Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839



Цитата(juvf @ Mar 31 2017, 11:30) *
По мойму нельзя.

Можно. Более того есть смысл оформить обработчик так:
Код
void Default_Handler(void)
{
volatile int i = 1;
  while (i)
  {
  }
}

Тогда можно переменную i в отладчике поменять на 0 и пройтись до выхода из HardFault, выйдет как раз в место его возникновения, бывает очень удобно. Можно конечно адрес из стека вытащить, но так проще, удобней, нагляднее.
Go to the top of the page
 
+Quote Post
Forger
сообщение Mar 31 2017, 09:08
Сообщение #44


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(ViKo @ Mar 31 2017, 11:14) *
Можно. Только, когда ошибка появляется в рабочем приборе, вдалеке от отладчика, вот тогда нужно пересылать информацию.

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


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 31 2017, 09:13
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Шаманъ @ Mar 31 2017, 11:02) *
Тогда можно переменную i в отладчике поменять на 0 и пройтись до выхода из HardFault, выйдет как раз в место его возникновения, бывает очень удобно. Можно конечно адрес из стека вытащить, но так проще, удобней, нагляднее.

У Cortex есть неточные ошибки с памятью (Imprecise Bus Fault). Так Вы их место не найдёте. А через регистры - найдёте.
Да и очень неудобно каждый раз вспоминать где какой стек, лучше иметь готовый код.
Не зря же даже в винде подобный обработчик сделали с регистрами и стеком (синий экран). Вот у меня как раз подобный для Cortex есть wink.gif

Цитата(Forger @ Mar 31 2017, 11:08) *
Все HF следует отлавливать еще на этапе отладки и прогона на месте, иначе грош-цена такому коду.
А вот для фиксации различных событий и т. п. следует использовать самописный или готовый журнал событий, который писать на внешнюю или внутр. флэшку.

Это конечно всё хорошо и правильно. Но на практике почему-то случаются такие ошибки (в том числе и HF), которые проявляются почему-то только у заказчика laughing.gif
Вот тут-то фиксация в журнал спасает (а особенно - в энергонезависимый).
Go to the top of the page
 
+Quote Post

5 страниц V  < 1 2 3 4 5 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 10th July 2025 - 01:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01522 секунд с 7
ELECTRONIX ©2004-2016