硬汉嵌入式论坛

 找回密码
 立即注册
查看: 8120|回复: 30
收起左侧

[ThreadX全家桶] 裸机移植FileX+LevelX NOR FLASH 与 NANDFLASH实现

  [复制链接]

8

主题

104

回帖

138

积分

初级会员

积分
138
发表于 2020-7-14 17:50:29 | 显示全部楼层 |阅读模式
采用裸机实现 未使用ThreadX系统 , 使用的是STM32CubeMX生成的Truestudio 工程, CubeMX配置FMC生成的NAND 驱动很奇怪,无论是main区还是spare区的数据的读与写都是整页的读写或者整个Spare区,已经在NAND文件夹中的驱动修改成了可以读写指定大小的接口,Spare区只有64字节,我就直接全读了,只返回给上层想要的字节,写也是直接64字节全读,修改指定字节再重新写入。不知道是不是我对ST 提供的Nand驱动接口理解错误导致的, 懂得同学们能该说道说道吗?谢谢。

F767_FileX_LevelX_Nor_Nand.7z

614.91 KB, 下载次数: 650

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106847
QQ
发表于 2020-7-14 17:55:07 | 显示全部楼层
非常感谢楼主分享。
回复

使用道具 举报

8

主题

104

回帖

138

积分

初级会员

积分
138
 楼主| 发表于 2020-7-14 18:06:00 | 显示全部楼层
eric2013 发表于 2020-7-14 17:55
非常感谢楼主分享。

硬汉大哥一个人搞完ThreadX全集桶太吃力了,大家一起做贡献让ThreadX全家桶尽快投入到日常开发中。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106847
QQ
发表于 2020-7-14 18:11:57 | 显示全部楼层
李益达 发表于 2020-7-14 18:06
硬汉大哥一个人搞完ThreadX全集桶太吃力了,大家一起做贡献让ThreadX全家桶尽快投入到日常开发中。



感谢
回复

使用道具 举报

3

主题

1223

回帖

1232

积分

至尊会员

积分
1232
发表于 2020-7-14 20:56:30 | 显示全部楼层
回复

使用道具 举报

39

主题

929

回帖

1051

积分

至尊会员

积分
1051
发表于 2020-7-14 22:41:28 | 显示全部楼层
给力
回复

使用道具 举报

19

主题

150

回帖

207

积分

高级会员

积分
207
发表于 2020-7-15 11:38:21 | 显示全部楼层
弱鸡只能上个说明。。
Azure RTOS FileX嵌入式文件系统是Azure RTOS的高级工业级解决方案,适用于Microsoft FAT文件格式,专门针对深度嵌入式,实时和IoT应用程序而设计。Azure RTOS FileX支持Microsoft的所有文件格式,包括FAT12,FAT16,FAT32和exFAT。FileX还通过一个称为Azure RTOS LevelX的附加产品提供了可选的容错和FLASH磨损均衡。所有这些,再加上占地面积小,执行速度快和易于使用,使Azure RTOS FileX成为要求最苛刻的嵌入式IoT应用程序的理想选择。
回复

使用道具 举报

610

主题

3055

回帖

4905

积分

至尊会员

积分
4905
发表于 2020-8-6 09:21:08 | 显示全部楼层
本帖最后由 hpdell 于 2020-8-6 09:33 编辑

你好,我移植  nand 貌似没有成功,但是会一直在
3002.jpg

貌似程序在上面的函数里面出不来 ??


我使用的 nand 型号是
MT29F16G08ABABA

相关配置:

//#define NAND_PAGE_SIZE             ((uint16_t)0x0800) /* 2 * 1024 bytes per page w/o Spare Area */
#define NAND_PAGE_SIZE             ((uint16_t)0x1000) /* 4 * 1024 bytes per page w/o Spare Area */

#define BAD_BLOCK_POSITION                  0           /*      0 is the bad block byte postion                         */
#define EXTRA_BYTE_POSITION                 2           /*      2 is the extra bytes starting byte postion              */
#define ECC_BYTE_POSITION                   40          /*      40 is the ECC starting byte position                    */


#define TOTAL_BLOCKS                        (512 * 1024 /128)    // 这个地方我目前不清楚配置的对不对呀 ??

