Commit 02bc3f56 authored by Mahmoud Rushdi's avatar Mahmoud Rushdi Committed by Oliver Horst
Browse files

[fix] Move the initialization of FreeRTOS queus to hal_can_init

To handle the case of CAN messages received on the bus before CAN port is opened.
parent 3b5a0f49
......@@ -131,6 +131,7 @@ static void prvSendCanMsg( void* );
* It configures the CAN controller hardware:
* - Requested baud rate
* - Correct CAN Bit timing
* - Create FreeRTOS queues needed by CAN
* And Connect to the Interrupt controller
*/
BaseType_t hal_can_init(hal_io_handle_t deviceId, uint32_t bitrate)
......@@ -228,6 +229,14 @@ BaseType_t hal_can_init(hal_io_handle_t deviceId, uint32_t bitrate)
canBitTimingtable[i].can_BTR_FIRST_TIMESEGMENT
);
/* Create a receiving queue. */
canInstPtr->xQueueRx = xQueueCreate( configHAL_CAN_MAX_RX_QUEUE_SIZE , sizeof(hal_can_message_t));
configASSERT( canInstPtr->xQueueRx );
/* Create a transmission queue. */
canInstPtr->xQueueTx = xQueueCreate( configHAL_CAN_MAX_TX_QUEUE_SIZE , sizeof(hal_can_message_t));
configASSERT( canInstPtr->xQueueTx );
/*
* Set interrupt handlers.
*/
......@@ -279,8 +288,9 @@ BaseType_t hal_can_init(hal_io_handle_t deviceId, uint32_t bitrate)
/**
* \brief Deinitialize the CAN controller.
*
* - Resets the CAN controller hardware.
* - Disconnect from the Interrupt controller
* - Resets the CAN controller hardware,
* - Disconnect from the Interrupt controller,
* - Destroy FreeRTOS queues used by CAN.
*/
BaseType_t hal_can_release(hal_io_handle_t deviceId)
{
......@@ -296,6 +306,9 @@ BaseType_t hal_can_release(hal_io_handle_t deviceId)
XScuGic_Disconnect(&xInterruptController, CanInterruptID[deviceId]);
// Reset the CAN device
XCanPs_Reset( &CanInstance[deviceId].canXilinxInst );
/* Delete Tx and Rx queues */
vQueueDelete( &CanInstance[deviceId].xQueueRx );
vQueueDelete( &CanInstance[deviceId].xQueueTx );
return pdPASS;
}
}
......@@ -303,8 +316,8 @@ BaseType_t hal_can_release(hal_io_handle_t deviceId)
/**
* \brief Open the CAN controller.
*
* It lookup for the CAN instance configuration. Creates the recourses
* needed by CAN and managed by FreeRTOS (queues, tasks)
* It lookup for the CAN instance configuration. Creates the FreeRTOS task
* needed for CAN transmission.
* CAN controller can be accessed by only one freeRTOS task.
* A CAN controller can not be opened twice.
*/
......@@ -328,14 +341,6 @@ BaseType_t hal_can_open(hal_io_handle_t deviceId, hal_can_handle_t * canHandlePt
canInstPtr = & CanInstance[deviceId];
*canHandlePtr = (hal_can_handle_t *) canInstPtr;
/* Create a receiving queue. */
canInstPtr->xQueueRx = xQueueCreate( configHAL_CAN_MAX_RX_QUEUE_SIZE , sizeof(hal_can_message_t));
configASSERT( canInstPtr->xQueueRx );
/* Create a transmission queue. */
canInstPtr->xQueueTx = xQueueCreate( configHAL_CAN_MAX_TX_QUEUE_SIZE , sizeof(hal_can_message_t));
configASSERT( canInstPtr->xQueueTx );
/* Create a transmission Task */
xReturned = xTaskCreate(
prvSendCanMsg, /* Function that implements the task. */
......@@ -362,7 +367,7 @@ BaseType_t hal_can_open(hal_io_handle_t deviceId, hal_can_handle_t * canHandlePt
/**
* \brief Close the CAN controller.
*
* It destroys the recourses managed by FreeRTOS (queues, tasks)
* It destroys the tasks managed by FreeRTOS
* and set the CAN port as closed.
*/
BaseType_t hal_can_close( hal_can_handle_t * canHandlePtr )
......@@ -374,9 +379,6 @@ BaseType_t hal_can_close( hal_can_handle_t * canHandlePtr )
{
/* Delete the receiving task */
vTaskDelete( canInstPtr->canTxHandle );
/* Delete Tx and Rx queues */
vQueueDelete( canInstPtr->xQueueRx );
vQueueDelete( canInstPtr->xQueueTx );
canInstPtr->isCtrlOpen = pdFALSE;
*canHandlePtr = NULL;
}
......@@ -467,45 +469,39 @@ static void RecvHandler(void *CallBackRef)
XCanPs *xilCanPtr = &canInstPtr->canXilinxInst;
/* Buffer to hold frames to receive.*/
static u32 RxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS];
int status;
hal_can_message_t message;
status = XCanPs_Recv(xilCanPtr, RxFrame);
if ( XST_SUCCESS != status )
while ( XST_SUCCESS == XCanPs_Recv(xilCanPtr, RxFrame))
{
xil_printf( "CAN: RecvHandler: No frame to be received from the controller FIFO. \n");
return;
}
if ((u32) 0 != ((RxFrame[0] & XCANPS_IDR_SRR_MASK) | (RxFrame[0] & XCANPS_IDR_RTR_MASK)))
{
/* Remote request frame is not supported by XME.
Although it is supported by Xilinx driver. */
xil_printf( "CAN: RecvHandler: Remote request CAN frame is not supported by XME. \n");
}
else
{
// Data CAN frame:
if ((u32) 0 == (RxFrame[0] & XCANPS_IDR_IDE_MASK))
if ((u32) 0 != ((RxFrame[0] & XCANPS_IDR_SRR_MASK) | (RxFrame[0] & XCANPS_IDR_RTR_MASK)))
{
// Standard CAN frame Identifier
message.msgID = (RxFrame[0] & XCANPS_IDR_ID1_MASK) >> XCANPS_IDR_ID1_SHIFT;
/* Remote request frame is not supported by XME.
Although it is supported by Xilinx driver. */
xil_printf( "CAN: RecvHandler: Remote request CAN frame is not supported by XME. \n");
}
else
{
// Extended CAN frame Identifier
message.msgID = (RxFrame[0] & XCANPS_IDR_ID2_MASK) >> XCANPS_IDR_ID2_SHIFT;
}
message.msgLen = (RxFrame[1] & XCANPS_DLCR_DLC_MASK) >> XCANPS_DLCR_DLC_SHIFT;
// Data CAN frame:
if ((u32) 0 == (RxFrame[0] & XCANPS_IDR_IDE_MASK))
{
// Standard CAN frame Identifier
message.msgID = (RxFrame[0] & XCANPS_IDR_ID1_MASK) >> XCANPS_IDR_ID1_SHIFT;
}
else
{
// Extended CAN frame Identifier
message.msgID = (RxFrame[0] & XCANPS_IDR_ID2_MASK) >> XCANPS_IDR_ID2_SHIFT;
}
message.msgLen = (RxFrame[1] & XCANPS_DLCR_DLC_MASK) >> XCANPS_DLCR_DLC_SHIFT;
/*
* Read Data field contents. Copy the full 8 bytes.
*/
memcpy( message.data, &RxFrame[2], sizeof(message.data));
/*
* Read Data field contents. Copy the full 8 bytes.
*/
memcpy( message.data, &RxFrame[2], sizeof(message.data));
/* Post the message to the receiving queue. */
xQueueSendToBackFromISR( canInstPtr->xQueueRx, &message, NULL );
/* Post the message to the receiving queue. */
xQueueSendToBackFromISR( canInstPtr->xQueueRx, &message, NULL );
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment