Skip to main content

K230 DMA API参考

1. 概述

1.1 概述

GSDMA:DMA 全称 Direct Memory Access,即直接存储器访问,将数据从一个地址空间复制到另一个地址空间,提供在存储器和存储器之间的高速数据传输。GDMA 全称 Graphic Direct Memory Access,负责将内存中的图像复制到另一块内存中,同时可以完成图像的旋转和镜像等功能。SDMA 全称 System Direct Memory Access,负责将内存中的数据复制到另一块内存中,即传统意义上的 DMA。

软件代码将 GSDMA 硬件的各个功能以 API 的方式提供给使用者使用,帮助用户快速实现图像传输、旋转、镜像、2D 功能及数据传输功能。同时实现了模块状态信息统计等功能。

1.2 功能描述

dma 驱动调用流程如下图所示:

图示 描述已自动生成

将 dma 硬件抽象为一个设备,八个通道,其中,通道 0~3 是 gdma 通道,通道 4~7 是 sdma 通道。

1.2.1 gdma

用户通过 gdma 来实现图像的旋转镜像工作,主要调用流程如下:

  1. 进行 dma 设备属性的配置;
  2. 启动 dma 设备。在调用此函数以后驱动会自动申请 VB 空间作为目的地址的数据缓冲区;
  3. 进行 gdma 通道属性的配置;
  4. 启动 gdma 通道;
  5. 用户在用户态申请 VB 空间作为源数据的数据缓冲区,调用 kd_mpi_dma_send_frame 发送数据的源地址给 gdma;
  6. 驱动会将源地址中的数据传输到步骤二中申请的目的地址数据缓冲区中;
  7. 用户调用 kd_mpi_dma_get_frame 获取目的地址中的数据地址。

1.2.2 sdma

用户通过 sdma 来实现数据搬移工作,主要调用流程如下:

  1. 进行 dma 设备属性的配置;
  2. 启动 dma 设备。在调用此函数以后驱动会自动申请 VB 空间作为目的地址的数据缓冲区;
  3. 进行 sdma 通道属性的配置;
  4. 启动 sdma 通道;
  5. 用户在用户态申请 VB 空间作为源数据的数据缓冲区,调用 kd_mpi_dma_send_frame 发送数据的源地址给 sdma;
  6. 驱动会将源地址中的数据传输到步骤二中申请的目的地址数据缓冲区中;
  7. 用户调用 kd_mpi_dma_get_frame 获取目的地址中的数据地址。

2. API 参考

2.1 DMA 使用

该功能模块提供以下API:

2.1.1 kd_mpi_dma_set_dev_attr

【描述】

配置 dma 设备属性

【语法】

k_s32 kd_mpi_dma_set_dev_attr(k_dma_dev_attr_t *attr);

【参数】

参数名称描述输入/输出
attrdma 设备属性结构体指针。输入

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

无。

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

【举例】

【相关主题】

k_dma_dev_attr_t

2.1.2 kd_mpi_dma_get_dev_attr

【描述】

获取已经配置的 dma 设备属性。

【语法】

k_s32 kd_mpi_dma_get_dev_attr(k_dma_dev_attr_t *attr);

【参数】

参数名称描述输入/输出
attrdma 设备属性结构体指针输入

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

需要在配置 dma 设备属性之后才可以获取 dma 设备属性。

【举例】

【相关主题】

k_dma_dev_attr_t

2.1.3 kd_mpi_dma_start_dev

【描述】

启动 dma 设备。

【语法】

k_s32 kd_mpi_dma_start_dev();

【参数】

参数名称描述输入/输出

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

  • 需要配置 dma 设备属性之后才可以调用此函数启动 dma

【举例】

【相关主题】

2.1.4 kd_mpi_dma_stop_dev

【描述】

停止 dma 设备。

【语法】

kd_mpi_dma_stop_dev();

【参数】

参数名称描述输入/输出

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

  • 只有启动 dma 设备之后才可以调用此函数来停止 dma 设备。

