6.3.5. 设计说明

6.3.5.1. 源码说明

源代码位于 bsp/artinchip/

  • bsp/artinchip/drv/dvp/drv_dvp.c,DVP Driver 层实现

  • bsp/artinchip/hal/dvp/hal_dvp.c,DVP HAL 层实现

  • bsp/artinchip/include/hal/hal_dvp.h,DVP HAL 层接口头文件

6.3.5.2. 模块架构

整个软件系统的架构图如下:

../../../_images/sw_system6.png
  • DVP驱动需要和我司的MPP中间件配合一起使用,DVP Driver层采用普通的API方式向上提供接口。

  • 同时,DVP还需要和Camera外设的驱动配合一起完成图像数据的采集

  • MPP VIN模块对APP提供类似ioctl的接口封装,这样设计是为了和Linux中MPP VIN保持一致

  • DVP暂不支持在裸机环境中运行。

6.3.5.3. 关键流程设计

6.3.5.3.1. 初始化流程

总体上看,DVP驱动的初始化过程分为两大段:

  1. 阶段一:由probe()接口完成,完成中断申请、管理状态初始化等;

  2. 阶段二:由open()接口完成(需要等Sensor执行完初始化后才能执行),完成的操作有:使能时钟、使能DVP控制器、初始化Buf链表信息等。

6.3.5.3.2. Buf 管理

详见MPP VIN模块中的 Buf队列管理

6.3.5.3.3. 中断处理流程

DVP的中断处理函数中主要处理Buf的队列切换操作。 DVP硬件提供的中断可以反映出多个状态(包括出错状态),其中有两个比较重要:

  1. Update done

    表示硬件已经读走了当前的Register值(影子寄存器),软件可以为下一帧去修改了;

  2. Frame done

    表示当前帧的数据传输完成。

可见,Update done会先于Frame done发生,驱动中用Update done判断当前Register是否可以修改,用Frame done判断当前buf是否完成(done状态),该buf就可以从QBuf list切换到DQbuf list了。

按照DVP硬件设计的逻辑,Update done和Frame done会间隔着产生(不会连续两个Update done): Update done -> Frame done -> Update done -> Frame done -> Update done -> Frame done ...

../../../_images/dvp_irq_flow.png

图 6.60 DVP 驱动中IRQ处理流程

“处理Frame done事件”的子流程如下:

../../../_images/dvp_frame_done_flow.png

图 6.61 DVP 驱动中Frame done处理流程

“处理Update done事件”的子流程如下:

../../../_images/dvp_update_done_flow.png

图 6.62 DVP 驱动中Update done处理流程

  • “异常!DVP同时使用了两个Buf”

    理论上不应该发生,可认为是DVP硬件异常,但因为DVP还在向Buf写数据,所以先不执行stop,软件上报错。

  • “DVP在使用”

    表示“DVP控制器硬件正在使用”。

6.3.5.4. 数据结构设计

6.3.5.4.1. struct aic_dvp

属于 Driver 层接口,定义了DVP控制器的设备管理信息:

struct aic_dvp {
    struct aic_dvp_config   cfg; /* The configuration of DVP HW */
    struct dvp_out_fmt      fmt; /* The format of output data */

    /* Videobuf */
    struct vb_queue         queue;
    struct list_head        active_list;
    aicos_mutex_t           active_lock; /* lock of active buf list */
    unsigned int            sequence;
    unsigned int            streaming;

    aicos_mutex_t           lock;
};

6.3.5.4.2. struct aic_dvp_config

属于 HAL 层接口,定义了媒体数据的配置信息:

/* Save the configuration information for DVP controller. */
struct aic_dvp_config {
    /* Input format */
    enum dvp_input          input;
    enum dvp_input_yuv_seq  input_seq;
    u32                     flags;

    /* Output format */
    enum dvp_output output;
    u32             width;
    u32             height;
    u32             stride[DVP_PLANE_NUM];
    u32             sizeimage[DVP_PLANE_NUM];
};

6.3.5.4.3. 输入输出的数据格式

