Jump to content

    
winniethepooh

task stack, register dump

Recommended Posts

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

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

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

Share this post


Link to post
Share on other sites
19 minutes ago, winniethepooh said:

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

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

Share this post


Link to post
Share on other sites
On 12/3/2021 at 6:28 PM, haker_fox said:

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

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

Share this post


Link to post
Share on other sites
10 minutes ago, winniethepooh said:

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

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

10 minutes ago, winniethepooh said:

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

Да.

 

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

Share this post


Link to post
Share on other sites

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

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-кодом. Это единственное моё изменение.

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

 

Edited by winniethepooh

Share this post


Link to post
Share on other sites
18 minutes ago, winniethepooh said:

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

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

Share this post


Link to post
Share on other sites
11 minutes ago, haker_fox said:

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

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

Edited by winniethepooh

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.