大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是在i.MXRT1170上PXP對CM7 TCM進行隨機地址短小數據寫入操作限制。
在 MCU 里能夠對片內外映射的存儲器進行讀寫操作的主設備(Master)除了常見的 Core 以及 DMA 外,其實還有一些面向高速數據傳輸(比如 USB、uSDHC、ENET 接口等)或其他特定功能(比如 GPU、LCD、Crypto 等)的外設,但就用戶數據搬移處理而言,一般我們只借助 Core 和 DMA。
在 i.MXRT 四位數上,還有一個叫 PXP 的外設,這本是一個面向像素數據處理的模塊,但是它也能夠完成一般數據搬移處理任務。當我們借助這個 PXP 來做數據搬移時,發(fā)現它在對 CM7 TCM 寫入時有一些使用限制。今天我們就來聊聊這個話題:
一、PXP功能簡介
先來看一下 PXP 模塊功能框圖,既然是面向圖像數據處理,那常見的圖像縮放、色彩空間轉換、圖像旋轉功能支持必不可少(即下圖藍框里的三個獨立引擎被整合在 PXP 里),這些操作實際上都涉及到 FrameBuffer 像素數據處理(讀改寫) 。
再進一步細讀 PXP 特性,我們發(fā)現除了像素處理之外,它還是個標準的 2D DMA(這里 2D 的意思是為搬移二維圖像數據而設計的),這就是我們所要的數據搬移特性。在用 PXP 做數據搬移操作時,當源 FrameBuffer 和目的 FrameBuffer 大小相同,且搬移目標尺寸就是 FrameBuffer 長度時,其就蛻變成了大家所熟悉的普通 DMA。
二、一個RT1170的Errata
在我們實測 PXP 數據搬移功能時,我們先來看一個 RT1160/1170 上獨有的 Errata,也正是因為這個 Errata 讓痞子衡關注到了 PXP 的 2D DMA 功能。
這個 Errata 提及到 RT1160/1170 里若干個具有存儲器讀寫能力的主設備在對 CM7 TCM 進行 Sparse write(隨機地址短小數據寫入操作)時可能會導致數據出錯,PXP 就是其一,解決方案就是 CM7 TCM 不要作為目的 FrameBuffer。
- Note:列出來的有限制的主設備大多是 RT1170 里新增的外設(CAAM, ENET_1G, ENET_QOS, GC355, LCDIFv2),除了 PXP 是 RT10xx 上也存在的,但是 RT10xx PXP 并沒有這個限制。
三、在PXP下實測數據搬移
要實測 PXP 數據搬移功能可以直接借助 SDK_2_16_000_MIMXRT1170-EVKBboardsevkbmimxrt1170driver_examplespxpcopy_piccm7 例程,其主要函數 APP_CopyPicture() 摘錄如下,代碼清晰明了。我們要做不同的測試,只需要將 s_inputBuf、s_outputBuf 分別鏈接在不同存儲器空間里,并且設置不同的拷貝塊大小與坐標位置即可。
- Note:僅需調整 COPY_WIDTH、DEST_OFFSET_X 值來測試對一維數據搬移影響(數據長度、起始地址對齊因素)
#include?"fsl_pxp.h"
//?源/目標?Buffer?長寬設置(為測試方便,可設置成一樣)
#define?BUF_WIDTH???64
#define?BUF_HEIGHT??64
//?拷貝塊長寬及在目標?Buffer?坐標設置(從源?Buffer?坐標固定為?[0,0])
#define?COPY_WIDTH????????8
#define?COPY_HEIGHT???????8
#define?DEST_OFFSET_X?????1
#define?DEST_OFFSET_Y?????1
uint16_t?s_inputBuf[BUF_HEIGHT][BUF_WIDTH];
uint16_t?s_outputBuf[BUF_HEIGHT][BUF_WIDTH];
static?void?APP_CopyPicture(void)
{
????pxp_pic_copy_config_t?pxpCopyConfig;
????//?設置拷貝參數(將s_inputBuf里坐標[0,0]開始的大小為8x8的數據拷貝到s_outputBuf里[1,1]位置處)
????//?源?Buffer?地址與拷貝塊坐標設置
????pxpCopyConfig.srcPicBaseAddr??=?(uint32_t)s_inputBuf;
????pxpCopyConfig.srcPitchBytes???=?sizeof(uint16_t)?*?BUF_WIDTH;
????pxpCopyConfig.srcOffsetX??????=?0;
????pxpCopyConfig.srcOffsetY??????=?0;
????//?目的?Buffer?地址與拷貝塊坐標設置
????pxpCopyConfig.destPicBaseAddr?=?(uint32_t)s_outputBuf;
????pxpCopyConfig.destPitchBytes??=?sizeof(uint16_t)?*?BUF_WIDTH;
????pxpCopyConfig.destOffsetX?????=?DEST_OFFSET_X;
????pxpCopyConfig.destOffsetY?????=?DEST_OFFSET_Y;
????//?拷貝塊大小設置(像素點格式為?RGB565?即?2bytes)
????pxpCopyConfig.width???????????=?COPY_WIDTH;
????pxpCopyConfig.height??????????=?COPY_HEIGHT;
????pxpCopyConfig.pixelFormat?????=?kPXP_AsPixelFormatRGB565;
????//?啟動拷貝(將拷貝塊數據從源?Buffer?搬移到目的?Buffer)
????PXP_StartPictureCopy(PXP,?&pxpCopyConfig);
????while?(!(kPXP_CompleteFlag?&?PXP_GetStatusFlags(PXP)));
????PXP_ClearStatusFlags(PXP,?kPXP_CompleteFlag);
}
經測試當 s_outputBuf 放在 OCRAM 或者外部 RAM 空間里時,搬移結果完全如預期。而當 s_outputBuf 放在 CM7 ITCM 或者 DTCM 時,則會出現異常結果,在 ITCM/DTCM 異常表現是一致的。
設置不同的 COPY_WIDTH、DEST_OFFSET_X 值組合帶來的異常結果不盡相同,這里僅放出一個 COPY_WIDTH = 1、DEST_OFFSET_X = 3 的情況供參考,可以看到除了目標地址數據之外,前后還會有一些額外數據被寫入,這樣的數據搬移操作顯然不可靠了。
當然并不是 s_outputBuf 放在 CM7 TCM 就一定能引起異常,只要拷貝的一維數據長度是 16bytes 整數倍,且目的起始地址以 8 對齊時,此時并無出錯情況發(fā)生。不滿足這個條件的寫入我們即稱之為有風險的 Sparse write(隨機地址短小數據寫入)。
至此,在i.MXRT1170上PXP對CM7 TCM進行隨機地址短小數據寫入操作限制痞子衡便介紹完畢了,掌聲在哪里~~~