在上篇关于 ISP Graph 创建实例的推文中,利用 S32V DS 工具创建 ISP Graph,并且在 ISP Graph 的基础上 Emit 生成了对应的源代码。但 ISP Graph 生成的源代码我们要怎样用起来?今天我们就来分析和移植这部分代码,从而生成可执行文件,最后在 S32V 的板子上运行 ISP Demo 程序。
一、创建 ISP Demo 程序
ISP Graph 生成的源代码包含 2 部分,头文件 isp_graph_test_c.h,包含了相关参数数组的声明。参数文件 isp_graph_test.c,包含了 ISP Graph 所生成的参数组成的数组。
生成的代码中有 2 个关键的数据结构:
extern SEQ_Head_Ptr_t gpGraph[];
extern GraphMetadata_t gGraphMetadata;
我们需要借助框架代码将这 2 个结构的参数下载到 Sequencer 里面。此外还需要在上一节创建的工程 isp_app_test 中,对 main.c 添加必要的初始化代码和抓取图像数据的代码以及输出显示的代码。下面将详细介绍一步步添加代码的过程。
Step1:将参数声明的头文件包含进来
#include "oal.h" #include "isp_gen.h" #include "isp_user_define.h" #include "sdi.hpp" #include "isp_graph_test_c.h" #include "frame_output_v234fb.h" |
Step2:定义模组输出分辨率
#define CHNL_CNT io::IO_DATA_CH3 #define WIDTH 1280 #define HEIGHT 720 #define DDR_BUFFER_CNT 3 |
Step3:定义数据结构和初始化
struct AppContext { sdi_grabber *mpGrabber; sdi_FdmaIO *mpFdma; bool mError; uint32_t mFrmDoneCnt; uint32_t mFrmCnt; }; static void ContextInit(AppContext &arContext) { arContext.mpGrabber = NULL; arContext.mpFdma = NULL; arContext.mError = false; arContext.mFrmCnt = 0; arContext.mFrmDoneCnt = 0; } |
Step4:定义初始化库函数
static int32_t LibsPrepare(AppContext &arContext) { sdi::Initialize(0); arContext.mpGrabber = new(sdi_grabber); arContext.mpGrabber->ProcessSet(gpGraph, &gGraphMetadata); arContext.mpFdma = (sdi_FdmaIO*)arContext.mpGrabber->IoGet(SEQ_OTHRIX_FDMA); return 0; } |
Step5:定义初始化存储空间
static int32_t DdrBuffersPrepare(AppContext &arContext) { SDI_ImageDescriptor lFrmDesc; lFrmDesc = SDI_ImageDescriptor(WIDTH, HEIGHT, RGB888); arContext.mpFdma->DdrBufferDescSet(FDMA_IX_FDMA_0, lFrmDesc); arContext.mpFdma->DdrBuffersAlloc(DDR_BUFFER_CNT); return 0; } |
Step6:逐个调用上述初始化函数
static int32_t Prepare(AppContext &arContext) { ContextInit(arContext); LibsPrepare(arContext); DdrBuffersPrepare(arContext); arContext.mpGrabber->PreStart(); arContext.mpGrabber->SeqEventCallBackInstall(NULL, &arContext); return 0; } |
Step7:定义程序运行主体函数
static int32_t Run(AppContext &arContext) { io::FrameOutputV234Fb lDcuOutput( WIDTH, HEIGHT, io::IO_DATA_DEPTH_08, CHNL_CNT); arContext.mpGrabber->Start(); SDI_Frame lFrame; for(;;) { lFrame = arContext.mpGrabber->FramePop(); arContext.mFrmCnt++; lDcuOutput.PutFrame(lFrame.mUMat); arContext.mpGrabber->FramePush(lFrame); } return 0; } |
Step8:定义程序退出清理函数
static int32_t Cleanup(AppContext &arContext) { arContext.mpGrabber->Stop(); arContext.mpGrabber->Release(); delete(arContext.mpGrabber); arContext.mpGrabber = NULL; sdi::Close(0); } |
Step9:定义程序 main 主函数
int main(int, char **) { AppContext lContext; Prepare(lContext); Run(lContext); Cleanup(lContext); } |
Step10:切换到 C/C++ 视图,并保存所有源文件的修改
在编译按钮处选择 1 A53 选项,对 ISP APP Project 进行编译
编译完成后生成 isp_app_test.elf 可执行文件
二、Demo程序的运行
通过 S32 DS 工具生成可执行文件 isp_app_test.elf。下面介绍如何将该可执行文件运行到 Demo 板上面。
Step1:先将 isp_app_test.elf 文件复制到 S32V 根文件对应目录下面
Step2:修改可执行文件的权限
Step3:连接好 Demo 板硬件环境,启动进入到命令行模式,进入可执行文件所在目录
Step4:运行 Demo 程序
运行显示的效果如下图所示:
The end
大联大旗下世平集团 ATU 部门可以提供相关设计方案和技术支持,需要请联系 atu.cn@wpi-group.com
评论