osMessageGet Crashing
I have lots of experience in the general area, but am new to both STM32 and FreeRTOS specifically.
I'm adding a message queue to my program, using the Code at https://www.keil.com/pack/doc/CMSIS/RTOS/html/group__CMSIS__RTOS__Message.html#gac9a6a6276c12609793e7701afcc82326 as an example to follow.
It seems that osMessageGet is crashing. I have a breakpoint both on and after the call to osMessageGet(). I can single step debug into osMessageGet(). It behaves as expected, finds a message, sets up the "event" structure that is to be returned, and gets to the function return statement. If I let the program run from that point, I expect to reach my second breakpoint that's after the call. Instead, I don't reach it. When I pause the program, I see it's stuck in the HardFault_Handler(). So something must be wrong with the return happening.
The only thing I can think of is to ask, "huh? It's returning a complex data type that is a structure?" Do I have to set up some special flags or something in order for the compiler to do this correctly?
Meanwhile, I printed out the size of the structure and it's only 12 bytes. I bumped my stack up that much and there was no change. So I don't think it's a stack size problem.
I set a breakpoint in the interrupt routine that's filling the queue with pointers to structures from a pool, and that breakpoint wasn't hit between the time I let the return in question execute and the program being in hard fault. So I do not think the issue is a task switch and the fault actually occurring due to something other than the return itself.
What could be wrong here?
Below is a screenshot of the hard fault:
and below are germane segments of my code:
// Global declarations
int can1_rx_drop_count = 0;
typedef struct {
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
} RxPacket_t;
RxPacket_t RxPacket;
osPoolDef(RxPool, 16, RxPacket_t);
osPoolId RxPool = NULL;
osMessageQDef(RxQueue, 16, RxPacket_t);
osMessageQId RxQueue = NULL;
...
// From my CAN RX interrupt routine...
RxPacket_t *ppacket;
if (RxPool && RxQueue) {
ppacket = osPoolAlloc(RxPool); // Allocate memory for packet in pool
if (ppacket) {
memcpy(ppacket, &RxPacket, sizeof(RxPacket_t)); // Copy packet to pool
osMessagePut(RxQueue, (uint32_t)ppacket, osWaitForever); // Put pooled packet on RxQueue
} else {
// DROP CAN PACKET
++can1_rx_drop_count;
}
}
...
// From my main task setup
RxPool = osPoolCreate(osPool(RxPool)); // Create memory pool for RxPackets
RxQueue = osMessageCreate(osMessageQ(RxQueue), NULL); // Create queue for RxPackets
...
// From my main task loop
if (RxPool && RxQueue) {
RxPacket_t localPacket;
RxPacket_t *ppacket;
osEvent event;
// THIS IS THE OFFENDING CALL TO osMessageGet <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
event = osMessageGet(RxQueue, osWaitForever); // Wait for packet in queue
if (event.status == osEventMessage) { // Is there a packet in the queue
...
}
}
...