您好、Wang、根据您之前的建议、我们在应用每次读取 DMA 缓冲区之前都使用了 DMB 指令。 但我们仍然看到高速缓存和 RAM 不一致、并且观察到数据缺失。
我们对我们应该做的事情一无所知。 但是、当共享 RAM 区域禁用缓存时、不会发现问题。 但是、在缓存禁用模式下运行可能会影响计时、因此我们在想、我们需要做的确切事情就是解决这个问题。
当缓存被禁用时、我们使用了以下配置。
谢谢、
Kishore
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好、Wang、根据您之前的建议、我们在应用每次读取 DMA 缓冲区之前都使用了 DMB 指令。 但我们仍然看到高速缓存和 RAM 不一致、并且观察到数据缺失。
我们对我们应该做的事情一无所知。 但是、当共享 RAM 区域禁用缓存时、不会发现问题。 但是、在缓存禁用模式下运行可能会影响计时、因此我们在想、我们需要做的确切事情就是解决这个问题。
当缓存被禁用时、我们使用了以下配置。
谢谢、
Kishore
您好、Wang、这里是链接。
我使用使数据高速缓存无效进行了测试、因此存储器区域变得 一致。 CPU 可以从 SRAM 读取更新后的数据。
这是我的示例代码:
数据缓冲区被分配给.sharedRAM、该 RAM 被写回和写分配
DMA 传输的目标地址在.sharedRAM 部分
3.在 DMA 传输前先将数据分配给 rx_buffer []
DMA 将数据从 SCI RD 寄存器传输到 Rx_buffer []
5.当 DMA 传输完成时,使高速缓存无效
6.在 CCS 存储器浏览器中检查存储器内容。 内容已更新。
/* DMA 控制数据包配置堆栈*/
G_dmaCTRL g_dmaCTRLPKT;
uint32 dma_Comp_Flag;
uint8 data_buff [128];
#pragma SET_DATA_SECTION (".sharedRAM")
uint8 rx_buffer[128]={0};//系统 RAM 中的接收缓冲区
#pragma SET_DATA_SECTION ()
/*用户代码结束*/
int main (空)
{
/*用户代码开始(3)*/
#if ((__little_endian__= 1)||(__little_ENDIAN__= 1)
uint8 src_addr_offset = 0;对于 LE */、//为//
其他
uint8 src_addr_offset = 3;/* 3表示为*/
#endif
UINT32 IDLECOUNT = 0、I;
_mpuInit_();
/*将标志重置为“未完成”*/
DMA_Comp_Flag =~0x55AAD09E;
sciInit();
for (i=0;i<16;i++){
RX_BUFFER[I]= 0x55;
}
asm (" nop");
for (i=0;i<16;i++){
RX_BUFFER[I]= 0x5A;
}
/* SCI1上的打印标题*/
SCI_printf (" Hercule SCI RX DMA 示例-版本%\n\r\n);
SCI_printf ("********) \n\n");
/*启用 CPU 中断*/
_enable_IRQ ();
/*启用 DMA */
dmaEnable();
/*接收数据后启用中断*/
dmaEnableInterrupt (DMA_CH0、BTC、DMA_INTA);/* DMA_CH0为最高优先级*/
/*-填充 DMA 控制数据包结构*/
G_dmaCTRLPKT.Sadd =(uint32)(&(sciREG1->RD)+ src_addr_offset;
G_dmaCTRLPKT.DADD =(uint32)(&Rx_buffer[0]);
G_dmaCTRLPKT.CHCTRL = 0;/*通道控制*/
G_dmaCTRLPKT.ELCNT = 1;/*元素计数*/
G_dmaCTRLPKT.FRCNT = 16;/*帧计数*/
G_dmaCTRLPKT.ELDOFFSET = 0;/*元素目标偏移量*
G_dmaCTRLPKT.ELSOFFSET = 0;/*元素源偏移*
G_dmaCTRLPKT.FRDOFFSET = 0;/*帧目标偏移量*
G_dmaCTRLPKT.FRSOFFSET = 0;/*帧源偏移*
G_dmaCTRLPKT.PORTASGN = PORTB_READ_PORTA_WRITE;
G_dmaCTRLPKT.RDSIZE = ACCESS_8_BIT;/*读取大小*
G_dmaCTRLPKT.WRSIZE = ACCESS_8_BIT;/*写入大小*
G_dmaCTRLPKT.tType = frame_transfer;/* transfer type *
G_dmaCTRLPKT.ADDMODERD = ADDR_FIXED;/*地址模式读取*/
G_dmaCTRLPKT.ADDMODEWR = ADDR_INC1;/*地址模式写入*
G_dmaCTRLPKT.AUTOINIT = AUTOINIT_OFF;/*自动初始化*/
/*-设置用于传输的 DMA 控制数据包*/
dmaSetCtrlPacket (DMA_CH0、g_dmaCTRLPKT);
/*分配 DMA 请求:带有请求线路的通道0 - 1 - RX*/
/* DMA 请求28用于 LIN (SCI1)接收*/
/*请参阅数据表-默认 DMA 请求映射部分*/
dmaReqAssign (DMA_CH0、DMA_REQ28);
/*将 DMA 通道设置为在硬件请求时触发*/
dmaSetChEnable (DMA_CH0、DMA_HW);
/*启用 RX DMA */
sciREG1->SETINT =(3 << 17);
sci_printf ("sci DMA Rx 示例\n\r");
//请从 TeraTerm 终端输入16个字符
/*等待 DMA 中断 ISR 设置标志*/
while (DMA_Comp_Flag!= 0x55AAD09E){
IDLECOUNT++;
}
coreInvalidateICDCByAddress (0x0807F000、0x1000);
asm (" nop");
/*用户代码结束*/
返回0;
}