[X]关闭

[米联客-XILINX-H3_CZ08_7100] LINUX驱动篇连载-10 PS读写EMMC或者SD卡实验

文档创建者:LINUX课程
浏览次数:360
最后更新:2024-09-10
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 2_LINUX应用开发
本帖最后由 LINUX课程 于 2024-9-11 10:32 编辑

软件版本:vitis2021.1(vivado2021.1)
操作系统:WIN10 64bit
硬件平台:适用XILINX Z7/ZU系列FPGA
登录“米联客”FPGA社区-www.uisrc.com视频课程、答疑解惑!

1 概述
ZYNQ MPSOC具有2个独立的SD控制器。在SD模式下数据支持1bit/4bit方式通信。在Emmc模式数据支持1bit/4bit/8bit方式通信。SD控制器还可以通过EMIO映射到PL IO使用。控制器通过APU或者RPU以及AXI总线互联,控制内部还包括一个带FIFO的DMA控制器,以提高传输速度。
本文主要以SD模式的数据卡做介绍,同时给出EMMC的读写demo。由于本文内容涉及概念非常广泛,有不详尽和介绍错误的地方,请读者指正。如果读者不想深究这些概念,可以简要阅读,主要看代码的如何应用。
本文的代码给出了SD卡读写程序和EMMC读写程序,其中SD卡支持raw无协议读写和FAT带文件系统读写,但是EMMC程序只支持raw读写。
本文实验目的:
  • 熟悉SD接口卡的硬件参数包括容量、速度模式、卡的类型
  • 熟悉SD接口的通信协议
  • 熟悉ZYNQ-MPSOC SDIO控制器的硬件资源
