cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429DISCOVERY, STM32CUBEIDE 1.12.0 I've created a class for a communication packet. It has global scope. Upon instantiation, the code hard faults.

DavidLee74
Associate

If I comment out the instantiation, compile and run, then uncomment the instantiation, compile and run, the code will work fine from that point on. But it will not run without hard faulting unless I do the comment / uncomment thing. Here's the code for the class:

class MDIO_Packet

{

public:

short OPCode; // This defines whether the packet is Read, Write or Address assignment.

short TA;

uint32_t PHYAddress;

uint32_t DEVAddress;

uint32_t* Register;

double Packet;

MDIO_Packet(short OpCode, uint32_t PHAddress, uint32_t DVAddress, uint32_t* REGISTER)

{

OPCode = OpCode;

PHYAddress = PHAddress;

DEVAddress = DVAddress;

Register = REGISTER;

}// end Constructor

MDIO_Packet()

{

OPCode = 0x0000;

PHYAddress = 0x0000;

DEVAddress = 0x0000;

*Register = 0x0000;

} // end Constructor

uint32_t Packetize()

{

uint32_t BitMask = 0;

BitMask |= (OPCode << 28);

BitMask |= (PHYAddress << 23);

BitMask |= (DEVAddress << 18);

switch (OPCode)

{

case 0x00:

TA = 0x02;

break;

case 0x01:

TA = 0x02;

break;

case 0x02:

TA = 0x0;

case 0x003:

TA = 0x00; // Binary Z0

break;

} // end switch

BitMask |= (TA << 16);

BitMask |= *Register;

return BitMask;

}// end Packetize

}; // class dismissed

And here is the instantiation:

 /* Initialize all configured peripherals */

 MX_GPIO_Init();

 MX_CRC_Init();

 MX_DMA2D_Init();

 MX_FMC_Init();

 MX_I2C3_Init();

 MX_SPI5_Init();

 MX_TIM1_Init();

 MX_USART1_UART_Init();

 MX_USB_HOST_Init();

 MX_SPI3_Init();

 MX_SPI4_Init();

 MX_USART6_UART_Init();

 MX_TIM2_Init();

 /* USER CODE BEGIN 2 */

 MDIO_Packet MyPacket;

 MyPacket.PHYAddress = 0xc050;

 MyPacket.DEVAddress = 1;

 /* USER CODE END 2 */

3 REPLIES 3
Bob S
Principal

When you instantiate the MDIO_Packet instance you are calling the DEFAULT constructor, which you do not provide. So the compiler generates one for you - which sets all members to zero. That means your "register" pointer is a NULL pointer. That may not be THE problem but it is A problem.

To use your constructor:

MDIO_Packet MyPacket( OpCode, PHAddress, DVAddress, REGISTER );  // Fill in real values for these params

Also, if your functions take no parameters, declare them with "void" in the param list. Just good practice. I.e. "uint32_t Packetize( void )"

DavidLee74
Associate

I do provide an explicit constructor for zero parameter instantiation:

MDIO_Packet()

{

OPCode = 0x0000;

PHYAddress = 0x0000;

DEVAddress = 0x0000;

*Register = 0x0000;

} // end Constructor

Thanks for the reminder on void parameters!

Bob S
Principal

Oops - missed that. Though the (potential) issue still exists of de-referencing a NULL pointer. The code you posted doesn't do that (use that pointer). Is that really all the code, and just commenting out the instantiation line (and following 2 lines, I presume) causes the code to run/not fault?

Regardless, the answer comes back to debugging the fault. CubeIDE has a fault analyzer that will show you the fault registers. You can see what instruction caused the fault. You should also consider adding your own fault handler code to collect the registers, maybe print then out a debug port or save them for later. There are several examples/mentions of this on this forum.