【举例】

【相关主题】

2.1.5 kd_mpi_dma_set_chn_attr

【描述】

配置 dma 通道属性。

【语法】

k_s32 kd_mpi_dma_set_chn_attr(k_u8 chn_num, k_dma_chn_attr_u *attr);

【参数】

参数名称描述输入/输出
chn_num通道号输入
attrdma 通道属性,该参数是一个联合体,可以选择配置 gdma 通道属性,也可以选择配置 sdma 通道属性。通道 0~3 是 gdma,通道 4~7 是 sdma输入

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

【举例】

【相关主题】

k_dma_chn_attr_u

2.1.6 kd_mpi_dma_get_chn_attr

【描述】

获取已经配置的 dma 通道属性。

【语法】

k_s32 kd_mpi_dma_get_chn_attr(k_u8 chn_num, k_dma_chn_attr_u *attr);

【参数】

参数名称描述输入/输出
chn_num通道号输入
attrdma 通道属性,该参数是一个联合体,可以选择获取 gdma 通道属性,也可以选择获取 sdma 通道属性。通道 0~3 是 gdma,通道 4~7 是 sdma输出

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

  • 需要在配置 dma 通道属性之后才可以获取 dma 通道属性。

【举例】

【相关主题】

k_dma_chn_attr_u

2.1.7 kd_mpi_dma_start_chn

【描述】

启动 dma 通道。

【语法】

k_s32 kd_mpi_dma_start_chn(k_u8 chn_num);

【参数】

参数名称描述输入/输出
chn_num通道号。输入

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

  • 只有在配置启动 dma 设备,配置 dma 通道属性之后才可以启动 dma 通道。

【举例】

【相关主题】

2.1.8 kd_mpi_dma_stop_chn

【描述】

暂停 dma 通道

【语法】

k_s32 kd_mpi_dma_stop_chn(k_u8 chn_num);

【参数】

参数名称描述输入/输出
chn_num通道号。输入

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

  • 只有启动 dma 通道之后才可以调用此函数来停止 dma 通道。

【举例】

【相关主题】

2.1.9 kd_mpi_dma_send_frame

【描述】

从用户空间发送数据到目的地址。

【语法】

k_s32 kd_mpi_dma_send_frame(k_u8 chn_num, k_video_frame_info *df_info, k_s32 millisec);

【参数】

参数名称描述输入/输出
chn_num通道号。输入
df_info发送数据的地址信息。输入
millisec等待时间。 当此参数设置为 -1 时,阻塞; 当此参数设置为 0 时,非阻塞; 当此参数设置为大于 0 的值时,会等待相应时间直到成功发送数据,如果超时后仍未成功发送,返回失败。输入

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

【举例】

【相关主题】

k_video_frame_info

2.1.10 kd_mpi_dma_get_frame

【描述】

获取 dma 搬运后的数据。

【语法】

k_s32 kd_mpi_dma_get_frame(k_u8 chn_num, k_video_frame_info *df_info, k_s32 millisec);

【参数】

参数名称描述输入/输出
chn_num通道号。输入
df_info获取数据的地址信息。输出
millisec等待时间。 当此参数设置为 -1 时,阻塞; 当此参数设置为 0 时,非阻塞; 当此参数设置为大于 0 的值时,会等待相应时间知道成功获取数据,如果超时后仍未成功发送,返回失败。输入

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

【举例】

【相关主题】

k_video_frame_info

2.1.11 kd_mpi_dma_release_frame

【描述】

释放获取的 dma 数据。

【语法】

k_s32 kd_mpi_dma_release_frame(k_u8 chn_num, k_video_frame_info *df_info);

【参数】

参数名称描述输入/输出
chn_num通道号。输入
df_info要释放的数据。输入

【返回值】

返回值描述
0成功
非0失败,其值参见错误码

【芯片差异】

【需求】

  • 头文件:mpi_dma_api.h
  • 库文件:libdma.a

