问题
When I use this struct just after flashing device it works well, but after restarting (power on/off) using this struct(assign to any bit) cause a HardFault irq. I use Keil uVision with STM32F205. Why it not works? and what should I change/remove/add to fix it? Direct using GPIOC->ODR don't cause any problems what is wrong with bitfields in Kail?
#pragma anon_unions
typedef union {
struct {
__IO uint16_t Data_Bus:8; // 0-7 data bus
__IO uint16_t Ctr_Pins:6; // 8-13 control pins
__IO uint16_t :2; // 14-15 unused here
};
struct {
__IO uint16_t D0:1; // 0 data bus pin
__IO uint16_t D1:1; // 1 data bus pin
__IO uint16_t D2:1; // 2 data bus pin
__IO uint16_t D3:1; // 3 data bus pin
__IO uint16_t D4:1; // 4 data bus pin
__IO uint16_t D5:1; // 5 data bus pin
__IO uint16_t D6:1; // 6 data bus pin
__IO uint16_t D7:1; // 7 data bus pin
// --------------------------------
__IO uint16_t RS:1; // 8 reset
__IO uint16_t CS:1; // 9 chip select
__IO uint16_t CD:1; // 10 control / data
__IO uint16_t RD:1; // 11 read tick
__IO uint16_t WR:1; // 12 write tick
__IO uint16_t EN:1; // 13 enable display
// ---------------------------------
__IO uint16_t :1; // 14 unused
__IO uint16_t LD:1; // 15 led
};
} *PC_STRUCT_PTR, PC_STRUCT;
PC_STRUCT_PTR __TMP = (PC_STRUCT_PTR)(GPIOC_BASE+0x14);
#define PINOUTS (*__TMP)
it's used like this:
void Write_Reg(unsigned char command)
{
PINOUTS.CD = 0; PINOUTS.RD = 1; PINOUTS.CS = 0; PINOUTS.WR = 0;
PINOUTS.Data_Bus = command; wait();
PINOUTS.WR = 1; PINOUTS.CS = 1; PINOUTS.CD = 1; wait();
}
回答1:
In file 'startup_stm32f20x.s', make sure that you have the following piece of code:
EXTERN HardFault_Handler_C ; this declaration is probably missing
__tx_vectors ; this declaration is probably there
DCD HardFault_Handler
Then, in the same file, add the following interrupt handler (where all other handlers are located):
PUBWEAK HardFault_Handler
SECTION .text:CODE:REORDER(1)
HardFault_Handler
TST LR, #4
ITE EQ
MRSEQ R0, MSP
MRSNE R0, PSP
B HardFault_Handler_C
Then, in file 'stm32f2xx.c', add the following ISR:
void HardFault_Handler_C(unsigned int* hardfault_args)
{
printf("R0 = 0x%.8X\r\n",hardfault_args[0]);
printf("R1 = 0x%.8X\r\n",hardfault_args[1]);
printf("R2 = 0x%.8X\r\n",hardfault_args[2]);
printf("R3 = 0x%.8X\r\n",hardfault_args[3]);
printf("R12 = 0x%.8X\r\n",hardfault_args[4]);
printf("LR = 0x%.8X\r\n",hardfault_args[5]);
printf("PC = 0x%.8X\r\n",hardfault_args[6]);
printf("PSR = 0x%.8X\r\n",hardfault_args[7]);
printf("BFAR = 0x%.8X\r\n",*(unsigned int*)0xE000ED38);
printf("CFSR = 0x%.8X\r\n",*(unsigned int*)0xE000ED28);
printf("HFSR = 0x%.8X\r\n",*(unsigned int*)0xE000ED2C);
printf("DFSR = 0x%.8X\r\n",*(unsigned int*)0xE000ED30);
printf("AFSR = 0x%.8X\r\n",*(unsigned int*)0xE000ED3C);
printf("SHCSR = 0x%.8X\r\n",SCB->SHCSR);
while (1);
}
If you can't use printf
at the point in the execution when this specific Hard-Fault interrupt occurs, then save all the above data in a global buffer instead, so you can view it after reaching the while (1)
.
Then, refer to the 'Cortex-M Fault Exceptions and Registers' section at http://www.keil.com/appnotes/files/apnt209.pdf in order to understand the problem, or publish the output here if you want further assistance.
来源:https://stackoverflow.com/questions/21148774/bit-fields-keil-hardfault-after-restarting