请教或讨论:SD卡在什么情况下会变成只读的?

韦东山
企业官方账号
2009-05-06 11:14:15
我有一个板子,是用SPI模式的SD卡;
发现如果突然断电的话,再次启动后,SD卡就变成只读的了。

通常的原因是什么?
...全文
2024 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
flying520520 2009-05-11
  • 打赏
  • 举报
回复
SD卡中没有扇区的概念,一般叫BLOCK或SECTOR,
SD卡只能整块或整SECTOR操作,先擦后写。
韦东山 2009-05-09
  • 打赏
  • 举报
回复
“SD一般都是Controller+Nand,对于Nand的wear-leaving和坏块管理都是在卡内的firmware做好了的。”
那么,是不是我每次格式化的话,用同一个地址访问SD卡时,它可能对应的物理扇区是不一样的?
我之所以这样问,是发现:用mkfs.vfat格式化有问题的卡之后,它就一切正常了。

实验如下:
我使用mkfs.vfat重新格式化SD卡后,一切都正常了:
原来出错的0xda00地址也可以正确读出了;

① 在格式化之前,我在ubuntu下用cat命令把整个SD卡读出存为sd.bin文件;
② mkfs.vfat后,再用cat命令把sd.bin导入SD卡
于是奇迹发生了:我的单板无论怎么访问这个SD卡,都是正确的;
并且,在单板上再次把整个SD卡cat出来,与ubuntu下cat出的sd.bin也是完全一致的。

韦东山 2009-05-09
  • 打赏
  • 举报
回复
gsymichael,现在别管只读的问题了,我已经深入到扇区的读操作了。

发现读一些扇区的时候出现Card ECC Failed错误,

但是这些出错的扇区在XP下用winhex或是在ubuntu下用dd命令是可以读出来的。

我能否禁止ECC功能呢?如果可以,用什么命令?
gsymichael 2009-05-09
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 thisway_diy 的回复:]
我可能把ECC与CRC弄混了,
读SD卡时,卡在发出数据之后,再发出16BIT的CRC;

至于ECC,应该是这样:SD卡基于NAND FLASH,它受位反转等NAND的固有缺点影响,所以需要内部进行ECC较验。

上面是我的猜测,请指教。
[/Quote]
SD一般都是Controller+Nand,对于Nand的wear-leaving和坏块管理都是在卡内的firmware做好了的。
LZ说的卡变成只读具体是什么,是你无法写入还是在写入的过程中出现提示?
一般来说文件系统会去获取是否写保护的状态,如果是写保护那么在写入或是删除过程中应当会弹出对话框提示;
韦东山 2009-05-09
  • 打赏
  • 举报
回复
cat后,再读就成功,我想原因可能是这样:
由于SD卡的智能,重写一个扇区时,它可能并不是修改当前的扇区,而是把这个地址重新对应到另一个扇区上去;
所以再读取时,其实读的是另一个扇区,由于这是个新的扇区,所以读取没问题。

我用winhex验证了我的上述猜测:我只修改0xda00扇区的一个字节,
然后在单板下再读这个地址,就成功了。

所以,现在问题回到:当出现ECC错误时,怎样才能读到正确的数据?
我试过“出错重试”的方法,但是错误依旧。
韦东山 2009-05-08
  • 打赏
  • 举报
回复
读0xda00的扇区时,是这样进行的:
从0xd000开始的扇区开始,使用CMD18读多个块,读到第5个扇区,就是0xda00时出错;

我修改代码,读0xda00开始的扇区时,重新发一个CMD18命令,就是说0xda00这个扇区是CMD18读取的第1个扇区,
读出的数据是对的,与XP下winhex读到的数据完全一致!

这说明,SD卡没坏,可能是CMD18命令有某些限制,或者说这种SD卡在某些区域不能连续读取。

上面只是我的猜测,大家一起探讨一下,或是指点一下我。
gooogleman 2009-05-08
  • 打赏
  • 举报
回复
我的是把写保护去掉即可。、、、





楼主的非常经典的情况,真不知道。有可能是卡垃圾。或者坏了。

好久没有来非wince板块杀分了。
韦东山 2009-05-08
  • 打赏
  • 举报
回复
对于出错的卡,我读出的CID很奇怪:
CID的16个字节的16进制数如下:
00 00 00 53 44 00 00 00 00 00 00 04 2c 00 7c 57

按规范说,第2、3个数据应该是0x53, 0x54,下面的是好卡的CID:
03 53 44 53 55 31 32 38 80 40 df e2 99 00 7c d9

这就带来我两个疑问:
1. 这个坏卡是山寨的?
2. 如果是山寨的,除了某些扇区不能读外,其他扇区又是可以正常读的(我用dd命令)
韦东山 2009-05-08
  • 打赏
  • 举报
回复
我可能把ECC与CRC弄混了,
读SD卡时,卡在发出数据之后,再发出16BIT的CRC;

至于ECC,应该是这样:SD卡基于NAND FLASH,它受位反转等NAND的固有缺点影响,所以需要内部进行ECC较验。

上面是我的猜测,请指教。
韦东山 2009-05-08
  • 打赏
  • 举报