【注意】

  • 当前设计中 dma 输出 buffer 为 3,如果获取 3 帧数据都没有调用此函数进行释放,那么无法继续输入数据。因此,用户应该在获取数据,使用完之后及时释放。

【举例】

【相关主题】

k_video_frame_info

3 数据类型

3.1 公共数据类型

3.1.1 DMA_MAX_DEV_NUMS

【说明】

DMA 最大设备数

【定义】

#define DMA_MAX_DEV_NUMS (1)

【注意事项】

【相关数据类型及接口】

3.1.2 DMA_MAX_CHN_NUMS

【说明】

DMA 最大通道数

【定义】

#define DMA_MAX_CHN_NUMS (8)

【注意事项】

【相关数据类型及接口】

3.1.3 k_dma_mode_e

【说明】

定义 dma 工作模式。

【定义】

typedef enum
{
DMA_BIND,
DMA_UNBIND,
} k_dma_mode_e;

【成员】

成员名称描述
BIND绑定模式。
UNBIND非绑定模式

【注意事项】

【相关数据类型及接口】

k_gdma_chn_attr_t k_sdma_chn_attr_t

3.1.4 k_dma_dev_attr_t

【说明】

定义 dma 设备属性。

【定义】

typedef struct
{
k_u8 burst_len;
k_u8 outstanding;
k_bool ckg_bypass;
} k_dma_dev_attr_t;

【成员】

成员名称描述
burst_len配置 dma 的 burst length
outstanding配置 dma outstanding
ckg_bypass配置 clock gate bypass

【注意事项】

【相关数据类型及接口】

kd_mpi_dma_set_dev_attr kd_mpi_dma_get_dev_attr

3.1.5 k_dma_chn_attr_u

【说明】

定义 dma 通道属性。

【定义】

typedef union
{
k_gdma_chn_attr_t gdma_attr;
k_sdma_chn_attr_t sdma_attr;
} k_dma_chn_attr_u;

【成员】

成员名称描述
gdma_attrgdma 通道属性
sdma_attrsdma 通道属性
ckg_bypass配置 clock gate bypass

【注意事项】

【相关数据类型及接口】

k_gdma_chn_attr_t k_sdma_chn_attr_t kd_mpi_dma_set_chn_attr kd_mpi_dma_get_chn_attr

3.1.6 k_video_frame_info

【说明】

定义 dma 数据地址。

【定义】

typedef struct
{
k_video_frame v_frame; /**< Video picture frame */
k_u32 pool_id; /**< VB pool ID */
k_mod_id mod_id; /**< Logical unit for generating video frames */
} k_video_frame_info;

【成员】

成员名称描述
v_frame时间戳,绑定模式下有效。
pool_id数据 vb 池的 pool id。
mod_id模块 id

【注意事项】

【相关数据类型及接口】

kd_mpi_dma_send_frame kd_mpi_dma_get_frame kd_mpi_dma_release_frame

3.1.7 k_video_frame

【说明】

定义 dma 数据地址。使用公用的数据结构 k_video_frame,只使用到了其中的一部分成员。

【定义】

typedef struct
{
k_u64 phys_addr[3];
k_u64 virt_addr[3];
k_u32 time_ref;
k_u64 pts;
} k_video_frame;

【成员】

成员名称描述
phys_addr图像的物理地址,如果是单通道图像,只需配置第一个物理地址;如果是双通道图像,只需配置前两个物理地址;如果是三通道图像,需要配置三个物理地址。
virt_addr图像的虚拟地址,如果是单通道图像,只需配置第一个虚拟地址;如果是双通道图像,只需配置前两个虚拟地址;如果是三通道图像,需要配置三个虚拟地址。
time_ref透传的帧号,在绑定模式下,由前级输入
pts透传的时间戳,在绑定模式下,由前级输入

【注意事项】

【相关数据类型及接口】

kd_mpi_dma_send_frame kd_mpi_dma_get_frame