#define PHYSICAL_PAGES_PER_BLOCK            128         /* Min value of 2                                               */
#define BYTES_PER_PHYSICAL_PAGE             4096        /* 4096 bytes per page                                          */
#define WORDS_PER_PHYSICAL_PAGE             BYTES_PER_PHYSICAL_PAGE/4      /* Words per page                                               */
#define SPARE_BYTES_PER_PAGE                224         /* 224 "spare" bytes per page                                    */
                                                        /* For 2048 byte block spare area:                              */




  /* hnand1.Config */
  NAND_Handle.Config.PageSize = 4096;   //NAND memory page (without spare area) size measured in bytes
                                        //for 8 bits adressing or words for 16 bits addressing
                                                                                                                                                                //NAND内存页(无备用区)大小,以字节为单位,用于8位地址或用于16位地址的字

        NAND_Handle.Config.SpareAreaSize = 224; //NAND memory spare area size measured in bytes
                                          //for 8 bits adressing or words for 16 bits addressin
                                                                                                                                                                        //NAND存储器备用区大小(以字节为单位,用于8位寻址或以16字节地址为单位
        
  NAND_Handle.Config.BlockSize = 128;     //NAND memory block size measured in number of pages
                                                                                                                                                                        //NAND存储块大小,以页数为单位
                                                                                                                                                                        
  NAND_Handle.Config.BlockNbr = 4096;     //NAND memory number of total blocks,NAND存储器总块数
        
  NAND_Handle.Config.PlaneNbr = 2;        //NAND memory number of planes,NAND内存层数
  NAND_Handle.Config.PlaneSize = 2048;                //NAND memory zone size measured in number of blocks,NAND存储区大小以块数为单位



3003.png



        if(IsNandFormate)
        {
                status = fx_media_format(&nand_disk,
                                                                nand_flash_driver,  // Driver entry
                                                                FX_NULL,                          // Unused
                                                                nand_media_memory,                     // Media buffer pointer
                                                                sizeof(nand_media_memory),             // Media buffer size
                                                                NAND_FX_NAME,                   // Volume Name
                                                                2,                                // Number of FATs
                                                                32,                               // Directory Entries
                                                                0,                                // Hidden sectors
                                                                (1024*1024*1024*2/512),             // Total sectors
                                                                512,                             // Sector size
                                                                1,                                // Sectors per cluster
                                                                1,                                // Heads
                                                                1);                               // Sectors per track
                                                               
                if(status == FX_SUCCESS)  nand_init_ok=1;
                                                               
        }







回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106847
QQ
发表于 2020-8-6 10:15:43 | 显示全部楼层
hpdell 发表于 2020-8-6 09:21
你好,我移植  nand 貌似没有成功,但是会一直在

你用的多大容量的? 2GB的吗
回复

使用道具 举报

610

主题

3055

回帖

4905

积分

至尊会员

积分
4905
发表于 2020-8-6 10:49:06 | 显示全部楼层
eric2013 发表于 2020-8-6 10:15
你用的多大容量的? 2GB的吗

是 2GB 的,

硬件是没有问题的,因为之前使用 其他 方法读写时是完全正常的
另外这个历程里面貌似 nand 芯片 的 rb 信号没有使用吧
回复

使用道具 举报

8

主题

104

回帖

138

积分

初级会员

积分
138
 楼主| 发表于 2020-8-6 11:12:16 | 显示全部楼层
NAND FLASH的驱动是通过CubeMX生成的,使用之前一定要格式化一下NAND FLASH 首次使用FileX一定要调用fx_media_format才能使用。 底层频繁调用读函数,修改ptintk 取消所有日志打印 会快很多。  当然也许是我移植的有些问题,我也只是测试了一段时间,且测试的字节数比较少 ,(我测试时是取消了驱动中所有的打印,测试是OK的)。所以可能存在某种情况下会失败,不一定完全OK,

另外在另外一个nor的bsp驱动中,chiperase函数的操作校验中busy应该是while(BSP_W256_GetStatus() != W25Q256_BUSY)才对  (之前写成了==)
回复

使用道具 举报

610

主题

3055

回帖

4905

积分

至尊会员

