Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Devices
关于SPI Flash注册使用块设备是的擦写问题
发布于 2019-12-25 15:56:39 浏览:1490
订阅该版
之前的设备中用到了SPI Flash,因此采用了块设备+FAT的结构 在rt-htread系统中,块设备是属于I/O设备模型的, 因此有一套统一的接口标准, 而SPI Flash设备在写入数据时要求先必须先擦除一下, 将其注册为块设备使用是,I/O设备模型却并未提供擦除接口; 提供的control函数似乎可以实现此功能,但却不能传递flash地址, 所以也没法使用(地址使用全局变量传递倒是可以解决) I/O设备模型结构体如下 ```struct rt_device { struct rt_object parent; /**< inherit from rt_object */ enum rt_device_class_type type; /**< device type */ rt_uint16_t flag; /**< device flag */ rt_uint16_t open_flag; /**< device open flag */ rt_uint8_t ref_count; /**< reference count */ rt_uint8_t device_id; /**< 0 - 255 */ /* device call back */ rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size); rt_err_t (*tx_complete)(rt_device_t dev, void *buffer); /* common device interface */ rt_err_t (*init) (rt_device_t dev); rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag); rt_err_t (*close) (rt_device_t dev); rt_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); rt_size_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); rt_err_t (*control)(rt_device_t dev, rt_uint8_t cmd, void *args); void *user_data; /**< device private data */ }; ``` 之前的解决办法是,直接在数据写入时对快进行擦除, 弊端很明显,就是SPI Flash的寿命大打折扣, 经过对比fat与littlefs文件系统的差异,给系统移植了littlefs文件系统, 要求提供read、prog、erase、sync函数供littlefs操作SPI, 结构体如下 ```struct lfs_config { // Opaque user provided context that can be used to pass // information to the block device operations void *context; // Read a region in a block. Negative error codes are propogated // to the user. int (*read)(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); // Program a region in a block. The block must have previously // been erased. Negative error codes are propogated to the user. // May return LFS_ERR_CORRUPT if the block should be considered bad. int (*prog)(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size); // Erase a block. A block must be erased before being programmed. // The state of an erased block is undefined. Negative error codes // are propogated to the user. // May return LFS_ERR_CORRUPT if the block should be considered bad. int (*erase)(const struct lfs_config *c, lfs_block_t block); // Sync the state of the underlying block device. Negative error codes // are propogated to the user. int (*sync)(const struct lfs_config *c); // Minimum size of a block read. All read operations will be a // multiple of this value. lfs_size_t read_size; // Minimum size of a block program. All program operations will be a // multiple of this value. lfs_size_t prog_size; // Size of an erasable block. This does not impact ram consumption and // may be larger than the physical erase size. However, non-inlined files // take up at minimum one block. Must be a multiple of the read // and program sizes. lfs_size_t block_size; // Number of erasable blocks on the device. lfs_size_t block_count; // Number of erase cycles before we should move data to another block. // May be zero, in which case no block-level wear-leveling is performed. uint32_t block_cycles; // Size of block caches. Each cache buffers a portion of a block in RAM. // The littlefs needs a read cache, a program cache, and one additional // cache per file. Larger caches can improve performance by storing more // data and reducing the number of disk accesses. Must be a multiple of // the read and program sizes, and a factor of the block size. lfs_size_t cache_size; // Size of the lookahead buffer in bytes. A larger lookahead buffer // increases the number of blocks found during an allocation pass. The // lookahead buffer is stored as a compact bitmap, so each byte of RAM // can track 8 blocks. Must be a multiple of 4. lfs_size_t lookahead_size; // Optional statically allocated read buffer. Must be cache_size. // By default lfs_malloc is used to allocate this buffer. void *read_buffer; // Optional statically allocated program buffer. Must be cache_size. // By default lfs_malloc is used to allocate this buffer. void *prog_buffer; // Optional statically allocated lookahead buffer. Must be lookahead_size // and aligned to a 64-bit boundary. By default lfs_malloc is used to // allocate this buffer. void *lookahead_buffer; // Optional upper limit on length of file names in bytes. No downside for // larger names except the size of the info struct which is controlled by // the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in // superblock and must be respected by other littlefs drivers. lfs_size_t name_max; // Optional upper limit on files in bytes. No downside for larger files // but must be <= LFS_FILE_MAX. Defaults to LFS_FILE_MAX when zero. Stored // in superblock and must be respected by other littlefs drivers. lfs_size_t file_max; // Optional upper limit on custom attributes in bytes. No downside for // larger attributes size but must be <= LFS_ATTR_MAX. Defaults to // LFS_ATTR_MAX when zero. lfs_size_t attr_max; };``` 其中sync并未做实际操作,read、prog均可通过rt_device提供, 唯独erase操作只能再次使用全局函数解决, 不知各位在rt-thread中使用SPI Flash是有啥好的思路。 (有关SPI Flash注册为MTD设备使用的方式还在研究中)
查看更多
2
个回答
默认排序
按发布时间排序
RTT_User1
2019-12-25
这家伙很懒,什么也没写!
[i=s] 本帖最后由 RTT_User1 于 2019-12-25 16:09 编辑 [/i] 楼主有没有试过fal呢 [http://packages.rt-thread.org/detail.html?package=fal](http://packages.rt-thread.org/detail.html?package=fal) 最近使用字库使用的fal ``` void W25QXX_Init(void) { sf_fal_dev = fal_flash_device_find("nor_flash"); if (sf_fal_dev == NULL) { rt_kprintf("[ZK] flash init err\n"); } else { rt_kprintf("[ZK] flash init success\n"); } } size_t W25QXX_Write(uint8_t *buf, long offset, size_t size) { size_t w_size = 0; w_size = sf_fal_dev->ops.write(offset, buf, size); return w_size; } size_t W25QXX_Read(uint8_t *buf, long offset, size_t size) { size_t r_size = 0; r_size = sf_fal_dev->ops.read(offset, buf, size); return r_size; } size_t W25QXX_Erase(long offset, size_t size) { size_t e_size = 0; e_size = sf_fal_dev->ops.erase(offset, size); return e_size; } ```
通宵敲代码
2019-12-25
这家伙不懒,他只是什么都不想写
>楼主有没有试过fal呢 http://packages.rt-thread.org/detail.html?package=fal >最近使用字库使用的fal --- 之前的系统没用fal,块设备直接对接的dfs接口, 官方推荐的例程中,littlefs就是跟fal结合使用的, 还在研究中
撰写答案
登录
注册新账号
关注者
0
被浏览
1.5k
关于作者
通宵敲代码
这家伙不懒,他只是什么都不想写
提问
8
回答
25
被采纳
0
关注TA
发私信
相关问题
1
问个问题,ili9320驱动里面rt_hw_lcd_draw_blit_line 这个函数是干什么用的
2
LCD双缓冲有什么好的办法实现
3
LCD NT35510 驱动代码
4
io设备驱动的疑惑与建议
5
液晶屏驱动 U8g2 移植
6
求助:在模板上添加LCD模块出现L6406E错误
7
hwtimer硬件定时器驱动和使用经验
8
硬件定时器超时时间计算问题
9
请教spi驱动lcd显示屏问题
10
rtt-master(3.1.1)bsp—armfly中drv_lcd.c中是不是错了啊?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
机器人操作系统 (ROS2) 和 RT-Thread 通信
4
国产MCU移植系列教程汇总,欢迎查看!
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
mcxn947 dht11温湿度采集
2
【24嵌入式设计大赛】基于RT-Thread星火1号的AI广告终端设计
3
基于stm32f407 芯片创建 rt-thread工程——使用Arduino兼容层RTduino
4
星火1号:CAN通信初步
5
【24嵌入式设计大赛】基于RT-Thread火星一号智能终端采集系统
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
ART-Pi
FinSH
USB
文件系统
DMA
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
ota在线升级
I2C_IIC
WIZnet_W5500
UART
flash
packages_软件包
cubemx
PWM
freemodbus
BSP
潘多拉开发板_Pandora
定时器
ADC
中断
flashDB
socket
Debug
GD32
编译报错
msh
keil_MDK
at_device
MicroPython
rt_mq_消息队列_msg_queue
ulog
C++_cpp
本月问答贡献
出出啊
1513
个答案
341
次被采纳
小小李sunny
1438
个答案
289
次被采纳
张世争
775
个答案
167
次被采纳
crystal266
546
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
1
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部