3.2 gdma 通道数据类型

该模块有如下数据类型

3.2.1 GDMA_MAX_CHN_NUMS

【说明】

GDMA 最大通道数

【定义】

define GDMA_MAX_CHN_NUMS (4)

【注意事项】

【相关数据类型及接口】

3.2.2 k_gdma_rotation_e

【说明】

定义 gdma 通道旋转角度。

【定义】

typedef enum
{
DEGREE_0, /**< Rotate 0 degrees */
DEGREE_90, /**< Rotate 90 degrees */
DEGREE_180, /**< Rotate 180 degrees */
DEGREE_270, /**< Rotate 270 degrees */
} k_gdma_rotation_e;

【注意事项】

【相关数据类型及接口】

k_gdma_chn_attr_t

3.2.3 k_pixel_format_dma_e

【说明】

定义 gdma 图像格式。

【定义】

typedef enum
{
DMA_PIXEL_FORMAT_RGB_444 = 0,
DMA_PIXEL_FORMAT_RGB_555,
DMA_PIXEL_FORMAT_RGB_565,
DMA_PIXEL_FORMAT_RGB_888,

DMA_PIXEL_FORMAT_BGR_444,
DMA_PIXEL_FORMAT_BGR_555,
DMA_PIXEL_FORMAT_BGR_565,
DMA_PIXEL_FORMAT_BGR_888,

DMA_PIXEL_FORMAT_ARGB_1555,
DMA_PIXEL_FORMAT_ARGB_4444,
DMA_PIXEL_FORMAT_ARGB_8565,
DMA_PIXEL_FORMAT_ARGB_8888,

DMA_PIXEL_FORMAT_ABGR_1555,
DMA_PIXEL_FORMAT_ABGR_4444,
DMA_PIXEL_FORMAT_ABGR_8565,
DMA_PIXEL_FORMAT_ABGR_8888,

DMA_PIXEL_FORMAT_YVU_PLANAR_420_8BIT,
DMA_PIXEL_FORMAT_YVU_PLANAR_420_10BIT,
DMA_PIXEL_FORMAT_YVU_PLANAR_420_16BIT,
DMA_PIXEL_FORMAT_YVU_PLANAR_444_8BIT,
DMA_PIXEL_FORMAT_YVU_PLANAR_444_10BIT,

DMA_PIXEL_FORMAT_YUV_PLANAR_420_8BIT,
DMA_PIXEL_FORMAT_YUV_PLANAR_420_10BIT,
DMA_PIXEL_FORMAT_YUV_PLANAR_420_16BIT,

DMA_PIXEL_FORMAT_YVU_SEMIPLANAR_420_8BIT,
DMA_PIXEL_FORMAT_YVU_SEMIPLANAR_420_10BIT,
DMA_PIXEL_FORMAT_YVU_SEMIPLANAR_420_16BIT,

DMA_PIXEL_FORMAT_YUV_SEMIPLANAR_420_8BIT,
DMA_PIXEL_FORMAT_YUV_SEMIPLANAR_420_10BIT,
DMA_PIXEL_FORMAT_YUV_SEMIPLANAR_420_16BIT,

DMA_PIXEL_FORMAT_YUV_400_8BIT,
DMA_PIXEL_FORMAT_YUV_400_10BIT,
DMA_PIXEL_FORMAT_YUV_400_12BIT,
DMA_PIXEL_FORMAT_YUV_400_16BIT,

DMA_PIXEL_FORMAT_YUV_PACKED_444_8BIT,
DMA_PIXEL_FORMAT_YUV_PACKED_444_10BIT,

/* SVP data format */
DMA_PIXEL_FORMAT_BGR_888_PLANAR,
} k_pixel_format_dma_e;

3.2.4 k_gdma_chn_attr_t

【说明】

定义 gdma 通道属性。

【定义】

