2023-05-15 12:52 PM
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 */
2023-05-16 12:40 PM
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 )"
2023-05-16 01:12 PM
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!
2023-05-16 02:11 PM
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.