QCC300x笔记(5) -- 外部Flash的读写操作

哈喽大家好,这是该系列博文的第五篇~ 篇~


<<【系列博文索引】快速通道 >

1.    QCC300X 外部Flash的读写
        QCC300x是使用外部Flash片子,使用外部flash的好处就是成本下来了,大家都知道,CSR的片子一直是很贵的,这样的片子就只能对成本要求不高的项目优先,在使用外部Flash时,我们一般默认使用32M(因为官方配置就是这个参数,会让使用方便的多),然而我们在使用过程往往使用不了这么大的空间,现在我们就利用起来,一起来学习对外部Flash的应用。

        1.1.    为外部flash分区
            要对外部Flash使用,必先是对外部Flash进行分区,上一节做Upgrade时有对分区文件说明,即XXX.ptn文件。
          需要注意的是外部的Flash可以作为两种用途使用,一种是只读的文件系统,另一种是未处理的连续数据分区(Raw Serial),只读的文件系统是对于代码,语音文件,用户文件等保存于Flash中,但是这个需要以文件的形式打包写入,在代码中不可以被修改,仅仅可以读取。
        未处理的连续数据分区,就是纯粹的Flash数据,在程序中可以写入和读取。

        使用文件系统时我们需要挂载分区,使用Raw Serial分区时 不需要挂载分区。

        我们想实现一个在Flash中的数据写入和读取,所以Flash在原来的分区下添加一个Raw Serial分区:

        0, 8K, PS, (none) # For PS Store
        1, 32K, RO, i1107e_patch_bundle.xuv # Logical #0 : For DSP & firmware patches #0,1
        2, 32K, RO, (erase) # Logical #0 : For DSP & firmware patches #0,2
        3, 612K, RO, (erase) # Logical #1 Audio prompts #1,1
        4, 612K, RO, (erase) # Logical #1 Audio prompts #1,2
        5, 300K, RO, i1107e.xuv # Logical #2 Main application image and other files. #2,1
        6, 300K, RO, (erase) # Logical #2 Main application image and other files. #2,2
        7, 8K, RO, system_i1107e.xuv # Logical #3 PSFS  #3,1
        8, 8K, RO, (erase) # Logical #3 PSFS #3,2
        9, 8K, RS, (erase) 
        10, 8K, RS, (erase) 
        11, *, RS, (erase)
        即添加分区9和10,大小为8K,分区类型是RS(Raw Serial),(erase)每次下载重新擦除。

        需要说明一下,这个分区文件涉及下载软件Xide.exe的下载流程,新添加的分区尽量填写每次下载擦除,否则会影响下载,
        我之前有调试过使用(none)会导致下载有很久的卡顿,导致下载时间超长。

        1.2.    Flash写入数据
        Flash在分好区后就可以读写了,Flash的读写也是一个流的概论,写入需要获取一个Sink,读取需要获取一个Source ,需要注意的是Flash在没有数据时是读取不到数据的,直接读取未写入数据的Flash会是空。

        1.2.1.    获取Flash的Sink
        获取Sink的方法,ADK提供了两个函数,可以获取Flash的Sink,分别是
        Sink StreamPartitionOverwriteSink(partition_filesystem_devices device,
        uint16 partition) 
        Sink StreamPartitionResumeSink(partition_filesystem_devices device,
        uint16 partition,uint16 first_word); 

        可以在Partition 和Stream的代码文件中找到。

        第一个函数重新写入Flash,获取的Sink写入后会覆盖之前写入的数据。

        第二个函数是再次写入Flash。第三个参数是需要写入的起始地址,如果Sink中已经存在数据,可以使用
        uint32 PartitionSinkPosition(Sink sink)函数来获取已经存在的Flash数据大小

        partition_filesystem_devices :是选择分区文件的类型,我们需要选择Flash
        Partition:这个参数就是我们分区时分的分区号,就是XXX.ptn文件中添加的9或10分区号。

        1.2.2.    设置Flash的写入配置
        Flash在写入是需要设置其写入配置,配置需要如下函数设置:
        bool PartitionSetMessageDigest(Sink sink, partition_message_digest_type md_ty, uint16 *data, uint16 len) 
        这个函数可以设置Flash的配置,
        sink: The sink that is writing to the partition
        md_type: The type of message digest:
            PARTITION_MESSAGE_DIGEST_APP_SIGNATURE: Signed with the application DFU key (see note)
            PARTITION_MESSAGE_DIGEST_CRC: Filesystem CRC
            PARTITION_MESSAGE_DIGEST_SKIP: Do not perform verification
        data: pointer to the message digest
        len: length of message digest. 2 for CRC verification, 66 for signature verification 

        1.2.3.    获取Flash的状态
        这一步不是必要的,我们在操作Flash,如果需要查看看状态可使用:
        bool PartitionGetInfo(partition_filesystem_devices device, uint16 partition,partition_info_key key, uint32 *value) 

        参数说明:
        device: The device to query. Set to PARTITION_SERIAL_FLASH to query the serial flash device.
        partition: The number of the partition to query.
        key: The type of information requested:
            PARTITION_INFO_IS_MOUNTED: Whether a partition is mounted or not (1 = mounted, 0 = unmounted).
            PARTITION_INFO_SIZE: The size of the partition in words.
            PARTITION_INFO_TYPE: The type of the partition (0 = unused, 1 = filesystem, 2 = PS Store).
        value: The pointer to return the query result to 

        1.2.4.    写入Flash数据
        写入数据是最后的一步,但是没有前面的铺垫,是不能写入成功的,我们得到的分区Sink,就是我们写入数据入口。

        拿到Sink后,我们不能盲目写入,可以使用SinkSlack(Sink sink),查看一下Sink可以写入的最大数据量,我测试过程中获取到的是48,说明Flash每次最大只能写入48个字符,如果我们需要大量写入,可以分批写入数据。

        数据写入:
        第一步:使用SinkMap(Sink sink) 获取一个指针;SinkClaim(Sink sink ,uint16 extra) 声明一下写入的大小,为了检查能否写入,如果返回0xFFFF,说明不能写入。

        第二步:使用memcpy() 把需要写入的数据搬运到SinkMap()指针指向的地址上,

        第三步:使用SinkFlush(Sink sink uint6 amount)实现Flash的真正写入。

        第四步:使用SinkClose(Sink sink)关闭Sink
        需要注意的是:
        1,Sink写入数据后,如果需要读取,必先使用第四步关闭Sink才能读取,但是使用SinkClose()关闭Sink后,不能再次对Flash写入,需要使用重启写入函数对Flash重启写入。
        2,如果需要多次分批写入Flash,不要SinkClose()关闭Sink,完全写入完成后,再关闭Sink,关闭后,再次写入Flash失效,需要重新覆盖写入,

        3,Sink再次写入时,需要重新获取Sink,获取的Sink偏移需要PartitionSinkGetPosition函数获取即可。

        如果上面的步骤没有出错,恭喜你,你的Flash数据写入成功。

        1.2.5.    Flash写入程序附录
        示例代码只是初步演示:

        Flash的写入:        

完整代码请联系版主               ‘

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文化人Sugar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值