积分
4905
发表于 2020-8-6 12:15:12 | 显示全部楼层
李益达 发表于 2020-8-6 11:12
NAND FLASH的驱动是通过CubeMX生成的,使用之前一定要格式化一下NAND FLASH 首次使用FileX一定要调用fx_med ...

我使用之前是个格式化过了
IsNandFormate =1;
     if(IsNandFormate)
        {
                status = fx_media_format(&nand_disk,
                                                                nand_flash_driver,  // Driver entry
                                                                FX_NULL,                          // Unused
                                                                nand_media_memory,                     // Media buffer pointer
                                                                sizeof(nand_media_memory),             // Media buffer size
                                                                NAND_FX_NAME,                   // Volume Name
                                                                2,                                // Number of FATs
                                                                32,                               // Directory Entries
                                                                0,                                // Hidden sectors
                                                                (1024*1024*1024*2/512),             // Total sectors  我的是 2GByte 容量,我这样设置不知道对不对呀 ?
                                                                512,                             // Sector size
                                                                1,                                // Sectors per cluster
                                                                1,                                // Heads
                                                                1);                               // Sectors per track
                                                               
                if(status == FX_SUCCESS)  nand_init_ok=1;
                                                               
        }

另外还有其他的一些参数配置,你帮我看看我有没有配置错 ?? 先谢谢了


回复

使用道具 举报

610

主题

3055

回帖

4905

积分

至尊会员

积分
4905
发表于 2020-8-6 15:01:17 | 显示全部楼层
李益达 发表于 2020-8-6 11:12
NAND FLASH的驱动是通过CubeMX生成的,使用之前一定要格式化一下NAND FLASH 首次使用FileX一定要调用fx_med ...

你发的历程貌似是 正确的

/**
  * @brief  Erases the entire QSPI memory.This function will take a very long time.
  * @retval QSPI memory status
  */
uint8_t BSP_W25Q256_Erase_Chip(void)
{
    uint8_t cmd[4];
    uint32_t tickstart = HAL_GetTick();
    cmd[0] = CHIP_ERASE_CMD;

    /* Enable write operations */
    BSP_W25Q256_WriteEnable();

    /*Select the FLASH: Chip Select low */
    W25Q256_Enable();
    /* Send the read ID command */
    HAL_SPI_Transmit(&hspi5, cmd, 1, W25Q256_TIMEOUT_VALUE);
    /*Deselect the FLASH: Chip Select high */
    W25Q256_Disable();

    /* Wait the end of Flash writing */
    while(BSP_W25Q256_GetStatus() != W25Q256_BUSY)     //这个地方 貌似是按照你正确的方法写的
    {
        /* Check for the Timeout */
        if((HAL_GetTick() - tickstart) > W25Q256FV_BULK_ERASE_MAX_TIME)
        {
            return W25Q256_TIMEOUT;
        }
    }
    return W25Q256_OK;
}


回复

使用道具 举报

610

主题

3055

回帖

4905

积分

至尊会员

积分
4905
发表于 2020-8-7 09:01:54 | 显示全部楼层
李益达 发表于 2020-8-6 11:12
NAND FLASH的驱动是通过CubeMX生成的,使用之前一定要格式化一下NAND FLASH 首次使用FileX一定要调用fx_med ...

我目前貌似可以正常读取到正确的 nand id 号

回复

使用道具 举报

8

主题

104

回帖

138

积分

初级会员

积分
138
 楼主| 发表于 2020-8-7 10:52:15 | 显示全部楼层
十分不好意思,才看到回复:
1、我看到你的那个formate的参数中 sector size (Number of bytes per sector)只有512字节吗,
total sectors指的是(Total number of sectors),你这里好像写成了FLASH的大小了。

另外我指的格式化是有两部分完成了,第一是用户自己调用block erase api 对NAND FLASH
进行一次格式化(也可以只删除前面需要测试的部分块)。然后再调用一次formate api
进行文件系统的格式化(关于这点,我觉得可能是我移植有问题导致的,也有可能是我
之前对NAND FLASH 进行过其他测试,导致破坏了默认全FF的状态,不过按道理是无需
调用block erase 自己手动格式化的, 这点存疑)。

