Zynq7020-PS端裸机--EMMC/SD驱动实现

下面来介绍一下,emmc、sd的驱动实现。

一、vivado PL端设置

PL端 设置: 如果你是用sd卡、或者EMMC要在vivado zynq核上勾选 sd、emmc。
emmc和sd使用公用那几个IO.同一个时刻只能当做其中一个使用。
zynq有两个sd接口。也可以一个给sd卡,一个给EMMC使用。
下面的例子是修改官方例程。

二、ps端代码编写


SD 、emm初始化基本一样。这是裸机不需要文件系统。直接对sd卡/emmc进行读写
#ifdef __ICCARM__
#pragma data_alignment = 32
u8 DestinationAddress[10*1024];
#pragma data_alignment = 32
u8 SourceAddress[10*1024];
#else 
u8 DestinationAddress[10*1024] __attribute__ ((aligned(32)));
u8 SourceAddress[10*1024]__attribute__ ((aligned(32)));
#endif
#define TEST 7/* Number of SD blocks to test */
#define NUM_BLOCKS 16/* Sector offset to test */
#define SECTOR_OFFSET 204800
XSdPs SD_InstancePtr;
bool  SdCard_Init(void)
{             
	static XSdPs SdInstance;             
	XSdPs_Config *SdConfig;             
	int Status;             
	u32 BuffCnt;      
	 /* * Since block size is 512 bytes. File Size is 	512*BlockCount.              */        
      u32 FileSize = (512*NUM_BLOCKS); 
      /* File Size is only up to 2MB */            
       u32 Sector = SECTOR_OFFSET;             
       for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++)
       {                    		   
       		SourceAddress[BuffCnt] = 4;
       //TEST + BuffCnt;        
        }     
               /* * Initialize the host controller */          	
       SdConfig = XSdPs_LookupConfig(XPAR_XSDPS_1_DEVICE_ID);            
       if (NULL == SdConfig) 
       {                   
			return XST_FAILURE;            
       }            
	Status = XSdPs_CfgInitialize(&SdInstance, SdConfig,SdConfig->BaseAddress);           
	if (Status != XST_SUCCESS)
	 {		          
       	return XST_FAILURE;            
     }           
 	Status = XSdPs_CardInitialize(&SdInstance);		   
	if (Status != XST_SUCCESS)
	{                    
 		return XST_FAILURE;          
    }	           
/*              * Write data to SD/eMMC.              */             
 	if (!(SdInstance.HCS)) Sector *= XSDPS_BLK_SIZE_512_MASK;             
 	Status = XSdPs_WritePolled(&SdInstance, Sector, NUM_BLOCKS, SourceAddress);
 	if (Status != XST_SUCCESS) 
 	{                   
  		return XST_FAILURE;            
   	}           
/*              * Read data from SD/eMMC.              */
	if (!(SdInstance.HCS)) 
	Sector *= XSDPS_BLK_SIZE_512_MASK;             
	Status  = XSdPs_ReadPolled(&SdInstance, Sector, NUM_BLOCKS,                                    DestinationAddress);             
	if (Status!=XST_SUCCESS) 
	{                    
		return XST_FAILURE;            
	}             
/*              * Data verification              */
	for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++)           
	{                   
  	if(SourceAddress[BuffCnt] != DestinationAddress[BuffCnt])                    
  	{                          
    	 Uart_Send("qwert",5);                       
     	 return XST_FAILURE;                
 	 }          
	}
       Uart_Send(DestinationAddress,FileSize); //输出从sd或者emmc的数观察对不对
}


