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

task stack, register dump

Здравствуйте.

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

Как такое можно реализовать?

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


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

19 minutes ago, winniethepooh said:

Как такое можно реализовать?

Что Вы понимаете под фатальной ошибкой? Если HardFault, то это прерывание позволяет вычитать регистры процессора и указатели на стэк (MSP/PSP). О, кстати! А микроконтроллер или процессор какой у Вас? Я по умолчанию уже для Cortex'ов начанию рассказывать.

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


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

On 12/3/2021 at 6:28 PM, haker_fox said:

Что Вы понимаете под фатальной ошибкой? Если HardFault, то это прерывание позволяет вычитать регистры процессора и указатели на стэк (MSP/PSP). О, кстати! А микроконтроллер или процессор какой у Вас? Я по умолчанию уже для Cortex'ов начанию рассказывать.

Да я использую Cortex M4. Можно ли в случае ошибки в приложении FreeRTOS
отобразить стек задачи с ошибкой и значения регистров контроллера в момент ошибки?
Можно ли получить значения регистров, если ошибка произошла во время обработки прерывания?

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


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

10 minutes ago, winniethepooh said:

отобразить стек задачи с ошибкой и значения регистров контроллера в момент ошибки?

Да. Но к FreeRTOS не имеет никакого отношения) И зависит от ошибки. Например, если принудительно не включить эту опцию, то невыровненный доступ ошибкой считаться не будет на Cortex-M4. А на Cortex-M0 будет ошибкой всегда.

10 minutes ago, winniethepooh said:

Можно ли получить значения регистров, если ошибка произошла во время обработки прерывания?

Да.

 

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

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


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

Нахожу очень много вариаций этого кода:

https://community.arm.com/support-forums/f/embedded-forum/4749/error-hard-fault-handler

Собственно, нужен сам обработчик, который выведет сообщения, например, в консоль в виде дампа части стэка (весь восстановить сложновато, но и это уже что-то), и остановит выполнение.
Все используют printf(), или его аналоги.

Собственно, код:

Скрытый текст

void BusFault_Handler(void) {
    __asm volatile
    (
        " tst lr, #4                                                \n"
        " ite eq                                                    \n"
        " mrseq r0, msp                                             \n"
        " mrsne r0, psp                                             \n"
        " ldr r1, [r0, #24]                                         \n"
        " ldr r2, handler2_address_const                            \n"
        " bx r2                                                     \n"
        " handler2_address_const: .word BusFault_Handler_c    \n"
    );
}

void BusFault_Handler_c(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]);

	DumpText ("\r\n[Bus fault handler - all numbers in hex]\r\n");
	DumpText ("R0 = ");
	DumpHexDWord(stacked_r0);
	DumpText ("\r\nR1 = ");
	DumpHexDWord(stacked_r1);
	DumpText ("\r\nR2 = ");
	DumpHexDWord(stacked_r2);
	DumpText ("\r\nR3 = ");
	DumpHexDWord(stacked_r3);
	DumpText ("\r\nR12 = ");
	DumpHexDWord(stacked_r12);
	DumpText ("\r\nLR [R14] (subroutine call return address) = ");
	DumpHexDWord(stacked_lr);
	DumpText ("\r\nPC [R15] (program counter) = ");
	DumpHexDWord(stacked_pc);
	DumpText ("\r\nPSR = ");
	DumpHexDWord(stacked_psr);
	DumpText ("\r\nBFAR = ");
	DumpHexDWord((*((volatile unsigned long *)(0xE000ED38))));
	DumpText ("\r\nCFSR = ");
	DumpHexDWord((*((volatile unsigned long *)(0xE000ED28))));
	DumpText ("\r\nHFSR = ");
	DumpHexDWord((*((volatile unsigned long *)(0xE000ED2C))));
	DumpText ("\r\nDFSR = ");
	DumpHexDWord((*((volatile unsigned long *)(0xE000ED30))));
	DumpText ("\r\nAFSR = ");
	DumpHexDWord((*((volatile unsigned long *)(0xE000ED3C))));
	DumpText ("\r\nSCB_SHCSR = ");
	DumpHexDWord(SCB->SHCSR);
	DumpText("\r\n");
  while (1);
};

 

BusFault_Handler - может быть как сам BusFault, так и остальные обработчики. Он НЕ должен изменять значение стэка.
Я переписал под минималистические функции DumpXXX, которые почти не обрабатывают данные. Текст - просто выводит строку, HexDWord - выводит 32 бита HEX-кодом. Это единственное моё изменение.

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


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

спасибо за быстрый ответ haker_fox и AlanDarkes.

Насколько я понял принцип такой:

-вызвать событие HardFault или BusFault и в обработчике получить значения стека и регистров?

да и еще watchdog до того как отправит контроллер на перезагрузку способен выдать прерывание.

Можно ли использовать прерывание watchdog'a для события HardFault и насколько действительны данные 

в регистрах и стеке задачи в этом случае?

 

Изменено пользователем winniethepooh

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


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

18 minutes ago, winniethepooh said:

-вызвать событие HardFault или BusFault и в обработчике получить значения стека и регистров?

Дарагой, ну ты книгу-то уже почитай))) У того же Джозефа Ю. всё хорошо про этот "фолт" описано. Ничего вызывать не надо.

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


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

11 minutes ago, haker_fox said:

Дарагой, ну ты книгу-то уже почитай))) У того же Джозефа Ю. всё хорошо про этот "фолт" описано. Ничего вызывать не надо.

Простите за малую осведомленность, у нас Джозефе пока никто не слышал..  

Изменено пользователем winniethepooh

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


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

нужно наверное пояснить что хотелось бы в итоге получить.

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

затем задача контролирующая watchdog не получает уведомления от задачи в бесконечном цикле и не препятствует watchdog'y в перезагрузке контроллера.

Фактически меня интересует рабочий вариант контроля задач и отображения состояния стека задачи и регистров. 

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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