Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DIY综合交流区
RK瑞芯微_Rockchip
音乐播放器
RK2706播放器filesystem
发布于 2011-11-05 10:13:57 浏览:7601
订阅该版
对于filesystem部分,建议大家都多去看看bsp下stm32f10x与mini2440分支SD部分. 这里参考了bsp下stm32f10x的sdcard.c. 熟悉RT-Thread的朋友肯定会知道有`rt_hw_sdcard_init()`这么一函数. 此函数负责初试化底层SDIO相关寄存器接着读取第0扇区传给dfs以获得最后第一分区信息,最后向RT-Thread注册sdcard这Block设备. 综上,如果只要求filesystem跑起来的话,只需实现开始的底层SD/MMC相关寄存器配置与读扇区函数就行. 先看实现了初始化SD/MMC相关寄存器的函数 ```c int sd_init(void) { int ret; rt_sem_init(&transfer_completion_signal, "t_com", 0, RT_IPC_FLAG_FIFO); rt_sem_init(&command_completion_signal, "c_com", 0, RT_IPC_FLAG_FIFO); rt_mutex_init(&sd_mtx,"sd_init",RT_IPC_FLAG_FIFO); /* 初始化 SD/MMC 相关寄存器 */ init_controller(); /* 初始化 SD/MMC 卡 */ ret = sd_init_card(); if (ret < 0) { rt_kprintf("SD init fail!! the ret is : 0x%x ",ret); return ret; } return 0; } ``` 这里值得注意的是transfer_completion_signal与command_completion_signal信号量,顾名思义是数据发送完成信号与命令发送完成信号. 这意味着向SD/MMC发送命令与数据都得等待各自完成信号(会在中断上释放各自信号量). 现阶段暂时无法改为轮询方式. 对于sd_init_card()的兼容性也有待验证,分别测试了1G与4G TF卡都可成功初始化问题. 成功初试化后便可读扇区了. ```c static __inline void read_sd_data(unsigned char **dst) { commit_discard_dcache_range((const void *)*dst, 512); A2A_IDST0 = (unsigned long)*dst; A2A_CON0 = (3<<9) | /* burst 16 */ (1<<6) | /* fixed src */ (1<<3) | /* DMA start */ (2<<1) | /* word transfer size */ (1<<0); /* software mode */ /* wait for DMA engine to finish transfer */ while (A2A_DMA_STS & 1); *dst += 512; } int sd_read_sectors(unsigned long start, void* buf,int count) { unsigned long response; unsigned int retry_cnt = 0; int cnt, ret = 0; unsigned char *dst; sd_enable(true); if (count <= 0 || start + count > card_info.numblocks) return -1; if (!(card_info.ocr & (1<<30))) start <<= 9; /* not SDHC */ while (retry_cnt++ < 20) { cnt = count; dst = (unsigned char *)buf; ret = 0; retry = false; /* reset retry flag */ mmu_buff_reset(); if (cnt == 1) { /* last block to transfer */ SD_DATAT = DATA_XFER_START | DATA_XFER_READ | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | DATA_XFER_SINGLE; } else { /* more than one block to transfer */ SD_DATAT = DATA_XFER_START | DATA_XFER_READ | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | DATA_XFER_MULTI; } /* issue read command to the card */ if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response)) { ret = -2; continue; } while (cnt > 0) { /* wait for transfer completion */ rt_sem_take(&transfer_completion_signal,RT_WAITING_FOREVER); if (retry) { /* data transfer error */ ret = -3; break; } /* exchange buffers */ mmu_switch_buff(); cnt--; if (cnt == 0) { if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response)) ret = -4; read_sd_data(&dst); break; } else if (cnt == 1) { /* last block to transfer */ SD_DATAT = DATA_XFER_START | DATA_XFER_READ | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | DATA_XFER_SINGLE; read_sd_data(&dst); } else { /* more than one block to transfer */ SD_DATAT = DATA_XFER_START | DATA_XFER_READ | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | DATA_XFER_MULTI; read_sd_data(&dst); } } /* while (cnt > 0) */ /* transfer successfull - leave retry loop */ if (ret == 0) break; } /* while (retry_cnt++ < 20) */ sd_enable(false); return ret; } ``` 这里值得一说的是`read_sd_data(&dst)`函数,此函数会调用`commit_discard_dcache_range()`清除目标地址+512范围的cache,以保证DMA过程数据正确. 实现读扇区函数后,便是向RT-Thread注册sdcard这Block设备了,这里填充相应函数即可. ```c static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { rt_uint32_t nr = size, retry; rt_err_t err; rt_mutex_take(&sd_mtx,RT_WAITING_FOREVER); err = sd_read_sectors((part.offset+pos),(rt_uint32_t*)buffer,size); rt_mutex_release(&sd_mtx); if (err == RT_EOK) return size; return 0; } void rt_hw_sdcard_init() { if (sd_init() == RT_EOK) { rt_uint8_t *sector; rt_err_t status; /* get the first sector to read partition table */ sector = (rt_uint8_t*) rt_malloc (512); if (sector == RT_NULL) { rt_kprintf("allocate partition sector buffer failed "); return; } status = sd_read_sectors(0, (rt_uint32_t*)sector, 1); if (status == RT_EOK) { /* get the first partition */ if (dfs_filesystem_get_partition(&part, sector, 0) != 0) { /* there is no partition */ part.offset = 0; part.size = 0; } } else { /* there is no partition table */ part.offset = 0; part.size = 0; } /* release sector buffer */ rt_free(sector); /* register sdcard device */ sdcard_device.type = RT_Device_Class_Block; sdcard_device.init = rt_sdcard_init; sdcard_device.open = rt_sdcard_open; sdcard_device.close = rt_sdcard_close; sdcard_device.read = rt_sdcard_read; sdcard_device.write = rt_sdcard_write; sdcard_device.control = rt_sdcard_control; /* no private */ sdcard_device.user_data = &card_info; rt_device_register(&sdcard_device, "sd0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); return; } __return: rt_kprintf("sdcard init failed "); } ``` 最后值得注意的是filesystem配置的问题,由于架构原因,rtconfig.h中不能定义`RT_DFS_ELM_WORD_ACCESS`此宏. 如无意外,SD/MMC已经mount成功,顺带加入readspeed.c测速. ![read_speed.jpg](/uploads/2304_46f0beef05c5897f0debc9400313d458.jpg) ![sd_card.rar](/uploads/2304_02d582bb789291b0ee6ee8f7a46ed08e.rar)
查看更多
5
个回答
默认排序
按发布时间排序
bernard
2011-11-09
这家伙很懒,什么也没写!
这个播放器有nandflash吧?可以提前试试下一个版本的yaffs2移植,应该只差个驱动就能够使用起来。
zzm24
2011-11-09
这家伙很懒,什么也没写!
>这个播放器有nandflash吧?可以提前试试下一个版本的yaffs2移植,应该只差个驱动就能够使用起来。 驱动起这nandflash有难度,因为要真正用起来得usb部分也得弄好.
bernard
2011-11-10
这家伙很懒,什么也没写!
那就一起都转起来,Flash文件系统、USB Device/Host不正是下一个版本要干的事情么。
shehzad
2014-10-02
这家伙很懒,什么也没写!
nice post..............
撰写答案
登录
注册新账号
关注者
0
被浏览
7.6k
关于作者
zzm24
这家伙很懒,什么也没写!
提问
12
回答
26
被采纳
0
关注TA
发私信
相关问题
1
[项目]搞个开源的硬件项目
2
硬件计划贴,及时更新,欢迎提意见
3
软件计划贴,及时更新,欢迎提意见::WMA,MOUNT,LWIP等问题急需解决.
4
MMS协议
5
定点的wma解压库-libwma
6
QQ群记录 [20090821]
7
STM32网络收音机PCB报名征集
8
第一版调试记录
9
第二版硬件讨论
10
RADIO项目相关模块规格--欢迎大家自己做板时规格与此兼容,减少重复劳动
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
2
RT-Thread EtherKit开源以太网硬件正式发布
3
如何在master上的BSP中添加配置yml文件
4
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
5
RT-Thread 发布 EtherKit开源以太网硬件!
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
15
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部