最近刚新买了一个中星微芯片zc0301p的摄像头,碰到了一些问题,如下:
PC平台:装了3系统,SUSE Linux 9.3(2.6核),Red Hat Linux 9(2.4.20-8),Windows XP
嵌入式平台:华恒HHARM9-EDU-R2
1.首先在嵌入式平台试了spca5xx-LE驱动,可以驱动。移植的Servfox可以工作,spcaview可以接收到图像,但会掉帧。但这还不是首要问题。
2.用spca5xx-LE驱动时,我自己写的程序无法使用,运行到设置图像格式(RGB565或RGB24)时出错,说不支持此参数。原因在于:(摘自驱动程序主页http://mxhaard.free.fr/spca5le.html)
The spca5xx-LE design is very different from the spca5xx full package(LE版的驱动和完全版的差很多)。
The memory in use are the most smaller as possible(LE版的驱动会尽量减少内存的使用)
The spcadecoder is reduce and only raw jpeg webcam are used.(驱动模块只支持输出原始jpeg格式,my god!)
3.明显LE的驱动不符合我的要求。我所要做的是:我已经有了自己的摄像头应用程序,只想在驱动方面多支持一些市面上常用摄像头。(如果只能支持现在已经基本灭绝的几款摄像头,那还有什么意义,不过实在不行也没办法就是了)
4.那么只能移植完整版的驱动到实验箱了。问题来了,按照spca5xx完整版的INSTALL安装指南,在SuSE 9.3上轻松编译安装(也就只是make;make install而已)。用我自己写的程序测试可以驱动并成功截图,但分辨率不支持240x240(shit!难道我还得改实验箱上弄好的程序),只支持640x480和320x240,并且240x320也不支持。难道要把输出的320x240图像,旋转90度,再显示在lcd上,那可真够麻烦的。
5.试着做了一下:安装指南里并没有讲如何移植,难道只要在编译的时候指定gcc为armv4l-unknown-gcc就可以?(试过,失败)或者像LE版驱动一样,复制到usb驱动文件夹,建个spca5xx文件夹,修改makefile和config.in?(试过,仍然不行,make modules可以生成驱动模块,但insmod时出错,说找不到支持的核心版本),谁能给出一个详细的移植过程(要的是完整版的spca5xx驱动)
6.在Red Hat9上编译失败(解决办法在后面,但是我并没有去试,因为我的SuSE已经可以用了),原因在于:
这里引用一个大牛的说法(原文连接http://blog.wulei.net/2006/04/10/62.html#more-62):"RedHat 的内核是非标准内核,他将 remap_page_range从4个参数擅自更改为5个参数。然而这5个参数的remmap_page_range是内核2.5.0中使用的 ,2.6中也已经弃用了。换句话说,就是RedHat linux己制造了不兼容!!!感觉这种手段和xxx何其相似!!!在此严重鄙视一下Redhat.也就是如果你选择了redhat的产品,要么掏钱去请求其服务,要么自己解决问题。而隔绝了和其他linux社区的帮助。于是我决定抛弃其提供的内核,升级到标准内核。于是,开始疯狂的下载内核,编译内核,试图通过这种方式来解决这个不兼容的问题。我尝试 redhat自己的2.4.21的更高版本2.4.21-40.EL, 但是编译spca之后发现出现的错误更加多, 说明现在redhat自己的内核已经离标准愈来愈远了。太息之余,我想试试标准的内核能否工作。我于是在kernel.org下载并编译了2.4.32和2.4.31,这两个内核都可以完全正确的编译spca5xx 驱动。但是严重的是,我的其他软件变的非常不稳定,而且系统自带的mysql和我的XFree86完全启动不了。这再次印证了RedHat的非标准作风。证实了其试图将用户帮定在其平台的野心。我决心以后一定皈依到debian门下。但是我目前还得想办法解决。"
请继续看:"通过阅读我有了一个重要的发现在05年初期的开发版中,很多人都说只要将RH9_REMMAP宏定义打开就可以了。于是我决定试试这个时候的版本。于是下载了spca5xx20050111版本,结果出乎我意料,真的可以运行了!!!但是,效果非常差。没有我实验的在2.6内核下的那么好。但是我终于有了一个可用的版本。现在有好的开始了。我终于能找到门路了。我只要从这个版本开始跟踪开发,就能知道到底是什么导致了在我们的系统上不能成功。于是我陆续下载了20050319和20050419,结果发现前者是可以运行的,后者开始出错。好了,我现在十分满意,通过对这两个版本的比较,我就能搞清楚问题所在了。"
原因真相大白:"于是我通过emacs的ediff对比阅读了这两个版本的spca5xx.c文件。原来不光是remap_page_range这一个函数的问题,而是围绕这个问题的一些程序的架构。估计是从20050419以后由于大部分人都从redhat 9转到了Fedra结果着个问题就不重要了,因此该驱动在redhat下的分支已经没有人维护了,才导致了代码的不兼容。"
解决方法:此大牛提供了一个patch,放在最后吧,需要注意的是他的系统是redhat企业版,内核:2.4.21-4.EL i686,不过spca5xx在sourceforge也提供了它的解决方法,如下:
Q:I'm using Redhat 9, and the driver won't compile!(我用Redhat9,但驱动无法成功编译)
A:This problem is caused by the fact that Redhat has tweaked the default kernel included in Redhat 9(redhat公司修改了默认的内核), to solve this problem get different kernel(想要解决这个问题,要么下载新的内核(源代码)), or do this:(要么只能……自己看吧)
Download the CVS version of the driver, and add #define RH9_REMAP 1 to the top of spca50x.c. then compile and install.
原文连接http://spca50x.sourceforge.net/spca50x.php?page=faq#5
=========================================================================
总结如下:
1.我需要完整版的spca5xx驱动详细的移植过程(如果你有耐心看到这里,就一定有耐心再写一篇文章出来,大侠们,快点跳出来吧)
2.spca5xx-LE驱动只支持输出jpeg格式图像
3.许多2.6核的linux系统编译spca5xx完整版会很顺利(有些甚至直接就支持)
4.Red hat 9编译完整版spca5xx时,版本号在20050319之前的可能不会出错(但效果很差),而之后的会出错。
出错有解决办法(并且这些方法没有经过我自己的验证,所以不保证能用):第一种方法:去www.kernel.org下载官方的核心源代码编译。第二种方法:spca5xx开发站点提供的做法Download the CVS version of the driver, and add #define RH9_REMAP 1 to the top of spca50x.c. then compile and install. 第三种方法:把下面的内容(源自http://blog.wulei.net/2006/04/10/62.html#more-62)存成spca5xx20060402.patch,然后将该文件放在解压后的spca5xx20060402/目录下,执行patch -p1 < spca5xx20060402.patch
========================================================================
diff -rc spca5xx-20060402/drivers/usb/spca5xx.c spca5xx-20060402-wu/drivers/usb/spca5xx.c
*** spca5xx-20060402/drivers/usb/spca5xx.c2006-04-03 03:33:50.000000000 +0800
--- spca5xx-20060402-wu/drivers/usb/spca5xx.c2006-04-10 18:05:48.000000000 +0800
***************
*** 81,86 ****
--- 81,91 ----
#endif
//#define RH9_REMAP 1
+ #if defined(RHEL3)
+ #ifndef RH9_REMAP
+ #define RH9_REMAP 1
+ #endif
+ #endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
#include "spcaCompat.h"
***************
*** 1174,1180 ****
{
void *mem;
unsigned long adr;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23)
unsigned long page;
#endif
size = PAGE_ALIGN(size);
--- 1179,1185 ----
{
void *mem;
unsigned long adr;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) && !defined(RHEL3)
unsigned long page;
#endif
size = PAGE_ALIGN(size);
***************
*** 1188,1194 ****
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 68)
SetPageReserved(vmalloc_to_page((void *) adr));
#else
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 23)
mem_map_reserve(vmalloc_to_page((void *) adr));
#else
page = kvirt_to_pa(adr);
— 1193,1199 —-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 68)
SetPageReserved(vmalloc_to_page((void *) adr));
#else
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,23) || defined(RHEL3)
mem_map_reserve(vmalloc_to_page((void *) adr));
#else
page = kvirt_to_pa(adr);
***************
*** 1205,1211 ****
static void rvfree(void *mem, unsigned long size)
{
unsigned long adr;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23)
unsigned long page;
#endif
if (!mem)
--- 1210,1216 ----
static void rvfree(void *mem, unsigned long size)
{
unsigned long adr;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) && !defined(RHEL3)
unsigned long page;
#endif
if (!mem)
***************
*** 1216,1222 ****
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 68)
ClearPageReserved(vmalloc_to_page((void *) adr));
#else
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 23)
mem_map_unreserve(vmalloc_to_page((void *) adr));
#else
page = kvirt_to_pa(adr);
— 1221,1227 —-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 68)
ClearPageReserved(vmalloc_to_page((void *) adr));
#else
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,23) || defined(RHEL3)
mem_map_unreserve(vmalloc_to_page((void *) adr));
#else
page = kvirt_to_pa(adr);
***************
*** 3869,3875 ****
spin_unlock_irqrestore(&spca50x->v4l_lock, flags);
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int spca5xx_open(struct inode *inode, struct file *file)
{
struct video_device *vdev = video_devdata(file);
— 3874,3880 —-
spin_unlock_irqrestore(&spca50x->v4l_lock, flags);
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
static int spca5xx_open(struct inode *inode, struct file *file)
{
struct video_device *vdev = video_devdata(file);
***************
*** 3912,3918 ****
spca5xx_setFrameDecoder(spca50x);
spca50x->user++;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
file->private_data = vdev;
#endif
err = spca50x_init_isoc(spca50x);
— 3917,3923 —-
spca5xx_setFrameDecoder(spca50x);
spca50x->user++;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
file->private_data = vdev;
#endif
err = spca50x_init_isoc(spca50x);
***************
*** 3922,3928 ****
spca5xx_kill_isoc(spca50x);
up(&spca50x->lock);
spca5xx_dealloc(spca50x);
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
file->private_data = NULL;
#endif
goto out2;
— 3927,3933 —-
spca5xx_kill_isoc(spca50x);
up(&spca50x->lock);
spca5xx_dealloc(spca50x);
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
file->private_data = NULL;
#endif
goto out2;
***************
*** 3978,3984 ****
}
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int spca5xx_close(struct inode *inode, struct file *file)
{
— 3983,3989 —-
}
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
static int spca5xx_close(struct inode *inode, struct file *file)
{
***************
*** 4017,4023 ****
MOD_DEC_USE_COUNT;
#endif
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
file->private_data = NULL;
return 0;
#endif
— 4022,4028 —-
MOD_DEC_USE_COUNT;
#endif
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
file->private_data = NULL;
return 0;
#endif
***************
*** 4037,4043 ****
return 0;
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int
spca5xx_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
void *arg)
— 4042,4048 —-
return 0;
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
static int
spca5xx_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
void *arg)
***************
*** 4058,4064 ****
switch (cmd) {
case VIDIOCGCAP:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_capability *b = arg;
#else
struct video_capability j;
— 4063,4069 —-
switch (cmd) {
case VIDIOCGCAP:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_capability *b = arg;
#else
struct video_capability j;
***************
*** 4076,4082 ****
b->minwidth = spca50x->minwidth;
b->minheight = spca50x->minheight;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, b, sizeof(struct video_capability)))
return -EFAULT;
#endif
--- 4081,4087 ----
b->minwidth = spca50x->minwidth;
b->minheight = spca50x->minheight;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, b, sizeof(struct video_capability)))
return -EFAULT;
#endif
***************
*** 4085,4091 ****
}
case VIDIOCGCHAN:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_channel *v = arg;
#else
struct video_channel k;
— 4090,4096 —-
}
case VIDIOCGCHAN:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_channel *v = arg;
#else
struct video_channel k;
***************
*** 4148,4154 ****
v->flags = 0;
v->tuners = 0;
v->type = VIDEO_TYPE_CAMERA;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, v, sizeof(struct video_channel)))
return -EFAULT;
#endif
--- 4153,4159 ----
v->flags = 0;
v->tuners = 0;
v->type = VIDEO_TYPE_CAMERA;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, v, sizeof(struct video_channel)))
return -EFAULT;
#endif
***************
*** 4163,4169 ****
of video_channel is an int channel number
and we just ignore the rest
*/
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_channel *v = arg;
#else
struct video_channel k;
— 4168,4174 —-
of video_channel is an int channel number
and we just ignore the rest
*/
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_channel *v = arg;
#else
struct video_channel k;
***************
*** 4184,4190 ****
}
case VIDIOCGPICT:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_picture *p = arg;
#else
struct video_picture p1;
— 4189,4195 —-
}
case VIDIOCGPICT:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
struct video_picture *p = arg;
#else
struct video_picture p1;
***************
*** 4327,4333 ****
}
}
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, p, sizeof(struct video_picture)))
return -EFAULT;
#endif
--- 4332,4338 ----
}
}
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, p, sizeof(struct video_picture)))
return -EFAULT;
#endif
***************
*** 4337,4343 ****
case VIDIOCSPICT:
{
int i;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_picture *p = arg;
#else
struct video_picture p1;
— 4342,4348 —-
case VIDIOCSPICT:
{
int i;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
struct video_picture *p = arg;
#else
struct video_picture p1;
***************
*** 4555,4561 ****
}
case VIDIOCSCAPTURE:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_capture *vc = arg;
#else
struct video_capture vc1;
— 4560,4566 —-
}
case VIDIOCSCAPTURE:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
struct video_capture *vc = arg;
#else
struct video_capture vc1;
***************
*** 4574,4580 ****
case VIDIOCSWIN:
{
int result;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_window *vw = arg;
#else
struct video_window vw1;
— 4579,4585 —-
case VIDIOCSWIN:
{
int result;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_window *vw = arg;
#else
struct video_window vw1;
***************
*** 4632,4638 ****
}
case VIDIOCGWIN:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_window *vw = arg;
#else
struct video_window vw1;
— 4637,4643 —-
}
case VIDIOCGWIN:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_window *vw = arg;
#else
struct video_window vw1;
***************
*** 4647,4653 ****
vw->flags = 0;
PDEBUG(4, “VIDIOCGWIN: %dx%d”, vw->width, vw->height);
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, vw, sizeof(struct video_capture)))
return -EFAULT;
#endif
--- 4652,4658 ----
vw->flags = 0;
PDEBUG(4, “VIDIOCGWIN: %dx%d”, vw->width, vw->height);
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, vw, sizeof(struct video_capture)))
return -EFAULT;
#endif
***************
*** 4656,4662 ****
}
case VIDIOCGMBUF:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_mbuf *vm = arg;
#else
struct video_mbuf vm1;
— 4661,4667 —-
}
case VIDIOCGMBUF:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
struct video_mbuf *vm = arg;
#else
struct video_mbuf vm1;
***************
*** 4671,4677 ****
for (i = 0; i < SPCA50X_NUMFRAMES; i++) {
vm->offsets[i] = MAX_DATA_SIZE * i;
}
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, vm, sizeof(struct video_mbuf)))
return -EFAULT;
#endif
--- 4676,4682 ----
for (i = 0; i < SPCA50X_NUMFRAMES; i++) {
vm->offsets[i] = MAX_DATA_SIZE * i;
}
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, vm, sizeof(struct video_mbuf)))
return -EFAULT;
#endif
***************
*** 4681,4687 ****
case VIDIOCMCAPTURE:
{
int ret, depth;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_mmap *vm = arg;
#else
struct video_mmap vm1;
— 4686,4692 —-
case VIDIOCMCAPTURE:
{
int ret, depth;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_mmap *vm = arg;
#else
struct video_mmap vm1;
***************
*** 4816,4822 ****
case VIDIOCSYNC:
{
int ret;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
unsigned int frame = *((unsigned int *) arg);
#else
unsigned int frame;
— 4821,4827 —-
case VIDIOCSYNC:
{
int ret;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
unsigned int frame = *((unsigned int *) arg);
#else
unsigned int frame;
***************
*** 4875,4881 ****
}
case VIDIOCGFBUF:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_buffer *vb = arg;
#else
struct video_buffer vb1;
— 4880,4886 —-
}
case VIDIOCGFBUF:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_buffer *vb = arg;
#else
struct video_buffer vb1;
***************
*** 4883,4889 ****
#endif
memset(vb, 0, sizeof(struct video_buffer));
vb->base = NULL;/* frame buffer not supported, not used */
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, vb, sizeof(struct video_buffer)))
return -EFAULT;
#endif
--- 4888,4894 ----
#endif
memset(vb, 0, sizeof(struct video_buffer));
vb->base = NULL;/* frame buffer not supported, not used */
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, vb, sizeof(struct video_buffer)))
return -EFAULT;
#endif
***************
*** 4892,4898 ****
}
case SPCAGVIDIOPARAM:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_param *vp = arg;
#else
struct video_param vp1;
— 4897,4903 —-
}
case SPCAGVIDIOPARAM:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_param *vp = arg;
#else
struct video_param vp1;
***************
*** 4901,4907 ****
vp->autobright = (__u8) spca50x->autoexpo;
vp->quality = (__u8) spca50x->qindex;
vp->time_interval = (__u16) spca50x->dtimes;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, vp, sizeof(struct video_param)))
return -EFAULT;
#endif
--- 4906,4912 ----
vp->autobright = (__u8) spca50x->autoexpo;
vp->quality = (__u8) spca50x->qindex;
vp->time_interval = (__u16) spca50x->dtimes;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, vp, sizeof(struct video_param)))
return -EFAULT;
#endif
***************
*** 4910,4916 ****
case SPCASVIDIOPARAM:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_param *vp = arg;
#else
struct video_param vp1;
— 4915,4921 —-
case SPCASVIDIOPARAM:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_param *vp = arg;
#else
struct video_param vp1;
***************
*** 4957,4963 ****
return 0;
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int
spca5xx_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
— 4962,4968 —-
return 0;
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
static int
spca5xx_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
***************
*** 4974,4987 ****
#endif
rc = video_usercopy(inode, file, cmd, arg, spca5xx_do_ioctl);
#if 0
! /* see 7 lines up */ */
up(&spca50x->lock);
#endif
return rc;
}
#endif
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static ssize_t
spca5xx_read(struct file *file, char *buf, size_t cnt, loff_t * ppos)
{
— 4979,4992 —-
#endif
rc = video_usercopy(inode, file, cmd, arg, spca5xx_do_ioctl);
#if 0
! /* see 7 lines up */
up(&spca50x->lock);
#endif
return rc;
}
#endif
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)||defined(RHEL3)
static ssize_t
spca5xx_read(struct file *file, char *buf, size_t cnt, loff_t * ppos)
{
***************
*** 5089,5095 ****
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int spca5xx_mmap(struct file *file, struct vm_area_struct *vma)
{
— 5094,5100 —-
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
static int spca5xx_mmap(struct file *file, struct vm_area_struct *vma)
{
***************
*** 5144,5150 ****
return 0;
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION (2,4,22)
static struct file_operations spca5xx_fops = {
.owner = THIS_MODULE,
.open = spca5xx_open,
— 5149,5155 —-
return 0;
}
! #if LINUX_VERSION_CODE >= KERNEL_VERSION (2,4,22) || defined(RHEL3)
static struct file_operations spca5xx_fops = {
.owner = THIS_MODULE,
.open = spca5xx_open,
***************
*** 8458,8464 ****
}
! #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
static struct usb_driver spca5xx_driver = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
.owner = THIS_MODULE,
--- 8463,8469 ----
}
! #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) || defined(RHEL3)
static struct usb_driver spca5xx_driver = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
.owner = THIS_MODULE,
***************
*** 8470,8476 ****
};
#else
static struct usb_driver spca5xx_driver = {
! #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)
THIS_MODULE,
#endif
“spca5xx”,
— 8475,8481 —-
};
#else
static struct usb_driver spca5xx_driver = {
! #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,23)||defined(RHEL3)
THIS_MODULE,
#endif
“spca5xx”,
Only in spca5xx-20060402-wu/drivers/usb: spca5xx.c~
diff -rc spca5xx-20060402/Makefile spca5xx-20060402-wu/Makefile
*** spca5xx-20060402/Makefile2006-04-03 04:27:03.000000000 +0800
— spca5xx-20060402-wu/Makefile2006-04-10 18:14:27.000000000 +0800
***************
*** 32,37 ****
— 32,38 —-
# Setup defines
DEFINES += -DCONFIG_USB_SPCA5XX_MODULE=1 -DMODULE -D__KERNEL__
DEFINES += -DVID_HARDWARE_SPCA5XX=0xFF -DSPCA5XX_VERSION=”$(VERSION)”
+ DEFINES += -DRHEL3
ifneq ($(shell uname -r | cut -d. -f1,2), 2.4)
Only in spca5xx-20060402-wu: Makefile~
----------------------------------
没有用过CDMA,只用过实验箱上的GPRS模块,插上动感地带的手机号码卡,pppd拨号。
拨上了之后除了慢、贵、不稳定和网络不好时会掉线以外,用tcp/ip协议传输消息、文件,与普通的以太网没区别。
感觉GPRS网用UDP协议发短一些的消息,还行,但有时还是会丢。
发文件或图像一定得用TCP协议,虽然慢了一点,但毕竟TCP有出错重传的机制。
网上的说法是:实际速度CDMA在150K左右,而GPRS在45K左右,CDMA是GPRS速度的三倍多。
但实验箱上GPRS模块实际就是一个接在串口的调制解调器,GPRS模块与串口通讯的速度为115200bps
8比特/秒bps(bits per second)= 1字节/秒Bps(bytes per second)
1024 Bps = 1 KBps
115200bps/8/1024=14KB/s,虽然网上说的理论上的GPRS访问速度很高,但受限于串口的速度,实际速度都在10KB/s以下。
分辨率240*240,quality为50的jpeg图片大小约4KB,以1KB为单位发送的话
TCP发送的过程:
A发送端:我要传了(等接收端回应要延迟)
B接收端:传吧
A发送端:传1KB的数据(传送也要延迟)
A发送端:收到了么?(确认还要延迟)
B接收端:我收到了
发1帧图像4KB就要4次这样的过程,还没算上出错重传。再加上,10KB/s说的只是下行速度,不知道上行速度怎么样。
如此小的分辨率和如此低的图像质量,发送1帧图像要1秒吧?
大点的分辨率高点的质量,那就是:惨、惨、惨、惨不忍睹!
除非课题要求一定要用GPRS,不然我发图像和文件肯定选择用以太网。
===================================================================
综上所述:CDMA没用过,但再怎么说都比GPRS好点吧。