LPC54016 Posibble bug in fsl_mcan.c

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

LPC54016 Posibble bug in fsl_mcan.c

507 次查看
kstasch
Contributor I

Hello, I think there is a bug in fsl_mcan.c module in the function:

void MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle)

......

     valueIR = base->IR;

......

/* Store Current MCAN Module Error and Status. */
     valueIR = base->IR;
} while (0U != valueIR);

This causes that disabled interrupt lines are also handled in the loop. Especially the reception related flags like kMCAN_RxFifo0NewFlag may be handled before MCAN_TransferReceiveFifoNonBlocking() function was called and the handle->rxFifoFrameBuf points at NULL (0x0), thus causing that the data are copied to wrong address 0x0.

I think it should be like this:

void MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle)

......

     valueIR = base->IR & base->IE;

......

/* Store Current MCAN Module Error and Status. */
     valueIR = base->IR & base->IE;
} while (0U != valueIR);

 

0 项奖励
回复
1 回复

489 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I suppose that the MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle) in the original fsl_mcan.c is correct.

In the function, the CAN module state is reflected by the IR register, so the IR register is read/saved to a variable valueIR, so the remaining code checks the bit of IR and take corresponding action. Even if the flag is not required to generate interrupt, the state is also required to take action.

Hope it can help you

BR

XiangJun Rong

/*!

* brief MCAN IRQ handle function.

*

* This function handles the MCAN Error, the Buffer, and the Rx FIFO IRQ request.

*

* param base MCAN peripheral base address.

* param handle MCAN handle pointer.

*/

void MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle)

{

/* Assertion. */

assert(NULL != handle);

 

status_t status = kStatus_MCAN_UnHandled;

uint32_t valueIR;

uint32_t result;

 

/* Store Current MCAN Module Error and Status. */

valueIR = base->IR;

 

do

{

if (0U != (valueIR & ((uint32_t)kMCAN_ErrorWarningIntFlag | (uint32_t)kMCAN_ErrorPassiveIntFlag |

(uint32_t)kMCAN_BusOffIntFlag)))

{

/* Solve error. */

result = (uint32_t)kMCAN_ErrorWarningIntFlag | (uint32_t)kMCAN_ErrorPassiveIntFlag |

(uint32_t)kMCAN_BusOffIntFlag;

status = kStatus_MCAN_ErrorStatus;

}

else if (0U != (valueIR & (uint32_t)kMCAN_TxTransmitCompleteFlag))

{

/* Solve Tx interrupt. */

result = (uint32_t)kMCAN_TxTransmitCompleteFlag;

status = kStatus_MCAN_TxIdle;

MCAN_TransferAbortSend(base, handle, handle->txbufferIdx);

}

else if (0U != (valueIR & (uint32_t)kMCAN_RxFifo0NewFlag))

{

(void)MCAN_ReadRxFifo(base, 0U, handle->rxFifoFrameBuf);

result = (uint32_t)kMCAN_RxFifo0NewFlag;

status = kStatus_MCAN_RxFifo0Idle;

MCAN_TransferAbortReceiveFifo(base, 0U, handle);

}

else if (0U != (valueIR & (uint32_t)kMCAN_RxFifo0LostFlag))

{

result = (uint32_t)kMCAN_RxFifo0LostFlag;

status = kStatus_MCAN_RxFifo0Lost;

}

else if (0U != (valueIR & (uint32_t)kMCAN_RxFifo1NewFlag))

{

(void)MCAN_ReadRxFifo(base, 1U, handle->rxFifoFrameBuf);

result = (uint32_t)kMCAN_RxFifo1NewFlag;

status = kStatus_MCAN_RxFifo1Idle;

MCAN_TransferAbortReceiveFifo(base, 1U, handle);

}

else if (0U != (valueIR & (uint32_t)kMCAN_RxFifo1LostFlag))

{

result = (uint32_t)kMCAN_RxFifo1LostFlag;

status = kStatus_MCAN_RxFifo0Lost;

}

else

{

/* Handle the interrupt flag unsupported in current version of MCAN driver.

* User can get these unsupported interrupt flags by callback function,

* we can clear directly in the handler to prevent endless loop.

*/

result = valueIR;

result &= ~((uint32_t)kMCAN_ErrorWarningIntFlag | (uint32_t)kMCAN_ErrorPassiveIntFlag |

(uint32_t)kMCAN_BusOffIntFlag | (uint32_t)kMCAN_TxTransmitCompleteFlag |

(uint32_t)kMCAN_RxFifo0NewFlag | (uint32_t)kMCAN_RxFifo0LostFlag |

(uint32_t)kMCAN_RxFifo1NewFlag | (uint32_t)kMCAN_RxFifo1LostFlag);

}

 

/* Clear Error interrupt, resolved Rx FIFO, Tx Buffer IRQ and other unsupported interrupt flags. */

MCAN_ClearStatusFlag(base, result);

 

/* Calling Callback Function if has one. */

if (handle->callback != NULL)

{

handle->callback(base, handle, status, result, handle->userData);

}

 

/* Reset return status */

status = kStatus_MCAN_UnHandled;

 

/* Store Current MCAN Module Error and Status. */

valueIR = base->IR;

} while (0U != valueIR);

}

 

0 项奖励
回复