2 系统框图
image.jpg
3 SD协议简介
本小节内容摘录自“Part_1_Physical_Layer_Simplified_Specification_4_10.pdf”。本人主要对SD卡的类型、容量、速度模式做简要介绍,以及对SD卡的识别模式,数据传输模式做简要介绍。由于篇幅有限,更多了关于SD接口 command命令描述、Responses响应描述、错误情况、时钟控制等读者如果要进一步了解需要继续阅读“Part_1_Physical_Layer_Simplified_Specification_4_10.pdf”。本身使用的SDIO接口协议,对于SD的SPI通信方式不做介绍。
3.1 SD接口卡简介
SD接口卡包括SD卡、TF卡、MMC卡、SDIO卡。其中SD卡和TF卡软件使用上一致,但是TF卡具有更小的尺寸,因此被更加广泛使用,用TF卡插入SD卡套也可以直接当作SD卡使用,通常来说,本文所指的TF卡就是SD卡。而SDIO卡一般是非存储的卡,比如SDIO接口的WIFI模块。那么SD卡和MMC卡的主要使用区别在于初始化过程不一样。
1:SD存储容量
SD卡按容量分类分为标准容量卡、高容量卡,扩展容量卡:
类别
容量
Standard Capacity SD Memory Card (SDSC)
<=2GB
High Capacity SD Memory Card (SDHC)
>2GB && <32GB
Extended Capacity SD Memory Card (SDXC)
>32GB&&<2TB
一般目前市场上常用的SD接口存储卡容量都在2GB以上
2:SD接口卡的速度模式
SD接口卡支持的速度模式如下:
模式
电压模式
最高频率
最高速度
Default Speed mode
3.3V
25MHz
12.5MB/sec
High Speed mode
3.3V
50MHz
25MB/sec
SDR12 mode
1.8V
25MHz
12.5MB/sec
SDR25 mode
1.8V
50MHz
25MB/sec
SDR50 mode
1.8V
100MHz
50MB/sec
SDR104 mode
1.8V
208MHz
104MB/sec
DDR50 mode
1.8V
50MHz
50MB/sec
SDR(Single Date Rate):一个周期只能采集一次数据,即一个bit,由于SD卡是4条数据线并行传输,所以一个周期能传输4bit,如果频率是50MHz(即1秒传输次数为50 000 000),那么1秒能传输的数据量为25MB(这里1MB为1 000 000 Byte)。所以这就是为什么各种SDR模式里面,频率上限是速度上限的两倍。
DDR(Double Data Rate):在时钟上升沿和下降沿都可以采集数据,也就是单一周期内可读取或写入2次,因此4条并行数据线在一个周期内能传输8bit。
3:SD卡的速度类别
通常来说,我们看到的TF卡上都有规格描述,每种规格都表示卡能够支持的最小速度:
Class 0 - 这种卡没有性能要求
Class 2 - 要求在 Default Speed mode 下,性能至少要达到(大于等于) 2MB/sec
Class 4 - 要求在 Default Speed mode 下,性能至少要达到 4MB/sec
Class 6 - 要求在 Default Speed mode 下,性能至少要达到 6MB/sec
Class 10 - 要求在 High Speed mode 下,性能至少要达到 10MB/sec
4:供电电压
根据工作电压,我们定义了两种SD存储卡:
类别
工作电压
高压SD存储卡
工作电压范围为2.7 ~ 3.6 V。
UHS-II SD存储卡
工作电压范围为VDD1: 2.7 ~ 3.6 V, VDD2: 1.70 ~ 1.95V
3.2 SD总线协议
不管Command,还是Response或者Data,都开始于一个start bit (bit值0),结束于一个end bit(bit值1)。
传输类型
功能描述
Command
一个命令代表着将开始一个操作。命令通过CMD线传输,方向从host到card
Response
响应是card对前一次host发送的命令的执行情况的反馈。也是通过CMD线传输,方向从card到host
Data
方向可以从card到host,也可以从host到card
1:无Response和无data操作
image.jpg
2:多次块读操作
image.jpg
3:多次块写操作
image.jpg
4:Command格式
每个命令有1个start bit(val=0 )开始,和一个end bit(val=1)结束,总长度为48位,并且具有crc校验。
image.jpg
5:Response格式
Response一共有4种编码方案,长度可以是48bit或者136bit.
image.jpg
6:常用数据包格式(8位宽)
image.jpg
7:宽数据包格式
image.jpg
3.3 SD数据卡寄存器
1:SD卡的引脚定义
image.jpg
image.jpg
1) S: power supply; I: input; O: output using push-pull drivers; PP: I/O using push-pull drivers;  
2) The extended DAT lines (DAT1-DAT3) are input on power up. They start to operate as DAT lines after
SET_BUS_WIDTH command. The Host shall keep its own DAT1-DAT3 lines in input mode, as well, while they are not
used.  
3) At power up this line has a 50KOhm pull up enabled in the card. This resistor serves two functions Card detection and
Mode Selection. For Mode Selection, the host can drive the line high or let it be pulled high to select SD mode. If the host
wants to select SPI mode it should drive the line low. For Card detection, the host detects that the line is pulled high. This
pull-up should be disconnected by the user, during regular data transfer, with SET_CLR_CARD_DETECT (ACMD42)
command
4) DAT1 line may be used as Interrupt Output (from the Card) in SDIO mode during all the times that it is not in use for
data transfer operations (refer to "SDIO Card Specification" for further details).  
5) DAT2 line may be used as Read Wait signal in SDIO mode (refer to "SDIO Card Specification" for further details).
2:SD数据卡的功能结构
image.jpg
3:SD卡寄存器说明
image.jpg
SD卡内部有7个寄存器:OCR,CID,CSD和SCR寄存器保存卡的配置信息;
RCA寄存器保存着通信过程中卡当前暂时分配的地址(只适合SD模式);
CSR寄存器卡状态(Card Status)和SSR寄存器SD状态(SD Status)寄存器保存着卡的状态(例如,是否写成功,通信的CRC校验是否正确等),这两个寄存器的内容与通信模式(SD模式或SPI模式)相关。
MMC卡没有SCR和SSR寄存器。
下面对以上寄存器做进一步说明。
3.1:Operating Conditions Register(OCR)寄存器
SD卡支持的电压范围如下图所示,如果相应的bit1就是支持,否则如果是0就是不支持。
OCR bit position
OCR Fields Definition
0-6
reserved
7
Reserved for Low Voltage Range
8-14
reserved
15
2.7V-2.8V
16
2.8V-2.9V
17
2.9V-3.0V
18
3.0V-3.1V
19
3.1V-3.2V
20
3.2V-3.3V
21
3.3V-3.4V
22
3.4V-3.5V
23
3.5V-3.6V
24
Switching to 1.8V Accepted (S18A) 只有UHS-I卡支持此位
25-28
reserved
29
UHS-II Card Status
30
Card Capacity Status (CCS) 只有当卡上电状态位被设置时,此位才有效
31
Card power up status bit (busy) 如果卡没有完成上电程序,此位被设置为低
3.2:Card Identification Register(CID)寄存器
卡识别(CID)寄存器是128位宽。它包含在卡识别阶段使用的卡识别信息。每个读写(RW)卡都应有一个唯一的识别号码。CID寄存器的定义如下:
Name
Field
Width
COID-slice
Manufacturer ID
MID
8
[127:120]
OEM/Application ID
OID
16
[119:104]
Product name
PNM
40
[103:64]
Product revision
PRV
8
[63:56]
Product serial number
PSN
32
[55:24]
reserved
4
[23:20]
reserved
MDT
12
[19:8]
CRC7 checksum
CRC
7
[7:1]
not used, always 1
1
[0:0]
3.3:Card Specific Data Register(CSD)寄存器
CSD数据寄存器提供有关访问卡内容的信息。CSD定义了数据格式、纠错类型、最大数据访问时间、是否可以使用DSR寄存器等。寄存器的可编程部分(用W或E标记的条目,见下文)可以用CMD27改变。下表项的类型编码如下:R =可读,W(1) =一次可写,W =多次可写。
在SD3.0协议中,CSD分为版本1.0和版本2.0,版本1.0对应标准容量的SD卡,版本2.0对应高容量和超高容量的SD卡。
CSD寄存器的字段结构是不同的,取决于物理层规范版本和卡容量。CSD寄存器中的CSD_STRUCTURE字段表示它的结构版本。
CSD_STRUCTURE
CSD structure version
Card Capacity
0
CSD Version 1.0
Standard Capacity
1
CSD Version 2.0
High Capacity and Extended Capacity
2-3
reserved
CSD寄存器1.0版本定义如下:
Name
Field
Width
Value
Cell Type
CSD-slice
CSD structure
CSD_STRUCTURE
2
00b
R
[127:126]
reserved
-
6
00 0000b
R
[125:120]
data read access-time-1
TAAC
8
xxh
R
[119:112]
data read access-time-2 in CLK cycles (NSAC*100)
NSAC
8
xxh
R
[111:104]
max. data transfer rate
TRAN_SPEED
8
32hor 5Ah
R
[103:96]
card command classes
CCC
12
01x110110101b
R
[95:84]
max. read data block length
READ_BL_LEN
4
xh
R
[83:80]
partial blocks for read allowed
READ_BL_PARTIAL
1
1b
R
[79:79]
write block misalignment
WRITE_BLK_MISALIGN
1
xb
R
[78:78]
read block misalignment
READ_BLK_MISALIGN
1
xb
R
[77:77]
DSR implemented
DSR_IMP
1
xb
R
[76:76]
reserved
-
2
00b
R
[75:74]
device size
C_SIZE
12
xxxh
R
[73:62]
max. read current @VDD min
VDD_R_CURR_MIN
3
xxxb
R
[61:59]
max. read current @VDD max
VDD_R_CURR_MAX
3
xxxb
R
[58:56]
max. write current @VDD min
VDD_W_CURR_MIN
3
xxxb
R
[55:53]
max. write current @VDD max
VDD_W_CURR_MAX
3
xxxb
R
[52:50]
device size multiplier
C_SIZE_MULT
3
xxxb
R
[49:47]
erase single block enable
ERASE_BLK_EN
1
xb
R
[46:46]
erase sector size
SECTOR_SIZE
7
xxxxxxxb
R
[45:39]
write protect group size
WP_GRP_SIZE
7
xxxxxxxb
R
[38:32]
write protect group enable
(WP_GRP_ENABLE)
1
xb
R
[31:31]
reserved (Do not use)
2
00b
R
[30:29]
write speed factor
R2W_FACTOR
3
xxxb
R
[28:26]
max. write data block length
WRITE_BL_LEN
4
xxxxb
R
[25:22]
partial blocks for write allowed
WRITE_BL_PARTIAL
1
xb
R
[21:21]
reserved
5
00000b
R
[20:16]
File format group
FILE_FORMAT_GRP
1
xb
R/W(1)
[15:15]
copy flag
COPY
1
xb
R/W(1)
[14:14]
permanent write protection
PERM_WRITE_PROTECT
1
xb
R/W(1)
[13:13]
temporary write protection
TMP_WRITE_PROTECT
1
xb
R/W
[12:12]
File format
FILE_FORMAT
2
xxb
R/W(1)
[11:10]
reserved
2
00b
R/W
[9:8]
CRC
CRC
7
xxxxxxxb
R/W
[7:1]
not used, always'1'
-
1
1b
-
[0:0]
CSD 2.0版本应用于SDHCSDXC卡。括号中的字段名被设置为固定值,表示主机不需要引用这些字段。固定值使引用这些字段的host能够保持与CSD 1.0版本的兼容性。单元格类型字段编码如下:R =可读,W(1) =一次可写,W =多次可写。
CSD寄存器2.0版本定义如下:
Name
Field
Width
Value
Cell Type
CSD-slice
CSD structure
CSD_STRUCTURE
2
00b
R
[127:126]
reserved
-
6
00 0000b
R
[125:120]
data read access-time-1
(TAAC)
8
xxh
R
[119:112]
data read access-time-2 in CLK cycles (NSAC*100)
(NSAC)
8
xxh
R
[111:104]
max. data transfer rate
(TRAN_SPEED)
8
32h,5Ah,0Bh,2Bh
R
[103:96]
card command classes
CCC
12
01x110110101b
R
[95:84]
max. read data block length
(READ_BL_LEN)
4
xh
R
[83:80]
partial blocks for read allowed
(READ_BL_PARTIAL)
1
1b
R
[79:79]
write block misalignment
(WRITE_BLK_MISALIGN)
1
xb
R
[78:78]
read block misalignment
(READ_BLK_MISALIGN)
1
xb
R
[77:77]
DSR implemented
DSR_IMP
1
xb
R
[76:76]
reserved
-
6
00000b
R
[75:70]
device size
C_SIZE
22
xxxxxxh
R
[69:48]
reserved
-
1
0
R
[47:47]
erase single block enable
(ERASE_BLK_EN)
1
xb
R
[46:46]
erase sector size
(SECTOR_SIZE)
7
xxxxxxxb
R
[45:39]
write protect group size
(WP_GRP_SIZE)
7
xxxxxxxb
R
[38:32]
write protect group enable
(WP_GRP_ENABLE)
1
xb
R
[31:31]
reserved (Do not use)
2
00b
R
[30:29]
write speed factor
(R2W_FACTOR)
3
xxxb
R
[28:26]
max. write data block length
(WRITE_BL_LEN)
4
xxxxb
R
[25:22]
partial blocks for write allowed
(WRITE_BL_PARTIAL)
1
xb
R
[21:21]
reserved
5
00000b
R
[20:16]
File format group
(FILE_FORMAT_GRP)
1
xb
R/W(1)
[15:15]
copy flag
COPY
1
xb
R/W(1)
[14:14]
permanent write protection
PERM_WRITE_PROTECT
1
xb
R/W(1)
[13:13]
temporary write protection
TMP_WRITE_PROTECT
1
xb
R/W
[12:12]
File format
(FILE_FORMAT)
2
xxb
R/W(1)
[11:10]
reserved
2
00b
R/W
[9:8]
CRC
CRC
7
xxxxxxxb
R/W
[7:1]
not used, always'1'
-
1
1b
-
[0:0]
3.4:SD card Configuration Register (SCR)寄存器
除了CSD寄存器外,还有一个名为SD卡配置寄存器(SCR)的配置寄存器。SCR提供关于SD存储卡的特殊特性的信息,这些特性被配置到给定的存储卡中。可控硅寄存器的大小是64位。此寄存器由SD卡厂家在工厂内设置。
Description
Field
Width
Cell Type
SCR Slice
SCR Structure
SCR_STRUCTURE
4
R
[63:60]
SD Memory Card - Spec. Version
SD_SPEC
4
R
[59:56]
data_status_after erases
DATA_STAT_AFTER_ERASE
1
R
[55:55]
CPRM Security Support
SD_SECURITY
3
R
[54:52]
DAT Bus widths supported
SD_BUS_WIDTHS
4
R
[51:48]
Spec. Version 3.00 or higher
SD_SPEC3
1
R
[47]
Extended Security Support
EX_ SECURITY
4
R
[46:43]
Spec. Version 4.00 or higher
SD_SPEC4
1
R
[42]
Reserved
6
R
[41:36]
Command Support bits
CMD_SUPPORT
4
R
[35:32]
reserved for manufacturer usage
-
32
R
[31:0]
SCR_STRUCTURE 关于SD卡内的物理级说明中SCR结构的版本号。
SD_SPEC描述这张SD卡在物理级上所支持的说明版本。
DATA_STAT_AFTER_ERASE 定义了数据在擦除后的状态。是“0”或“1”中的任何一个(这要依赖卡的供应商)。
SD_SECURITY 描述了该卡所支持的安全算法。0:无 1:安全协议1.0 安全说明版本 0.96 2:安全协议2.0 安全说明版本 1.0 - 1.01。其他保留
SD_BUS_WIDTHS描述该卡所支持的所有数据总线宽度。从SD 卡支持最少1 位或4 位宽度这两种总线模式开始,任何SD 卡都将最少要设置0 和2 这两个位(即SD_BUS_WIDTH = 0101 ),1.4位保留。
3.5:Relative card address (RCA)寄存器
该16位卡地址寄存器保存了在卡识别过程中卡发布的器件地址。该地址用于在卡识别后主机利用该地址与卡进行通信。RCA寄存器的缺省值是0x0000。0x0000是预留值,用于将所有卡设置为CMD7备用状态。该寄存器只有在SD总线模式下才有效。
3.6:Driver stage register (DSR)寄存器
该16bit寄存去在扩展的操作条件下可以选择使用它来改善总线性能(取决于总线长度、传输速率或卡的数量等参数)。CSD寄存器携带关于DSR寄存器使用的信息。DSR寄存器的默认值是0x404。
3.4 UHS(Ultra High Speed)SD总线标准
ZYNQ不支持该模式,但是MPSOC可以支持到UHS-I模式,所以我们也保留了这部分内容介绍。
UHS(Ultra High Speed)是与SDXC同时推出的SD卡总线标准。此标准适用于SDHC和SDXC。UHS-I最高传输速度(理论值)为104MB/s。英文字母I代表该设备(SD卡或读卡器)支持UHS-I接口。英文字母U,包含数目字1,代表该设备读写速度达U1。UHS-II最高传输速度达312MB/s,是UHS-I的三倍。
设备(如智能手机)必须支持UHS,才能保证达到U1或U3最低写入速度。
由于Ultrascale+ MPSOC不支持UHS-II,所以下面只介绍UHS-I初始化的命令序列流程。
image.jpg
-上电后,卡会处于3.3V 通信电平模式下。第一个CMD0命令会选择bus模式:SD模式或SPI模式。只有在SD模式下,才能进入1.8V 通信电平模式。一旦卡进入1.8V 通信电平模式,卡不能切换到SPI模式或者3.3V 通信电平模式,除非重新上电。(不同的电平模式,是为了获取不同的SDIO接口通信时序,以获取最佳的通信速度。)
收到CMD0命令后,卡将进入空闲状态(Idle state),但是仍然工作在SDR12时序下。UHS-I只提供了SD模式,没有提供SPI模式。
-通常来说速度越高,通信的IO电压越低,对SDR50、DDR50和SDR104模式,主控制器通信的信号电压为1.8V。也就是说SDCLK、CMD和DAT[3:0]线需要是1.8V的。一般的SD卡都是工作在3.3V,IO电平也是3.3V所以,而通常ZYNQ或者MPSOC的SDIO是工作在1.8V,所以需要用1.8V和3.3V的专用电平芯片完成信号转换。
主机和SD卡通过ACMD41命令来确认双方是否支持1.8V 通信电平模式。如果主机和卡都支持1.8V 通信电平模式,这就意味着UHS-I卡可用。
-UHS-I只能使用4-bit的bus模式,CMD42是个例外。如果卡被锁住了,就需要通过发送CMD42命令(1-bit模式)解锁,然后发送ACMD6命令将bus模式切换到4-bit。
-在卡解锁的情况下,CMD19命令执行在1.8V通信电平的传输状态。其他情况,CMD19都会被当做非法命令。
3.5 SD内存卡功能描述
主机和卡之间的所有通信都由主机(主)控制。对SD卡与主机(host)来说,有两种操作模式:
Card identification mode: 对卡reset重置后,主机进入卡识别模式,对卡来说,在reset后,除非收到CMD3命令,否则卡一直处于该模式下。
Data transfer mode: 当卡第一次发布它的RCA后,该卡将处于数据传输模式。而对主机来说,在它识别了bus线上的所有卡后,进入该模式。
1: SD卡的识别模式
当处于卡识别模式时,host主机重置处于卡识别模式的所有卡,验证操作电压范围,识别卡并要求它们发布相对卡地址(RCA)。这个操作是在每个卡各自的CMD行上分别执行的。在卡识别模式下的所有数据通信都只使用CMD命令行。在卡的识别过程中,卡必须在识别时钟速率为fOD的SD时钟频率下运行。
1.1:SD卡的复位
在SD模式下,命令GO_IDLE_STATE (CMD0)是软件复位命令,将每个卡置为空闲状态,而不考虑当前卡的状态。处于非活动状态的卡不受此命令影响。
host主机上电后,所有卡都处于空闲状态,包括之前处于Inactive状态的卡。
上电或CMD0后,所有卡的CMD行都处于输入模式,等待下一条命令的开始位。这些卡被初始化为一个默认的相对卡地址(RCA=0x0000)和一个具有400KHz时钟频率的默认驱动程序强度。在3.3V信号电平模式的情况下,如果支持并选择最高的驱动电流能力,默认驱动强度由驱动级寄存器(DSR)指定。在1.8V信号电平模式的情况下,默认驱动强度由B型驱动指定。在UHS-II模式(ZYNQ以及MPSOC不支持)下,CMD0不会将RCA清除到0x0000,只保留它的设备ID,设备ID是通过枚举确定的。
1.2:SD卡的操作条件验证
1-在host主机和卡开始通信时,主机可能不知道SD卡支持的电压,SD卡也可能不知道它是否支持当前提供的电压。主机发出一个带有指定电压的reset复位命令(CMD0),同时假定它可能被卡支持。为了验证电压,主机再发送一个CMD8命令。
2-通过发送SEND_IF_COND (CMD8)命令,去获取SD卡支持的工作电压。SD卡通过检测CMD8的参数部分来检查主机使用的工作电压,主机通过分析卡CMD8的response参数来确认SD卡是否可以在所给电压下工作,如果SD卡可以在指定电压下工作,则它的response里面会包含cmd8参数里面提供的电压 。如果SD卡不支持所给电压,则SD卡不会给出任何响应信息,并保持IDLE状态。如果要初始化SDHC和SDXC,在第一次发送ACMD41命令前,必须先发送CMD8。
3-SD_SEND_OP_COND (ACMD41)用来识别和拒绝与主机所需的VDD范围不匹配的SD卡。在指定的电压范围内而不能传输数据的卡应该放弃总线操作,Inactive State状态。ACMD41是特定于应用程序的命令;因此APP_CMD (CMD55)应该始终在ACMD41之前。在idle_state中用于CMD55的RCA应该是SD卡的默认RCA = 0x0000。
4-主机发出复位命令(CMD0)复位SD卡后,主机在ACMD41之前发出CMD8重新初始化SD存储卡。
5-主机发送ACMD41命令时,可以通过将该命令所带的OCR参数设置为0,用来查询卡支持的工作电压范围。当ACMD41被用于查询时,卡将忽略掉ACMD41里面的HCS参数。主机在查询到卡的工作电压后,也许会将该电压作为接下来发送的ACMD41命令的参数。
6-在初始化过程中,主机不允许改变正在操作的电压范围。
下图是SD卡状态图(card identification mode)
image.jpg
image.jpg
(*1) Note : Card returns busy when
-Card executes internal initialization process
-Card is High or Extended capacity SD Memory Card and host doesn't support High or Extended capacity This means that CMD8 is mandatory to initialize High capacity SD Memory Card.
1.3:SD卡的初始化和识别过程
1:当总线被激活后,主机开始卡初始化和识别过程。在主机发送SD_SEND_OP_COND(ACMD41)命令开始处理SD卡初始化时,ACMD41种的参数HCS位被设置为1表示主机支持SDHC或者SDXC;HCS被设置为0表示主机不支持SDHC和SDXC。
2:SD卡通过设置OCR里面的busy位来通知主机ACMD41的初始化已经完成。busy位为0,表示卡还在初始化;busy位为1,说明初始化已经完成。主机会在1s的时间内,重复不断地发送ACMD41命令,直到busy位被置1为止。SD卡只有在第一次收到设置电压的ACMD41命令时,才会去检查操作条件和OCR中的HCS位。并且在重复发送ACMD41命令的这段时间里,主机不应该发送任何命令,除了CMD0。
3:如果SD卡能正确响应CMD8,SD卡对ACMD41命令的响应会包含一个CCS字段,CCS在卡返回ready时(busy位置1)有效。CCS=0表示卡是SDSC,CCS=1表示卡是SDHC或者SDXC。
4:在ACMD41之后,主机会发送 ALL_SEND_CID (CMD2),获取卡的CID。在卡发送它的CID之后,卡进入识别状态(Identification State)。
5:接着,主机发送CMD3 (SEND_RELATIVE_ADDR),请求卡发布卡的RCA。RCA是一个比CID短的,并且将来在数据传输模式中使用的地址。
下图是SD卡的初始化和识别流程图(Card Initialization and Identification Flow)
image.jpg
1.4:初始化命令ACMD41
ACMD41参数的一般规则如下:
(1)如果参数中的电压设置(bit 23-0)为0,则称为“inquiry CMD41”,它不进行初始化,只用于获取OCR,(bit31-24)是无效的。
(2)如果参数中的电压设置(bit 23-0)非0称为first ACMD41开始初始化,(bit31-24)是有效的。
(3)下一个ACMD41相关bit应与第一个ACMD41保持一致。
(1) Argument of ACMD41
如果SDXC卡初始化为XPC=0,则该SD卡在默认速度模式或SDR12模式下工作功耗0.36W (100mA,在VDD1上3.6V),如果卡不支持速度类,则SD状态显示为0类。如果SDXC卡初始化为XPC=1,则该卡在默认速度模式或SDR12模式下工作0.54W (150mA, VDD1上3.6V),支持速度类。每次更改XPC选项需要重新初始化。
设置ACMD41参数中S18R=1,请求SD卡切换1.8V电平模式,当SD卡进行了电平切换后SD卡再次设置S18R=0,保持电平电压不变。
image.jpg
(2) Response of ACMD41 (R3)
image.jpg
1.5使用ACMD41切换电平模式
image.jpg
1.6UHS-Ihost初始化流程图
image.jpg
1.7:电平模式切换命令CMD11
image.jpg
如果ACMD41命令种请求了切换电平模式,而且R3 response的S18A==1表面SD卡准备好切换电平了,此时发送CMD11完成电平切换,并且返回R1 response.如果没有response,说明S18A==0,表示SD卡不能进行电平切换,主机不应发送CMD11.
当进入tran状态时,应该检查R1响应中的CARD_IS_LOCKED状态(在CMD7响应中表示)。如果卡处于锁定状态,则需要CMD42对卡进行解锁。如果卡未解锁,可以跳过CMD42。
对于UHS-I卡,CMD6功能组3选择合适的驱动强度,CMD6功能组1选择其中一种UHS-I模式。在SDR50和SDR104模式下,如果需要调优采样点,则反复下发CMD19,直到调优完成。
CMD11无响应的情况有四种:
(1)SD卡不支持电压开关;(2)SD卡支持电压开关,接收ACMD41, S18R=0;(3)SD卡收到CMD11未就绪状态;(4)信号电平已切换到1.8V。
1.8调优命令CMD19
通过调优模块(Tuning block)可以获取数据最佳的采样点,补偿静态延迟、PCB负载、信号抖动等造成时序影响。采样点的调优能力对于HOST-SDR-VD是必需的,对于HOST-SDR-FD是可选的。
image.jpg
CMD19定义为发送调优块命令。定义R1类型响应。SD卡未解锁时,可在1.8V信令模式传输状态下执行CMD19。另一种情况,CMD19被视为非法命令。数据块,由DAT[3:0]携带,包含一个模式来调整采样位置以接收CMD和DAT[3:0]行上的数据。如果CMD19的块长度是固定的,则不需要CMD16
Host连续发送CMD19命令,并且SD卡返回R1 responded,和读取SD数据总线上的数据。SD卡需要在不超过150ms的时间内完成CMD19序列执行40次。调优过程通常小于40次执行,因此应该小于150ms。这个时间不包括任何主机处理时间,如果主机在执行之间需要时间来处理CMD19,则序列可能要长这个时间。
调优模块的测试数据如下:
image.jpg
2:数据传输模式
因为一些卡在识别模式(Identification Mode)下,对操作频率有限制,所以在识别模式结束前,主机需要一直保持在fOD频率。在数据传输模式下,主机可以在fPP频率范围内操作卡。主机发出SEND_CSD (CMD9)以获取与卡相关的数据(CSD寄存器),例如块长度、卡存储容量等。
广播命令SET_DSR (CMD4)配置所有识别卡的驱动程序阶段。它根据应用总线的布局(长度)、总线上的卡的数量和数据传输频率来编程它们的DSR寄存器。时钟速率也从fOD切换到fPP。对卡和主机来说,SET_DSR(CMD4)命令是个可选。
CMD7用于选择一张卡,并且将卡设置为传输状态(Transfer State)。当发送的CMD7的RCA地址参数为"0x0000",所有卡将跳回到准备状态(Stand-by State )。
SD卡数据传输模式的流程图(SD Memory Card State Diagram (data transfer mode)):
image.jpg
对已经拥有RCA的卡来说,对它发送identification commands(比如ACMD41、CMD2),它将不会有任何回应。在数据传输模式下,主机与被选中的卡(使用定向命令)之间的数据传输都是点对点的。通过cmd线,所有定向命令(addressed commands)都会收到一个用于确认的response。
2.1:总线位宽的选择和取消
宽总线(4位总线宽度)操作模式可以使用ACMD6选择/取消选择。上电或GO_IDLE (CMD0)后总线的缺省宽度是1位总线宽度。改变总线位宽需要满足以下条件:
1-SD卡处于'tran state'状态
2-SD卡不处于锁住状态
2.2:2GB容量SD卡(已淘汰)
如果要制作2GByte的卡,则最大块长度(READ_BL_LEN=WRITE_BL_LEN)应设置为1024字节。但CMD16设置的块长度应不超过512字节,以保持与最大块长度512字节卡(小于等于2GByte卡)一致。由于这种卡已经淘汰,可以了解下就可以。
2.3:读数据
无数据传输时,DAT总线保持上拉。数据总线的数据包含起始位(低1bit或低4bits),数据流(包含有效数据和CRC校验),以及结束位(高1bit或高4bits)。
SD的数据块传输单位最大是512字节。CMD16设置的块长度可以设置为最大512字节,而不考虑READ_BL_LEN。CRC校验附加在每个数据块的末尾,用于校验数据。单个数据块传输实用CMD17命令。使用CMD18传输多个连续数据块,直到发出停止传输命令CMD12。由于发出的停止CMD12有延迟,所以host主机应该在准备发出CMD12前,忽略总线上还在传输的数据。
image.jpg
1-“Current Blocklen”大小是由CMD16设置或更改的。如果value小于等于512字节(与Misalign和Partial选项没有关系),则设置不出错。
2-当Blocklen size数据范围超过512字节的块边界时,SD卡输出数据直到512字节的块边界”,此时数据变为无效,可能发生 CRC错误。SD卡片将在下一个命令响应中发送“ADDRESS_ERROR”。主机应该发出CMD12来恢复。
2.4:写数据
写数据传输格式和读数据类似。在块写命令(CMD24 - 27,42,56 (w))执行期间,一个或多个数据块从主机传输到卡上,主机在每个块的末尾加上1位或4位的CRC。无论WRITE_BL_LEN设置为1k还是2k,都要求支持块写的SD卡块长度通过CMD16设置为512字节。但是,如果SD卡支持WRITE_BL_PARTIAL(= 1)那么和读操作一样可以支持1~512字节的写操作。下表是种Partial是不支持的。
image.jpg
1-“Current Blocklen”大小是由CMD16设置或更改的。如果value小于512字节(与Misalign和Partial选项没有关系),则设置为无错误。然后在执行写命令时测试“Current Blocklen”大小。
2-如果当前的Blocklen值不是该值,则Write命令的response响应,SD卡会响应“BLOCK_LEN_ERROR”。
3-如果“起始地址”不是这个值,那么SD卡将在Write命令的response响应中发送“ADDRESS_ERROR”。
如果SD卡的写缓冲区已经满,不能接收新的WRITE_BLOCK命令,那么SD卡需要在开始写卡的同时,保持DAT0为低电平。Host主机通过轮询发送CMD13,卡返回的respons中的READY_FOR_DATA状态位,表示卡正在写或者已经可以进行新一次的写命令。
写操作的时候使用预擦除命令ACMD23可以获得更高的块写速度。Host主机机将使用这个命令来定义在下一个写操作中将要发送多少个写块。在块传输过程中,主机可以终止写操作,剩余的块内容是未知的。如果host主机发送比ACMD23中定义的更多的写块,SD卡将一个接一个地擦除块(当接收到新数据时)。在多个块写操作后,这个数值将被重置为默认值(=1)。建议在CMD25之前使用此命令,一些卡对于多个写块操作会更快。如果主机想要使用预擦除特性,那么主机应该在写命令之前发送ACMD23。如果没有发送ACMD23,pre-erase-count可能会在执行其他命令(例如:安全应用程序命令)时自动清除。
使用Pipeline机制的数据缓存管理,在发送错误的情况下可能无法确认最后发送的缓冲区是那一个,SD卡可以响应ACMD22命令,返回已经写成功的数据块。
2.5擦除操作
为了提高数据吞吐量,需要同时擦除多个写块。通过启动写块擦除命令CMD32, 结束写块擦除命令CMD33来识别这些写块。
为了实现块擦除,Host的命令顺序:ERASE_WR_BLK_START(擦除写块开始CMD32)、ERASE_WR_BLK_END(擦除写块结束CMD33)和ERASE (CMD38)(擦除)。
如果接收到的erase (CMD38)或address setting (CMD32, 33)命令顺序错误,卡需要在状态寄存器中设置ERASE_SEQ_ERROR位,并重置整个顺序。如果收到了除SEND_STATUS之外的顺序错误命令,卡需要在状态寄存器中设置ERASE_RESET状态位,重置清除顺序,然后执行最后一个命令。
如果擦除范围包括写保护扇区,它们将保持完整,只有非保护扇区将被擦除。保护扇区应该在状态寄存器中设置WP_ERASE_SKIP状态位。
地址设置命令中的地址字段是一个以字节为单位的写块地址。卡将忽略WRITE_BL_LEN(参见CSD)大小以下的所有LSB。
如上所述,对于块写,该SD卡将通过保持DAT0低来指示正在进行擦除操作。实际的擦除时间可能会很长,主机可能会发出CMD7来取消卡的选择或执行卡的断开连接。
在擦除操作后,卡上的数据是'0'或'1',这取决于卡供应商。SCR寄存器位DATA_STAT_AFTER_ERASE(第55位)定义了它是'0'还是'1'。
3.6 ZYNQ SD/SDIO控制器介绍
ZYNQ具有2个SDIO控制器,都可以支持SD卡接口模式,ZYNQ的SDIO控制器完全兼容“SD Host Controller Specification Version 2.0”规范中SDMA(单词DMA模式)、ADMA1(4KB DMA)、ADMA2(允许在 32 位系统内存中传输任何位置和任何大小的数据并且支持链式DMA(地址可以不连续的传输))
由于EMMC的协议和SD卡的协议都一样,所以ZYNQ的SDIO也可以支持EMMC,但是需要注意可能时序上会存在问题应为XILINX没有做过充分测试。EMMC不支持作为BOOT外设,但是可以作为二级BOOT外设。这个在UG821中有说明,在LINUX的应用中很多场合会采用QSPI+EMMC的方式完成启动和系统加载。
ZYNQ的SDIO控制器硬件参数做以下总结:
1:符合SD/SDIO2.0协议标准
2:支持SDHS(最大2GB)  SDHC(最大32GB)的SD卡,也就是SD卡容量小于32GB容量的卡
3:支持SD卡的SD_CLK最高速度是50MHZ,对于EMIO方式的是25MHZ
4:支持中断或者轮询方式方位SD卡
5:支持DMA,包括SDMA、ADMA1、ADMA2
如下图所示为ZYNQ SDIO控制器通过AHB总线完成数据交互,我们把左边归纳用户层,右边为接口层:
用户层:DMA控制模块、SD/SDIO Host控制器、CPRM功能(内容保护功能)、数据FIFO、中断模块
接口层:解码器、应答产生模块、数据收发模块。
image.jpg
4 搭建SOC系统工程
本实验无须搭建新工程,可运行于任意系统之上。若无可运行系统请参考《3-4-1Linux入门》第五课内容,重新制作系统。
5 程序分析
5.1 应用分析
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <unistd.h>

  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <dirent.h>

  10. int main(int arg, char *args[])
  11. {
  12.     if (arg != 2)
  13.     {
  14.         printf("Usage: %s text\n", args[0]);
  15.         return 0;
  16.     }

  17.     char s[] = "text";
  18.     int fd = open(s, O_CREAT | O_RDWR | O_APPEND, S_IRWXU | S_IRWXG | S_IRWXO);
  19.     if (fd == -1)
  20.     {
  21.         printf("error is %s\n", strerror(errno));
  22.         return 0;
  23.     }

  24.     printf("sucess fd = %d\n", fd);
  25.     char buf[100];
  26.     memset(buf, 0, sizeof(buf));
  27.     strcpy(buf, args[1]);
  28.     write(fd, buf, strlen(buf));
  29.     write(fd, "\n", 1);
  30.     memset(buf, 0, sizeof(buf));

  31.     close(fd);
  32.     return 0;
  33. }