typedef struct
{
k_u8 buffer_num;
k_gdma_rotation_e rotation;
k_bool x_mirror;
k_bool y_mirror;
k_u16 width;
k_u16 height;
k_u16 src_stride[3];
k_u16 dst_stride[3];
k_dma_mode_e work_mode;
k_pixel_format_dma_e pixel_format;
} k_gdma_chn_attr_t;

【成员】

成员名称描述
buffer_numgdma 通道 buffer 数量,至少为 1。
rotationgdma 通道旋转角度。
x_mirrorgdma 通道是否进行水平镜像
y_mirrorgdma 通道是否进行垂直镜像
widthgdma 通道宽度,以像素为单位。
heightgdma 通道高度,以像素为单位。
src_stridegdma 源数据 stride。如果图像格式是单通道模式,只需配置src_stride[0];如果图像格式是双通道模式,需要配置src_stride[0]src_stride[1];如果图像格式是三通道模式,需要配置 src_stride[0]src_stride[1]src_stride[2]
dst_stridegdma目的数据 stride。如果图像格式是单通道模式,只需配置dst_stride[0];如果图像格式是双通道模式,需要配置dst_stride[0]dst_stride[1];如果图像格式是三通道模式,需要配置 dst_stride[0]dst_stride[1]dst_stride[2]
work_mode工作模式,可以选择绑定模式或者非绑定模式。
pixel_format图像格式。

【注意事项】

  • 无。

【相关数据类型及接口】

3.3 sdma 通道数据类型

本模块有如下数据类型

3.3.1 SDMA_MAX_CHN_NUMS

【说明】

SDMA 最大通道数

【定义】

#define SDMA_MAX_CHN_NUMS (4)

【注意事项】

【相关数据类型及接口】

3.3.2 k_sdma_data_mode_e

【说明】

定义 sdma 通道传输数据的模式

【定义】

typedef enum
{
DIMENSION1,
DIMENSION2,
} k_sdma_data_mode_e;

【成员】

成员名称描述
DIMENSION1一维 dma 传输模式
DIMENSION1二维 dma 传输模式

【注意事项】

【相关数据类型及接口】

k_sdma_chn_attr_t

3.3.3 k_sdma_chn_attr_t

【说明】

定义 sdma 通道属性。

【定义】

typedef struct
{
k_u8 buffer_num;
k_u32 line_size;
k_u16 line_num;
k_u16 line_space;
k_sdma_data_mode_e data_mode;
k_dma_mode_e work_mode;
} k_sdma_chn_attr_t;

【成员】

成员名称描述
buffer_numsdma 通道 buffer 数量,至少为 1。
line_size对于 1d 模式来说,是传输数据的总长度;对于 2d 模式来说,是单行数据的长度。
line_num对于 1d 模式来说,此成员无效;对于 2d 模式来说,是传输的行的个数。
line_space对于 1d 模式来说,此成员无效;对于 2d 模式来说,是行与行之间的间隔。
data_modesdma 传输数据的模式,包括 1d 模式和 2d 模式。
work_mode工作模式,可以选择绑定模式或者非绑定模式。

【注意事项】

【相关数据类型及接口】

k_dma_chn_attr_u

4. 错误码

4.1 dma 错误码

表 41

错误代码宏定义描述
0xa00148001K_ERR_DMA_INVALID_DEVID无效的设备号
0xa00148002K_ERR_DMA_INVALID_CHNID无效的通道号
0xa00148003K_ERR_DMA_ILLEGAL_PARAM参数错误
0xa00148004K_ERR_DMA_EXISTDMA 设备已经存在
0xa00148005K_ERR_DMA_UNEXISTDMA 设备不存在
0xa00148006K_ERR_DMA_NULL_PTR空指针错误
0xa00148007K_ERR_DMA_NOT_CONFIG尚未配置 DMA
0xa00148008K_ERR_DMA_NOT_SUPPORT不支持的功能
0xa00148009K_ERR_DMA_NOT_PERM操作不允许
0xa0014800cK_ERR_DMA_NOMEM分配内存失败,如系统内存不足
0xa0014800dK_ERR_DMA_NOBUFBUFF 不足
0xa0014800eK_ERR_DMA_BUF_EMPTYBUFF 为空
0xa0014800fK_ERR_DMA_BUF_FULLBUFF 已满
0xa00148010K_ERR_DMA_NOTREADY设备未就绪
0xa00148011K_ERR_DMA_BADADDR错误的地址
0xa00148012K_ERR_DMA_BUSYDMA 处与忙状态

