SDI(Sensor Data Interface)
SDI 控制圖像的輸出,用來支援ISP子系統。ISP支援不同的接口:
輸入:mipi-csi2,viu,ethernet,FastDMA
處理:scalar/vector IPU,H264 decoder,jpeg decoder,vision Sequencer
輸出:H264 encoder,ethernet,FDMA

由圖,可以看出,SDI僅僅是在app下層。算是屬于比較上層的東西了。
主要的工作是三個方面:
硬體資源的配置設定(ISP engine,SRAM/DDR )
資料預處理通道配置
frame capture 控制
---------------------------------------------------------------------------------------------------------------------------------------------------
類:
sdi_graph
NXP開發了一套S32V DS,可以用來開發graph。至于graph的詳細使用,請看我之前的博文
https://blog.csdn.net/qq_24687591/article/details/90377599
DS編輯的graph可以生成.c,主要包括 gpGraph,gGraphMetadata。
sdi_graph調用Finalize()初始化 SRAM buffers,調用Download() 下載下傳graph 到sequencer的memory,SEQ_GraphDownload--->
SEQ_DRV_GraphDownload
int32_t SEQ_DRV_GraphDownload(SEQ_GraphPackage_t *apGraph)
{
int32_t lRet = SEQ_DRV_SUCCESS;
SEQ_GraphPackage_t lGraph;
if (copy_from_user( &lGraph,
apGraph,
sizeof(SEQ_GraphPackage_t)) != 0)
{
VDB_LOG_ERROR("Copy from user failed.\n");
lRet = -EIO;
} // if copy from user failed
sdi_io
主要的方法:
Reverse():初始化硬體驅動程式
Release(): 清除硬體驅動程式
Setup():将指定的配置應用于初始化好的硬體子產品
Start():啟動攝像頭或者是CSI接口
Stop():停止攝像頭或者是CSI接口
繼承了sdi_io的類:
sdi_FdmaIO
配置FDAM子產品和DDR buffers的處理,FDAM主要是将資料從SRAM搬到DDR。每個graph最多可以有16個FDMA通道。
sdi_H264EncIO
sdi_JpegDecIO
sdi_MipiCsiIO
sdi_ViuIO
此外,還有兩個有用的結構體:
SDI_Frame
struct SDI_Frame
{
vsdk::UMat mUMat; ///< image container
friend sdi_grabber;
uint32_t mFrmSeqNum; ///< frame sequence number
private:
uint32_t mChannelIdx; ///< index of related FDMA channel
uint32_t mBufferIdx; ///< index of the buffer in the buffer array for particular channel
}; // SDI_DdrBufList
SDI_DdrBufferArr
struct SDI_DdrBufferArr
{
uint32_t mFdmaTcIdx; ///< index of FDMA TC
uint32_t mCnt; ///< number buffers in the array
vsdk::UMat *mpUmat;
bool mDeallocate; ///< true if to be deallocated automatically
friend sdi_FdmaIO;
public:
SDI_ImageDescriptor mDesc; ///< buffer image descriptor
...
}
sdi_process
提供了sdi_graph類的api。目前和sdi_graph的類基本一緻,這個類是為了以後預留可以管理多個graph的接口。
sdi_grabber
基本上包含了以上類的所有封裝,一個通用的流程:
1-3在 LibsPrepare函數裡
1.建立一個sdi_grabber執行個體:
arContext.mpGrabber = new(sdi_grabber);
sdi::Initialize(0);
2.graph的處理
arContext.mpGrabber->ProcessSet(gpGraph, &gGraphMetadata)
3.get IOs
arContext.mpFdma = (sdi_FdmaIO*)arContext.mpGrabber->IoGet(SEQ_OTHRIX_FDMA);
4.記憶體的配置設定 DdrBuffersPrepare函數裡
arContext.mpFdma->DdrBufferDescSet(FDMA_IX_FastDMA_Out, lFrmDesc)
arContext.mpFdma->DdrBuffersAlloc(DDR_BUFFER_CNT)
5.prestart grabber 初始化硬體資源
arContext.mpGrabber->PreStart()
SEQ_Reserve
IOsReserve
mProcess.Finalize()
IOsSetup()
mProcess.Download()
SEQ_Reset()
SEQ_Boot()
6.有些攝像頭還需要配置camera參數
CamConfig();
7. start grabbing 初始化ISP pipeline
arContext.mpGrabber->Start()
SEQ_GraphStart
IOsStart
8.在死循環裡pop & push
for(;;)
{
for (int i = 0;i < 4;i++)
{
lpFrame[i] = arContext.mpGrabber->FramePop(i);
}
for (int i = 0;i < 4;i++)
{
arContext.mpGrabber->FramePush(lpFrame[i]);
}
}
9.程式結束的時候釋放資源
arContext.mpGrabber->Stop()
arContext.mpGrabber->Release()
sdi::Close(0)