Ov511usb camera driver with Linux-2.4.18 kernel transplanted on S3C2410 Development Board
Content
1. Driver
2. Application writing
1. Driver
The Linux-2.4.18 is a drive with an ov511 camera by default, selected from the USB device, and activated the video option to support ov511.
2. Application writing
This is a program in MiniGUI. It can be simulated using qvfb and run on the board.
V4l. h
/*
* W3v4l. h
*
* Copyright (c) 1998-2000 Rasca, Berlin
* Email: thron@gmx.de
*
* This program is free software; you can redistribute it and/or modify
* It under the terms of the GNU General Public License as published
* The Free Software Foundation; either version 2 of the license, or
* (At your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* But without any warranty; without even the implied warranty
* Merchantability or fitness for a special purpose. See
* GNU General Public License for more details.
*
* You shoshould have written ed a copy of the GNU General Public License
* Along with this program; if not, write to the Free Software
* Foundation, inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# Ifndef _ w3v4l_h __
# DEFINE _ w3v4l_h __
Class cv4l {
Public:
Cv4l ();
Cv4l (char * szdevname );
~ Cv4l ();
Bool Init (INT channel, int width, int height );
Unsigned char * read ();
Void destroy ();
PRIVATE:
Char * szdevname;
Bool initialized;
Unsigned char * m_buff;
Int m_buffsize;
Int fdvideo;
Int m_width, m_height;
Int m_mapsize;
};
# Endif
V4l. cpp
/*
* V4l. c
*
*
* This program is free software; you can redistribute it and/or modify
* It under the terms of the GNU General Public License as published
* The Free Software Foundation; either version 2 of the license, or
* (At your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* But without any warranty; without even the implied warranty
* Merchantability or fitness for a special purpose. See
* GNU General Public License for more details.
*
* You shoshould have written ed a copy of the GNU General Public License
* Along with this program; if not, write to the Free Software
* Foundation, inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
# Include <stdio. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <fcntl. h>
# Include <sys/IOCTL. h>
# Include <sys/Mman. h>
# Include <Linux/types. h>
# Include <string. h>
# Include <Linux/videodev. h>
# Include "v4l. H"
/* V4l_init ()
* Function: init the video device
* References:
* Dev: device name.
* Input: Channel Number of video_channel structure.
* Width: width value of video_window Structure
* Height: height value of video_window Structure
*/
Bool cv4l: Init (INT channel, int width, int height)
{
Int FD;
Struct video_capability vid_caps;
Struct video_mbuf vid_mbuf;
Struct video_channel vid_chnl;
// Open the video device
FD = open (szdevname, o_rdwr );
If (FD =-1 ){
Perror (szdevname );
Return false;
}
Fdvideo = FD;
// Get video_capability structrue
If (IOCTL (FD, vidiocgcap, & vid_caps) =-1 ){
Perror ("IOCTL (vidiocgcap )");
Return false;
}
// Get the buffer information in video_mbuf Structure
// If can't use MMAP ()
If (IOCTL (FD, vidiocgmbuf, & vid_mbuf) =-1 ){
Struct video_window vid_win;
M_mapsize = 0;
// Set video window information
If (IOCTL (FD, vidiocgwin, & vid_win )! =-1 ){
Vid_win.width = width;
Vid_win.height = height;
IOCTL (FD, vidiocswin, & vid_win );
}
} Else {
M_mapsize = vid_mbuf.size;
M_buffsize = m_mapsize;
}
# Ifdef debug
Printf ("% s: mbuf. size = % d/N", _ file __, vid_mbuf.size );
# Endif
If (Channel>-1 ){
Vid_chnl.channel = channel;
If (IOCTL (FD, vidiocgchan, & vid_chnl) =-1 ){
Perror ("IOCTL (vidiocgchan )");
} Else {
Vid_chnl.channel = channel;
If (IOCTL (FD, vidiocschan, & vid_chnl) =-1 ){
Perror ("IOCTL (vidiocschan )");
}
}
}
If (m_mapsize> 0 ){
M_buff = (unsigned char *) MMAP (0, m_mapsize, prot_read | prot_write, map_shared, FD, 0 );
If (unsigned char *)-1 = (unsigned char *) m_buff ){
Perror ("MMAP ()");
Close (FD );
Return false;
}
} Else {
M_buffsize = width * height * 3;
M_buff = (unsigned char *) malloc (m_buffsize );
}
M_width = width;
M_height = height;
Return true;
}
Unsigned char
* Cv4l: Read ()
{
Struct video_mmap vid_mmap;
If (m_mapsize = 0 ){
Printf (_ file _ ": Reading image ../N ");
If (read (fdvideo, (void *) m_buff, m_buffsize) <= 0 ){
Free (m_buff );
Return (0 );
}
} Else {
Vid_mmap.format = video_palette_rgb565; // video_palette_rgb24;
Vid_mmap.frame = 0;
Vid_mmap.width = m_width;
Vid_mmap.height = m_height;
If (IOCTL (fdvideo, vidiocmcapture, & vid_mmap) =-1 ){
Perror ("IOCTL (vidiocmcapture )");
Return (0 );
}
If (IOCTL (fdvideo, vidiocsync, & vid_mmap) =-1 ){
Perror ("IOCTL (vidiocsync )");
Return (0 );
}
}
Return m_buff;
}
Void cv4l: Destroy ()
{
If (fdvideo> = 0 ){
If (m_mapsize = 0)
Free (m_buff );
Else
Munmap (m_buff, m_mapsize );
Close (fdvideo );
}
}
Cv4l: cv4l ()
{
//
}
Cv4l: cv4l (char * _ szdevname)
{
Szdevname = (char *) malloc (strlen (_ szdevname) + 1 );
Strcpy (szdevname, _ szdevname );
// Init (0, int width, int height );
//
}
Cv4l ::~ Cv4l ()
{
Destroy ();
}
Video. cpp
/*
** $ ID: helloworld. C, V 1.7 2003/06/13 07:15:49 weiym exp $
**
** Listing 2.1:
**
** Helloworld. C: Sample program for MiniGUI programming guide
** The first MiniGUI application.
**
** Copyright (c) 2003 Feynman software.
**
** License: GPL
*/
# Include <stdio. h>
# Include <MiniGUI/common. h>
# Include <MiniGUI/MiniGUI. h>
# Include <MiniGUI/GDI. h>
# Include <MiniGUI/window. h>
# Include <string. h>
# Include <malloc. h>
# Include "v4l. H"
# Define vid_w 320
# Define vid_h 240
Static bitmap BMP;
Cv4l * cvid; // "/dev/video0"
Unsigned char * Buf;
Static int COUNT = 0;
Static int xdir =-3;
Static int ydir =-3;
Static int x = 1;
Static int y = 11;
/* Bool switchbuf24tobmp 16 (unsigned char * buf24, pbitmap pbmp)
{
Mybmp. Bits = buf24;
// Expandmybitmap (hdc_screen, & BMP, & mybmp, RGB, 0 );
Printf ("BMP. bmtype = % I/N", BMP. bmtype );
Printf ("BMP. bmbitsperpixel = % I/N", BMP. bmbitsperpixel );
Printf ("BMP. bmbytesperpixel = % I/N", BMP. bmbytesperpixel );
Printf ("BMP. bmalpha = % I/N", BMP. bmalpha );
Printf ("BMP. bmcolorkey = % I/N", BMP. bmcolorkey );
Printf ("BMP. bmwidth = % I/N", BMP. bmwidth );
Printf ("BMP. bmheight = % I/N", BMP. bmheight );
Printf ("BMP. BMP itch = % I/N", BMP. BMP itch );
Printf ("BMP. bmbits = % I/N", BMP. bmbits );
Printf ("BMP. bmalphapixelformat = % I/N", BMP. bmalphapixelformat );
Return true;
}*/
Void fillbitmap (Bitmap * BMP)
{
BMP-> bmtype = 0;
BMP-> bmbitsperpixel = 16;
BMP-> bmbytesperpixel = 2;
BMP-> bmalpha = 0;
BMP-> bmcolorkey = 0;
BMP-> bmwidth = vid_w;
BMP-> bmheight = vid_h;
BMP-> BMP = vid_w * 2;
BMP-> bmbits = NULL;
BMP-> bmalphapixelformat = NULL;
}
Void fillmybitmap (pmybitmap my_bmp)
{
My_bmp-> flags = mybmp _rgbsize_3 | mybmp _type_bgr | mybmp _flow_down;
My_bmp-> frames = 1;
My_bmp-> depth = 24;
My_bmp-> alpha = 0;
My_bmp-> reserved [0] = 0;
My_bmp-> reserved [1] = 0;
My_bmp-> transparent = 0;
My_bmp-> W = 240;
My_bmp-& gt; H = 180;
My_bmp-> pitch = 240*3;
My_bmp-> size = 240*180*3;
My_bmp-> bits = NULL;
}
Static int hellowinproc (hwnd, int message, wparam, lparam)
{
HDC;
Rect RC;
Switch (Message ){
Case msg_paint:
HDC = beginpaint (hwnd );
If (BMP. bmbits)
Fillboxwithbitmap (HDC, 0, 0, BMP. bmwidth, BMP. bmheight, & BMP );
Setbkcolor (HDC, rgb2pixel (HDC, 0xff, 0xff, 0xff ));
Setbkmode (HDC, bm_transparent );
Settextcolor (HDC, rgb2pixel (HDC, 0xff, 0x00, 0x00 ));
RC. Left = 0;
RC. Top = 0;
RC. Right = 300;
RC. Bottom = 60;
Textout (HDC, 0, 0 ,"?????? ");
If (x> = vid_w | x <= 0)
{
Xdir = 0-xdir;
}
If (Y> = vid_w | Y <= 10)
{
Ydir = 0-ydir;
}
X + = xdir;
Y + = ydir;
Textout (HDC, X, Y, "KDF ");
Rectangle (HDC, 0, 0, BMP. bmwidth, BMP. bmheight );
/* Fillboxwithbitmap (HDC, 100, 0,200,200, & BMP );
Rectangle (HDC, 100, 0,300,200 );
Fillboxwithbitmappart (HDC, 0,200,400,200, 0, 0, & BMP, 10, 10 );
Rectangle (HDC, 0,200,400,400 );*/
Endpaint (hwnd, HDC );
Return 0;
Case msg_create:
/* If (loadbitmap (hdc_screen, & BMP, "bkgnd.bmp "))
Return-1 ;*/
Return 0;
Case msg_close:
Unloadbitmap (& BMP );
Destroymainwindow (hwnd );
Postquitmessage (hwnd );
Return 0;
}
Return defamainmainwinproc (hwnd, message, wparam, lparam );
}
Int miniguimain (INT argc, const char * argv [])
{
MSG;
Hwnd hmainwnd;
Mainwincreate createinfo;
# Ifdef _ lite_version
Setinclutoprect (0, 0, 1024,768 );
# Endif
Createinfo. dwstyle = ws_visible | ws_border | ws_caption;
Createinfo. dwexstyle = ws_ex_none;
Createinfo. spcaption = "Hello, world ";
Createinfo. hmenu = 0;
Createinfo. hcursor = getsystemcursor (0 );
Createinfo. hicon = 0;
Createinfo. mainwindowproc = hellowinproc;
Createinfo. Lx = 0;
Createinfo. Ty = 0;
Createinfo. RX = vid_w;
Createinfo. By = vid_h;
Createinfo. ibkcolor = color_lightwhite;
Createinfo. dwadddata = 0;
Createinfo. hhosting = hwnd_desktop;
Hmainwnd = createmainwindow (& createinfo );
If (hmainwnd = hwnd_invalid)
Return-1;
Showwindow (hmainwnd, sw_shownormal );
//////////////////////////////////////// //////////////////////
// 1. Create my video class cv4l.
Cvid = new cv4l ("/dev/video0 ");
//////////////////////////////////////// //////////////////////
// 2. init the video device with Channel and map size.
If (cvid-> Init (0, vid_w, vid_h) = false)
Return-1;
// Fillmybitmap (& mybmp );
Fillbitmap (& BMP );
//////////////////////////////////////// //////////////////////
// 3. Read the data from Video device.
If (BUF = cvid-> Read ())
{
BMP. bmbits = Buf;
// Invalidaterect ();
Sendmessage (hmainwnd, msg_paint, 0, 0 );
}
While (true)
{
If (! Havependingmessage (hmainwnd ))
{
If (! Getmessage (& MSG, hmainwnd ))
Break;
Translatemessage (& MSG );
Dispatchmessage (& MSG );
} Else {
//////////////////////////////////////// //////////////////////
// 3. Read the data from Video device.
If (BUF = cvid-> Read ())
{
BMP. bmbits = Buf;
Sendmessage (hmainwnd, msg_paint, 0, 0 );
} Else {
// If buffer is null, vedeo device have pluged out.
Postquitmessage (hmainwnd );
}/* End of read video buffer */
}/* End of havependingmessage ()*/
}/* End of while */
//////////////////////////////////////// //////////////////////
// 4. Destroy the cv4l class, and release resources.
Cvid-> destroy ();
Unloadbitmap (& BMP );
// Free (BMP. bmbits );
Mainwindowthreadcleanup (hmainwnd );
Return 0;
}
# Ifndef _ lite_version
# Include <MiniGUI/syslog. c>
# Endif
Add the code to the miniugi-1.3.3's helloworld program to compile it, you can also use the following command
G ++-O video-I/MiniGUI/include-L/MiniGUI/lib video. cpp v4l. cpp