基于2.6.35内核的OV9650摄像头驱动移植


分类: ARM Linux设备驱动   64人阅读  评论(0)  收藏  举报

基于2.6.35内核的OV9650摄像头驱动移植

作者:冯利美,华清远见嵌入式学院讲师。

一、 移植环境:

【移植环境】

1、 主机:Ubuntu 10.10发行版

2、 目标机:FS_S5PC100平台

3、 交叉编译工具:arm-none-linux-gnueabi-4.5.1

4、 摄像头模块:OV9650

5、Linux文件系统:rootfs. cramfs.

6、内核:linux-2.6.35-farsigt

二、 内核配置

1.修改vi drivers/i2c/busses/Kconfig

(参考实验二十六 I2C驱动编写及测试)

修改

config I2C_S3C2410
                tristate "S3C2410 I2C Driver"
                depends on ARCH_S3C2410 || ARCH_S3C64XX
                help
                        Say Y here to include support for I2C controller in the
                        Samsung S3C2410 based System-on-Chip devices.

为:

config I2C_S3C2410
                tristate "S3C2410 I2C Driver"
                depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100
                help
                        Say Y here to include support for I2C controller in the
                        Samsung S3C2410 based System-on-Chip devices.

2.内核配置并重新编译内核
        $ make menuconfig
         Device Drivers --->
                <*> I2C support --->
                        <*> I2C device interface
                                I2C Hardware Bus support --->
                                        <*> S3C2410 I2C Driver

3.修改vi arch/arm/mach-s5pc100/mach-smdkc100.c

查看原理图可以知道我们的摄像头是接在I2C-1上所以修改i2c_devs1添加ov9650的内容,主要是ov9650的地址,这个在芯片手册上可以查到是0x30

修改:
        static struct i2c_board_info i2c_devs1[] __initdata = {
        };

为:
        static struct i2c_board_info i2c_devs1[] __initdata = {
                {
                I2C_BOARD_INFO("ov9650", 0x30),
                },
        };

添加s5pc100 摄像头控制器平台设备相关内容,这些内容我们可以通过查看S5PC100的芯片手册查到
        static struct resource s3c_camif_resource[] = {
                [0] = {
                        .start = 0xEE200000,
                        .end = 0xEE200000 + SZ_1M - 1,
                        .flags = IORESOURCE_MEM,
                },
                [1] = {
                        .start = IRQ_FIMC0,
                        .end = IRQ_FIMC0,
                        .flags = IORESOURCE_IRQ,
                }

};

static u64 s3c_device_camif_dmamask = 0xffffffffUL;

struct platform_device s3c_device_camif = {
                 .name = "s5pc100-camif",
                .id = 0,
                .num_resources = ARRAY_SIZE(s3c_camif_resource),
                 .resource = s3c_camif_resource,
                 .dev = {
                         .dma_mask = &s3c_device_camif_dmamask,
                         .coherent_dma_mask = 0xffffffffUL
                 }
         };

EXPORT_SYMBOL(s3c_device_camif);

注册摄像头控制平台设备:

在smdkc100_devices中添加s3c_device_camif
        static struct platform_device *smdkc100_devices[] __initdata = {
                &s3c_device_camif, //添加内容
        };

4. 添加驱动(video)
        Make menuconfig
         Device Drivers ---> 
                <*> Multimedia support --->
                         <*> Video For Linux 
         [*] Enable Video For Linux API 1 (DEPRECATED) (NEW)
         [*] Video capture adapters (NEW) --->
         [*] V4L USB devices (NEW) ---> 
        <*> USB Video Class (UVC) 
         [*] UVC input events device support (NEW)
         <*> USB ZC0301[P] webcam support (DEPRECATED)

三、 驱动编写

四、 网络视频服务器移植

对于内核linux-2.6.35,不能再使用servfox,如果要使用的需要修改大量的代码,在此选用新的方法来移植。需要两个文件jpeg,mjpg-stream.移植如下:

mkdir /source/rootfs/mjpg

1. jpeg库的移植

mkdir /home/linux/jpeg

jpeg源码包通过下面这个网址下载

http://www.ijg.org/files/jpegsrc.v8b.tar.gz

解压源码包

tar xvf jpegsrc.v8b.tar.gz

配置源码

cd jpeg-8b
        ./configure --prefix=/home/linux/jpeg --host=arm-none-linux-gnueabi
        ./configure --prefex=/home/linux/jpeg --host=arm-none-linux-gnueabi

(./configure 配置源代码树 
        安装目录:
        --prefix=PREFIX
        体系无关文件的顶级安装目录PREFIX ,也就Apache的安装目录。[/usr/local/apache2]

系统类型:
        --host=HOST

指定Apache HTTP服务器将要运行的目标系统类型HOST 。

[BUILD]

)

编译

make

安装

make install

拷贝库到文件系统中

cp /home/linux/jpeg/lib/libjpeg.so.8 /source/rootfs/lib

2. mjpg-stream的移植

mjpg-stream源码包通过下面这个网址下载
        http://sourceforge.net/projects/mjpg-streamer/

解压源码

tar xvf mjpg-streamer-r63.tar.gz

修改源码

cd mjpg-streamer-r63

修改顶层makefile及plugins目录中的各级makefile将所有 (注意这里需要修改的内容)

CC=gcc

修改为

cc=arm-none-linux-gnueabi-gcc

修改plugins/input_uvc/Makfile

