├── .gitattributes ├── .gitignore ├── README ├── inc └── div.h └── src ├── div.c ├── fault_handler.c └── main.c /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | ARM Cortex-M3/Cortex-M4 (ARMv7-M) Hard Fault Exception Handler 2 | 3 | See blog.feabhas.com for full details. 4 | 5 | Base project built using ARM/Keil MDK-ARM v4.60 6 | -------------------------------------------------------------------------------- /inc/div.h: -------------------------------------------------------------------------------- 1 | #ifndef DIV_H 2 | #define DIV_H 3 | 4 | int div(int lho, int rho); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/div.c: -------------------------------------------------------------------------------- 1 | #include "div.h" 2 | 3 | int div(int lho, int rho) 4 | { 5 | return lho/rho; 6 | } 7 | -------------------------------------------------------------------------------- /src/fault_handler.c: -------------------------------------------------------------------------------- 1 | #include "ARMCM3.h" 2 | #include 3 | 4 | void printErrorMsg(const char * errMsg); 5 | void printUsageErrorMsg(uint32_t CFSRValue); 6 | void printBusFaultErrorMsg(uint32_t CFSRValue); 7 | void printMemoryManagementErrorMsg(uint32_t CFSRValue); 8 | void stackDump(uint32_t stack[]); 9 | 10 | void Hard_Fault_Handler(uint32_t stack[]) 11 | { 12 | static char msg[80]; 13 | //if((CoreDebug->DHCSR & 0x01) != 0) { 14 | printErrorMsg("In Hard Fault Handler\n"); 15 | sprintf(msg, "SCB->HFSR = 0x%08x\n", SCB->HFSR); 16 | printErrorMsg(msg); 17 | if ((SCB->HFSR & (1 << 30)) != 0) { 18 | printErrorMsg("Forced Hard Fault\n"); 19 | sprintf(msg, "SCB->CFSR = 0x%08x\n", SCB->CFSR ); 20 | printErrorMsg(msg); 21 | if((SCB->CFSR & 0xFFFF0000) != 0) { 22 | printUsageErrorMsg(SCB->CFSR); 23 | } 24 | if((SCB->CFSR & 0xFF00) != 0) { 25 | printBusFaultErrorMsg(SCB->CFSR); 26 | } 27 | if((SCB->CFSR & 0xFF) != 0) { 28 | printMemoryManagementErrorMsg(SCB->CFSR); 29 | } 30 | } 31 | stackDump(stack); 32 | __ASM volatile("BKPT #01"); 33 | //} 34 | while(1); 35 | } 36 | 37 | void printErrorMsg(const char * errMsg) 38 | { 39 | while(*errMsg != '\0'){ 40 | ITM_SendChar(*errMsg); 41 | ++errMsg; 42 | } 43 | } 44 | 45 | void printUsageErrorMsg(uint32_t CFSRValue) 46 | { 47 | printErrorMsg("Usage fault: "); 48 | CFSRValue >>= 16; // right shift to lsb 49 | 50 | if((CFSRValue & (1<<9)) != 0) { 51 | printErrorMsg("Divide by zero\n"); 52 | } 53 | } 54 | 55 | void printBusFaultErrorMsg(uint32_t CFSRValue) 56 | { 57 | printErrorMsg("Bus fault: "); 58 | CFSRValue = ((CFSRValue & 0x0000FF00) >> 8); // mask and right shift to lsb 59 | } 60 | 61 | void printMemoryManagementErrorMsg(uint32_t CFSRValue) 62 | { 63 | printErrorMsg("Memory Management fault: "); 64 | CFSRValue &= 0x000000FF; // mask just mem faults 65 | } 66 | 67 | #if defined(__CC_ARM) 68 | __asm void HardFault_Handler(void) 69 | { 70 | TST lr, #4 71 | ITE EQ 72 | MRSEQ r0, MSP 73 | MRSNE r0, PSP 74 | B __cpp(Hard_Fault_Handler) 75 | } 76 | #elif defined(__ICCARM__) 77 | void HardFault_Handler(void) 78 | { 79 | __asm( "TST lr, #4 \n" 80 | "ITE EQ \n" 81 | "MRSEQ r0, MSP \n" 82 | "MRSNE r0, PSP \n" 83 | "B Hard_Fault_Handler\n" 84 | ); 85 | } 86 | #else 87 | #warning Not supported compiler type 88 | #endif 89 | 90 | enum { r0, r1, r2, r3, r12, lr, pc, psr}; 91 | 92 | void stackDump(uint32_t stack[]) 93 | { 94 | static char msg[80]; 95 | sprintf(msg, "r0 = 0x%08x\n", stack[r0]); 96 | printErrorMsg(msg); 97 | sprintf(msg, "r1 = 0x%08x\n", stack[r1]); 98 | printErrorMsg(msg); 99 | sprintf(msg, "r2 = 0x%08x\n", stack[r2]); 100 | printErrorMsg(msg); 101 | sprintf(msg, "r3 = 0x%08x\n", stack[r3]); 102 | printErrorMsg(msg); 103 | sprintf(msg, "r12 = 0x%08x\n", stack[r12]); 104 | printErrorMsg(msg); 105 | sprintf(msg, "lr = 0x%08x\n", stack[lr]); 106 | printErrorMsg(msg); 107 | sprintf(msg, "pc = 0x%08x\n", stack[pc]); 108 | printErrorMsg(msg); 109 | sprintf(msg, "psr = 0x%08x\n", stack[psr]); 110 | printErrorMsg(msg); 111 | } 112 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include "ARMCM3.h" 2 | #include "div.h" 3 | 4 | void SysTick_Handler(void) 5 | { 6 | ITM_SendChar('.'); 7 | } 8 | 9 | int main(void) 10 | { 11 | int a = 10; 12 | int b = 0; 13 | int c; 14 | 15 | SysTick_Config(SystemCoreClock/100); 16 | 17 | SCB->CCR |= 0x10; 18 | 19 | c = div(a, b); 20 | 21 | while(1); 22 | } 23 | --------------------------------------------------------------------------------