尊敬的团队:
我正在努力实现 AM263x 消息流 MCU+ SDK 版本 MCU_PLUS_SDK_am263x_09_02_00_55 。
我在中使用的是 UART 启用了 DMA 的回调模式 。
要求
我的接收长度是动态的:
-
首先、I 接收 4 个字节(标头)。
-
第 2 个字节和第 3 个字节决定有效载荷长度。
-
在此基础上,我更新
UART_Transaction.count. -
然后我
UART_read()再次调用以接收剩余的有效负载。 -
有效载荷接收完成后、我重新启动下一个 4 字节标头的接收。
来自外部器件的传入数据流是连续的。
发现问题
接收缓冲区将正确填充至 64 字节 。
64 字节后:
-
第 65 个字节之后出现损坏。
-
数据看起来像是从索引 0 重新启动或被覆盖。
-
行为表明可能发生 FIFO 溢出(UART FIFO 大小看起来为 64 字节)。
要临时恢复、当 LSR 指示数据就绪时、我通过读取 RHR 寄存器来手动刷新 UART FIFO、但我不确定这是否是将 UART 驱动程序与 DMA 搭配使用的正确方法。
这是我的代码
static uint8_t gRadioComReceivebuffer[UART_COM_BUFSIZE]
__attribute__((aligned(CacheP_CACHELINE_ALIGNMENT))) = {0U};
static uint8_t gRadioCOMCopyDMA[1024] = {0U};
#define UART_COM_BUFSIZE (1024)
static void SL_SetRadioCOMByteCount(uint16_t bCount)
{
RMC_RxTrans.buf = gRadioComReceivebuffer;
RMC_RxTrans.count = bCount;
}
static void RADIO_MODEM_RX_CALLBACK(UART_Handle handle,
UART_Transaction *trans)
{
printf("received count = %d\n", trans->count);
RMCRxBuf.rxCompleteFlag = 1U;
}
处理功能:
static void CopyReceiveData(void)
{
if (RMCRxBuf.rxCompleteFlag == 1U)
{
RMCRxBuf.rxCompleteFlag = 0U;
CacheP_inv((void *)gRadioComReceivebuffer,
RadioRXDMALen,
CacheP_TYPE_ALL);
if (RadioRXDMALen == 4U)
{
for(uint8_t i = 0; i < 4; i++)
{
gRadioCOMCopyDMA[i] = gRadioComReceivebuffer[i];
}
RadioRXDMALen =
((gRadioCOMCopyDMA[2] << 8) |
(gRadioCOMCopyDMA[3])) + 5U;
SL_SetRadioCOMByteCount(RadioRXDMALen);
UART_read(gUartHandle[RADIO_COMM_PORT], &RMC_RxTrans);
}
else
{
for(uint16_t i = 0; i < RadioRXDMALen; i++)
{
gRadioCOMCopyDMA[i + 4U] =
gRadioComReceivebuffer[i];
}
RadioRXDMALen = 4U;
SL_SetRadioCOMByteCount(RadioRXDMALen);
UART_read(gUartHandle[RADIO_COMM_PORT], &RMC_RxTrans);
VadateDMAmodel1(radioCOMRxByteCount);
radioCOMRxByteCount = 0U;
}
}
}
uart configuration:
.baudRate = 57600,
.dataLength = UART_LEN_8,
.stopBits = UART_STOPBITS_1,
.parityType = UART_PARITY_NONE,
.readMode = UART_TRANSFER_MODE_CALLBACK,
.readReturnMode = UART_READ_RETURN_MODE_PARTIAL,
.writeMode = UART_TRANSFER_MODE_CALLBACK,
.readCallbackFxn = RADIO_MODEM_RX_CALLBACK,
.writeCallbackFxn = RADIO_MODEM_TX_CALLBACK,
.hwFlowControl = FALSE,//TRUE,
.hwFlowControlThr = UART_RXTRIGLVL_16,
.transferMode = UART_CONFIG_MODE_DMA,
.skipIntrReg = FALSE,
.uartDmaIndex = 1,
.intrNum = 39U,
.intrPriority = 8U,
.operMode = UART_OPER_MODE_16X,
.rxTrigLvl = UART_RXTRIGLVL_1,
.txTrigLvl = UART_TXTRIGLVL_1,
.rxEvtNum = 0U,
.txEvtNum = 0U