基于Cortex處理芯片+Linux操作系統(tǒng)設(shè)計數(shù)碼照相機系統(tǒng)_第1頁
基于Cortex處理芯片+Linux操作系統(tǒng)設(shè)計數(shù)碼照相機系統(tǒng)_第2頁
基于Cortex處理芯片+Linux操作系統(tǒng)設(shè)計數(shù)碼照相機系統(tǒng)_第3頁
基于Cortex處理芯片+Linux操作系統(tǒng)設(shè)計數(shù)碼照相機系統(tǒng)_第4頁
基于Cortex處理芯片+Linux操作系統(tǒng)設(shè)計數(shù)碼照相機系統(tǒng)_第5頁
已閱讀5頁,還剩38頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

緒論1.1背景隨著數(shù)碼相機的盛行,傳統(tǒng)相機逐漸退出歷史的舞臺。對于數(shù)碼相片的欣賞和擺設(shè),人們一般只能通過PC機,極其不方便。數(shù)碼相框正是迎合這種需求,它體積小,能隨時更換相片,并具有USB主機功能,能夠即插即用,擁有較大的存儲空間。1.2數(shù)碼相框的特點1.3系統(tǒng)開發(fā)目標本設(shè)計結(jié)合了使用Cortex處理芯片的開發(fā)板和源代碼開放的嵌入式Linux操作系統(tǒng)共同建立的平臺設(shè)計了數(shù)碼照相機系統(tǒng),主要實現(xiàn)的功能有對多種格式相片在800×480觸摸LCD上顯示、USB主機讀取功能、對攝像頭采集的視頻流進行截圖(拍照)等功能。1.4設(shè)計路線及開發(fā)工具1.4.1設(shè)計路線本系統(tǒng)將按照軟件工程管理思想對軟件的研究、可行性分析、需求分析、概念結(jié)構(gòu)設(shè)計、邏輯結(jié)構(gòu)設(shè)計、功能設(shè)計、詳細設(shè)計、編碼、實施、維護各階段進行嚴格的控制。保證系統(tǒng)開發(fā)質(zhì)量。根據(jù)數(shù)碼相框系統(tǒng)所需要的硬件配置和開發(fā)目標,查閱相關(guān)的資料,深入研究開發(fā)本系統(tǒng)所需要的相關(guān)理論知識和所需的硬件環(huán)境,通過需求分析來確定該系統(tǒng)的總體設(shè)計方案。1.4.2開發(fā)工具硬件配置名稱說明CPUs5pv210,DDR2-800數(shù)據(jù)傳輸頻率800MHz,外部時鐘頻率200MHz,內(nèi)部時鐘頻率100MHz,nandfalsh外部時鐘頻率133MHz內(nèi)核ARMCortex-A8FLASH256MBSLCNANDFLASH內(nèi)存512MBDDR2USB4個USBHost2.0接口,1個USBOTG2.0接口網(wǎng)口1個串口2串口調(diào)試接口20-pin,2.54mm標準JTAG接口攝像頭接口兩個,支持最大12M(8192x8192)接口8-bitITU601/656和MPDI/CSISD接口4MATAinterface標準CAMERA接口2個,獨立I/O8路I/OLCD7寸TFT-LCD屏觸摸屏LCD電容屏A/D轉(zhuǎn)換器10bit電壓0-3V蜂鳴器1個led燈2個用戶,一個電源顯示JTAG接口標準用戶擴展接口2路SPI接口,2路IIC接口,3路PWM,4路UART,6路ADC,1路SDIO接口和其它用戶擴展IOPCB板層8層userkey8個電源供電+5/2A工作溫度-20~+70度軟件配置名稱說明操作系統(tǒng)Linux-2.6.14ubuntu12.04LTS內(nèi)核版本linux-3.0.8開發(fā)工具GNU工具啟動代碼u-boot-2010.03驅(qū)動程序所有硬件驅(qū)動文件系統(tǒng)根文件系統(tǒng)采用cramfs,用戶文件系統(tǒng)采用yaffs2,nfs文件系統(tǒng)協(xié)議棧TCP/IPPPP,tftp,nfs1.5嵌入式系統(tǒng)環(huán)境搭建1.5.1arm-gcc交叉編譯工具鏈的安裝和使用在官網(wǎng)下載arm-gcc的源碼解壓工具鏈的壓縮包cd~tarxvfarm-cortex_a8-linux-gnueabi.tar.bz2環(huán)境變量的添加 修改文件/etc/bash.bashrc添加如下內(nèi)容 exportPATH=$PATH:/home/linux/arm-cortex_a8/bin 重啟配置文件 $source/etc/bash.bashrc工具鏈的測試arm-cortex_a8-linux-gnueabi-gcc–v1.5.2u-boot的燒寫及使用SD啟動盤制作將第一天/SD卡啟動制作工具/sd_fusing拷貝到Linux下將SD卡插入電腦并識別進入sd_fusing執(zhí)行如下操作$make$chmod777sd_fusing.sh$sudo./sd_fusing.sh/dev/sdb(sdb為sd卡在ubuntu的設(shè)備節(jié)點)u-boot的燒寫運行串口通信程序(putty)關(guān)閉開發(fā)板電源,將撥碼開關(guān)SW2調(diào)至0110(SD啟動模式)后打開電源將剛才做好的SD啟動盤插入SD卡插槽重新打開開發(fā)板能夠看到如下界面設(shè)置板子環(huán)境變量#setenvserverip00//和ubuntuip一直#setenvipaddr00 //板子的ip不要和windows和Ubuntu沖突將第一天/鏡像文件/u-boot.bin拷貝到ubuntu的/tftpboot目錄下燒寫#tftp20008000u-boot.bin#nanderase0100000#nandwrite200080000100000關(guān)閉開發(fā)板電源,將撥碼開關(guān)SW2調(diào)至1000(NAND啟動模式)后打開電源可以看到如下界面表示燒寫成功通過網(wǎng)絡(luò)加載內(nèi)核和文件系統(tǒng)將第一天/鏡像文件/zImage拷貝到ubuntu的/tftpboot下將第一天/鏡像文件/rootfs.tar.bz2拷貝到ubuntu的/source下并解壓修改虛擬機nfs配置文件/etc/exports,添加如下內(nèi)容并重啟nfs服務(wù)source/rootfs*(rw,sync,no_subtree_check,no_root_squash)重新驅(qū)動nfs服務(wù)$sudo/etc/init.d/nfs-kernel-serverrestart設(shè)置啟動參數(shù)#setenvbootcmdtftp20008000zImage\;go20008000#setenvbootargsroot=nfsnfsroot=00:/source/rootfsip=00init=/linuxrcconsole=ttySAC0,115200#saveenv啟動開發(fā)板看到如下現(xiàn)象表示成功通過網(wǎng)絡(luò)掛載:1.5.3內(nèi)核的配置和編譯 解壓內(nèi)核將linux-3.0.8.tar.bz2拷貝到/home/linux下并解壓$tarxvflinux-3.2.tar.bz2$cdlinux-3.0.8修改內(nèi)核頂層目錄下的Makefile$vimMakefile修改:ARCH ?=$(SUBARCH)CROSS_COMPILE ?=$(CONFIG_CROSS_COMPILE:"%"=%)為:ARCH ?=armCROSS_COMPILE ?=arm-cortex_a8-linux-gnueabi-拷貝標準板配置文件$makes5pv210_defconfig配置內(nèi)核$makemenuconfig SystemType---> (0)S3CUARTtouseforlow-levelmessages該命令執(zhí)行時會彈出一個菜單,我們可以對內(nèi)核進行詳細的配置。這里我們先查看一下,內(nèi)核都提供了那些功能!編譯內(nèi)核$makezImage通過上述操作我們能夠在arch/arm/boot目錄下生成一個zImage文件,這就是經(jīng)過壓縮的內(nèi)核鏡像。1.5.4嵌入式文件系統(tǒng)的移植一、根文件系統(tǒng)制作 源碼下載我們選擇的版本是busybox-1.17.3.tar.bz2下載路徑為:/downloads/解壓源碼$tarxvfbusybox-1.17.3.tar.bz2進入源碼目錄$cdbusybox-1.17.3配置源碼$makemenuconfigBusyboxSettings---> BuildOptions---> [*]BuildBusyBoxasastaticbinary(nosharedlibs) []ForceNOMMUbuild []BuildwithLargeFileSupport(foraccessingfiles>2GB) (arm-cortex_a8-linux-gnueabi-)CrossCompilerprefix ()AdditionalCFLAGS編譯$make安裝busybox默認安裝路徑為源碼目錄下的_install$makeinstall進入安裝目錄下$cd_install$lsbinlinuxrcsbinusr創(chuàng)建其他需要的目錄$mkdirdevetcmntprocvartmpsysroot添加庫將工具鏈中的庫拷貝到_install目錄下$cp/home/linux/arm-cortex_a8-linux-gnueabi/lib/sysroot/lib./-a刪除靜態(tài)庫和共享庫文件中的符號表$rmlib/*.a$rmlib/*.la$arm-cortex_a8-linux-gnueabi-striplib/*刪除不需要的庫,確保所有庫大小不超過4M$du-mhlib/添加系統(tǒng)啟動文件在etc下添加文件inittab,文件內(nèi)容如下:#thisisrunfirstexceptwhenbootinginsingle-usermode.::sysinit:/etc/init.d/rcS#/bin/shinvocationsonselectedttys#startan"askfirst"shellontheconsole(whateverthatmaybe)::askfirst:-/bin/sh#stufftodowhenrestartingtheinitprocess::restart:/sbin/init#stufftodobeforerebooting::ctrlaltdel:/sbin/reboot在etc下添加文件fstab,文件內(nèi)容如下:#devicemount-point type optionsdumpfsckorderproc /proc proc defaults 0 0tmpfs /tmp tmpfs defaults 0 0sysfs /sys sysfs defaults 0 0tmpfs /dev tmpfs defaults 0 0 這里我們掛載的文件系統(tǒng)有三個proc、sysfs和tmpfs。在內(nèi)核中proc和sysfs默認都支持,而tmpfs是沒有支持的,我們需要添加tmpfs的支持修改內(nèi)核配置:Filesystems---> Pseudofilesystems---> [*]Virtualmemoryfilesystemsupport(formershmfs) [*]TmpfsPOSIXAccessControlLists重新編譯內(nèi)核 在etc下創(chuàng)建init.d目錄,并在init.d下創(chuàng)建rcS文件,rcS文件內(nèi)容為:#!/bin/sh#Thisisthefirstscriptcalledbyinitprocess/bin/mount-aecho/sbin/mdev>/proc/sys/kernel/hotplug/sbin/mdev-s 為rcS添加可執(zhí)行權(quán)限: $chmod+xinit.d/rcS 在etc下添加profile文件,文件內(nèi)容為:#!/bin/shexportHOSTNAME=farsightexportUSER=rootexportHOME=rootexportPS1="[$USER@$HOSTNAME\W]\#"PATH=/bin:/sbin:/usr/bin:/usr/sbinLD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATHexportPATHLD_LIBRARY_PATH重要:新制作的文件系統(tǒng)尺寸若超出8M,刪除不需要的庫文件 二、NFS測試 1、刪除原先的/source/rootfs $sudorm-rf/source/rootfs 2、將我們新建的根文件系統(tǒng)拷貝到/source/rootfs目錄下$sudomkdir/source/rootfs $sudocp_install/*/source/rootfs–a 3、設(shè)置uboot環(huán)境變量#setenvbootcmdtftp20008000zImage\;go20008000#setenvbootargsroot=nfsnfsroot=00:/source/rootfsinit=/linuxrcconsole=ttySAC0,115200ip=00#saveenv重新啟動開發(fā)板,查看是否能夠正常掛載,功能是否正常1.6論文結(jié)構(gòu)緒論本章主要是對數(shù)碼相框系統(tǒng)進行一個背景和設(shè)計思路的一個總體闡述。相關(guān)技術(shù)介紹本章主要是對數(shù)碼相框系統(tǒng)所需要的一些技術(shù)性的點進行一個統(tǒng)一的闡述。系統(tǒng)需求分析系統(tǒng)可行性分析系統(tǒng)概要設(shè)計系統(tǒng)詳細設(shè)計系統(tǒng)測試結(jié)語相關(guān)技術(shù)介紹2.1基于CortexA8的嵌入式系統(tǒng)介紹嵌入式系統(tǒng)是以應用為中心、以計算機技術(shù)為基礎(chǔ)、軟件硬件可裁剪、適應應用系統(tǒng)對功能、可靠性、成本、體積、功耗嚴格要求的專用計算機系統(tǒng)。主要有系統(tǒng)內(nèi)核小,專用性強,系統(tǒng)精簡,高實時性的系統(tǒng)軟件(OS)等特點。2.2圖像處理技術(shù)介紹我們都知道,一個圖片是由一個一個像素組成的,而一個個的像素都是由紅,綠,藍三種顏色組合而成。常用的圖片格式處理如下:BMP是位圖的存儲格式,JPG是照片的存儲格式,GIF是閃圖的存儲格式,PNG是一種無損壓縮圖片的格式。JPG格式是最常用的圖像文件格式,是一種有損壓縮格式,能把圖像壓縮在很小的存儲空間,圖像中重復或不重要的資料會被丟失。JPEG格式壓縮的主要是高頻信息,對色彩的信息保留較好,適合應用于互聯(lián)網(wǎng),減少圖片傳輸時間,可以支持24bit真彩色,也普遍應用于需要連續(xù)色調(diào)的圖像。PNG是網(wǎng)景公司開發(fā)的支持新一代WWW標準而制定的較為新型的圖形格式,它綜合了JPG和GIF格式的優(yōu)點,支持24bit色彩(256*256*256),壓縮不失真并支持透明背景和漸顯圖像的制作,所以稱它為傳統(tǒng)GIF的替代格式。在Web頁面中,瀏覽器支持的格式有JPG、GIF和PNG。2.3Framebuffer設(shè)備驅(qū)動技術(shù)介紹在多媒體應用的推動下,彩色LCD越來越多地應用到了嵌入式系統(tǒng)中,掌上電腦(PDA)、手機等多采用TFT顯示器件,支持彩色圖形界面,能顯示圖片并進行視頻媒體播放。幀緩沖(Framebuffer)是Linux為顯示設(shè)備提供的一個接口,它允許上層應用程序在圖形模式下直接對顯示緩沖區(qū)進行讀寫操作。幀緩沖(framebuffer)是Linux系統(tǒng)為顯示設(shè)備提供的一個接口,它將顯示緩沖區(qū)抽象,屏蔽圖像硬件的底層差異,允許上層應用程序在圖形模式下直接對顯示緩沖區(qū)進行讀寫操作。用戶不必關(guān)心物理顯示緩沖區(qū)的具體位置及存放方式,這些都由幀緩沖設(shè)備驅(qū)動本身來完成。對于幀緩沖設(shè)備而言,只要在顯示緩沖區(qū)中與顯示點對應的區(qū)域?qū)懭腩伾?,對應的顏色會自動在屏幕上顯示,2.4USB設(shè)備驅(qū)動技術(shù)介紹2.5進程間通信技術(shù)介紹進程是操作系統(tǒng)中一個非常重要的概念,程序的運行是通過進程來完成的,在本系統(tǒng)中,我們用到了進程間通信技術(shù)的異步通知。異步通知的意思就是一旦系統(tǒng)設(shè)備準備好以后就主動的通知應用程序,這樣,應用程序就不用查詢系統(tǒng)設(shè)備的狀態(tài)了。異步通知意味著設(shè)備通知應用程序自身可訪問。一個用戶在用戶空間處理一個設(shè)備釋放的信號,需要以下三個步驟:(1)通過F_SETOWN控制指令設(shè)置設(shè)備文件的擁有者為本進程,這樣從設(shè)備驅(qū)動中發(fā)出的信號才能被本進程收到。(2)通過F_SETFLIO控制命令設(shè)置設(shè)備文件支持FASYNC,即異步通知模式。(3)通過signal()鏈接信號和信號處理函數(shù)。系統(tǒng)需求分析3.1業(yè)務(wù)描述隨著PC時代數(shù)碼技術(shù)的發(fā)展,數(shù)碼相機以其低廉的價格,方便的操作成為攝影器材未來的發(fā)展方向。目前,很多家庭都持有數(shù)碼相機,一次拍攝下來的照片往往會有上百張,使用PC機來查看拍攝下來的圖片,操作繁瑣,而且依賴于PC機。作為數(shù)碼相機的一種附屬產(chǎn)品,數(shù)碼相框不僅具有傳統(tǒng)相框的特點,而且可以直接從數(shù)碼相機中選擇心儀的照片,定時更新照片。數(shù)碼相框是展示數(shù)碼照片而非紙質(zhì)照片的相框。眾多的數(shù)碼攝影產(chǎn)生的相片保存起來后,查看過程繁瑣不方便,大量打印出來又非常浪費,如果用數(shù)碼相框直接插上相機的存儲卡展示照片,就非常簡單。3.2系統(tǒng)目標(1)工作模式:團隊設(shè)計的系統(tǒng)采用實時視頻模式,在這種模式下系統(tǒng)通過攝像頭獲取視屏流,在用戶下達指令后可以將(4)操作性:用戶接口采用直接觸摸LCD顯示屏實現(xiàn)。(5)界面簡潔,美觀,直觀易操作,友好,富于人性化,更加適合家居實用。3.3系統(tǒng)功能描述系統(tǒng)可以通過攝像頭獲取視頻數(shù)據(jù);用戶可以通過LCD獲取圖像;用戶可以通過摁下按鍵拍攝和查看圖像;3.4系統(tǒng)性能需求攝像頭精度要求:攝像頭獲取的視頻流實時顯示兼容性:數(shù)碼相框應能識別和處理當前數(shù)碼相機主要的圖像格式,能訪問主流的外部存儲卡穩(wěn)定性:系統(tǒng)穩(wěn)定可靠3.5數(shù)據(jù)保存需求由于嵌入式設(shè)備上存儲空間容量有限,所以系統(tǒng)采集的圖片信息需要轉(zhuǎn)存到相應的存儲設(shè)備上,比如SD卡等設(shè)備上,這樣用戶可以很方便查看事件的記錄,系統(tǒng)應該提供相應的接口,來實現(xiàn)相應的數(shù)據(jù)保存功能3.6流程圖系統(tǒng)可行性分析4.1可行性研究的前提4.1.1系統(tǒng)基本需求當用戶插入U盤時,系統(tǒng)會自動識別U盤里的圖片,并將U盤里bmp和jpng格式的圖片以800x480的大小在LCD液晶屏上顯示出來。攝像頭采集的視頻流通過LCD液晶屏顯示出來,并實現(xiàn)拍照的功能。4.1.2數(shù)據(jù)保存需求系統(tǒng)采集的圖片信息需要轉(zhuǎn)存到相應的存儲設(shè)備上,用戶可以查看之前的圖片信息記錄。4.1.3條件、假定和限制(1)用戶接口屏幕的要求:直觀性好,友好,富于人性化。(2)硬件接口攝像頭硬件需求:支持設(shè)備的種類:ARM系列,并支持嵌入式linux操作系統(tǒng)。支持設(shè)備的方式:移植嵌入式linux系統(tǒng)和上層的用戶的應用程序。(3)軟件接口應用軟件的需求:驅(qū)動程序:基于linux-3.0.8內(nèi)核版本的驅(qū)動程序。4.2所建議技術(shù)可行性分析4.2.1對系統(tǒng)的簡要描述當用戶插入U盤時,系統(tǒng)會自動識別U盤里的圖片,并將U盤里bmp和jpng格式的圖片以800x480的大小在LCD液晶屏上顯示出來。攝像頭采集的視頻流通過LCD液晶屏顯示出來,并實現(xiàn)拍照的功能。4.2.2處理流程和數(shù)據(jù)流程4.2.3系統(tǒng)技術(shù)分析(1)對USB設(shè)備驅(qū)動的技術(shù)可行性分析USB設(shè)備類驅(qū)動可以包含多個,不同的功能接口對應不同的驅(qū)動程序,它們不直接與USB設(shè)備硬件打交道,而是通過協(xié)議軟件的抽象處理來完成與設(shè)備的不同功能接口之間的通信。在Linux系統(tǒng)中,支持兩種類型的USB驅(qū)動程序:USB主機端驅(qū)動程序和USB設(shè)備端驅(qū)動程序。其中,USB設(shè)備驅(qū)動程序是操作內(nèi)核和機器硬件之間進行交互的接口,它為用用程序屏蔽了底層硬件的具體細節(jié),我們開發(fā)的各種應用程序會把所有的硬件設(shè)備當做普通文件進行處理和相關(guān)操作。(2)對Framebuffer設(shè)備驅(qū)動的技術(shù)可行性分析 Framebuffer是一種驅(qū)動程序接口。Linux是工作保護模式下,所以用戶態(tài)進程是無法象DOS那樣使用顯卡BIOS里提供的中斷調(diào)用來實現(xiàn)直接寫屏,Linux抽象出FrameBuffer這個設(shè)備來供用戶態(tài)進程實現(xiàn)直接寫屏。Framebuffer機制模仿顯卡的功能,將顯卡硬件結(jié)構(gòu)抽象掉,可以通過Framebuffer的讀寫直接對顯存進行操作。用戶可以將Framebuffer看成是顯示內(nèi)存的一個映像,將其映射到進程地址空間之后,就可以直接進行讀寫操作,而寫操作可以立即反應在屏幕上。這種操作是抽象的,統(tǒng)一的。用戶不必關(guān)心物理顯存的位置、換頁機制等等具體細節(jié),這些都是由Framebuffer設(shè)備驅(qū)動來完成的。(3)對MTD設(shè)備驅(qū)動的技術(shù)可行性分析在Linux系統(tǒng)中,提供了MTD系統(tǒng)來建立flash針對Linux的統(tǒng)一、抽象的接口。MTD將文件系統(tǒng)與底層的flash存儲器進行了隔離,使flash驅(qū)動工程師無需關(guān)心flash作為字符設(shè)備和塊設(shè)備與Linux內(nèi)核的接口。在引入MTD后,Linux系統(tǒng)中的flash設(shè)備驅(qū)動及接口可分為4層,從上到下依次是:設(shè)備節(jié)點、MTD設(shè)備層、MTD原始設(shè)備層和硬件驅(qū)動層。底層flash驅(qū)動直接與MTD原始設(shè)備層進行交互,利用其提供的接口注冊設(shè)備和分區(qū)。用于描述MTD原始設(shè)備的數(shù)據(jù)結(jié)構(gòu)是mtd_info,這其中定義了大量關(guān)于MTD的數(shù)據(jù)和操作函數(shù)。drivers/mtd/mtdchar.c文件實現(xiàn)了MTD字符設(shè)備接口,通過它,用戶可以直接操作flash設(shè)備。(4)對圖像解碼的技術(shù)可行性分析對于圖像解碼技術(shù),本系統(tǒng)主要是對JPG格式的圖片進行解碼,使用libjpeg庫對JPG格式的圖片進行解碼比較簡單方便,libjpeg是一個完全用C語言編寫的庫,包含了被廣泛使用的JPEG解碼、JPEG編碼和其他的JPEG功能的實現(xiàn)。通過調(diào)用jpeglib庫即可對圖片進行解碼,這樣就可以將JPEG格式的文件解析出來。4.3所建議系統(tǒng)經(jīng)濟可行性分析序號功能數(shù)量單價1開發(fā)板1個8002U盤1個205攝像頭模塊1個30小計850系統(tǒng)概要設(shè)計5.1體系架構(gòu)5.1.1系統(tǒng)架構(gòu)系統(tǒng)的物理架構(gòu)如圖所示:5.1.2軟件架構(gòu)系統(tǒng)的軟件架構(gòu)如下所示:數(shù)碼相框->|->驅(qū)動層代碼->|->framebuffer驅(qū)動代碼||->按鍵驅(qū)動代碼|||->應用層代碼->|->main.c->|->src(showjpegcamera)|->include(showjpegcamera)|->lib(jpeglib)5.2系統(tǒng)各模塊概要設(shè)計5.2.1Framebuffer模塊設(shè)計設(shè)計流程:Framebuffer->|->內(nèi)核層代碼->|->注冊platformdevice||->注冊platformdriver|||->用戶層代碼->|->打開fb設(shè)備,對其進行操作驅(qū)動層主要的結(jié)構(gòu)體:fb_info結(jié)構(gòu)體包括了對frambuffer設(shè)備驅(qū)動的屬性和操作完整的描述fb_var_screeninfo

