FreeRTOS - Анализ неисправностей - Отказ - PullRequest
0 голосов
/ 09 июля 2019

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

В отличие от учебного пособия, моя функция HardFault_Handler () не является напрямую голой функцией, а перенаправляет ее одной (prepareRegistersFromStack ()). В отладчике я вижу переход к функции prepareRegistersFromStack ().

Эта функция, prepareRegistersFromStack () затем должна перейти к функции getRegistersFromStack (), хотя этого никогда не происходит.

Я также попытался напрямую, как в примере, поэтому сделал HardFault_Handler () голой функцией, которая должна перейти к getRegistersFromStack (), но, к сожалению, то же самое применимо, без перехода.

Может ли кто-нибудь помочь мне здесь? Почему getRegistersFromStack () не вызывается?

Спасибо

extern "C" __attribute__((naked)) void HardFault_Handler()
{
  __disable_fault_irq();
  __disable_irq();
  prepareRegistersFromStack();
}

extern "C" void prepareRegistersFromStack()
{
  __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 getRegistersFromStack       \n"
  );
}

extern "C" void getRegistersFromStack( uint32_t *pulFaultStackAddress )
{
  uint32_t dummy;
  /* These are volatile to try and prevent the compiler/linker optimising them
     away as the variables never actually get used.  If the debugger won't show the
     values of the variables, make them global my moving their declaration outside
     of this function. */
  volatile uint32_t r0;
  volatile uint32_t r1;
  volatile uint32_t r2;
  volatile uint32_t r3;
  volatile uint32_t r12;
  volatile uint32_t lr; /* Link register. */
  volatile uint32_t pc; /* Program counter. */
  volatile uint32_t psr;/* Program status register. */

  r0 = pulFaultStackAddress[ 0 ];
  r1 = pulFaultStackAddress[ 1 ];
  r2 = pulFaultStackAddress[ 2 ];
  r3 = pulFaultStackAddress[ 3 ];

  r12 = pulFaultStackAddress[ 4 ];
  lr  = pulFaultStackAddress[ 5 ];
  pc  = pulFaultStackAddress[ 6 ];
  psr = pulFaultStackAddress[ 7 ];

  /* When the following line is hit, the variables contain the register values. */
  for(;;);

  /* remove warnings */
  dummy = r0;
  dummy = r1;
  dummy = r2;
  dummy = r3;
  dummy = r12;
  dummy = lr;
  dummy = pc;
  dummy = psr;
  dummy = dummy;
}

1 Ответ

1 голос
/ 11 июля 2019

В вашем модифицированном подходе вы изменили кадр стека (когда вы вызывали prepareRegistersFromStack ()), поэтому он не будет работать так, как написано.Вернитесь к исходному образцу.Ранее я использовал следующий пример, который, на мой взгляд, основан на вашем фрагменте кода: https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

Однако теперь я предпочитаю использовать функцию, встроенную в IDE, или следующий подход "C", которыйможет использовать последовательный порт или IDE: https://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/

...