5. 调试信息

5.1 概述

调试信息采用了 proc 文件系统,可实时反映当前系统的运行状态,所记录的信息可供问题定位及分析时使用

【文件目录】

/proc/

【文件清单】

文件名称描述
umap/dma记录当前 dma 模块的使用情况

5.2 系统绑定

5.2.1 系统绑定调试信息

【调试信息】

msh /\>cat /proc/umap/dma
-------------------------------dma dev attr info---------------------------------
DevId burst_len outstanding ckg_bypass
0 0 0 0

-------------------------------dma chn 0\~3 attr info-------------------------------
ChnId rotation x_mirror y_mirror width height work_mode
0 0 false false 0 0 BIND
1 0 false false 0 0 BIND
2 0 false false 0 0 BIND
3 0 false false 0 0 BIND

-------------------------------dma chn 4\~7 attr info-------------------------------
ChnId line_size line_num line_space data_mode work_mode
4 0 0 0 1 DIMENSION BIND
5 0 0 0 1 DIMENSION BIND
6 0 0 0 1 DIMENSION BIND
7 0 0 0 1 DIMENSION BIND

【调试信息分析】

记录当前 dma 模块的使用情况

【设备参数说明】

参数描述
DevId设备号
burst_lendma burst length
outstandingdma outstanding

【gdma 通道参数说明】

参数描述
ChnId通道号
rotation旋转度数
x_mirror是否进行了水平镜像
y_mirror是否进行了垂直镜像
width图像宽度,以像素为单位
height图像高度,以像素为单位
work_mode工作模式

【sdma 通道参数说明】

参数描述
ChnId通道号
line_size对于 1d 模式来说,是传输数据的总长度;对于 2d 模式来说,是单行数据的长度。
ine_num对于 1d 模式来说,此成员无效;对于 2d 模式来说,是传输的行的个数。
line_space对于 1d 模式来说,此成员无效;对于 2d 模式来说,是行与行之间的间隔。
data_modesdma 传输数据的模式,包括 1d 模式和 2d 模式
work_mode工作模式,可以选择绑定模式或者非绑定模式。

6. demo 描述

6.1 非绑定模式 demo

非绑定模式 demo 位于 /bin/sample_dma.elf,执行 /bin/sample_dma.elf 后开始循环运行,按 e + 回车结束运行。

demo 主要实现了以下功能:

  • 使用通道 0 搬运分辨率为 1920*1080,8bit,YUV400 单通道的图像,gdma 旋转 90 度后输出;
  • 使用通道 1 搬运分辨率为 1280*720,8bit,YUV420 双通道的图像,gdma 旋转 180 度后输出;
  • 使用通道 2 搬运分辨率为 1280*720,10bit,YUV420 三通道的图像,gdma 进行水平和垂直镜像后输出;
  • 使用通道 4 搬运数据,sdma 使用 1d 模式搬运;
  • 使用通道 5 搬运数据,sdma 使用 2d 模式搬运。

6.2 绑定模式 demo

绑定模式 demo 位于 /bin/sample_dma_bind.elf,执行 /bin/sample_dma_bind.elf 后开始循环运行,按 e + 回车结束运行。

demo 主要实现了以下功能:

  • 以 vvi 模块作为 gsdma 前级绑定的模拟输入,实现绑定功能的测试;
  • 两个通道分别输入分辨率为 640*320,8bit,YUV400 单通道的图像,gdma 分别旋转 90 度和 180 度后输出。