Used hardware: KEIL ARM MCB1700, eval
How can the line: NVIC_EnableIRQ(UART0_IRQn); create an error HardFault
715: NVIC_EnableIRQ(UART0_IRQn); 0x000024B0 2005 MOVS r0,#0x05 0x000024B2 F000F9AF BL.W NVIC_EnableIRQ (0x00002814) 0x000024B6 E002 B 0x000024BE 1504: NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ 0x00002814 F000021F AND r2,r0,#0x1F 0x00002818 2101 MOVS r1,#0x01 0x0000281A 4091 LSLS r1,r1,r2 0x0000281C 0942 LSRS r2,r0,#5 0x0000281E F04F23E0 MOV r3,#0xE000E000 0x00002822 EB030282 ADD r2,r3,r2,LSL #2 0x00002826 F8C21100 STR r1,[r2,#0x100] <one step> 0x00000232 E7FE B HardFault_Handler (0x00000232) 143: B . 144: ENDP
before the STR r1,[r2,#0x100] instruction R2=0xe000e000 and r1 = 0x20 bit 5 = ISE_UART0 0xe000,e100 so everything looks alright
similar command example in same program works 100% NVIC_EnableIRQ(TIMER0_IRQn); // Enable the TIMER0 Interrupt
R2 = 0xe000e000, R3 = 0x02 0x0000168E F8C23100 STR r3,[r2,#0x100] bit 1 = ISE_TIMER0 0xe000,e100
Difference betwee both is the irq vector and the serial in NOT inline assembled. My thougth was the serial irq routine but i found nothing wrong, so i changed NVIC_EnableIRQ(UART0_IRQn); to NVIC_DisableIRQ(UART0_IRQn);
0x0000282E F8421023 STR r1,[r2,r3,LSL #2]
(R1 =0x20,R2= 0xe000,e180, R3=0) again the program crashed after the STR routine! but the parameters seem right.
Logical thinking this can't be a Keil compiler problem but as i am evaluating the tools i would like to know if within the toolchain it is possible to find the source of this kind of errors.
NVIC registers can be accessed only from privileged mode. User mode access will cause a fault.
Is the CPU running in privileged mode?
Keil examples without RTOS usually run in privileged mode. Examples using RTX usually run in user mode but this can be changed by enabling "Run in privileged mode" in RTX configuration file.
Thanks, just found something similar. The reason is indeed Privileged and unprivileged mode (protected). http://www.keil.com/support/man/docs/rlarm/rlarm_ar_cfgrunpriv.htm
Timer which was working did it before entering unprivileged mode with the RTX tasks. The serial irq was enabled/disabled within a task.
(program did work on an cortex-M0 this must be a little different) Now i have so look for the best way to solve it.
One Question remains was there an easy way i could have seen this was the reason, or is it just: You should have read al the manuals (Cortex M3/ RealView / etc)