6.3.5.4.3.1. enum dvp_input

属于 HAL 层接口,定义了DVP输入数据的格式:

enum dvp_input {
    DVP_IN_RAW  = 0,
    DVP_IN_YUV422   = 1,
    DVP_IN_BT656    = 2,
};

6.3.5.4.3.2. enum dvp_input_yuv_seq

属于 HAL 层接口,定义了DVP输入数据的YUV格式:

enum dvp_input_yuv_seq {
    DVP_YUV_DATA_SEQ_YUYV   = 0,
    DVP_YUV_DATA_SEQ_YVYU   = 1,
    DVP_YUV_DATA_SEQ_UYVY   = 2,
    DVP_YUV_DATA_SEQ_VYUY   = 3,
};

6.3.5.4.3.3. enum dvp_output

属于 HAL 层接口,定义了DVP输出数据的格式:

enum dvp_output {
    DVP_OUT_RAW_PASSTHROUGH     = 0,
    DVP_OUT_YUV422_COMBINED_NV16    = 1,
    DVP_OUT_YUV420_COMBINED_NV12    = 2,
};

6.3.5.5. Driver 层接口设计

6.3.5.5.1. aic_dvp_probe

函数原型

int aic_dvp_probe(void)

功能说明

完成中断申请、管理状态初始化等

参数定义

返回值

0,成功;<0,失败

注意事项

6.3.5.5.2. aic_dvp_open

函数原型

int aic_dvp_open(void)

功能说明

使能时钟、使能DVP控制器、初始化Buf链表信息等

参数定义

返回值

0,成功;<0,失败

注意事项

6.3.5.5.3. aic_dvp_close

函数原型

int aic_dvp_close(void)

功能说明

关闭时钟、关闭DVP控制器

参数定义

返回值

0,成功;<0,失败

注意事项

6.3.5.5.4. aic_dvp_set_in_fmt

函数原型

int aic_dvp_set_in_fmt(struct mpp_video_fmt *fmt)

功能说明

设置DVP的输入视频格式

参数定义

fmt - 指向struct mpp_video_fmt类型的指针

返回值

0,成功;<0,失败

注意事项

fmt一般是从Camera设备中读取到的格式信息

6.3.5.5.5. aic_dvp_set_out_fmt

函数原型

int aic_dvp_set_out_fmt(struct dvp_out_fmt *fmt)

功能说明

设置DVP的输出图像格式

参数定义

fmt - 指向struct dvp_out_fmt类型的指针

返回值

0,成功

注意事项

6.3.5.5.6. aic_dvp_stream_on

函数原型

int aic_dvp_stream_on(void)

功能说明

启动视频流

参数定义

返回值

0,成功;<0,失败

注意事项

6.3.5.5.7. aic_dvp_stream_off

函数原型

int aic_dvp_stream_off(void)

功能说明

关闭视频流

参数定义

返回值

0,成功;<0,失败

注意事项

6.3.5.5.8. aic_dvp_req_buf

函数原型

int aic_dvp_req_buf(char *buf, u32 size, struct vin_video_buf *vbuf)

功能说明

按照给定的Video Buf配置信息从内存池中申请Buf

参数定义

buf - 指向内存池的指针
size - 内存池的总大小
vbuf - Video Buf的配置信息

返回值

0,成功;<0,失败

注意事项

6.3.5.5.9. aic_dvp_q_buf

函数原型

int aic_dvp_q_buf(u32 index)

功能说明

释放指定index的Buf进入空闲队列(queued_list)

参数定义

index - Buf的索引号

返回值

0,成功;<0,失败

注意事项

6.3.5.5.10. aic_dvp_dq_buf

函数原型

int aic_dvp_dq_buf(u32 *pindex)

功能说明

从DVP处理完成后的队列(done_list)中获取一个Buf

参数定义

pindex - 用于保存获取到的Buf索引号

返回值

0,成功;<0,失败

注意事项

6.3.5.6. APP Demo

详见 MPP VIN模块中的 参考Demo