<think>好的,用户的问题是关于在Zynq平台上实现eMMC存储设备的读写操作,特别是驱动开发方面的教程。首先,我需要回忆一下Zynq平台的基本架构,尤其是PS和PL部分的区别。用户提到的引用内容中提到,eMMC是通过PS的MIO接口连接的,没有用到PL资源,所以在开发时可能不需要涉及FPGA部分的编程,而是集中在PS的配置。 接下来,我需要考虑如何配置Zynq的硬件系统。根据引用1中的信息,系统框图显示使用了SD控制器来驱动eMMC,因为接口类似。所以在Vivado中配置SD0控制器,选择正确的MIO引脚,并将接口类型设置为eMMC,数据模式为8bit,还要启用复位引脚。这些步骤是硬件配置的基础。 然后,软件部分可能需要使用Xilinx提供的SD驱动库,或者直接通过FATFS文件系统来操作eMMC。引用中提到实验是在“Hello World”基础上另存为“emmc_rw”工程,所以可能需要在Vitis中创建应用工程,初始化eMMC控制器,并使用块读写函数。 用户可能还想知道如何验证读写操作是否正确,比如通过写入测试数据并回读。另外,引用2提到PLEMMC IP核,支持不同的位宽和吞吐率,但用户的问题是关于PS的操作,所以可能需要区分PS和PL的不同方法。不过用户的问题更偏向PS,所以重点放在PS的配置和驱动上。 还需要注意硬件连接是否正确,比如eMMC的引脚是否连接到正确的MIO,以及设备树中是否正确配置了eMMC节点。此外,软件驱动可能涉及中断处理、DMA配置等,但根据引用中的描述,可能Xilinx已经提供了相应的驱动库,简化了开发步骤。 最后,用户可能需要具体的代码示例,比如初始化代码、读写函数调用,以及如何在应用层使用FATFS进行文件操作。需要确保提供的代码示例正确,并符合Xilinx SDK/Vitis的环境要求。</think>在Zynq平台上实现eMMC存储设备读写操作,可分为硬件配置与软件开发两个阶段,以下是具体实现步骤: ### 一、硬件系统配置 1. **MIO接口配置** - 在Vivado中为Zynq UltraScale+ MPSoC选择SD0控制器,配置MIO13-MIO22引脚为eMMC接口[^1] - 设置Slot Type为eMMC模式,Data Transfer Mode选择8bit总线宽度 - 启用复位信号引脚配置,确保与硬件设计匹配 2. **时钟与电压设置** - 配置SD控制器时钟频率为eMMC设备支持范围(通常0-52MHz) - 验证I/O Bank电压与eMMC设备电平标准一致(一般为1.8V或3.3V) ### 二、软件开发流程 1. **驱动层开发** ```c // 初始化eMMC控制器 int status = XSdPs_Initialize(&SdInstance, XPAR_XSDPS_0_DEVICE_ID); status = XSdPs_CardInitialize(&SdInstance); // 块读写操作示例 u8 *buffer = (u8 *)XCsuDma_GetVirtAddr(XPAR_XCSUDMA_0_DEVICE_ID); status = XSdPs_ReadPolled(&SdInstance, 0, 1, buffer); // LBA=0,1个块 status = XSdPs_WritePolled(&SdInstance, 0, 1, buffer); ``` 2. **文件系统集成** - 在BSP配置中启用FATFS组件 ```c // 挂载文件系统 FATFS fs; f_mount(&fs, "", 0); // 文件读写示例 FIL fil; f_open(&fil, "test.txt", FA_READ | FA_WRITE); f_write(&fil, "Hello eMMC", 10, &bw); f_close(&fil); ``` ### 三、性能优化要点 1. **DMA传输配置** - 通过CSU DMA控制器实现高速数据传输,最大吞吐率可达52MB/s(8bit模式)[^2] -SD控制器配置中启用DMA模式,设置合适的数据缓冲区 2. **中断处理优化** ```c // 注册中断服务程序 XScuGic_Connect(&Intc, XPAR_XSDPS_0_INTR, (Xil_ExceptionHandler)XSdPs_IntrHandler, &SdInstance); XSdPs_SetCallback(&SdInstance, TransferHandler, &SdInstance); ``` ### 四、验证与调试 1. 使用SDK中的XSdPs_Examples测试基础读写功能 2. 通过性能分析工具测量实际吞吐率 3. 利用ILA核实时监控总线信号(PL实现时适用)[^2]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值