Sequencer 分为HW和SW
Sequencer HW
Sequencer HW是针对S32V234 SOC设计来控制视频数据。其中特定的图像处理可以由不同的硬件模块处理,这些模块就叫ISP。Sequencer HW被ARM M0+ core的firmware所控制。
Sequencer SW
Sequencer SW由两层,第一层是kernel驱动层。第二层是应用层。LLDCMD是连接应用程序和驱动程序的函数。层级结构如下:
数据类型:
消息类:
SEQ_Message
typedef struct SEQ_Message
{
uint16_t mStatus; ///< message status
uint16_t mType; ///< message type - always required
uint8_t mData[60]; ///< message data
} SEQ_Message_t
SEQ_MessagePool
typedef struct SEQ_MessagePool
{
struct SEQ_Message *mpRead;
struct SEQ_Message *mpWrite;
struct SEQ_Message *mpBase;
struct SEQ_Message *mpLast;
} SEQ_MessagePool_t;
数据处理类:
SEQ_FrmBuffer
typedef struct SEQ_FrmBuffer
{
uint32_t mBufferIdx; ///< index of the buffer
uintptr_t mOffset; ///< offset of the buffer/or user pointer
uint32_t mPhyAddr; ///< physical address of the buffer
enum SEQ_FrmBufferState mState; ///< current state of the buffer
uint32_t mStreamIdx; ///< index of buffer stream
uint32_t mFrmSeqNum; ///< frame sequence number
struct VDList_Node mVDListNode;///< list node
} SEQ_FrmBuffer_t;
SEQ_FrmBufferInfo
typedef struct SEQ_FrmBufferInfo
{
uint32_t mBufferIdx; ///< index of the buffer
enum SEQ_FrmBufferState mState; ///< current state of the buffer
uint32_t mStreamIdx; ///< index of buffer stream
uint32_t mFrmSeqNum; ///< frame sequence number
uint32_t mSize; ///< size of the buffer
} SEQ_FrmBufferInfo_t;
SEQ_FrmStream
typedef struct SEQ_FrmStream
{
uint32_t mCnt; ///< number of available buffers
SEQ_FrmBuffer_t* mpBufferTable; ///< table of buffers
size_t mBufferSize; ///< size of one buffer in bytes
SEQ_FrmBuffer_t* mpNextBuffer; ///< pointer to buffer that is sheduled
struct VDList mWorkQueue; ///< queue of frames to be captured
struct VDList mDoneQueue; ///< queue of done frames
uint16_t mSramLpF; ///< lines/frame for the SRAM buffer
uint16_t mSramLineOffs; ///< line offset in SRAM buffer
} SEQ_FrmStream_t;
SEQ_BufferRequest
typedef struct SEQ_BufferRequest
{
uint32_t mStreamIdx; ///< index of a frame stream
uint32_t mCnt; ///< number of requested buffers
uint32_t mBaseShift; ///< shift from base address to valid pixel data
size_t mBufferSize; ///< size of one buffer in bytes
uint16_t mSramLpF; ///< lines/frame for the SRAM buffer
uint16_t mSramLineOffs; ///< line offset in SRAM buffer
uint32_t* mpBuffers; ///< pointer to array of HW addresses
} SEQ_BufferRequest_t;
SEQ_FrmBufferState
typedef enum SEQ_FrmBufferState
{
SEQ_FRM_BUFFER_STATE_WORK = 0, ///< in the work queue
SEQ_FRM_BUFFER_STATE_DONE, ///< in the done queue
SEQ_FRM_BUFFER_STATE_USER, ///< available for user
} SEQ_FrmBufferState_t; // enum SEQ_FrmBufferState
驱动内部管理结构:
SEQ_DrvInfo
typedef struct SEQ_DrvInfo
{
SEQ_CtrlBlkRegs_t *mpSeqCBregs; ///< control block registers
SEQ_EvtCtrlRegs_t *mpSeqECregs; ///< event control block registers
uint8_t *mpCram; ///< M0+ code RAM
uint8_t *mpDbgPram; ///< M0+ debug parameter RAM
uint8_t *mpPram; ///< M0+ parameter RAM
uint8_t *mpKram; ///< M0+ kernel RAM
SEQ_IpusRegs_t *mppIpusRegs[8]; ///< IPUs registers
SEQ_IpuvRegs_t *mppIpuvRegs[4]; ///< IPUv registers
SEQ_IrqNums_t mIrqNums; ///< irqnumbers
SEQ_pram_map_t *mpCommInfo; ///< pram map
void (*mpSigInvoke)(int32_t, int32_t); ///< invokes event signaling
} SEQ_DrvInfo_t;
SEQ_FwType
enum SEQ_FwType
{
SEQ_FW_CM0, ///< CM0 firmware code placed in CRAM
SEQ_FW_KERNEL, ///< IPUx kernel code placed in KRAM
SEQ_FW_GRAPH, ///< IPUx kernel code placed in KRAM
}; //SEQ_FwType
SeqFw
typedef struct SeqFw
{
uint32_t mLineCnt;
SEQ_FwLine_t *mpLines;
} SEQ_Fw_t;
SEQ_GraphPackage
typedef struct SEQ_GraphPackage
{
uint32_t mGraphSize; ///< overall size of the packed graph
void* mpGraphData; ///< pointer to packed graph data
uint32_t mBufferListSize; ///< size of the buffer list in bytes
void* mpBufferList; ///< pointer to list of buffers
uint32_t mCSINumLines; ///< # of lines expected from csi per frame
} SEQ_GraphPackage_t;
时间相关类:
SEQ_EventHandler_t
///< Pointer to a user function handling Sequencer event
typedef void(*SEQ_EventHandler_t)(uint32_t aEventType);
SEQ_IpuHist
typedef struct SEQ_IpuHist
{
uint32_t mPeak; ///< peak value of the histogram
uint32_t mPeakAddr; ///< bin index of the peak value
uint32_t mFrmSeqNum; ///< frame sequence number
SEQ_IpuEngine_t mIpuIdx; ///< IPU engines
uint32_t mpData[IPU_HIST_SIZE]; ///< pointer to histogram data
} SEQ_IpuHist_t;
SEQ_IpuHistHead
typedef struct SEQ_IpuHistHead
{
uint32_t mPeak; ///< peak value of the histogram
uint32_t mPeakAddr; ///< bin index of the peak value
uint32_t mFrmSeqNum; ///< frame sequence number
SEQ_IpuEngine_t mIpuIdx; ///< IPU engines
uint32_t *mpData; ///< pointer to histogram data
} SEQ_IpuHistHead_t;
SeqRegList
typedef struct SeqRegList
{
uint32_t mCnt;
uint8_t mDirection; // IPU_REGLIST_READ or IPU_REGLIST_WRITE
SEQM_ipu_reg_t *mpData;
} SEQ_RegList_t;
SEQ_EventDesc
typedef union SEQ_EventDesc
{
uint32_t R;
struct
{
uint32_t mRegister:26;
uint32_t mType:6;
} B;
} SEQ_EventDesc_t;
kernel 层:
"Work queue"
"Done queue"
应用层:
注册接收信息的过程:
PreStart
SEQ_EventHandlerSet
SeqSigHandler
spEventHandlerClass->SeqEventHandler(*lpVal);
注册发送信息的过程:
PreStart
SEQ_Reserve
SEQ_DRV_Setup
SeqDrvDataInit
spSeqDrvInfo = apSeqDrvInfo;
SEQ_MsgPoolInit
发送信息的过程:
SEQ_DRV_Setup
SeqIrqsRequest
request_irq(spSeqDrvInfo->mIrqNums.mMsgRdy, &SEQ_MsgIrqHandler,
SEQ_MsgIrqHandler
tasklet_schedule(&gSeqMsg_tasklet);
DECLARE_TASKLET(gSeqMsg_tasklet, SEQ_S2hMsgTasklet, 0);
SEQ_S2hMsgTasklet
Sig2UsrSend
spSeqDrvInfo->mpSigInvoke(aPid, aValue);