移远通信SC200L芯片Linux平台摄像头应用开发

一、交叉编译器        

        

        对于Linux平台的开发,官方只提供了yocto工程的源码,没有SDK,yocto工程也不能制作SDK包,可能是我自己的问题,最后只能在yocto中自建layer来进行开发。

        由于官方源码编译采用arm-unisoc-linux-gnueabi-gcc,32位arm,所以整个软件包工程均为32位,包括生成的镜像。源码中有一个aarch64的交叉编译链安装脚本,好像是用来做chipram的编译。

        

        对于简单的应用开发,可以使用linaro提供的arm-linux-gnueabihf来做交叉编译,但是对于依赖较多的复杂应用,例如摄像头开发,需要sysroot的支持。因此本次实验需要在yocto工程中新建自己的meta来实现,根据源码中已经编译过的库来进行编译。

二、源码移植

        开发板的主摄像头为三星的s5k4h7,出厂源码烧录至开发板后,/dev目录下看不到video设备:

        使用常规的USB方式open系统调用无法打开,因为确实没有这个设备节点。使用官方提供的摄像头demo却可以正常运行,拍照和视频都可以。

        翻看源码后发现,demo程序封装了一个V4l2AdapterInterface的接口:

class V4l2AdapterInterface {
  public:
    virtual ~V4l2AdapterInterface(){};
    virtual int open(const char *__path, int __flags) = 0;
    virtual long ioctl(int fd_, unsigned long request, void *argp) = 0;
    virtual void *mmap(void *addr, size_t length, int prot, int flags, int fd,
                       off_t offset) = 0;
    virtual int munmap(void *addr, size_t length) = 0;
    virtual int poll(struct pollfd *fds, nfds_t nfds, int timeout) = 0;
    virtual int close(int __flags) = 0;
    virtual int write_i2c_t(int fd_, void *reg, int count) {
        return this->write_i2c_t(fd_, reg, count);
    };
    virtual int read_i2c(int fd_, unsigned short reg_addr) {
        return this->read_i2c(fd_, reg_addr);
    };

    template<class T,int N> int write_i2c(int fd_, T (&array)[N]){
        int count = 0;
        for(int i=0;i<N;i++) {
            if(!array)
              break;
            if(!((struct sensor_reg_info)array[i]).reg_addr &&
               !((struct sensor_reg_info)array[i]).reg_value)
              continue;
            count++;
        }
        return write_i2c_t(fd_, (void *)array, count);
    };
    const char *name_;
};

class V4l2Client {
  public:
    V4l2Client(const char *name);
    virtual ~V4l2Client() {}

    static V4l2AdapterInterface *create();
    static void registerType(V4l2Client *factory);
    const std::string &name() const { return name_; }

  private:
    virtual V4l2AdapterInterface *createInstance();
    std::string name_;
};
class V4l2Adapter : public V4l2AdapterInterface {
public:
  V4l2Adapter() { std::cout << "constructor V4l2Adapter" << std::endl; }
  ~V4l2Adapter() { std::cout << "deconstructor  ~V4l2Adapter" << std::endl; }
  int open(const char *__path, int __flags) { return ::open(__path, __flags); }
  long ioctl(int fd_, unsigned long request, void *argp) {
    return ::ioctl(fd_, request, argp);
  }
  void *mmap(void *addr, size_t length, int prot, int flags, int fd,
             off_t offset) {
    return mmap(addr, length, prot, flags, fd, offset);
  }

  int munmap(void *addr, size_t length) {
      return munmap(addr, length);
  }

  int poll(struct pollfd *fds, nfds_t nfds, int timeout) {
    return poll(fds, nfds, timeout);
  }

  int close(int __flags) {
    return close(__flags);
  }
};

        这个接口也只是对常用的几个系统调用做了封装,并没有施加什么魔法,我引入这个头文件重新封装了自己的app,结果还是不行,依然无法打开,于是直接复制源码到自己的meta中,干脆在源码上做修改。

         不改变最基本的摄像头开发框架,只在数据读取时,根据需要写入文件即可。先快速编写一个应用,再去深入了解每一个ioctl操作。

        网上有很多开发框可参考,例如:

手把手教你使用linux摄像头(V4L2框架)_linux摄像头 v4l2-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/small_po_kid/article/details/119913184

三、数据格式

         需要注意camera支持的pixelformat,也就是数据流格式,大部分摄像头都支持YUV 4:2:0格式,参数为 V4L2_PIX_FMT_YUV420,部分camera支持 V4L2_PIX_FMT_MJPEG 直接导出jpg图片。如果是YUV格式可能会需要转码至RGB色彩空间,编码为jpg图片方便其他设备打开,可参考:yuv420p转jpg linux(纯C语言实现) - quinncy - 博客园 (cnblogs.com)icon-default.png?t=N7T8https://www.cnblogs.com/zhq-blog/p/8832157.html

        最后生成的yuv文件可用 YUView 软件打开,github上开源的。

       

四、编译烧录

        bb文件的编写可以参考yocto官方的指南,复制其他bb文件做简单的修改,边用边学上手较快。注意更改 SRC_URI 源码路径,S工作路径位于build目录temp文件夹下,根据需要自行修改。

         我的bb文件中只实现了makefile的调用,makefile根据源码中的做了部分修改,install的路径也做了修改,方便push到开发板。

       

编译时只需要添加 -b 参数来指定单个bb文件编译即可。

五、总结

        网上很少有移远通信智能模组相关的社区讨论与学习资料(毕竟正经学生谁玩移远), 本篇博客在于学习记录与提供应用开发的思路,很多知识没有细讲,我也是Linux新鸟,欢迎广大读者交流学习。

  • 25
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

plmm烟酒僧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值