野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10082|回复: 26

flash 如何实现存代码的同时可以读写

[复制链接]
发表于 2018-6-29 15:52:39 | 显示全部楼层 |阅读模式
    现在使用norflash来装代码,但是外置 8M 的flash,代码往往只有几百k,因为有些数据需要保存,如何能对falsh后4M的空间进行读写,又不破坏code的部分呢 ?
回复

使用道具 举报

发表于 2018-6-29 16:21:38 | 显示全部楼层
这就需要我们新版本的工程了

代码存储在FLASH,然后上电后加载到SDRAM或ITCM执行,在SDRAM或ITCM执行的代码就可以对FLASH进行读写了,

具体的代码目录如下:
固件库例程\FlexSPI—读写外部SPI NorFlash


回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-6-29 16:26:41 | 显示全部楼层
flyleaf 发表于 2018-6-29 16:21
这就需要我们新版本的工程了

代码存储在FLASH,然后上电后加载到SDRAM或ITCM执行,在SDRAM或IT ...

好的,谢谢了。
回复 支持 反对

使用道具 举报

发表于 2018-6-29 16:54:08 | 显示全部楼层
能不能使用分段加载的功能,把读写函数专门制定到ITCM中,然后调用执行这些个函数的时候不会动用到spinorflash部分的代码,应该就能够安安静静的操作数据了吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-6-29 17:02:18 | 显示全部楼层
吕布-单片机 发表于 2018-6-29 16:54
能不能使用分段加载的功能,把读写函数专门制定到ITCM中,然后调用执行这些个函数的时候不会动用到spinorfl ...

现在我也不知道,先试一试。谢谢了
回复 支持 反对

使用道具 举报

发表于 2018-6-29 17:02:35 | 显示全部楼层
吕布-单片机 发表于 2018-6-29 16:54
能不能使用分段加载的功能,把读写函数专门制定到ITCM中,然后调用执行这些个函数的时候不会动用到spinorfl ...

可以的,跟上面工程的区别就是全部加载与部分加载,这些都是通过分散加载文件实现的,
把部分代码定制比较麻烦,因为要筛选,所以我们就偷懒全部加载了,不过即使是使用部分加载,也要注意中断相关的内容都放到RAM里,不然中断出现时就挂了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-10 17:30:33 | 显示全部楼层
flyleaf 发表于 2018-6-29 17:02
可以的,跟上面工程的区别就是全部加载与部分加载,这些都是通过分散加载文件实现的,
把部分代码定制比 ...

参考你们的例子,你们用的是w25q256 我用的 w25q64,然后FLEXSPI_SetFlashConfig这一句就挂机了,是和参数配置有关系吗 ?
回复 支持 反对

使用道具 举报

发表于 2018-7-10 17:33:37 | 显示全部楼层
圆周率 发表于 2018-7-10 17:30
参考你们的例子,你们用的是w25q256 我用的 w25q64,然后FLEXSPI_SetFlashConfig这一句就挂机了,是和参 ...

LUT表里的命令改了没,代码里使用的是4字节地址的命令,w25Q64不支持4字节地址的
要改命令编码,以及表里的地址线宽度
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-10 17:38:02 | 显示全部楼层
flyleaf 发表于 2018-7-10 17:33
LUT表里的命令改了没,代码里使用的是4字节地址的命令,w25Q64不支持4字节地址的
要改命令编码,以及表 ...

