|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统 驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe |
使能Dcache后,DMA接收数据不正确,请帮忙 |
作者:ligenzhu 栏目:DSP技术 |
为了提高运行速度,我使能了指令Cache和数据Cache,结果发现,使能指令 Cache后,程序速度确实提高了一些;但是在使能数据Cache后,DMA接收出现异常。(呵呵,我做了点灯测试试验,使能数据Cache后,速度居然提高了6倍)。 在我的主程序中,添加如下代码使能指令Cache和数据Cache。 #include <cplb.h> #pragma retain_name //use cache,improve program speed int __cplb_ctrl = CPLB_ENABLE_ICPLBS| CPLB_ENABLE_ICACHE| CPLB_ENABLE_DCPLBS| CPLB_ENABLE_DCACHE; 在我的子程序中,有如下代码: unsigned CHAR ucBuf[126]; //define DMA recieve buffer and size InitDMARead(ucBuf, 126); //initialize DMA and enable DMA // send message to sensor, and Request Registers FPSWriteData(0x80); FPSWriteData(0x01); // Reset the sensor FPSWriteData(0x81); FPSWriteData(0x02); // Request Registers // Wait for DMA to finish reading the data while ((*pDMA5_IRQ_STATUS & DMA_DONE) == 0) { } *pDMA5_IRQ_STATUS = 0x000f; //clear bit DMA_DONE; *pDMA5_CONFIG = 0x00a2; //DMA disable, 8 bit transfer, write operation for( i = 0; i < 126; i++ ) // DISPLAY register. { printf("%2x ",ucBuf[i]); } 问题是使能数据Cache后,DMA接收的数据不正确,但是我把接收的Buffer尺寸改为1725后,居然接收正常。 unsigned CHAR ucBuf[126]; ---> unsigned CHAR ucBuf[1725]; 试着改为其它大小,发现接收的数据也不正确,(里面有时候有部分正确)。 其实我接收的只是126字节,我用示波器测量过了,我的命令确实正确发到了外围接口芯片上,而且外围接口芯片回来的数据用示波器测量也是正确的。 我也不知道发生了什么事情,请大家帮忙。 thanks. |
2楼: | >>参与讨论 |
作者: hardfire 于 2006/12/18 11:36:00 发布:
DMA是从哪到哪?PPI<-->SDRAM? 看看是否有需要用SSYNC的地方。 |
3楼: | >>参与讨论 |
作者: ligenzhu 于 2006/12/18 12:19:00 发布:
DMA是从SPI到SDRAM中的 void InitDMARead(unsigned CHAR * pDstBuf, unsigned int uiNumBytesToRead) { // Set destination address for DMA *pDMA5_START_ADDR = pDstBuf; // Set the count to read in the DMA *pDMA5_X_COUNT = uiNumBytesToRead; *pDMA5_X_MODIFY = 1; // Set the DMA Enable bit, Increment Destination, Don’t Increment Source, 8-bit Trasnfers *pDMA5_CONFIG = 0x00a3; //DMA enable, 8 bit transfer, write operation // Initialize the SPI PORT: Slave, 8-bit Xfer, Clock SPI Opposite *pSPI_CTL = 0x4412; //spi slave, spi 8 bit, DMA reciever // DMA is now ready to receive the data... } |
4楼: | >>参与讨论 |
作者: hardfire 于 2006/12/18 13:28:00 发布:
共同研究 我看linux下的spi_read代码一开始就执行: // TODO: remove this LINE as soon GFP_DMA MEMORY allocation is in place blackfin_dcache_invalidate_range(buf, buf+(count)*2); 你看看。 |
5楼: | >>参与讨论 |
作者: ligenzhu 于 2006/12/19 13:34:00 发布:
确实是BF531的一个BUG,在执行DMA时,需要把相应DATACache关掉。 6. 05000158 - Instruction DMA can cause data cache fills to fail (boot implications): DESCRIPTION: After a DMA or core MMR DTEST register access has occurred to the L1 instruction MEMORY, a data cache fill to the corresponding PORT may get corrupted data. This situation can ONLY occur if stalls are introduced because the core is accessing the same data MEMORY bank as the data cache fill. This data cache fill can occur many cycles after the L1 Instruction MEMORY DMA or MMR access. One example of the failure is when a program that enables data cache is booted. The Instruction DMA that occurred during the boot may prime the processor to be susceptible to data corruption in a data cache fill that occurs sometime during the main program's execution. For PORT A, data locations 0xFF80xxxx and instruction locations 0xFFA00000 -0xFFA07FFF (where applicable) are subject to the failure. For PORT B, data locations 0xFF90xxxx and instruction locations 0xFFA08000 - 0xFFA0FFFF (where applicable) are subject to the failure. The problem will also occur if the last DMA transaction was to the L1 instruction MEMORY while a low priority data cache fill is ongoing. WORKAROUND: The best workaround for this issue is to set bit 9 of any DCPLB Data register that you use. This bit is shown as a reserved bit in the HARDWARE Reference Manual, but the documentation is being updated to describe the functionality of this bit. A second workaround would be to perform a SOFTWARE.html">SOFTWARE core reset at the beginning of the program: P0.H = HI(SYSCR); // Check SYSTEM Reset Configuration Register P0.L = LO(SYSCR); R0.L = W[P0]; CC = BITTST(R0,4); // Check NO BOOT ON SOFTWARE RESET Bit IF CC JUMP _No_Boot_Set; BITSET(R0,4); // Set NO BOOT ON SOFTWARE RESET Bit W[P0] = R0; SSYNC; // Ensure write completes before executing RAISE RAISE 1; _No_Boot_Set: BITCLR(R0,4); // Reset SYSCR to original VALUE W[P0] = R0; If the program will be performing both data caching and L1 Instruction MEMORY DMA, perform a Data DMA to the data SRAM which shares a data PORT with the Instruction SRAM after performing an Instruction DMA. Do not perform any access that would cause data caching or victimization from the time the Instruction DMA begins until after the Data DMA has completed. Also, an MMR DTEST access to the corresponding data bank could also clear out the problem if the original problem was caused by the Instruction MEMORY DMA. If the program will access the L1 Instruction MEMORY through the core MMR DTEST register, follow this access with a core MMR DTEST register access to the corresponding Data Bank. If the processor is either not DMAing to instruction MEMORY or not using data cache, you will not encounter this problem. The VisualDSP++ runtime libraries cache supPORT functions contain a workaround for this anomaly where necessary. |
6楼: | >>参与讨论 |
作者: hardfire 于 2006/12/19 14:05:00 发布:
有些疑问一起讨论 L1 I MEM只能用64bit DMA访问,可见enable I cache后,DMA操作是时刻在发生的; 而linux下同时也enable 了D cache,那这样岂不是动辄就要diable D cache? 有些看晕了。 |
7楼: | >>参与讨论 |
作者: ligenzhu 于 2006/12/19 16:06:00 发布:
那倒不用。 可以把DMA所用的BUFFER不让它使用BUFFER。 例如调用下面这个函数一样。 blackfin_dcache_invalidate_range(buf, buf+(count)*2); 不过它的源码没有找到,我只能全部把它关掉了,然后再打开。 下面是我的代码的一部分。我想只要把那段内存空间不全能L1 Cache映射就可 以了,只是没有验证成功。 #include <defbf533.h> #include <cdefbf533.h> #include <stdio.h> #include "main.h" #define DCPLB_CNT 10 #define ICPLB_CNT 9 /************************************************/ /* */ /* Entries for the DCPLBx_ADDR */ /* */ /************************************************/ #pragma align4 section ("data1") unsigned int D_cplb_addrs[DCPLB_CNT] = { 0xff800000, 0xff900000, 0x00000000, 0x00400000, 0x00800000, 0x00C00000, 0x01000000, 0x01400000, 0x01800000, 0x01C00000 }; /************************************************/ /* */ /* Entries for the DCPLBx_DATA */ /* */ /************************************************/ #pragma align4 section ("data1") unsigned int D_cplb_data[DCPLB_CNT] = { 0x2001f, 0x2001f, 0x3D01f, 0x3D01f, 0x3D01f, 0x3D01f, 0x3D01f, 0x3D01f, 0x3D01f, 0x3D01f }; /************************************************/ /* */ /* Entries for the ICPLBx_ADDR */ /* */ /************************************************/ #pragma align4 section ("data1") unsigned int I_cplb_addrs[9] = { 0xFFA00000, 0x00000000, 0x00400000, 0x00800000, 0x00C00000, 0x01000000, 0x01400000, 0x01800000, 0x01C00000 }; /************************************************/ /* */ /* Entries for the ICPLBx_DATA */ /* */ /************************************************/ #pragma align4 section ("data1") unsigned int I_cplb_data[9] = { 0x00020003, 0x00031005, 0x00031005, 0x00031005, 0x00031005, 0x00031005, 0x00031005, 0x00031005, 0x00031005 }; /********************************/ /* */ /* LOCK CONTROL for the ICache */ /* 1: LOCK the way */ /* 0: Don't LOCK */ /* */ /** |
8楼: | >>参与讨论 |
作者: hardfire 于 2006/12/19 16:40:00 发布:
uClinux-dist/linux-2.6.x/arch/blackfin/mach-common/cache.S /* Throw away all D-cached data in specified region without any obligation to * write them BACK. However, we must clean the D-cached entries around the * boundaries of the start and/or end address is not cache aligned. * * Start: start address, * end : end address. */ ENTRY(_blackfin_dcache_invalidate_range) R2 = -L1_CACHE_BYTES; R2 = R0 & R2; P0 = R2; P1 = R1; CSYNC; FLUSHINV[P0]; 1: FLUSHINV[P0++]; CC = P0 < P1 (iu); IF CC JUMP 1b (bp); /* If the data crosses a cache LINE, then we'll be pointing to * the last cache LINE, but won't have flushed/invalidated it yet, * so do one more. */ FLUSHINV[P0]; SSYNC; RTS; |
9楼: | >>参与讨论 |
作者: ligenzhu 于 2006/12/19 17:25:00 发布:
你这里有没有BF531的汇编指令集呀, 没有对照,看得不太明白。。。 |
10楼: | >>参与讨论 |
作者: hardfire 于 2006/12/19 21:36:00 发布:
指令手册PROGRAMMING reference有啊 http://www.analog.com/processors/blackfin/technicalLibrary/manuals/index.html ADSP-BF53x/BF56x Blackfin Processor PROGRAMMING Reference (Revision 1.1, February 2006) (pdf, 3.40 MB) 就是啊。 |
|
|
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入 |
Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号 |