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的寫入:?? ??? ?
完整代碼請聯系版主? ? ? ? ? ? ? ?‘
’
總結
以上是生活随笔為你收集整理的QCC300x笔记(5) -- 外部Flash的读写操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【深度学习】特征值分解与特征向量
- 下一篇: SD 模块与FICO、MM、PS、QM、