修改

CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC

CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared –fPIC –I/homw/linux/jpeg/include

修改

$(CC) $(CFLAGS) -ljpeg -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo

$(CC) $(CFLAGS) -ljpeg -L/home/linux/jpeg/lib -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo

3. 拍照功能的实现

由于mjpg_stream中output-file.so能实现连续拍照的功能,不能实现单拍或连拍几张的功能所以需要对output_file原码进行修改。
         # cd mjpg-streamer-rc63/plugins/output_file
        # vim output_file.c
        在96行 函数 void *worker_thread(void *arg) 体中加入以下代码:
        char buf[10]; //用于存放从管道读取的命令
        int flags = 0; //拍照标志,1:表示11张照片,2:表示1张照片
        int fd_com = 0; //打开管道的文件描述符

stop_num = 0; //拍照计数
        if ( access(“/tmp/webcom”,F_OK) < 0 ) //创建有名管道用于接收拍照命令
        {
        if ( mkfifo(“/tmp/webcom”,0666 ) < 0)
        {
        Printf(“ photo fifo create failed\n”);
        }
        }
        fd_com = open (“/tmp/webcom”,O_RDONLY,0666);
        if (fd < 0)
        {
        perror (“open the file webcom error”);
        }

在while( ok >= 0 && !pglobal->stop){ 后加入
        if (flags == 0)
        {
        while(1)
        {
        reade(fd_com,buf,sizeof(buf));
        if (strncmp(buf,”danger”,6) == 0) //拍11张照片
        {
        flags = 1;
        bzero(buf,sizeof(buf));
        break;
         }
        if (strncmp(buf,”one”,3) == 0) //拍1张照片
        {
        flags = 2;
        bzero(buf,sizeof(buf));
        break;
        }

}
        }

在if (delay > 0){
        usleep(1000*delay);
        }后加入
        stop_num++
        if (flags == 1) //判断拍照的数量
        {
         if ( stop_num > 9)
        {
        stop_num = 0;
        flsgs = 0;
        }
         }
         else if (flags == 2)
         {
         stop_num = 0;
         flags = 0;
        }

编译

(make clean)
        Make
        mkdir /source/rootfs/pice
        mkdir /source/rootfs/mjpg
        cp *.so /source/rootfs/mjpg
        cp mjpg_streamer /source/rootfs/bin
        cp /home/linux/newyizhi_first/toolchain/arm-2010.09/arm-none-linux-gnueabi/libc/lib/* /source/rootfs/lib/

4. 将摄像头驱动s5pc100_cam.ko拷贝到 /source/rootfs目录下

所以只要向有名管道/tmp/webcom写入danger就能连拍11张照片,写入one就拍一张照片。

执行命令:
        mjpg_streamer -i "/mjpg/input_uvc.so -y" -o "/mjpg/output_file.so -f /pice -d 1000 " &

拍照一张:
        echo one > /tmp/webcom

五、 文件系统的制作

支持U盘自动挂载,需做以下步骤:

1、下载UDEV源码udev-080.tar.bz2,网址:

http://www.us.kernel.org/pub/linux/utils/kernel/hotplug/,并解压。

2、交叉编译。

修改Makefile,具体修改如下:

CROSS = arm-none-linux-gnueabi-

保存退出。

修改udevmointer.c,添加 #include <stddef.h>

执行命令:make 进行编译,然后执行arm-none-linux-gnueabi-strip udev udevd udevstart udevinfo udevtest。并拷贝这些文件到rootfs/bin目录下面。

3、修改/source/rootfs/etc/fstab为
         #device mount-point type options dump fsck order
        proc /proc proc defaults 0 0
        tmpfs /tmp tmpfs defaults 0 0
        sysfs /sys sysfs defaults 0 0 
        tmpfs /dev tmpfs defaults 0 0

4、修改/source/rootfs/etc/init.d/rcS,添加如下内容

/bin/udevd --daemon

/bin/udevstart

这样当我们插上U盘和SD卡的时候,就可以看到我们的设备节点而不需要手动创建设备节点。

5、SD卡或U盘自动挂载的实现

拷贝实验代码中udev目录到 /source/rootfs/etc

拷贝mount-sd.sh、 umount-sd.sh 、mount-usb.sh、lh到rootfs/sbin下

这个时候当插入U盘或SD卡时就会自动挂载在tmp下。可以通过修改mount-sd.sh和mount-usb.sh添加其他功能和修改挂载点。

六、 移植过程中出现的相关问题及解决:

1、 移植streamer的过程中 make出现 无法找到ljpeg库的问题

解决:查看 jpeg—lib 目录下 file libjpeg.so.8.0.2 是否是ARM体系

如果是386的,可能交叉编译工具链的问题,建议拷贝其他可用的jpeg库。

2、出现Init V4L2 failed opening V4L interface:NO such file

如果内核配置正确,一般都会支持V4L2, 我重启之后就再也没有出现这个问题

3.、streamer snapshot 未能正常显示

请确定加 –y 指令

如果在Window下正在使用viewer.exe 软件测试streamer,先关闭或者暂停该软件,然后再在浏览器中输入。。。。。测试

4、摄像头显示的内容是红色

因为内核里,没有配置I2C的驱动

5、拍照测试程序,拍摄前7张时不能正常显示

尚待解决

V4L2的使用说明

请参看 “相关资料”——“摄像头相关资料(v4l2)”

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值