記錄用戶可修改的顯示控制器參數(shù),包括屏幕分辨率和每個像素點的比特數(shù)。fb_fix_screeninfo中記錄用戶不能修改的顯示控制器的參數(shù),如屏幕緩沖區(qū)的物理地址、長度。5.2.2圖像處理模塊設(shè)計設(shè)計流程解析常用圖片->|->解析bmp圖片(直接解析)|||->解析png圖片(通過pnglib解析)||->解析jpeg圖片(通過jpeglib解析)主要結(jié)構(gòu)體Color結(jié)構(gòu)體里面存放了描述像素的三種顏色 struct{ char blue; char green; char red; }color;5.2.3.按鍵模塊設(shè)計設(shè)計流程Framebuffer->|->內(nèi)核層代碼->|->module_init(s5pv210_key_init);||->module_exit(s5pv210_key_exit);|||->用戶層代碼->|->通過異步通知來對按鍵事件進行處理主要結(jié)構(gòu)體及函數(shù)文件操作結(jié)構(gòu)體structfile_operationss5pv210_key_fops={ .owner=THIS_MODULE, .open=s5pv210_key_open, .release=s5pv210_key_release, .read=s5pv210_key_read, .fasync=s5pv210_key_fasync,};注冊中斷ret=register_chrdev_region(devno,number_of_device,"key");初始化中斷cdev_init(&cdev,&s5pv210_key_fops);添加ret=cdev_add(&cdev,devno,number_of_device);注銷 unregister_chrdev_region(devno,number_of_device);5.2.4拍照模塊設(shè)計拍照模塊->|->初始化攝像頭->|->video_enable()||->攝像頭獲取數(shù)據(jù)->|->ret=ioctl(fd,VIDIOC_DQBUF,&buf);||->將YUV數(shù)據(jù)轉(zhuǎn)化為jpeg數(shù)據(jù)->|->compress_yuyv_to_jpeg();||->將數(shù)據(jù)寫到文件中->|->fwrite(dest,ret,1,fp);主要數(shù)據(jù)結(jié)構(gòu)體typedefstructVideoBuffer{char*start;size_tlength;}VideoBuffer;typedefstruct{structjpeg_destination_mgrpub;/*publicfields*/JOCTET*buffer;/*startofbuffer*/unsignedchar*outbuffer;intoutbuffer_size;unsignedchar*outbuffer_cursor;int*written;}mjpg_destination_mgr;5.3主程序概要設(shè)計系統(tǒng)詳細設(shè)計6.1Framebuffer模塊詳細設(shè)計6.1.1數(shù)據(jù)描述6.1.2函數(shù)描述6.2圖像處理模塊詳細設(shè)計6.2.1數(shù)據(jù)流程6.2.2函數(shù)描述intread_jpeg_file(constchar*input_filename){structjpeg_decompress_structcinfo;//這個結(jié)構(gòu)體對象包含了JPEG解壓縮參數(shù)和一些工作函數(shù)的指針,JPEG庫的API需要它。structjpeg_error_mgrjerr;//定義了一個錯誤處理的結(jié)構(gòu)體FILE*input_file;//FILE*output_file;JSAMPARRAYbuffer;introw_width;unsignedchar*output_buffer;unsignedchar*tmp=NULL; initfb0();cinfo.err=jpeg_std_error(&jerr);//將錯誤處理結(jié)構(gòu)對象綁定在JPEG對象上if((input_file=fopen(input_filename,"rb"))==NULL) {fprintf(stderr,"can'topen%s\n",input_filename);return-1;} //打開一個用于讀取的二進制文件//初始化cinfo結(jié)構(gòu)體。jpeg_create_decompress(&cinfo);//指定解壓縮數(shù)據(jù)源jpeg_stdio_src(&cinfo,input_file);/*1.設(shè)置讀取jpg文件頭部,Readfileheader,setdefaultdecompressionparameters*/(void)jpeg_read_header(&cinfo,TRUE);/**在讀取文件頭后,開始解壓縮之前可以對解壓縮的參數(shù)進行設(shè)定*也就是對cinfo結(jié)構(gòu)的成員賦值*//*2.開始解碼數(shù)據(jù)Startdecompressor*/(void)jpeg_start_decompress(&cinfo);row_width=cinfo.output_width*cinfo.output_components;/*3.跳過讀取的頭文件字節(jié),為緩沖區(qū)分配空間 *,JPOOL_IMAGE表示分配的空間將在調(diào)用finish后被釋放 *row_width表示每行數(shù)據(jù)的實際大小 *1表示此處只分配了一行的數(shù)據(jù)*/buffer=(*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,JPOOL_IMAGE,row_width,1); output_buffer=(unsignedchar*)malloc(row_width*cinfo.output_height); memset(output_buffer,0,row_width*cinfo.output_height);tmp=output_buffer;/*4.Processdata由左上角從上到下行行掃描 *output_scanline表示當前已經(jīng)讀取的行數(shù),如此即可依次讀出圖像的所有數(shù)據(jù) *并填充到緩沖區(qū)去,參數(shù)1表示的是每次讀取的行數(shù)*/while(cinfo.output_scanline<cinfo.output_height) {(void)jpeg_read_scanlines(&cinfo,buffer,1);memcpy(tmp,*buffer,row_width);tmp+=row_width;} longintlocation=0; unsignedintx,y; struct{ char blue; char green; char red; }color; for(y=0;y<cinfo.output_height;y++) { for(x=0;x<cinfo.output_width;x++) { memcpy(&color,output_buffer,3); output_buffer=output_buffer+3; location=(x+vinfo.xoffset)*(vinfo.bits_per_pixel/8)+\ (y+vinfo.yoffset)*finfo.line_length; *((unsignedlong*)(fbp+location))=color.red|color.green<<8|color.blue<<16; } }(void)jpeg_finish_decompress(&cinfo);//解壓縮完畢jpeg_destroy_decompress(&cinfo);//釋放資源/*Closefiles,ifweopenedthem*/fclose(input_file); munmap(fbp,screensize); close(fbfd);return0;}6.3按鍵模塊詳細設(shè)計6.3.1數(shù)據(jù)流程6.3.2函數(shù)描述irqreturn_tkey_interrupt(intirqno,void*devid){ //printk("irqno=%d\n",irqno); switch(irqno) { caseIRQ_EINT(0):key=1;break; caseIRQ_EINT(1):key=2;break; caseIRQ_EINT(2):key=3;break; caseIRQ_EINT(3):key=4;break; caseIRQ_EINT(4):key=5;break; caseIRQ_EINT(5):key=6;break; caseIRQ_EINT(22):key=7;break; caseIRQ_EINT(23):key=8;break; } wake_up_interruptible(&readq); if(key_struct!=NULL) kill_fasync(&key_struct,SIGIO,POLL_IN); returnIRQ_HANDLED;}staticints5pv210_key_fasync(intfd,structfile*file,inton){ returnfasync_helper(fd,file,on,&key_struct);}staticints5pv210_key_open(structinode*inode,structfile*file){ intret; ret=request_irq(IRQ_EINT(0),key_interrupt,IRQF_DISABLED|IRQF_TRIGGER_FALLING,"key1",NULL); if(ret<0) gotoerr1; ret=request_irq(IRQ_EINT(1),key_interrupt,IRQF_DISABLED|IRQF_TRIGGER_FALLING,"key2",NULL); if(ret<0) gotoerr2; ret=request_irq(IRQ_EINT(2),key_interrupt,IRQF_DISABLED|IRQF_TRIGGER_FALLING,"key3",NULL); if(ret<0) gotoerr3; ret=request_irq(IRQ_EINT(3),key_interrupt,IRQF_DISABLED|IRQF_TRIGGER_FALLING,"key4",NULL); if(ret<0) gotoerr4; ret=request_irq(IRQ_EINT(4),key_interrupt,IRQF_DISABLED|IRQF_TRIGGER_FALLING,"key5",NULL); if(ret<0) gotoerr5; ret=request_irq(IRQ_EINT(5),key_interrupt,IRQF_DISABLED|IRQF_TRIGGER_FALLING,"key6",NULL); if(ret<0) gotoerr6; ret=request_irq(IRQ_EINT(22),key_interrupt,IRQF_DISABLED|IRQF_TRIGGER_FALLING,"key7",NULL); if(ret<0) gotoerr7; ret=request_irq(IRQ_EINT(23),key_interrupt,IRQF_DISABLED|IRQF_TRIGGER_FALLING,"key8",NULL); if(ret<0) gotoerr8; return0;err8: free_irq(IRQ_EINT(23),NULL);err7: free_irq(IRQ_EINT(22),NULL);err6: free_irq(IRQ_EINT(4),NULL);err5: free_irq(IRQ_EINT(3),NULL);err4: free_irq(IRQ_EINT(2),NULL);err3: free_irq(IRQ_EINT(1),NULL);err2: free_irq(IRQ_EINT(0),NULL);err1: returnret;}staticints5pv210_key_release(structinode*inode,structfile*file){ free_irq(IRQ_EINT(0),NULL); free_irq(IRQ_EINT(1),NULL); free_irq(IRQ_EINT(2),NULL); free_irq(IRQ_EINT(3),NULL); free_irq(IRQ_EINT(4),NULL); free_irq(IRQ_EINT(5),NULL);free_irq(IRQ_EINT(22),NULL);free_irq(IRQ_EINT(23),NULL);s5pv210_key_fasync(-1,file,0); return0;}staticssize_ts5pv210_key_read(structfile*file,char__user*buf,size_tcount,loff_t*loff){ if(key==0xff) { if(file->f_flags&O_NONBLOCK) return-EAGAIN; } wait_event_interruptible(readq,key!=0xff); if(copy_to_user(buf,(char*)&key,sizeof(int))) return-EINVAL; key=0xff; returnsizeof(int);}structfile_operationss5pv210_key_fops={ .owner=THIS_MODULE, .open=s5pv210_key_open, .release=s5pv210_key_release, .read=s5pv210_key_read, .fasync=s5pv210_key_fasync,};staticints5pv210_key_init(void){ intret; devno=MKDEV(key_major,key_minor); ret=register_chrdev_region(devno,number_of_device,"key"); if(ret<0) returnret; cdev_init(&cdev,&s5pv210_key_fops); cdev.owner=THIS_MODULE; ret=cdev_add(&cdev,devno,number_of_device); if(ret<0) gotoerr1; init_waitqueue_head(&readq); return0;err1: unregister_chrdev_region(devno,number_of_device); returnret;}6.4拍照模塊詳細設(shè)計6.4.1數(shù)據(jù)流程6.4.2函數(shù)描述intgetjpeg(){FILE*fp;intret=0;char*videodevice="/dev/video3";intfd;intdev_fd;dev_fd=open("/dev/lig",O_RDWR|O_NONBLOCK);if(dev_fd<0){ perror("open"); exit(1);}ioctl(dev_fd,LIG_ON); structv4l2_capabilitycap;structv4l2_formatfmt;structv4l2_requestbuffersrb;if((fd=open(videodevice,O_RDWR))==-1){perror("ERRORopeningV4Linterface");return-1;}memset(&cap,0,sizeof(structv4l2_capability));ret=ioctl(fd,VIDIOC_QUERYCAP,&cap);//查詢視頻設(shè)備功能//printf("DriverName:%s\nCardName:%s\nBusInfo:%s\nDriverVersion:%u.%u.%u\n",cap.driver,cap.card,cap.bus_info,(cap.version)>>16&0xff,(cap.version)>>8&0xff,(cap.version)&0xff);if(ret<0){fprintf(stderr,"Erroropeningdevice%s:unabletoquerydevice.\n",videodevice);return-1;}if((cap.capabilities&V4L2_CAP_VIDEO_CAPTURE)==0){//是否支持capturefprintf(stderr,"Erroropeningdevice%s:videocapturenotsupported.\n",videodevice);return-1;}if(!(cap.capabilities&V4L2_CAP_STREAMING)){fprintf(stderr,"%sdoesnotsupportstreamingi/o\n",videodevice);return-1;}/*if(!(cap.capabilities&V4L2_CAP_VIDEO_OVERLAY)){fprintf(stderr,"%sdoesnotsupportOVERLAY\n",videodevice);return-1;}*/intinput=0;ret=ioctl(fd,VIDIOC_S_INPUT,&input);if(ret<0){perror("Unabletosetinput\n");return-1;}//顯示設(shè)備支持的格式structv4l2_fmtdescfmtdesc;fmtdesc.index=0;fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//printf("Supportformat:\n");while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1){//printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description);fmtdesc.index++;if(fmtdesc.index>14)break;}/**setformatin*/memset(&fmt,0,sizeof(structv4l2_format));fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.width=WIDTH;fmt.fmt.pix.height=HEIGTH;fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;//vd->formatIn;fmt.fmt.pix.field=V4L2_FIELD_ANY;ret=ioctl(fd,VIDIOC_S_FMT,&fmt);//設(shè)置視頻數(shù)據(jù)格式,如長/寬/圖像格式(yuyv/jpeg)if(ret<0){perror("Unabletosetformat");return-1;}if(ioctl(fd,VIDIOC_G_FMT,&fmt)==-1){printf("Unabletogetformat\n");exit(-1);}//printf("fmt.type:\t\t%d\n",fmt.type);//printf("pix.pixelformat:\t%c%c%c%c\n",(fmt.fmt.pix.pixelformat)&0xff,(fmt.fmt.pix.pixelformat>>8)&0xff,(fmt.fmt.pix.pixelformat>>16)&0xff,(fmt.fmt.pix.pixelformat>>24)&0xff);if((fmt.fmt.pix.width!=WIDTH)||//如果設(shè)置不成功,會自己修改,所以應再次檢查(fmt.fmt.pix.height!=HEIGTH)){fprintf(stderr,"formataskedunavailablegetwidth%dheight%d\n",fmt.fmt.pix.width,fmt.fmt.pix.height); }/**requestbuffers*/intn_buffers=0;memset(&rb,0,sizeof(structv4l2_requestbuffers));rb.count=COUNT;rb.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;rb.memory=V4L2_MEMORY_MMAP;ret=ioctl(fd,VIDIOC_REQBUFS,&rb);//請求v4l2驅(qū)動分配視頻緩沖區(qū),申請的內(nèi)存位于內(nèi)核空間,所以通過mmap映射到用戶空間if(ret<0){ //v4l2是視頻設(shè)備的驅(qū)動層perror("Unabletoallocatebuffers");return-1;}/*if(rb.count<2){printf("insufficientbuffsmemory");printf("Numberofbuffersallocate=%d\n",rb.count);}*//**mapthebuffers*/structv4l2_bufferbuf;structVideoBuffer*buffers=calloc(rb.count,sizeof(*buffers));//(width*height)*2(<<1));for(n_buffers=0;n_buffers<rb.count;n_buffers++){memset(&buf,0,sizeof(buf));buf.index=n_buffers;buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory=V4L2_MEMORY_MMAP;ret=ioctl(fd,VIDIOC_QUERYBUF,&buf);//readtobuf查詢已經(jīng)分配的v4L2的視頻緩沖區(qū)的相關(guān)信息,通過QUERYbuf來獲取獲取內(nèi)核空間中的視頻緩沖區(qū)信息buffers[n_buffers].length=buf.length;//printf("buf.length=%d",buf.length);if(ret<0){perror("Unabletoquerybuffer");return-1;}//開始映射到用戶空間buffers[n_buffers].start=(char*)mmap(NULL/*startanywhere*/,buf.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,buf.m.offset);if(buffers[n_buffers].start==MAP_FAILED){perror("Unabletomapbuffer");}ret=ioctl(fd,VIDIOC_QBUF,&buf);if(ret<0){printf("VIDIOC_QBUF(%d)failed(%d)\n",n_buffers,ret);return-1;}}//執(zhí)行成功時,函數(shù)指針返回0,執(zhí)行成功后,指令的視頻緩沖去進入輸入隊列,在啟動視頻拍攝圖像時,相應的視頻數(shù)據(jù)被保存到視頻輸入隊列相應視頻的視頻緩沖區(qū)中video_enable(fd);//獲得圖像ret=ioctl(fd,VIDIOC_DQBUF,&buf);if(ret<0){printf("failedVIDIOC_DQBUFerror");return-1;}//保存圖片charstr[50];charfilename[50]; structtm*timeinfo; time_trawtime; time(&rawtime); timeinfo=localtime(&rawtime); sprintf(str,"%d%d%d%d%d%d",(1900+timeinfo->tm_year),(1+timeinfo->tm_mon),timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec); sprintf(filename,"%s.jpg",str);if((fp=fopen(filename,"wb+"))==NULL)//打開文件 { perror("Cannotopenorcreatefile!"); }unsignedcharsrc[buf.length+1];unsignedchardest[buf.length+1];if(buf.index>=COUNT){printf("buf.index!<COUNT");return-1;}memcpy(src,buffers[buf.index].start,buf.length);ret=compress_yuyv_to_jpeg(src,dest,(WIDTH*HEIGTH),80);fwrite(dest,ret,1,fp);//寫入文件inti=0;for(i=0;i<COUNT;i++){munmap(buffers[i].start,buffers[i].length);}ioctl(dev_fd,LIG_OFF);system("chmod777*.jpg");printf("picturenameis:%s\n",filename);close(dev_fd);fclose(fp);close(fd);read_jpeg_file(filename);return0;}6.5主程序詳細設(shè)計6.5.1數(shù)據(jù)流程6.5.2函數(shù)描述#include"main.h"#include"showjpeg.h"#include"camera.h"voidhandler(intsigno){ intkey; read(keyfd,&key,sizeof(key)); if(key==3) { initfb0(); munmap(fbp,screensize);//清屏 close(fbfd); charaddr1[]="/"; //跳轉(zhuǎn)工作目錄 chdir(addr1); selectjpg(); jpgnum=0;//每次挑選后從第一張開始 }

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論