复制代码
行14~18,判断输入格式是否正确,使用方法为 ./文件名 字符串
行21,打开文件,若文件不存在则新建文件。
行30,清空输入缓存,准备拷贝输入的字符串。
行31,拷贝当前出入的字符串到缓存区。
行32~33,写入数据。
5.2 驱动分析
本章代码使用了open等函数而非fopen函数,最主要的理由是open是Linux系统的驱动级函数,而fopen为c的库函数,因此此处使用open函数等进行操作。
1:open函数
  1. int open( const char * pathname,int flags, mode_t mode);
复制代码
pathname:
文件路径及文件名。
flags:
指定打开方式。
  • O_RDONLY  只读打开
  • O_WRONLY  只写打开
  • O_RDWR 读写打开
上面三个常量必须指定一个并且只能指定一个,下面一些常量则是可选的:
  • O_APPEND  将写入追加到文件的尾端
  • O_CREAT 若文件不存在,则创建它。使用该选项时,需要第三个参数mode,用来指定新文件的访问权限位
  • O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则会出错
  • O_TRUNC 如果此文件存在,而且为只写或读写模式成功打开,则将其长度截短为0
  • O_NOCTTY 如果pathname指的是终端设备,则不将该设备分配作为此进程的控制终端
  • O_NONBLOCK 如果pathname指的是一个FIFO文件、块设备文件或字符设备文件,则此选项将文件的本次打开操作和后续的I/O操作设置为非阻塞模式
