I am trying to implement the I2C bootloader (AN4775) on the KE02 and get a hard fault interrupt. I have tracked it down to the line that causes it using methods described in other posts which worked as when I remove the offending line I do not get the hard fault interrupt. The problem is that I don't understand why it is causing the interrupt.
in the FC_protocol.c module there are some variables declared:
static uint8_t u8MCU_ID_InfoBuff[64];
static uint8_t u8DataBuff[WRITE_BLOCK_SIZE];
static uint8_t u8MCU_ID_InfoLength;
and the line that causes the interrupt is the last line in a function within that module
void MCU_ID_Package( void )
{
ADDRESS_TYPE *pTempAddress;
uint32_t *pRxFrameLenth;
uint32_t u32Index;
uint32_t i;
uint8_t Sum;
u8MCU_ID_InfoBuff[4] = sMCU_Info.Version;
u8MCU_ID_InfoBuff[5] = (unsigned char)sMCU_Info.Sdid>>8;
u8MCU_ID_InfoBuff[6] = (unsigned char)sMCU_Info.Sdid;
u32Index = 7;
- - - - - -
- - - - - -
u8MCU_ID_InfoLength = u32Index;
}
I have made the problem go away in two ways:
1. Make u8MCU_ID_InfoLength non-static
2. Make u8MCU_ID_InfoLength a uint32_t
neither of which make any sense to me.
From map file in original state:
.bss.u8MCU_ID_InfoLength
0x1ffffe68 0x1 ./FC_protocol/FC_protocol.o
.bss.u8DataBuff
0x1ffffe69 0x40 ./FC_protocol/FC_protocol.o
.bss.u8MCU_ID_InfoBuff
0x1ffffea9 0x40 ./FC_protocol/FC_protocol.o
If I change u8MCU_ID_InfoLength to uint32_t it stays in same place and u8DataBuff is shifted by 3 bytes as expected, but why should this work?
.bss.u8MCU_ID_InfoLength
0x1ffffe68 0x4 ./FC_protocol/FC_protocol.o
.bss.u8DataBuff
0x1ffffe6c 0x40 ./FC_protocol/FC_protocol.o
.bss.u8MCU_ID_InfoBuff
0x1ffffeac 0x40 ./FC_protocol/FC_protocol.o
Have been over this again and discovered that while removing a line of code was making the problem go away, it was not the cause of the hard fault. The variable was being optimized out which was shifting an array which aligned it hence stopping the hard fault. Problem was actually occurring when a uint32 pointer was being pointed to the misaligned array.
Making sure the array is aligned :static uint8_t u8DataBuff[WRITE_BLOCK_SIZE] __attribute((aligned (4))) solves it.