改了的。如下:
[mw_shl_code=c,true]const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
        //普通读命令
        [4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_ReadData,
                            kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, FLASH_ADDR_LENGTH),
            
        [4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04,
                            kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

        /* 快速读指令 */
        [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_FastReadData,
                            kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, FLASH_ADDR_LENGTH),
            
        [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] =
          FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08,
                          kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

        /* QUAD 模式快速读操作 */
        [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_FastReadQuad,
                            kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, FLASH_ADDR_LENGTH),
        [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] =
          FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x08,
                          kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),

        /* Read Status Register */
        [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_ReadStatusReg,
                            kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

        /* 写使能 */
        [4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_WriteEnable,
                            kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

        /* 擦除扇区 Erase Sector  */
        [4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_SectorErase,
                            kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, FLASH_ADDR_LENGTH),

        /* 标准SPI模式 页写入 */
        [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_PageProgram,
                            kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, FLASH_ADDR_LENGTH),
        [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04,
                            kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

        /* QUAD 模式页写入 */
        [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_PageProgramQuad,
                            kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, FLASH_ADDR_LENGTH),
        [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04,
                            kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),  

        /* 读ID Read ID ID7-ID0*/
        [4 * NOR_CMD_LUT_SEQ_IDX_READID] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_DeviceID,
                            kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, FLASH_ADDR_LENGTH),
        [4 * NOR_CMD_LUT_SEQ_IDX_READID + 1] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04,
                            kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
        
        /* 读 JedecDeviceID,MF7-MF0+ID15-ID0 */
        [4 * NOR_CMD_LUT_SEQ_IDX_READJEDECID] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_JedecDeviceID,
                            kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

        /* 写状态寄存器 write status register */
        [4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_WriteStatusReg,
                            kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),

        /* 读状态寄存器 Read status register */
        [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_ReadStatusReg,
                            kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

        /* 擦除整片Flash Erase Chip */
        [4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_ChipErase,
                            kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
            
        
        /*给AHB命令访问的 QUAD模式页写入序列,包含写使能和页写入两条序列 */
        /* 写使能,write Enable */
        [4 * NOR_CMD_LUT_SEQ_IDX_AHB_PAGEPROGRAM_QUAD_1] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_WriteEnable,
                            kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

        /*quad 模式写入,Page Program- quad mode*/
        [4 * NOR_CMD_LUT_SEQ_IDX_AHB_PAGEPROGRAM_QUAD_2] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, W25Q_PageProgramQuad,
                            kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, FLASH_ADDR_LENGTH),
        [4 * NOR_CMD_LUT_SEQ_IDX_AHB_PAGEPROGRAM_QUAD_2 + 1] =
            FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04,
                            kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),  
}[/mw_shl_code]
回复 支持 反对

使用道具 举报

发表于 2018-7-10 17:42:41 | 显示全部楼层
FLEXSPI_SetFlashConfig还没到开始读写哦,用ITCM版本的代码能正常运行不?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-10 17:47:32 | 显示全部楼层
flyleaf 发表于 2018-7-10 17:42
FLEXSPI_SetFlashConfig还没到开始读写哦,用ITCM版本的代码能正常运行不?

我现在是把相关的函数定义成一个段里,然后把这个段放到SDRAM里面去了,如下
void __attribute__((section("fingertech_flashop"))) NorFlash_FlexSPI_ModeInit(void)

        #define  fingertech_ram_start                                         0x80000000        //放到外扩RAM的起始地址
        #define         fingertech_ram_size                                         0x01E00000               
        Efingertechram fingertech_ram_start fingertech_ram_size - Stack_Size - Heap_Size
        {
                .ANY(+RW +ZI)
                * (fingertech_flashop)
        }
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-12 11:02:48 | 显示全部楼层
flyleaf 发表于 2018-7-10 17:42
FLEXSPI_SetFlashConfig还没到开始读写哦,用ITCM版本的代码能正常运行不?

老哥,帮忙看下呀
回复 支持 反对

使用道具 举报

发表于 2018-7-12 11:15:58 | 显示全部楼层
圆周率 发表于 2018-7-12 11:02
老哥,帮忙看下呀

只放一部分函数进RAM的我也没测试过啊,哈哈,我都是整个代码放进去的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-12 12:50:50 | 显示全部楼层
flyleaf 发表于 2018-7-12 11:15
只放一部分函数进RAM的我也没测试过啊,哈哈,我都是整个代码放进去的

奇怪的是我初始化的时候卡住在这个地方。    while (!FLEXSPI_GetBusIdleStatus(base));
回复 支持 反对

使用道具 举报

发表于 2018-7-12 13:35:39 | 显示全部楼层
圆周率 发表于 2018-7-12 12:50
奇怪的是我初始化的时候卡住在这个地方。    while (!FLEXSPI_GetBusIdleStatus(base));

确认下这些访问SPI的库函数相关内容你也放到RAM了没
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-12 14:46:02 | 显示全部楼层
flyleaf 发表于 2018-7-12 13:35
确认下这些访问SPI的库函数相关内容你也放到RAM了没

你的意思是和SPI 相关的都需要放进去是吧
回复 支持 反对

使用道具 举报

发表于 2018-7-12 15:00:05 | 显示全部楼层
圆周率 发表于 2018-7-12 14:46
你的意思是和SPI 相关的都需要放进去是吧

是的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-17 10:51:59 | 显示全部楼层

spi 相关的都放到ram里面了,确实是可以运行。但是关闭DCache后发现运行很慢很慢,我是把中断放到flash里面,不知道这个是不是有影响。
回复 支持 反对

使用道具 举报

发表于 2018-7-17 11:22:15 | 显示全部楼层
圆周率 发表于 2018-7-17 10:51
spi 相关的都放到ram里面了,确实是可以运行。但是关闭DCache后发现运行很慢很慢,我是把中断放到flash里 ...

会影响,验证过了,在读写FLASH的时候如果中断触发了,需要访问FLASH加载中断向量表,导致出错,所以中断也要放到RAM
回复 支持 反对

使用道具 举报

发表于 2018-7-18 12:10:20 | 显示全部楼层
我的电路板用的是W25Q64JV,可以读到芯片ID,也能擦除成功,为什么读取数据全是0xCC,而不是0xFF?
回复 支持 反对

使用道具 举报

发表于 2018-7-18 12:11:18 | 显示全部楼层
原理图和野火的板子一样
回复 支持 反对

使用道具 举报

发表于 2018-7-18 13:26:40 | 显示全部楼层
elegoqq 发表于 2018-7-18 12:10
我的电路板用的是W25Q64JV,可以读到芯片ID,也能擦除成功,为什么读取数据全是0xCC,而不是0xFF?

一般看到0xCC的很可能是FLASH的 Quad Mode 没有使能
回复 支持 反对

使用道具 举报

发表于 2018-7-18 13:44:16 | 显示全部楼层
但是我用的野火的例程,因为的FLASH容量小,把扇区地址改小了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-18 13:55:41 | 显示全部楼层
elegoqq 发表于 2018-7-18 13:44
但是我用的野火的例程,因为的FLASH容量小,把扇区地址改小了

你是将代码全部放到ram钟还是只放了一部分 ?
回复 支持 反对

使用道具 举报

发表于 2018-7-18 14:46:50 | 显示全部楼层
圆周率 发表于 2018-7-18 13:55
你是将代码全部放到ram钟还是只放了一部分 ?

代码全部在ram,野火的配置itcm_txt_ram_debug
回复 支持 反对

使用道具 举报

发表于 2018-7-19 15:44:13 | 显示全部楼层
问题解决了,野火板子用的是w25q256jv,很多命令用的是W25Q_XXXX_4Addr,比如W25Q_ReadData_4Addr
而我的板子用的是w25q64jv,这个芯片没有W25Q_XXXX_4Addr指令,所以就不能工作,
把类似W25Q_ReadData_4Addr的指令改成W25Q_ReadData就可以了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-20 09:44:20 | 显示全部楼层
elegoqq 发表于 2018-7-19 15:44
问题解决了,野火板子用的是w25q256jv,很多命令用的是W25Q_XXXX_4Addr,比如W25Q_ReadData_4Addr
而我的板 ...

不知道你们关闭DCACHE 后慢不慢。
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-3 00:35 , Processed in 0.040305 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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