Hello!
I need to develop an application that receives messages on two CAN modules. I am using freeRTOS and would like to make it as easy as possible.
I was considering if using simple SDK functions in a single task would work - they are supposed to be non-blocking.
I was thinking about something like this:
uint8_t rx_mailbox1 = 1;
uint8_t rx_mailbox2 = 2;
// Set information about the data to be received
flexcan_data_info_t dataInfo =
{
.data_length = 1U, //don't care - larger msgs are also received
.msg_id_type = FLEXCAN_MSG_ID_STD,
.enable_brs = false,
.fd_enable = false,
.fd_padding = 0U
};
// Configure RX message buffer
FLEXCAN_DRV_ConfigRxMb(INST_CANCOM1, rx_mailbox1, &dataInfo, 1);
FLEXCAN_DRV_ConfigRxMb(INST_CANCOM2, rx_mailbox2, &dataInfo, 1);
// set the Mask to receive all the messages
FLEXCAN_DRV_SetRxMbGlobalMask(INST_CANCOM1, FLEXCAN_MSG_ID_STD, 0);
FLEXCAN_DRV_SetRxMbGlobalMask(INST_CANCOM2, FLEXCAN_MSG_ID_STD, 0);
while(1){
// Define receive buffer
flexcan_msgbuff_t recvBuff1, recvBuff2;
FLEXCAN_DRV_Receive(INST_CANCOM1, rx_mailbox1, &recvBuff);
FLEXCAN_DRV_Receive(INST_CANCOM2, rx_mailbox2, &recvBuff);
}
If this doesn't work I was thinking about using the interrupt flags to monitor any changes on the message buffers. However, I am not really sure if this approach could work.
My idea is as follows:
uint8_t rx_mailbox1 = 1;
uint8_t rx_mailbox2 = 2;
// Set information about the data to be received
flexcan_data_info_t dataInfo =
{
.data_length = 1U, //don't care - larger msgs are also received
.msg_id_type = FLEXCAN_MSG_ID_STD,
.enable_brs = false,
.fd_enable = false,
.fd_padding = 0U
};
// Configure RX message buffer
FLEXCAN_DRV_ConfigRxMb(INST_CANCOM1, rx_mailbox1, &dataInfo, 1);
FLEXCAN_DRV_ConfigRxMb(INST_CANCOM2, rx_mailbox2, &dataInfo, 1);
// set the Mask to receive all the messages
FLEXCAN_DRV_SetRxMbGlobalMask(INST_CANCOM1, FLEXCAN_MSG_ID_STD, 0);
FLEXCAN_DRV_SetRxMbGlobalMask(INST_CANCOM2, FLEXCAN_MSG_ID_STD, 0);
//enable interrupts for all the message buffers on two CANs
CAN0->IMASK1 |= CAN_IMASK1_BUF31TO0M_MASK; //for INST_CANCOM1 Interface
CAN1->IMASK1 |= CAN_IMASK1_BUF31TO0M_MASK; //for INST_CANCOM2 Interface
while(1){
flexcan_msgbuff_t recvBuff1, recvBuff2;
//check for a flag
if (*CAN0->IFLAG1 = 0x1){ //something on CAN0
FLEXCAN_DRV_Receive(INST_CANCOM1, rx_mailbox, &recvBuff);
CAN0->IFLAG &= 0x0; //clear the flag
}else if(*CAN1->IFLAG1 = 0x2){ //something on CAN1
FLEXCAN_DRV_Receive(INST_CANCOM2, rx_mailbox2, &recvBuff);
CAN1->IFLAG &= 0x0; //clear the flag
}
vTaskDelay(0)
}
However, I have few concerns:
- does every CAN instance have 96 Message Buffers? Or are there 96 MB in general?
- are Message Buffers in this case correctly assigned to Mailboxes?
- the whole code is located in a Task, however, the two comparisons are actually blocking calls. Would an interrupt routine be better?
- how come the CAN message ID needs to be set up BEFORE receiving a CAN message?
- do I need to enter any special mode to manipulate the IFLAG and IMASK registers?
And maybe the first approach is simply better?
Thanks for any suggestions?