回复
进一步实验发现,在出错的扇区,返回的错误代码是0x04(期望的是数据标记0xfe),
这个错误表示Card ECC Failed,
这很奇怪,在读数据的时候,ECC码应该是用SD卡输出的,怎么会报告这个错误呢?

韦东山 2009-05-07
  • 打赏
  • 举报
回复
做了很多试验,抛开文件系统,我在单板上用dd命令、在XP上用winhex来查看修改扇区。

有些奇怪的现象,
我有两张SD卡,在XP下用winhex工具读写扇区,在单板下用dd命令读扇区;
A卡在单板、windows XP上都读写正常;

B上在单板上发现读0xda00开始的这个扇区不成功,在XP上0xda00开始的这个扇区读写都正常。

由于A卡、B卡用winhex读写0xda00的扇区都正常,所以我认为卡并没有坏。

单板上读SD卡用的是SPI模式,使用CMD18(读多块)的方式进行读取,
读这个扇区发生时,发现没有获得前导字0xfe,读到的数据一直是0xff。

按SPI SD卡的协议,CMD18启动后,必须用CMD12来停止。


难道说:对于某些SD卡,CMD18会自动停止吗?

morris88 2009-05-06
  • 打赏
  • 举报
回复
貌似前面部分的扇区出问题了,
试试重新格式化后是否还有问题
ketao_78 2009-05-06
  • 打赏
  • 举报
回复
bad sector?
韦东山 2009-05-06
  • 打赏
  • 举报
回复
再做了一些实验:
① mount时出现错误
② 在LINUX下拷贝文件出错
③ 在XP下拷贝文件成功
④ 到LINUX下,刚才在XP下拷贝的文件名被修改了,但是内容正确
⑤ 再回到XP下查看,文件名变回正确的

操作记录如下:
① mount时出现错误
$ mount /dev/sd/0/part1 /mnt
sdcard_read error offset=105 num=8 ret=4
end_request: I/O error, dev sd0, sector 113
Buffer I/O error on device sd0p1, logical block 16
Buffer I/O error on device sd0p1, logical block 17
Buffer I/O error on device sd0p1, logical block 18
Buffer I/O error on device sd0p1, logical block 19
Buffer I/O error on device sd0p1, logical block 20
Buffer I/O error on device sd0p1, logical block 21
Buffer I/O error on device sd0p1, logical block 22
Buffer I/O error on device sd0p1, logical block 23
end_request: I/O error, dev sd0, sector 113
Buffer I/O error on device sd0p1, logical block 16
Buffer I/O error on device sd0p1, logical block 17
Buffer I/O error on device sd0p1, logical block 18
Buffer I/O error on device sd0p1, logical block 19
end_request: I/O error, dev sd0, sector 121

② 拷贝一个文件:
/mnt $ cp /etc/fstab .
sdcard_read error offset=112 num=1 ret=4
end_request: I/O error, dev sd0, sector 113
FAT: FAT read failed (blocknr 16)
cp: Write Error: Input/output error
/mnt $ end_request: I/O error, dev sd0, sector 586
printk: 20 messages suppressed.
Buffer I/O error on device sd0p1, logical block 489
lost page write due to I/O error on sd0p1

③ 在xp下,可以读出文件、写入文件,在LINUX下再读出来验证正确
但是在LINUX下文件名改变了,比如:s3c24x0fb.c变为s3c24x~1.c
再次到XP下接上SD卡,里面的文件名仍为s3c24x0fb.c,内容一致

④ 在LINUX下,再次拷贝数据到SD卡:
/mnt $ cp /etc/mtab /mnt
sdcard_read error offset=112 num=1 ret=4
end_request: I/O error, dev sd0, sector 113
FAT: FAT read failed (blocknr 16)
cp: Write Error: Input/output error
/mnt $ end_request: I/O error, dev sd0, sector 586
printk: 20 messages suppressed.
Buffer I/O error on device sd0p1, logical block 489
lost page write due to I/O error on sd0p1
韦东山 2009-05-06
  • 打赏
  • 举报
回复
与这类开关没关系,因为硬件部分都不动的;
是:用着用着,就变成只读了
gsymichael 2009-05-06
  • 打赏
  • 举报
回复
写保护打开就是只读了吧
韦东山 2009-05-06
  • 打赏
  • 举报
回复
忘说了,是FAT32文件系统
flying520520 2009-05-06
  • 打赏
  • 举报
回复
典型的fat文件系统的问题,并不是卡变成只读了的,而是fat32的索引区数据有错误,一般的fat32不支持掉电保护,因为fat表没有写回,要避免这此问题要修改fat32代码的几个地方,或者你干脆找一个比较成熟的fat32嵌入式的文件系统移植上去也可以。
zhoujiamurong 2009-05-06
  • 打赏
  • 举报
回复
估计:板子上有代码保护T卡,发现出错,设置标志位,不再写入
韦东山 2009-05-06
  • 打赏
  • 举报
回复
在XP、ubuntu下都是正常的,就是在单板上不行;
应该是单板上的驱动问题,我继续调试,有结果再来请教大家

21,600

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