mode:
  • 当flags参数包含O_REEAT时,需要对mode参数进行指定
  • S_IRWXU,00700 权限,代表该文件所有者具有可读、可写及可执行的权限。
  • S_IRUSR 或S_IREAD,00400权限,代表该文件所有者具有可读取的权限。
  • S_IWUSR 或S_IWRITE,00200 权限,代表该文件所有者具有可写入的权限。
  • S_IXUSR 或S_IEXEC,00100 权限,代表该文件所有者具有可执行的权限。
  • S_IRWXG 00070权限,代表该文件用户组具有可读、可写及可执行的权限。
  • S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。
  • S_IWGRP 00020权限,代表该文件用户组具有可写入的权限。
  • S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。
  • S_IRWXO 00007权限,代表其他用户具有可读、可写及可执行的权限。
  • S_IROTH 00004 权限,代表其他用户具有可读的权限
  • S_IWOTH 00002权限,代表其他用户具有可写入的权限。
  • S_IXOTH 00001 权限,代表其他用户具有可执行的权限。
返回值:
文件描述符。
2:write函数
  1. int write(int handle,void *buf,int len);
复制代码
handle:
文件描述符
*buf:
指向读取缓存区的指针。
len:
写入文件的长度。
返回值:
返回实际写入文件内容的长度。
6 演示结果
将与资料对应的demo拷贝至sd卡文件系统的/home/uisrc/内。
1725934398179.jpg
弹出sd卡插入开发板。
SD2.0 启动 01 而模式开关为 ON OFF(7100 需要先将系统烧录进qspi,然后才能从qspi启动sd卡,“[米联客-XILINX-H3_CZ08_7100] LINUX基础篇连载-04 从vitis移植Ubuntu实现二次开发”)
2f5038eb9880afd532753935815b079.jpg
将 PS 端串口线连接电脑,如果要使用 ssh 登录,将网口线同样连接至电脑,最后给开发板通电。每次重新上电,需要重新插拔 PS 串口,否则会登录失败。
image.jpg
登录板卡后,cd至demo的位置:
image.jpg
运行./filewrite abc查看结果,在命令前后分别ls,可以看到多了一个text的文件:
image.jpg
使用cat text查看文件内容:
image.jpg
可以看到文件中就是我们输入的内容,可以多输入几次或者输入其他字符,均可以在text文件中找到。
若想自己编译,可使用gcc命令:
image.jpg
可以看到编译完多了一个文件,gcc编译的默认输出名称为a.out。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则