Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
RT-Thread1.1RC elm 文件系统 read函数要4字节对齐?
发布于 2012-12-29 16:52:16 浏览:5573
订阅该版
[tocm] 硬件系统stm32f4,用sdio驱动。 发现read函数中形参buf要4字节对齐,同样形参len也要否则会导致失败。 lseek函数也出现问题。 ``` rt_size_t fd_fetch(void* parameter, rt_uint8_t *buffer, rt_size_t length) { int fd = (int)parameter; int read_bytes; #if 1 int d4= (unsigned long)buffer%4; if(d4) { rt_uint8_t *new_ptr; unsigned long k; rt_uint8_t *p=(rt_uint8_t*)&k; new_ptr = buffer -d4; //backup; k = *(unsigned long*)new_ptr; read_bytes = read(fd, (char*)new_ptr, length); if (read_bytes <= 0) return 0; memmove(buffer,new_ptr,read_bytes); while(d4--) { *new_ptr++ = *p++; } } else #endif { read_bytes = read(fd, (char*)buffer, length); } if (read_bytes <= 0) return 0; return read_bytes; }``` 这个是系统自带的helix mp3解码中的一个函数,若不对其的话会出错 ``` #if 1 t = Remaining%4; if(t) {//没有对齐 # if 0 unsigned char *ReadNewStart = ReadStart-t; //备份数据 rt_uint32_t k = *(rt_uint32_t*)ReadNewStart; unsigned char *p = (unsigned char*)&k; ReadSize = ReadSize&0xfffffffc; ReadSize=read(InputFp,ReadNewStart,ReadSize); if(ReadSize>0) { memmove(ReadStart,ReadNewStart,ReadSize); //还原 while(t--) { *ReadNewStart++ = *p++; } } # elif 0 unsigned char *ReadNewStart = ReadStart-t; ReadSize = (ReadSize+t)&0xfffffffc; lseek(InputFp,-t,SEEK_CUR); ReadSize=read(InputFp,ReadNewStart,ReadSize)-t; # else ReadSize=read(InputFp,ReadStart,ReadSize); # endif } else //Mp3ToWave("b.mp3","b.wma") #endif { ReadSize=read(InputFp,ReadStart,ReadSize); } ``` 这个是libmad0.15中的播放mp3的代码,也要对齐! lseek会出错
查看更多
9
个回答
默认排序
按发布时间排序
aozima
2012-12-29
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
文件系统没要求对齐,而是驱动里面需要。 但驱动不能限制上层应用,所以需要驱动里面做判断和软件修正。 同时上层应用也应该尽量避免非对齐访问。
lixun00
2012-12-29
这家伙很懒,什么也没写!
驱动里面在哪修正? 我跟了下,没发现。 由于时间问题,就没再搞下去。 mp3解码一定会出现不对齐的。 当不对其读的话解码就会出错! 不过文件读肯定有不对其的。
prife
2012-12-30
这家伙很懒,什么也没写!
这个问题能不能给出个具体的会出错的工程?
lixun00
2012-12-30
这家伙很懒,什么也没写!
这个真的没法给出。 昨天晚上我跟了下。 是stm32f4_sd.c出了问题。 只要是没对齐肯定会有问题。 奇怪的是lseek也会有问题,全部的源代码我是从readtouch拷过来的。
aozima
2012-12-30
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
sdio_sd.c在版本[https://github.com/RT-Thread/realtouch-stm32f4/commit/d4901f0f7fcb67ae5ecfb8058b0159a4105aeb16](d4901f0f7fcb67ae5ecfb8058b0159a4105aeb16)是由prife做过修正的。 不过SDIO方式的驱动没有做,楼主可以对比看看,欢迎提交 patch 或 pull requests。
lixun00
2013-01-01
这家伙很懒,什么也没写!
对sdio了解的不多,在block_dev.c里简单修复了下,测试未发现问题。 ``` static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector, void *buf, rt_size_t blks, rt_uint8_t dir) { //void *aligned_buf; struct rt_mmcsd_cmd cmd, stop; struct rt_mmcsd_data data; struct rt_mmcsd_req req; struct rt_mmcsd_host *host = card->host; rt_uint32_t r_cmd, w_cmd; static rt_uint8_t sd_buf[512]; mmcsd_host_lock(host); if((rt_uint32_t)buf&3) { rt_uint8_t *p_buf = (rt_uint8_t*)buf; while(blks--) { rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); rt_memset(&stop, 0, sizeof(struct rt_mmcsd_cmd)); rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); req.cmd = &cmd; req.data = &data; cmd.arg = sector; if (!(card->flags & CARD_FLAG_SDHC)) { cmd.arg <<= 9; } cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; data.blksize = SECTOR_SIZE; data.blks = 1; req.stop = RT_NULL; r_cmd = READ_SINGLE_BLOCK; w_cmd = WRITE_BLOCK; if (!dir) { cmd.cmd_code = r_cmd; data.flags |= DATA_DIR_READ; } else { cmd.cmd_code = w_cmd; data.flags |= DATA_DIR_WRITE; rt_memcpy(sd_buf,p_buf,512); } mmcsd_set_data_timeout(&data, card); data.buf = (rt_uint32_t*)sd_buf; mmcsd_send_request(host, &req); if (!controller_is_spi(card->host) && dir != 0) { do { rt_int32_t err; cmd.cmd_code = SEND_STATUS; cmd.arg = card->rca << 16; cmd.flags = RESP_R1 | CMD_AC; err = mmcsd_send_cmd(card->host, &cmd, 5); if (err) { rt_kprintf("error %d requesting status ", err); break; } /* * Some cards mishandle the status bits, * so make sure to check both the busy * indication and the card state. */ } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || (R1_CURRENT_STATE(cmd.resp[0]) == 7)); } if (!dir) { rt_memcpy(p_buf,sd_buf,512); } p_buf += 512; sector++; } } else { rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); rt_memset(&stop, 0, sizeof(struct rt_mmcsd_cmd)); rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); req.cmd = &cmd; req.data = &data; cmd.arg = sector; if (!(card->flags & CARD_FLAG_SDHC)) { cmd.arg <<= 9; } cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; data.blksize = SECTOR_SIZE; data.blks = blks; if (blks > 1) { if (!controller_is_spi(card->host) || !dir) { req.stop = &stop; stop.cmd_code = STOP_TRANSMISSION; stop.arg = 0; stop.flags = RESP_SPI_R1B | RESP_R1B | CMD_AC; } r_cmd = READ_MULTIPLE_BLOCK; w_cmd = WRITE_MULTIPLE_BLOCK; } else { req.stop = RT_NULL; r_cmd = READ_SINGLE_BLOCK; w_cmd = WRITE_BLOCK; } if (!dir) { cmd.cmd_code = r_cmd; data.flags |= DATA_DIR_READ; } else { cmd.cmd_code = w_cmd; data.flags |= DATA_DIR_WRITE; } mmcsd_set_data_timeout(&data, card); data.buf = buf; mmcsd_send_request(host, &req); if (!controller_is_spi(card->host) && dir != 0) { do { rt_int32_t err; cmd.cmd_code = SEND_STATUS; cmd.arg = card->rca << 16; cmd.flags = RESP_R1 | CMD_AC; err = mmcsd_send_cmd(card->host, &cmd, 5); if (err) { rt_kprintf("error %d requesting status ", err); break; } /* * Some cards mishandle the status bits, * so make sure to check both the busy * indication and the card state. */ } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || (R1_CURRENT_STATE(cmd.resp[0]) == 7)); } } mmcsd_host_unlock(host); if (cmd.err || data.err || stop.err) { rt_kprintf("mmcsd request blocks error "); rt_kprintf("%d,%d,%d, 0x%08x,0x%08x ", cmd.err, data.err, stop.err, data.flags, sector); return -RT_ERROR; } return RT_EOK; } ```
jiezhi320
2013-06-24
这家伙很懒,什么也没写!
mark
frenkie_wang
2013-08-16
这家伙很懒,什么也没写!
好文章,记下了
撰写答案
登录
注册新账号
关注者
0
被浏览
5.6k
关于作者
lixun00
这家伙很懒,什么也没写!
提问
10
回答
25
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
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
rt-thread 小内存算法源码分析
2
env中添加lvgl软件包后,keil编译包--c99错误
3
【NXP-MCXA153】 定时器驱动移植
4
GD32F450 看门狗驱动适配
5
【NXP-MCXA153】看门狗驱动移植
热门标签
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
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
18
个答案
1
次被采纳
红枫
5
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
11
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部