2、关于NorFlash驱动问题,昨天大脑一时短路,把问题和解决措施写反了,应该是修改为:
while(BSP_W25Q256_GetStatus() == W25Q256_BUSY)这样子才对。

读ID号无需对FLASH进行实质写操作,只是读取寄存器而已,所以你看不到错误。
当对NOR FLASH进行写入后,在执行整片擦除,然后再对之前写入过的地址进行读写
校验就会有问题,原因是整片擦除其实是失败的,BUSY逻辑判断反了。

3、关于NAND FLASH的驱动,正如此贴内容描述 是使用CubeMX生成的,完成NAND FLASH
的读写擦都是正常的,但是我有注意到ST 的NAND FLASH 读、写API都是对整页进行操作的
,也就是说至少读取一页数据字节大小,至少写入一页字节大小,这样在频繁进行小文件的
读写操作以及文件系统在操作元数据时特别低效,所有我对对ST的读、写驱动进行了修改,
使之可以读取地址、指定字节大小,写入指定地址、指定字节大小(这里同样存疑,一是不
确定修改是否正确 tip:自测是正确的,可以读写指定地址及字节;  二是可能我对ST的驱动理
解不正确,或者是文件系统接口移植理解有误)
回复

使用道具 举报

610

主题

3055

回帖

4905

积分

至尊会员

