semihost_hardfault.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // ****************************************************************************
  2. // semihost_hardfault.c
  3. // - Provides hard fault handler to allow semihosting code not
  4. // to hang application when debugger not connected.
  5. //
  6. // ****************************************************************************
  7. // Copyright 2017-2018 NXP
  8. // All rights reserved.
  9. //
  10. // Software that is described herein is for illustrative purposes only
  11. // which provides customers with programming information regarding the
  12. // NXP Cortex-M based MCUs. This software is supplied "AS IS" without any
  13. // warranties of any kind, and NXP Semiconductors and its licensor disclaim any
  14. // and all warranties, express or implied, including all implied warranties of
  15. // merchantability, fitness for a particular purpose and non-infringement of
  16. // intellectual property rights. NXP Semiconductors assumes no responsibility
  17. // or liability for the use of the software, conveys no license or rights under
  18. // any patent, copyright, mask work right, or any other intellectual property
  19. // rights in or to any products. NXP Semiconductors reserves the right to make
  20. // changes in the software without notification. NXP Semiconductors also makes
  21. // no representation or warranty that such application will be suitable for the
  22. // specified use without further testing or modification.
  23. //
  24. // Permission to use, copy, modify, and distribute this software and its
  25. // documentation is hereby granted, under NXP Semiconductors' and its
  26. // licensor's relevant copyrights in the software, without fee, provided that it
  27. // is used in conjunction with NXP Semiconductors microcontrollers. This
  28. // copyright, permission, and disclaimer notice must appear in all copies of
  29. // this code.
  30. // ****************************************************************************
  31. //
  32. // ===== DESCRIPTION =====
  33. //
  34. // One of the issues with applications that make use of semihosting operations
  35. // (such as printf calls) is that the code will not execute correctly when the
  36. // debugger is not connected. Generally this will show up with the application
  37. // appearing to just hang. This may include the application running from reset
  38. // or powering up the board (with the application already in FLASH), and also
  39. // as the application failing to continue to execute after a debug session is
  40. // terminated.
  41. //
  42. // The problem here is that the "bottom layer" of the semihosted variants of
  43. // the C library, semihosting is implemented by a "BKPT 0xAB" instruction.
  44. // When the debug tools are not connected, this instruction triggers a hard
  45. // fault - and the default hard fault handler within an application will
  46. // typically just contains an infinite loop - causing the application to
  47. // appear to have hang when no debugger is connected.
  48. //
  49. // The below code provides an example hard fault handler which instead looks
  50. // to see what the instruction that caused the hard fault was - and if it
  51. // was a "BKPT 0xAB", then it instead returns back to the user application.
  52. //
  53. // In most cases this will allow applications containing semihosting
  54. // operations to execute (to some degree) when the debugger is not connected.
  55. //
  56. // == NOTE ==
  57. //
  58. // Correct execution of the application containing semihosted operations
  59. // which are vectored onto this hard fault handler cannot be guaranteed. This
  60. // is because the handler may not return data or return codes that the higher
  61. // level C library code or application code expects. This hard fault handler
  62. // is meant as a development aid, and it is not recommended to leave
  63. // semihosted code in a production build of your application!
  64. //
  65. // ****************************************************************************
  66. // Allow handler to be removed by setting a define (via command line)
  67. #if !defined (__SEMIHOST_HARDFAULT_DISABLE)
  68. __attribute__((naked))
  69. void HardFault_Handler(void){
  70. __asm( ".syntax unified\n"
  71. // Check which stack is in use
  72. "MOVS R0, #4 \n"
  73. "MOV R1, LR \n"
  74. "TST R0, R1 \n"
  75. "BEQ _MSP \n"
  76. "MRS R0, PSP \n"
  77. "B _process \n"
  78. "_MSP: \n"
  79. "MRS R0, MSP \n"
  80. // Load the instruction that triggered hard fault
  81. "_process: \n"
  82. "LDR R1,[R0,#24] \n"
  83. "LDRH R2,[r1] \n"
  84. // Semihosting instruction is "BKPT 0xAB" (0xBEAB)
  85. "LDR R3,=0xBEAB \n"
  86. "CMP R2,R3 \n"
  87. "BEQ _semihost_return \n"
  88. // Wasn't semihosting instruction so enter infinite loop
  89. "B . \n"
  90. // Was semihosting instruction, so adjust location to
  91. // return to by 1 instruction (2 bytes), then exit function
  92. "_semihost_return: \n"
  93. "ADDS R1,#2 \n"
  94. "STR R1,[R0,#24] \n"
  95. // Set a return value from semihosting operation.
  96. // 32 is slightly arbitrary, but appears to allow most
  97. // C Library IO functions sitting on top of semihosting to
  98. // continue to operate to some degree
  99. "MOVS R1,#32 \n"
  100. "STR R1,[ R0,#0 ] \n" // R0 is at location 0 on stack
  101. // Return from hard fault handler to application
  102. "BX LR \n"
  103. ".syntax divided\n") ;
  104. }
  105. #endif