积分
4905
发表于 2020-8-7 14:04:12 | 显示全部楼层
李益达 发表于 2020-8-7 10:52
十分不好意思,才看到回复:
1、我看到你的那个formate的参数中 sector size (Number of bytes per secto ...

刚刚有空重新看了一下nand的驱动程序,貌似 是 读写我的 这个  nand 芯片时,列 ,页 地址不对

这个要修改修改才行
回复

使用道具 举报

610

主题

3055

回帖

4905

积分

至尊会员

积分
4905
发表于 2020-8-7 14:11:59 | 显示全部楼层
李益达 发表于 2020-8-7 10:52
十分不好意思,才看到回复:
1、我看到你的那个formate的参数中 sector size (Number of bytes per secto ...

我目前使用的这个 nand 芯片,列需要 2字节,页需要 3 字节,貌似 st 提供的 页最多只能支持到 2字节

看来修改有点大哟
回复

使用道具 举报

1

主题

19

回帖

22

积分

新手上路

积分
22
发表于 2020-10-24 22:05:59 | 显示全部楼层
请问可以用单片机内部的FLASH 来实现,levelx + filex吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106847
QQ
发表于 2020-10-25 01:08:35 | 显示全部楼层
see-flying 发表于 2020-10-24 22:05
请问可以用单片机内部的FLASH 来实现,levelx + filex吗?

也可以的。
回复

使用道具 举报

1

主题

19

回帖

22

积分

新手上路

积分
22
发表于 2020-11-1 20:46:38 | 显示全部楼层
谢谢eric2013
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
发表于 2020-11-5 10:51:23 | 显示全部楼层
请问有 SPI Flash 的移植代码吗?我看需要自己写 读写命令的实现,这个好理解,然后还要 读写boot的实现,这里就不懂了。
这里是需要自己了解文件系统的数据结构,找到头部分吗?还是什么情况?
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
发表于 2020-11-5 15:32:05 | 显示全部楼层
接着上一楼,我看了下,是不是读写 boot sector,就是把spi  flash的最开始512字节读出或写入就可以了?
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2022-3-7 19:33:44 | 显示全部楼层
李益达 发表于 2020-8-7 10:52
十分不好意思,才看到回复:
1、我看到你的那个formate的参数中 sector size (Number of bytes per secto ...

NANDFLASH本来就是按页读写的,不安页读写,ECC怎么办??
回复

使用道具 举报

8

主题

104

回帖

138

积分

初级会员

积分
138
 楼主| 发表于 2022-3-8 08:20:54 | 显示全部楼层
危险城堡 发表于 2022-3-7 19:33
NANDFLASH本来就是按页读写的,不安页读写,ECC怎么办??

目前FileX不支持同时打开硬件ECC和软件ECC,应该在最近会修复这个问题。 后面学习了NAND确实是整页读写的,我想之前操作没出问题应该是我根本没使能硬件ECC和软件ECC的缘故。所以应该说上面的修改确实是错误的。
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2022-3-8 17:30:59 | 显示全部楼层
李益达 发表于 2022-3-8 08:20
目前FileX不支持同时打开硬件ECC和软件ECC,应该在最近会修复这个问题。 后面学习了NAND确实是整页读写的 ...

我认为,不管是硬件ECC还是软件ECC还是不使用ECC,再对一页中局部数据更新时,即parital-page programs,安全起见,要先发读指令,将目标存储页数据复制到cache中,再通过更改你要更改的数据,更改之前,要确定此处数据确实可以更改才行,即需要确定你要修改的位是从1->0,否则容易产生异常,同时,每个nandflash的NOP是不一样的,有的是4,有的是1,在一些比较新的NAND中,是禁止NOP的,也就是说,一页只能写一次,包括spare area,写完就不能再更改了,哪怕你只写了一个字节,所以看到levelx源码中要经常修改extra字,我感觉很诧异,但手册中描述extra字是在block快满的时候只写一次,我看没太弄明白,你了解的话说说啊。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2022-3-11 10:13:49 | 显示全部楼层
本帖最后由 hzd317897509 于 2022-3-11 10:17 编辑
危险城堡 发表于 2022-3-8 17:30
我认为,不管是硬件ECC还是软件ECC还是不使用ECC,再对一页中局部数据更新时,即parital-page programs, ...

levelX的nand 驱动是有问题的,把它当做nor来用了,怀疑他们那边是用驱动仿真来写软件逻辑的;
1、page一次只能写一页,读也是一次只能读一页,不管是硬件ECC还是软件ECC,ECC都必须得加,这个是纠正偶尔位损坏或出厂位损坏的;
2、spare area的区域,一部分用来存放ECC的数据,这个数据和page的数据一样,是擦除后只能写一次;
3、spare area除ECC的其他数据,是可以仿照nor 多次写入的,你可以操作相同字节或者每次操作一个字节,利用flash只能写0不能写1的特性,作为你数据交换时的日志,通过这个就可以做掉电保护
4、正确的做法是可以改进它的数据存储结构,把逻辑页写在spare area区域,然后上电的时候自动生成一个逻辑页表(耗内存偏大)
5、同时spare area可以放置坏块标志(坏块管理)和block的块擦除次数(这个和顺序写一起使用可以做读写均衡[写的时候应该是从头到尾写一遍,回收垃圾页,垃圾块,或者垃圾块数据迁移])
总的来说:spare area 里面可以大作文章
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2022-3-16 11:23:37 | 显示全部楼层
hzd317897509 发表于 2022-3-11 10:13
levelX的nand 驱动是有问题的,把它当做nor来用了,怀疑他们那边是用驱动仿真来写软件逻辑的;
1、page ...

你说的对,但又不完全对,spare area确实大有可为,但也要因地制宜,在不少nand产品上,对bit的修改是有阈值限制的,也就是说你必须一次修改超过阈值规定的bit位数,发送10h才会真正的执行写入,若你只修改1个bit,修改是不会成功的,这样的操作在levex里很常见,但是它却并不适合所有的nand。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2023-2-2 13:53:09 | 显示全部楼层
hpdell 发表于 2020-8-7 14:11
我目前使用的这个 nand 芯片,列需要 2字节,页需要 3 字节,貌似 st 提供的 页最多只能支持到 2字节

...

请教一下 问题最后咋解决的
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2023-2-2 14:45:10 | 显示全部楼层
读写速度怎么样呢
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106847
QQ
发表于 2023-2-3 09:49:59 | 显示全部楼层
cheneyfc 发表于 2023-2-2 14:45
读写速度怎么样呢

NAND的读取速度还行,写入速度不是很快。
回复

使用道具 举报

1

主题

30

回帖

33

积分

新手上路

积分
33
发表于 2023-3-3 13:41:37 | 显示全部楼层
eric2013 发表于 2023-2-3 09:49
NAND的读取速度还行,写入速度不是很快。

硬汉哥,用FILEX levelX移植Nandflash驱动,结果发现初始化的时候,他的每个页不能超过4096个字节。但是实际的nandflash一页就是8192字节。。。。这种该怎么办。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-7 13:42 , Processed in 0.508568 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表