第一篇:嵌入式課程設(shè)計之觸摸屏程序設(shè)計
嵌入式課程設(shè)計
設(shè)計題目:觸摸屏驅(qū)動程序設(shè)計 班級: 學(xué)號: 姓名: 指導(dǎo)老師:
設(shè)計時間:2010年12月25日--12月28日
目錄
第一部分 要求................................................................................................................................1 1.1設(shè)計目的.................................................................................................................................1 1.2 設(shè)計意義................................................................................................................................1 1.3 設(shè)計內(nèi)容................................................................................................................................1 1.4 主要任務(wù)................................................................................................................................1 第二部分 正文................................................................................................................................2 2.1觸摸屏工作原理(觸摸屏接口工作模式).........................................................................2 2.2、設(shè)計總體方案......................................................................................................................3 2.3、設(shè)計所需工具......................................................................................................................6 2.4、平臺構(gòu)建過程......................................................................................................................6 2.4.1、硬件平臺搭建...............................................................................................................6 2.4.2根文件系統(tǒng)的制作..........................................................................................................8(1)根文件系統(tǒng).....................................................................................................................8 第三章 程序..................................................................................................................................13 3.1.程序流程圖:.......................................................................................................................13 3.2.分析驅(qū)動...............................................................................................................................13 3.2.1、觸摸屏設(shè)備驅(qū)動中數(shù)據(jù)結(jié)構(gòu).....................................................................................13 3.2.2、觸摸屏驅(qū)動模塊加載和卸載函數(shù).............................................................................15 3.2.3、觸摸屏設(shè)備驅(qū)動的讀函數(shù).........................................................................................17 3.2.4、觸摸屏設(shè)備驅(qū)動的輪詢與異步通知.........................................................................17 3.2.5源程序觸摸屏驅(qū)動代碼:............................................................................................18 3.2.6、實驗結(jié)果顯示:.........................................................................................................29 第四部分 心得..............................................................................................................................30 4.1 課程設(shè)計心得體會:..........................................................................................................30 第五部分 參考文獻(xiàn)......................................................................................................................32 5.1【參考文獻(xiàn)】........................................................................................................................32
第一部分 要求
1.1 設(shè)計目的
1.基于Linux操作系統(tǒng),以及Emest III實驗箱,利用觸摸屏返回觸點(diǎn)坐標(biāo)值及動作信息。
2.坐標(biāo)及動作的具體顯示:觸摸筆動作,觸點(diǎn)X坐標(biāo)值,觸點(diǎn)Y坐標(biāo)值。
1.2 設(shè)計意義
1.熟悉嵌入式系統(tǒng)開發(fā)平臺
2.掌握ARM嵌入式Linux操作系統(tǒng)下的各個指令的使用方法 3.了解觸摸屏的原理
1.3 設(shè)計內(nèi)容
1.Linux系統(tǒng)的正確移植和使用 2.根文件系統(tǒng)的正確移植和使用 3.驅(qū)動程序的編譯與裝載
4.嵌入式系統(tǒng)下應(yīng)用程序的交叉編譯及下載與調(diào)試
1.4 主要任務(wù)
1.熟悉實驗的流程
2.vivi,linux內(nèi)核的燒寫
3.cramfs文件系統(tǒng)(燒寫前需編譯)的燒寫 4.理解驅(qū)動程序源代碼
5.調(diào)用驅(qū)動程序的某些函數(shù),編譯與調(diào)試應(yīng)用程序
第二部分 正文
2.1觸摸屏工作原理(觸摸屏接口工作模式)
(1)普通轉(zhuǎn)換模式
普通轉(zhuǎn)換模式(AUTO_PST = 0,XY_PST = 0)是用作一般目的下的ADC轉(zhuǎn)換。這個模式可以通過設(shè)置ADCCON和ADCTSC來進(jìn)行對AD轉(zhuǎn)換的初始化;而后讀取ADCDAT0(ADC數(shù)據(jù)寄存器0)的XPDATA域(普通ADC轉(zhuǎn)換)的值來完成轉(zhuǎn)換。(2)分離的X/Y軸坐標(biāo)轉(zhuǎn)換模式:X軸坐標(biāo)轉(zhuǎn)換和Y軸坐標(biāo)轉(zhuǎn)換。
X軸坐標(biāo)轉(zhuǎn)換(AUTO_PST=0且XY_PST=1)將X軸坐標(biāo)轉(zhuǎn)換數(shù)值寫入到ADCDAT0寄存器的XPDATA域。轉(zhuǎn)換后,觸摸屏接口將產(chǎn)生中斷源(INT_ADC)到中斷控制器。
Y軸坐標(biāo)轉(zhuǎn)換(AUTO_PST=0且XY_PST=2)將X軸坐標(biāo)轉(zhuǎn)換數(shù)值寫入到ADCDAT1寄存器的YPDATA域。轉(zhuǎn)換后,觸摸屏接口將產(chǎn)生中斷源(INT_ADC)到中斷控制器。
(3)自動(連續(xù))X/Y軸坐標(biāo)轉(zhuǎn)換模式。
自動(連續(xù))X/Y軸坐標(biāo)轉(zhuǎn)換模式(AUTO_PST=1且XY_PST= 0)以下面的步驟工作:
觸摸屏控制器將自動地切換X軸坐標(biāo)和Y軸坐標(biāo)并讀取兩個坐標(biāo)軸方向上的坐標(biāo)。觸摸屏控制器自動將測量得到的X軸數(shù)據(jù)寫入到ADCDAT0寄存器的XPDATA域,然后將測量到的Y軸數(shù)據(jù)到ADCDAT1的YPDATA域。自動(連續(xù))轉(zhuǎn)換之后,觸摸屏控制器產(chǎn)生中斷源(INT_ADC)到中斷控制器。(4)等待中斷模式
當(dāng)觸摸屏控制器處于等待中斷模式下時,它實際上是在等待觸摸筆的點(diǎn)擊。在觸摸筆點(diǎn)擊到觸摸屏上時,控制器產(chǎn)生中斷信號(INC_TC)。中斷產(chǎn)生 2
后,就可以通過設(shè)置適當(dāng)?shù)霓D(zhuǎn)換模式(分離的X/Y軸坐標(biāo)轉(zhuǎn)換模式或自動X/Y軸坐標(biāo)轉(zhuǎn)換模式)來讀取X和Y的位置。(5)靜態(tài)(Standby)模式
當(dāng)ADCCON寄存器的STDBM位被設(shè)為1時,Standby模式被激活。在該模式下,A/D轉(zhuǎn)換操作停止,ADCDAT0寄存器的XPDATA域和ADCDAT1寄存器的YPDATA(正常ADC)域保持著先前轉(zhuǎn)換所得的值。
2.2、設(shè)計總體方案
1、軟件
(1)Embest Online Flash Programmer For ARM: Embest Flash在線編程器(2)HYPER TERMINAL(超級終端):傳送vivi.nand;
傳送vivi.nand
vivi> load flash kernel x <回車> 燒寫更新內(nèi)核,傳送zImage文件;等待傳送內(nèi)核文件
傳送內(nèi)核:
vivi>load flash root j <回車> 燒寫更新文件系統(tǒng);燒寫新的文件系統(tǒng) load flash root j
(3)EmbestIDE Pro for ARM: 應(yīng)用于嵌入式軟件開發(fā)的新一代集成開發(fā)環(huán)境,是一個高度集成的圖形界面操作環(huán)境,包含編輯器、編譯匯編鏈接器、調(diào)試器、工程管理、Flash 編程等工具;支持的開發(fā)語言包括標(biāo)準(zhǔn)C和匯編語言。(4)cygwin: 一個在windows平臺上運(yùn)行的unix模擬環(huán)境,它對于學(xué)習(xí)unix/linux操作環(huán)境,或者從unix到windows的應(yīng)用程序移植,或者進(jìn)行某些特殊的開發(fā)工作,尤其是使用gnu工具集在windows上進(jìn)行嵌 5
入式系統(tǒng)開發(fā),把gcc,gdb,gas等開發(fā)工具進(jìn)行了改進(jìn),能夠生成并解釋win32的目標(biāo)文件。
2、硬件
S3C2410處理器是Samsung公司基于ARM公司的ARM920T處理器核,32位微控制器。該處理器擁有:獨(dú)立的16KB指令Cache和16KB數(shù)據(jù)Cache,MMU,支持TFT的LCD控制器,NAND閃存控制器,3路UART,4路DMA,4路帶PWM的Timer,I/O口,RTC,8路10位ADC,Touch Screen接口,IIC-BUS 接口,IIS-BUS 接口,2個USB主機(jī),1個USB設(shè)備,SD主機(jī)和MMC接口,2路SPI。S3C2410處理器最高可運(yùn)行在203MHz。
2.3、設(shè)計所需工具
1.軟件: Embest Online Flash Programmer For ARM,HYPER TERMINAL(超級終端),EmbestIDE Pro for ARM,cygwin 1.硬件:s3c2410開發(fā)板,Embest實驗箱
2.4、平臺構(gòu)建過程
2.4.1、硬件平臺搭建
硬件流程圖:
(1)Vivi燒寫過程
1)首先把SW104斷開,F(xiàn)lash Programmer的Program,在File選擇Open打開要燒寫的配置文件S3C2410&NandFLash_vivi.cfg,在Flash Programmer的Program頁中選擇要燒寫的文件vivi.bon&load.bin。點(diǎn)擊按鈕 Progarm 開始燒寫,直到燒寫成功
2)連接串口線到 PC 機(jī) COM1,運(yùn)行光盤中提供的 Windows 超級終端Hyper Terminal.ht 把開發(fā)板重新加電,程序運(yùn)行后,在超級終端上可以看到串口輸出Wating,表示正在等待用戶從超級終端下載文件。這時,請點(diǎn)擊超級終端菜單“傳送”選擇 Xmodem 方式下載 vivi.nand 文件,點(diǎn)擊 OK 后等待下載燒寫結(jié)束即可。(2)內(nèi)核zImage燒寫
1)首先SW104設(shè)為短接(從Nand Flash啟動),并確定已經(jīng)燒寫vivi.nand,加電。)在vivi啟動等待中,敲入空格鍵進(jìn)入vivi界面環(huán)境,并輸入以下命令:vivi> load flash kernel x <回車> 燒寫更新內(nèi)核約1分鐘即可燒寫完畢 3)點(diǎn)擊超級終端菜單中的“傳送”,選“發(fā)送文件”zImage” 并選擇xModem方式傳送)燒寫結(jié)束,重起實驗板,觀測超級終端窗口提示信息就可以啟動linux內(nèi)核,(3)新文件系統(tǒng)的燒寫
1)首先SW104設(shè)為短接(從Nand Flash啟動),確定已經(jīng)成功燒寫vivi.nand,加電運(yùn)行可以看到vivi啟動信息,輸入空格進(jìn)入命令狀態(tài);
2)雙擊運(yùn)行Download.pjf(該文件在/tmp/edukit-2410/image/中)工程(將啟動Embest IDE環(huán)境),點(diǎn)擊連接Remote connect,程序應(yīng)該正在運(yùn)行(命令按鈕STOP為紅色);在串口輸入help,看看有沒有反應(yīng),如果沒反應(yīng),點(diǎn)擊IDE 按鈕:Reset->Start(F5);再輸入help測試,直到有反應(yīng)為止;
3)如果可以輸出一些信息,再點(diǎn)擊IDE中的Stop,配置Debug的Download地址為0x30000000,并點(diǎn)擊IDE菜單Project選擇Settings項,在Download頁下拉Category到Download項,在Download File選擇root.cramfs文件,點(diǎn)擊確定后:
點(diǎn)擊IDE菜單DEBUG選擇Download下載文件系統(tǒng)映象?約1分鐘
下載完畢后,點(diǎn)擊Start(F5)然后在超級終端里輸入: load flash root j(燒寫更新文件系統(tǒng))?約1分鐘即可燒寫完畢
注意:只能在“vivi的燒寫”操作完成后,才可以按以上方法正確燒寫root映象到Nand Flash。
重起實驗板,觀測超級終端窗口提示信息,引導(dǎo)整個系統(tǒng)啟動到linux行命令輸入狀態(tài)。
2.4.2根文件系統(tǒng)的制作(1)根文件系統(tǒng)
根文件系統(tǒng)是Linux系統(tǒng)的核心部分,包含系統(tǒng)使用的軟件和庫,以及所有用來為用戶提供支持架構(gòu)和用戶使用的應(yīng)用軟件,并作為儲存數(shù)據(jù)讀寫結(jié)果的區(qū)域。在Linux系統(tǒng)啟動時,首先完成內(nèi)核安裝及環(huán)境初始化,最后會尋找一個文件系統(tǒng)作為根文件系統(tǒng)被加載。Linux系統(tǒng)中使用“/”來唯一表示根文件系統(tǒng)的安裝路徑。嵌入式系統(tǒng)中通??梢詰抑母募到y(tǒng)有:Romfs、CRAMFS、RAMFS、JFFS2、EXT2等,甚至還可以使用NFS作為根文件系統(tǒng)。
(2)cramfs文件系統(tǒng)
Cramfs是Linux創(chuàng)始人Linux torvalds開發(fā)的一個適用于嵌入式系統(tǒng)的小文件系統(tǒng)。Cramfs是一個只讀文件系統(tǒng),采用zlib壓縮,壓縮比一般可以達(dá)到1:2,但仍可以做到高效的隨機(jī)讀取。Linux系統(tǒng)中,通常把需要修改的目錄壓縮存放,并在系統(tǒng)引導(dǎo)的時候再將壓縮文件解開。因為cramfs不會影響系統(tǒng)讀取文件的速度,而且是一個高度壓縮的文件系統(tǒng),因此非常廣泛應(yīng)用于嵌入式系統(tǒng)中。
(3)cygwin簡介
Cygwin是一個在windows平臺上運(yùn)行的unix/Linux模擬環(huán)境,是cygnus solutions公司開發(fā)的自由軟件。Cygwin中,“/”表示根目錄,即cygwin的安 8
裝目錄。我們常用的set_env_linux.sh中定義的目錄有:
SOURCEDIR:/tmp/edukit-2410存儲了vivi、linux、fs等源代碼和例程 WORKDIR:/usr/local/src/edukit-2410工作區(qū)。
一般情況下都要把已經(jīng)規(guī)劃好的目錄結(jié)構(gòu)轉(zhuǎn)換成一個映象文件,即使用命令工具 mkcramfs(cygwin下為 mkcramfs.exe),把相應(yīng)的 cramfs 目錄樹壓縮為單一的映象文件。其命令格式為:
mkcramfs [-h] [-e edition] [-i file] [-n name] dirname outfile 可以使用我們提供的 mkcramfs.exe 在 cygwin 下編譯生成文件系統(tǒng)映象文件 root.cramfs,再固化到開發(fā)系統(tǒng) FLASH 上運(yùn)行。
(4)常用的Linux行命令
1)、cd 改變當(dāng)前目錄(文件夾)。例如下,cd/ 返回到根目錄 cd..退回到上級目錄
cd/tmp/edukit-2410/進(jìn)入/tmp/edukit-2410/文件夾 2)、ls 列出當(dāng)前目錄中的內(nèi)容。Ls 簡單格式列表 ls–l 使用詳細(xì)格式列表。3)、pwd 顯示當(dāng)前所在的目錄。
(5)tar工具命令
tar 程序用于儲存或展開 tar 存檔文件。命令格式:
tar [-參數(shù)] [文件名][路徑]-x :extract |--get 從存檔展開文件-v :--verbose 詳細(xì)顯示處理的文件-j :--有 bz2 屬性的必須包含
-f :--file [HOSTNAME:]F 指定存檔或設(shè)備(缺省為 /dev/rmt0)
(6)解壓原文件系統(tǒng)(命令+解壓目錄的存放)
1)先將 root.cramfs.tar.bz2文件放在C:cygwin目錄中
2)解壓文件系統(tǒng)
運(yùn)行cygwin,執(zhí)行以下命令解壓安裝:
$> source /tmp/edukit-2410/set_env_linux.sh? Linux編譯環(huán)境變量設(shè)置 $> cd /
$> tar-xvjf root.cramfs.tar.bz2 $> ls ? root ?
root文件夾中就是我們想要的cramfs文件系統(tǒng) 3)如果在根目錄中產(chǎn)生root文件夾,解壓成功 4)在root目錄中新建xx文件夾,用于存放應(yīng)用程序
進(jìn)入該目錄后執(zhí)行以下命令編譯鏈接測試程序: $> cd root $>mkdir xx
(7)編譯應(yīng)用程序 ts.c(命令+生成文件格式+存放位置): 將編寫好的ts.c程序放在C:cygwin目錄中 進(jìn)入該目錄后執(zhí)行以下命令編譯鏈接測試程序: $> cd / $> arm-linux-gcc-o ts ts.c(也可以編寫Makefile來編譯)
生成文件: ts 如下圖所示
將ts文件放入root 下的xx文件夾中
(8)新文件系統(tǒng)的制作: 把剛才編譯輸出的ts文件拷貝到文件系統(tǒng)所在的工作目錄root目錄下,執(zhí)行以下命令生成新的文件系統(tǒng)映象: $> cd /
$> mkcramfs root root.new
剛剛編譯生成的文件系統(tǒng)映象 root.new 中已經(jīng)包含測試程序即生成文件。解壓文件系統(tǒng)
解壓成功如下
在root目錄中新建xx文件夾,用于存放應(yīng)用程序
將編寫好的ts.c程序放在C:cygwin目錄中
生成文件: ts 如下圖所示
新文件系統(tǒng)的制作
生成文件:
第三章 程序
3.1.程序流程圖:
3.2.分析驅(qū)動
觸摸屏驅(qū)動在/kernel/drivers/char/s3c2410-ts.c 文件中。
3.2.1、觸摸屏設(shè)備驅(qū)動中數(shù)據(jù)結(jié)構(gòu)
(1)觸摸屏的file_operations static struct file_operations s3c2410_fops={ owner: THIS_MODULE, open: s3c2410_ts_open, read: s3c2410_ts_read,release: s3c2410_ts_release, #ifdef USE_ASYNC fasync: s3c2410_ts_fasync,//異步通知
#endif poll: s3c2410_ts_poll,//輪詢 };(2)觸摸屏設(shè)備結(jié)構(gòu)體的成員與按鍵設(shè)備結(jié)構(gòu)體的成員類似,也包含一個緩沖區(qū),同時包括自旋鎖、等待隊列和fasync_struct指針 typedef struct { unsigned int penStatus;/* PEN_UP, PEN_DOWN, PEN_SAMPLE */ TS_RET buf[MAX_TS_BUF];/* protect against overrun(環(huán)形緩沖區(qū))*/ unsigned int head, tail;/* head and tail for queued events(環(huán)形緩沖區(qū)的頭尾)*/ wait_queue_head_t wq;//* 等待隊列數(shù)據(jù)結(jié)構(gòu) spinlock_t lock;//* 自旋鎖
#ifdef USE_ASYNC struct fasync_struct *aq;#endif #ifdef CONFIG_PM struct pm_dev *pm_dev;//友善之臂專有的,我后面的代碼刪除了這段 #endif } TS_DEV;
(3)觸摸屏結(jié)構(gòu)體中包含的TS_RET值的類型定義,包含X、Y坐標(biāo)和狀態(tài)(PEN_DOWN、PEN_UP)等信息,這個信息會在用戶讀取觸摸信息時復(fù)制到用戶空 間
typedef struct { 14
unsigned short pressure;//* 壓力,這里可定義為筆按下,筆抬起,筆拖曳
unsigned short x;//* 橫坐標(biāo)的采樣值 unsigned short y;//* 縱坐標(biāo)的采樣值 unsigned short pad;//* 填充位 } TS_RET;
(4)在觸摸屏設(shè)備驅(qū)動中,將實現(xiàn)open()、release()、read()、fasync()和poll()函數(shù),因此,其文件操作結(jié)構(gòu)體定義
觸摸屏驅(qū)動文件操作結(jié)構(gòu)體:static struct file_operations s3c2410_fops={} 3.2.2、觸摸屏驅(qū)動模塊加載和卸載函數(shù)
(1)在觸摸屏設(shè)備驅(qū)動的模塊加載函數(shù)中,要完成申請設(shè)備號、添加cdev、申請中斷、設(shè)置觸摸屏控制引腳(YPON、YMON、XPON、XMON)等多項工作 觸摸屏設(shè)備驅(qū)動的模塊加載函數(shù)
static int __init s3c2410_ts_init(void)觸摸屏設(shè)備驅(qū)動模塊卸載函數(shù)
static void __exit s3c2410_ts_exit(void)(2)可知觸摸屏驅(qū)動中會產(chǎn)生兩類中斷,一類是觸點(diǎn)中斷(INT-TC),一類是X/Y位置轉(zhuǎn)換中斷(INT-ADC)。在前一類中斷發(fā)生后,若之前處于PEN_UP狀態(tài),則應(yīng)該啟動X/Y位置轉(zhuǎn)換。另外,將抬起中斷也放在INT-TC處理程序中,它會調(diào)用tsEvent()完成等待隊列和信號的釋放 觸摸屏設(shè)備驅(qū)動的觸點(diǎn)/抬起中斷處理程序
static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)
當(dāng)X/Y位置轉(zhuǎn)換中斷發(fā)生后,應(yīng)讀取X、Y的坐標(biāo)值,填入緩沖區(qū) 觸摸屏設(shè)備驅(qū)動X/Y位置轉(zhuǎn)換中斷處理程序
static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg)觸摸屏設(shè)備驅(qū)動中獲得X、Y坐標(biāo)
static inline void s3c2410_get_XY(void)(3)tsEvent最終為tsEvent_raw(),這個函數(shù)很關(guān)鍵,當(dāng)處于PEN_DOWN狀態(tài)時調(diào)用該函數(shù),它會完成緩沖區(qū)的填充、等待隊列的喚醒以及異步通知信號的釋放;否則(處于PEN_UP狀態(tài)),將緩沖區(qū)頭清0,也喚醒等待隊列并釋放信號
觸摸屏設(shè)備驅(qū)動的tsEvent_raw()函數(shù) static void tsEvent_raw(void)(4)在包含了對拖動軌跡支持的情況下,定時器會被啟用,周期為10ms,在每次定時器處理函數(shù)被引發(fā)時,調(diào)用start_ts_adc()開始X/Y位置轉(zhuǎn)換過程
觸摸屏設(shè)備驅(qū)動的定時器處理函數(shù)
static void ts_timer_handler(unsigned long data)(5)在觸摸屏設(shè)備驅(qū)動的打開函數(shù)中,應(yīng)初始化緩沖區(qū)、penStatus和定期器、等待隊列及tsEvent時間處理函數(shù)指針 觸摸屏設(shè)備驅(qū)動的打開函數(shù)
static int s3c2410_ts_open(struct inode *inode, struct file *filp)16
(6)觸摸屏設(shè)備驅(qū)動的釋放函數(shù)非常簡單,刪除為用于拖動軌跡所使用的定時器即可
觸摸屏設(shè)備驅(qū)動的釋放函數(shù)
static int s3c2410_ts_release(struct inode *inode, struct file *filp)3.2.3、觸摸屏設(shè)備驅(qū)動的讀函數(shù)
觸摸屏設(shè)備驅(qū)動的讀函數(shù)實現(xiàn)緩沖區(qū)中信息向用戶空間的復(fù)制,當(dāng)緩沖區(qū)有內(nèi)容時,直接復(fù)制;否則,如果用戶阻塞訪問觸摸屏,則進(jìn)程在等待隊列上睡眠,否則,立即返回-EAGAIN 觸摸屏設(shè)備驅(qū)動的讀函數(shù)
static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)3.2.4、觸摸屏設(shè)備驅(qū)動的輪詢與異步通知
在觸摸屏設(shè)備驅(qū)動中,通過s3c2410_ts_poll()函數(shù)實現(xiàn)了輪詢接口,這個函數(shù)的實現(xiàn)非常簡單。它將等待隊列添加到poll_table,當(dāng)緩沖區(qū)有數(shù)據(jù)時,返回資源可讀取標(biāo)志,否則返回0 觸摸屏設(shè)備驅(qū)動的poll()函數(shù)
static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait)而為了實現(xiàn)觸摸屏設(shè)備驅(qū)動對應(yīng)用程序的異步通知,設(shè)備驅(qū)動中要實現(xiàn)s3c2410_ts_fasync()函數(shù) 觸摸屏設(shè)備驅(qū)動的fasync()函數(shù)
static int s3c2410_ts_fasync(int fd, struct file *filp, int mode)3.2.5源程序觸摸屏驅(qū)動代碼:
/* * s3c2410-ts.c * * touchScreen driver for SAMSUNG S3C2410 * * Author: Janghoon Lyu
#include
#include
#include
#ifdef CONFIG_PM #include
/* debug macros */ #undef DEBUG #ifdef DEBUG #define DPRINTK(x...)printk(“s3c2410-ts: ” ##x)#else #define DPRINTK(x...)#endif
#define PEN_UP 0
#define PEN_DOWN 1 #define PEN_FLEETING 2 #define MAX_TS_BUF 16 /* how many do we want to buffer */
#undef USE_ASYNC 1 #define DEVICE_NAME “s3c2410-ts” #define TSRAW_MINOR 1
typedef struct { unsigned int penStatus;/* PEN_UP, PEN_DOWN, PEN_SAMPLE */ TS_RET buf[MAX_TS_BUF];/* protect against overrun */ unsigned int head, tail;/* head and tail for queued events */ wait_queue_head_t wq;spinlock_t lock;#ifdef USE_ASYNC struct fasync_struct *aq;#endif #ifdef CONFIG_PM struct pm_dev *pm_dev;#endif } TS_DEV;
static TS_DEV tsdev;
#define BUF_HEAD(tsdev.buf[tsdev.head])#define BUF_TAIL(tsdev.buf[tsdev.tail])#define INCBUF(x,mod)((++(x))&((mod)-1))
static int tsMajor = 0;
static void(*tsEvent)(void);
#define HOOK_FOR_DRAG #ifdef HOOK_FOR_DRAG #define TS_TIMER_DELAY(HZ/100)/* 10 ms */ static struct timer_list ts_timer;#endif
#define wait_down_int(){ ADCTSC = DOWN_INT | XP_PULL_UP_EN |
XP_AIN | XM_HIZ | YP_AIN | YM_GND |
XP_PST(WAIT_INT_MODE);} #define wait_up_int(){ ADCTSC = UP_INT | XP_PULL_UP_EN | XP_AIN | XM_HIZ |
YP_AIN | YM_GND | XP_PST(WAIT_INT_MODE);} #define mode_x_axis(){ ADCTSC = XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ |
XP_PULL_UP_DIS | XP_PST(X_AXIS_MODE);} #define mode_x_axis_n(){ ADCTSC = XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ |
XP_PULL_UP_DIS | XP_PST(NOP_MODE);} #define mode_y_axis(){ ADCTSC = XP_AIN | XM_HIZ | YP_EXTVLT | YM_GND |
XP_PULL_UP_DIS | XP_PST(Y_AXIS_MODE);} #define start_adc_x(){ ADCCON = PRESCALE_EN | PRSCVL(49)|
ADC_INPUT(ADC_IN5)| ADC_START_BY_RD_EN |
ADC_NORMAL_MODE;
ADCDAT0;} #define start_adc_y(){ ADCCON = PRESCALE_EN | PRSCVL(49)|
ADC_INPUT(ADC_IN7)| ADC_START_BY_RD_EN |
ADC_NORMAL_MODE;
ADCDAT1;} #define disable_ts_adc(){ ADCCON &= ~(ADCCON_READ_START);}
static int adc_state = 0;static int x, y;/* touch screen coorinates */
static void tsEvent_raw(void){ if(tsdev.penStatus == PEN_DOWN){
BUF_HEAD.x = x;
BUF_HEAD.y = y;
BUF_HEAD.pressure = PEN_DOWN;
#ifdef HOOK_FOR_DRAG
ts_timer.expires = jiffies + TS_TIMER_DELAY;
add_timer(&ts_timer);#endif } else { #ifdef HOOK_FOR_DRAG
del_timer(&ts_timer);#endif
BUF_HEAD.x = 0;
BUF_HEAD.y = 0;
BUF_HEAD.pressure = PEN_UP;}
tsdev.head = INCBUF(tsdev.head, MAX_TS_BUF);wake_up_interruptible(&(tsdev.wq));
#ifdef USE_ASYNC if(tsdev.aq)
kill_fasync(&(tsdev.aq), SIGIO, POLL_IN);#endif
#ifdef CONFIG_PM pm_access(tsdev.pm_dev);#endif }
static int tsRead(TS_RET * ts_ret){ spin_lock_irq(&(tsdev.lock));ts_ret->x = BUF_TAIL.x;ts_ret->y = BUF_TAIL.y;ts_ret->pressure = BUF_TAIL.pressure;tsdev.tail = INCBUF(tsdev.tail, MAX_TS_BUF);spin_unlock_irq(&(tsdev.lock));
return sizeof(TS_RET);}
static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){ TS_RET ts_ret;
retry: if(tsdev.head!= tsdev.tail){
int count;
count = tsRead(&ts_ret);
if(count)copy_to_user(buffer,(char *)&ts_ret, count);
return count;} else {
if(filp->f_flags & O_NONBLOCK)
return-EAGAIN;
interruptible_sleep_on(&(tsdev.wq));
if(signal_pending(current))
return-ERESTARTSYS;
goto retry;}
return sizeof(TS_RET);}
#ifdef USE_ASYNC static int s3c2410_ts_fasync(int fd, struct file *filp, int mode){ return fasync_helper(fd, filp, mode, &(tsdev.aq));} #endif
static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait){ poll_wait(filp, &(tsdev.wq), wait);return(tsdev.head == tsdev.tail)? 0 :(POLLIN | POLLRDNORM);}
static inline void start_ts_adc(void){ adc_state = 0;mode_x_axis();start_adc_x();}
static inline void s3c2410_get_XY(void){ if(adc_state == 0){
adc_state = 1;
disable_ts_adc();
y =(ADCDAT0 & 0x3ff);
mode_y_axis();
start_adc_y();} else if(adc_state == 1){
adc_state = 0;
disable_ts_adc();
x =(ADCDAT1 & 0x3ff);
tsdev.penStatus = PEN_DOWN;
DPRINTK(“PEN DOWN: x: %08d, y: %08dn”, x, y);
wait_up_int();
tsEvent();} }
static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg){ #if 0 DPRINTK(“Occured Touch Screen Interruptn”);DPRINTK(“SUBSRCPND = 0x%08lxn”, SUBSRCPND);#endif spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_UP)s3c2410_get_XY();#ifdef HOOK_FOR_DRAG else s3c2410_get_XY();#endif spin_unlock_irq(&(tsdev.lock));}
static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg){ #if 0 DPRINTK(“Occured Touch Screen Interruptn”);DPRINTK(“SUBSRCPND = 0x%08lxn”, SUBSRCPND);#endif spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_UP){ start_ts_adc();} else { tsdev.penStatus = PEN_UP;DPRINTK(“PEN UP: x: %08d, y: %08dn”, x, y);wait_down_int();tsEvent();
} spin_unlock_irq(&(tsdev.lock));}
#ifdef HOOK_FOR_DRAG static void ts_timer_handler(unsigned long data){ spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_DOWN){
start_ts_adc();} spin_unlock_irq(&(tsdev.lock));} #endif
static int s3c2410_ts_open(struct inode *inode, struct file *filp){ tsdev.head = tsdev.tail = 0;tsdev.penStatus = PEN_UP;#ifdef HOOK_FOR_DRAG init_timer(&ts_timer);ts_timer.function = ts_timer_handler;#endif tsEvent = tsEvent_raw;init_waitqueue_head(&(tsdev.wq));
MOD_INC_USE_COUNT;return 0;}
static int s3c2410_ts_release(struct inode *inode, struct file *filp){ #ifdef HOOK_FOR_DRAG del_timer(&ts_timer);#endif MOD_DEC_USE_COUNT;return 0;}
static struct file_operations s3c2410_fops = { owner: THIS_MODULE, open: s3c2410_ts_open, read: s3c2410_ts_read,release: s3c2410_ts_release,#ifdef USE_ASYNC fasync: s3c2410_ts_fasync, #endif poll: s3c2410_ts_poll, };
void tsEvent_dummy(void){} #ifdef CONFIG_PM static int s3c2410_ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,void *data){ switch(req){
case PM_SUSPEND:
tsEvent = tsEvent_dummy;
break;
case PM_RESUME:
tsEvent = tsEvent_raw;
wait_down_int();
break;} return 0;} #endif
#ifdef CONFIG_DEVFS_FS static devfs_handle_t devfs_ts_dir, devfs_tsraw;#endif static int __init s3c2410_ts_init(void){ int ret;
tsEvent = tsEvent_dummy;
ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);if(ret < 0){ printk(DEVICE_NAME “ can't get major numbern”);return ret;} tsMajor = ret;
/* set gpio to XP, YM, YP and YM */ #if 0 set_GPIO_mode(GPIO106_nYPON_MD);
set_GPIO_mode(GPIO105_YMON_MD);set_GPIO_mode(GPIO104_nXPON_MD);set_GPIO_mode(GPIO103_XMON_MD);
GPUP(GPIO106_nYPON)|= GPIO_bit(GPIO106_nYPON);GPUP(GPIO105_YMON)&= GPIO_bit(GPIO105_YMON);GPUP(GPIO104_nXPON)|= GPIO_bit(GPIO104_nXPON);GPUP(GPIO103_XMON)&= GPIO_bit(GPIO103_XMON);#else set_gpio_ctrl(GPIO_YPON);set_gpio_ctrl(GPIO_YMON);set_gpio_ctrl(GPIO_XPON);set_gpio_ctrl(GPIO_XMON);#endif
/* Enable touch interrupt */ ret = request_irq(IRQ_ADC_DONE, s3c2410_isr_adc, SA_INTERRUPT,DEVICE_NAME, s3c2410_isr_adc);if(ret)goto adc_failed;ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT,DEVICE_NAME, s3c2410_isr_tc);if(ret)goto tc_failed;
/* Wait for touch screen interrupts */ wait_down_int();
#ifdef CONFIG_DEVFS_FS devfs_ts_dir = devfs_mk_dir(NULL, “touchscreen”, NULL);devfs_tsraw = devfs_register(devfs_ts_dir, “0raw”, DEVFS_FL_DEFAULT,tsMajor, TSRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,&s3c2410_fops, NULL);#endif
#ifdef CONFIG_PM #if 0 tsdev.pm_dev = pm_register(PM_GP_DEV, PM_USER_INPUT,s3c2410_ts_pm_callback);#endif tsdev.pm_dev = pm_register(PM_DEBUG_DEV, PM_USER_INPUT,s3c2410_ts_pm_callback);#endif printk(DEVICE_NAME “ initializedn”);
return 0;tc_failed: free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);adc_failed: return ret;}
static void __exit s3c2410_ts_exit(void){ #ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_tsraw);devfs_unregister(devfs_ts_dir);#endif unregister_chrdev(tsMajor, DEVICE_NAME);#ifdef CONFIG_PM pm_unregister(tsdev.pm_dev);#endif free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);free_irq(IRQ_TC, s3c2410_isr_tc);}
module_init(s3c2410_ts_init);module_exit(s3c2410_ts_exit);觸摸屏應(yīng)用程序
#include
#define PEN_UP 0 /* 觸摸筆抬筆,即觸摸屏不被壓下 */ #define PEN_DOWN 1 /* 觸摸筆下筆,即觸摸屏被壓下 */ #define PEN_FLEETING 2 /* 觸摸筆拖動 */
typedef struct { unsigned short pressure;/* 觸摸筆動作 */ unsigned short x;
/* 觸點(diǎn)x座標(biāo)值 */ unsigned short y;
/* 觸點(diǎn)y座標(biāo)值 */ unsigned short pad;}TS_RET;
int main(){ int fd,ret,i;
unsigned char suba;TS_RET tsret;
fd = open(“/dev/touchscreen/0raw”, O_RDWR);/* 打開設(shè)備 */ if(fd ==-1){ printf(“nCan't open I2C device!n”);exit(-1);}
while(1){
ret = read(fd,(char *)&tsret, sizeof(TS_RET));
if(ret!= sizeof(TS_RET))
{
printf(“read touch screen error!”);
close(fd);
exit(-1);
}
else
{
printf(“pressure is: %dn”, tsret.pressure);
printf(“x is: %dn”, tsret.x);
printf(“y is: %dn”, tsret.y);
} }
close(fd);return 0;} 3.3.應(yīng)用程序的調(diào)試
使用s3c2410_ts.c觸摸屏驅(qū)動編寫應(yīng)用程序,讀取觸摸屏的觸點(diǎn)坐標(biāo)值及動作信息(觸點(diǎn)x坐標(biāo)值,y坐標(biāo)及是否有壓力值press),并在串口中斷打印出來
對觸摸屏設(shè)別的操作有打開設(shè)備,關(guān)閉設(shè)備,讀操作等。編寫應(yīng)用程序讀取觸摸屏的觸點(diǎn)坐標(biāo)值及動作信息時,只需利用觸摸屏驅(qū)動程序便可實現(xiàn),先打開觸摸屏設(shè)備,然后調(diào)用讀函數(shù)即可。
其中,觸摸筆動作取值如下: #define PEN_UP 0 #define PEN_DOWN
/* 觸摸筆抬筆,即觸摸屏不被壓下 */ /* 觸摸筆下筆,即觸摸屏被壓下 */
#define PEN_FLEETING 2 結(jié)構(gòu)體定義如下: typedef struct { unsigned short pressure;unsigned short x;unsigned short y;unsigned short pad;}TS_RET 打開應(yīng)用程序:
/* 觸摸筆拖動 */
/* 觸摸筆動作 */ /* 觸點(diǎn)x座標(biāo)值 */ /* 觸點(diǎn)y座標(biāo)值 */
3.2.6、實驗結(jié)果顯示:
第四部分 感想
第四部分 心得
4.1 課程設(shè)計心得體會:
為期幾天的課程設(shè)計結(jié)束了,再次期間我積極親自實驗,用的目標(biāo)板是s3c2410核心子板,用JTAG仿真器,用Cygwin模擬軟件來學(xué)習(xí)觸摸板的設(shè)計。我學(xué)會了很多,學(xué)會了很多。
首先我捫主要了解整個設(shè)計過程,以及實驗環(huán)境的建立,這次用的是交叉編譯環(huán)境,通過這次課設(shè)我更清楚搭建嵌入式系統(tǒng)的開發(fā)平臺,我們用的目標(biāo)板是s3c2410核心子板,用JTAG仿真器,用Cygwin模擬軟件,課設(shè)的這幾天我學(xué)會了熟練的使用Cygwin軟件,掌握了一些常用的命令,加上研究生學(xué)長給我們的指導(dǎo),知道了如何學(xué)習(xí),如何思考,知道了運(yùn)linux操作系統(tǒng)開發(fā)嵌入式與wince操作系統(tǒng)開發(fā)嵌入式的區(qū)別。
其次是學(xué)會vivi,內(nèi)核,根文件系統(tǒng)的編譯與移植(燒寫),通過這個過程我熟悉了怎么把軟件固化到硬件上,知道了軟件怎么控制硬件,這個步驟很重要,要燒寫不成功,目標(biāo)板系統(tǒng)就運(yùn)行不起來,實驗就失敗了,這個過程我們練習(xí)了好多變呢,大家都很累哦!
再次我們就開始寫我們的應(yīng)用程序,通過以上步驟實驗系統(tǒng)搭建好了,只要調(diào)試好應(yīng)用程序,然后再運(yùn)行成功就行了,為此我又把課本上講得觸摸屏原理那章認(rèn)真看了,又看了實驗指導(dǎo)書,查資料,上網(wǎng)搜索,終于編出應(yīng)用程序,經(jīng)過不斷的調(diào)試才編譯成功,這個過程太辛苦了,加上實驗板不太好,真是對我們的挑戰(zhàn),不過看到運(yùn)行的 30
結(jié)果,大家都很高興,也很有成就感啊!還看懂了一些s3c2410的驅(qū)動程序的源代碼,了解了s3c2410一些控制器的使用,以及s3c2410A的一些接口原理與應(yīng)用。
我明白了只有不斷的努力,不斷的學(xué)習(xí),才能在將來遇到的問題中能夠游刃有余,才能夠不會捉襟見肘。
第五部分 參考文獻(xiàn)
5.1【參考文獻(xiàn)】 程昌南,方強(qiáng)等.《ARM Linux入門與實踐 》【M】.北京:北京航空航天大學(xué)出版社,2008.10 2 張曉林等.《嵌入式系統(tǒng)設(shè)計與實踐》【M】.北京:北京航空航天大學(xué)出版社,2006.1 3 李俊等.《嵌入式Linux設(shè)備驅(qū)動開發(fā)詳解》【M】.北京:北京人民郵電出版社,2008.3 4 黃智偉,鄧月明,王彥.《ARM9嵌入式系統(tǒng)設(shè)計基礎(chǔ)教程》.北京:北京航空航天大學(xué)出版社,2008.8 5 [美]Wayne Wolf.嵌入式計算系統(tǒng)設(shè)計原理.孫玉芳, 梁彬 羅保國 等譯.北京: 機(jī)械工業(yè)出版社, 2002 李劍, 趙鵬程, 湯建彬.32位ARM嵌入式處理器的調(diào)試技術(shù).電子技術(shù)應(yīng)用, 2003,(3)鐘漢如, 王創(chuàng)生.嵌入式Linux的中斷處理與實時調(diào)度的實現(xiàn)機(jī)制.計算機(jī)工程, 2002, 28(10)Arnold Berger.嵌入式系統(tǒng)設(shè)計.呂駿 譯.北京: 電子工業(yè)出版社, 2002
第二篇:嵌入式程序設(shè)計課程設(shè)計
課程設(shè)計
課 程 名嵌入式軟件開發(fā)技術(shù)
題 目 基于嵌入式Linux的溫度監(jiān)測系統(tǒng)的
設(shè)計與實現(xiàn)
專 業(yè) 計算機(jī)科學(xué)與技術(shù)(嵌入式系統(tǒng)方向)班 級 13計算機(jī)嵌入式系統(tǒng)班 學(xué) 號 學(xué)生姓名
2016年6月
摘要
溫度是個很普遍而又非常重要的參數(shù),在日常生活、工農(nóng)業(yè)生產(chǎn)以及科研領(lǐng)域都有著廣泛的應(yīng)用。因此,研制能夠準(zhǔn)確地測量和記錄這個參數(shù)值的系統(tǒng)具有十分重要的意義。
基于ARM的嵌入式溫度監(jiān)測系統(tǒng)是采用嵌入式Linux作為操作系統(tǒng),針對以S5PV210為處理器的開發(fā)板設(shè)計的一個嵌入式溫度監(jiān)測系統(tǒng)。論文在分析了Linux設(shè)備驅(qū)動程序的基本工作原理基礎(chǔ)上,討論了開發(fā)中經(jīng)常會碰到的中斷處理、擁塞處理、I/O端口,并在此基礎(chǔ)上實現(xiàn)了基于S5PV210嵌入式處理器的開、讀、寫、關(guān)外部RAM的字符設(shè)備驅(qū)動和網(wǎng)絡(luò)驅(qū)動。結(jié)合高精度溫度傳感器DS18B20,實現(xiàn)溫度的正確采集,并通過以太網(wǎng)絡(luò)將數(shù)據(jù)上傳給上位機(jī)客戶端。
論文首先介紹了通信網(wǎng)絡(luò)中各種設(shè)備特性、總線結(jié)構(gòu)及傳輸技術(shù),然后根據(jù)單片機(jī)與PC機(jī)之間的串行通信原理,用ubantu完成溫度監(jiān)測系統(tǒng)的軟件設(shè)計與實現(xiàn),為用戶提供一個友好的人機(jī)界面,對監(jiān)測系統(tǒng)進(jìn)行控制并顯示采集后的數(shù)據(jù)。本系統(tǒng)還通過多線程實現(xiàn)了多個客戶端與服務(wù)器的通信。
關(guān)鍵詞:S5PV210;嵌入式Linux操作系統(tǒng);DS18B20;網(wǎng)絡(luò)編程
I
Abstract
Temperature is a very common and very important parameter, in daily life, industrial and agricultural production and scientific research fields have a wide range of applications.Therefore, it is very important to develop a system that can accurately measure and record the value of this parameter.The temperature monitoring system of base on the ARM is use of embedded Linux as the operating system for the processor to S5PV210 development board designed for an embedded temperature monitoring system.Based on the analysis of the basic working principle based on the Linux device drivers discussed development often encounter interrupt handling, congestion handling, I / O ports, and on this basis to achieve the embedded processor based on open S5PV210 reading, writing, characters off the external RAM device driver and network drives.Combined with precision temperature sensor DS18B20, to achieve the correct temperature acquisition, and upload the data via Ethernet to a PC client.At first,the paper introduces the characteristics of various devices in a communication network, the bus structure and transmission technology, and according to the principle of serial communication between SCM and PC, with ubantu complete temperature monitoring system software design and implementation, to provide users with a friendly man-machine interface, the monitoring system to control and display the data after collection.The system also enables communication via a plurality of multi-threaded client and the server.Key words:S5PV210;embedded Linux operating system;DS18B20;Network programming
II
1.引言.......................................................................................................................................1 1.1 設(shè)計背景及意義...............................................................................................................1 1.2 設(shè)計的主要內(nèi)容................................................................................................................2 2.相關(guān)技術(shù)...............................................................................................................................2 2.1 嵌入式Linux......................................................................................................................2 2.2 S5PV210.............................................................................................................................3 2.3 socket網(wǎng)絡(luò)編程..............................................................................................................3 3.具體實現(xiàn)功能.......................................................................................................................4 3.1總體框架圖........................................................................................................................4 3.2客戶端功能........................................................................................................................5 3.3 服務(wù)器功能........................................................................................................................5 3.4 實驗板輸出信息...............................................................................................................5 4.具體實現(xiàn)過程.......................................................................................................................6 4.1 交叉編譯工具的安裝.......................................................................................................6 4.2 客戶端模塊的設(shè)計...........................................................................................................7 4.3 服務(wù)器模塊.......................................................................................................................8 4.4 LED點(diǎn)亮模塊..................................................................................................................10 4.5 溫度感應(yīng)模塊.................................................................................................................11 5.測試結(jié)果分析.....................................................................................................................13 5.1 各模塊運(yùn)行的效果.........................................................................................................13 5.2 可擴(kuò)展功能......................................................................................................................15 6.總結(jié)與展望.......................................................................................................................15
第一章 引言
1.1 設(shè)計背景及意義
溫度作為工業(yè)、農(nóng)業(yè)、國防和科研等部門最普遍的測量項目。它在工農(nóng)業(yè)生產(chǎn)、現(xiàn)代科學(xué)研究以及高新技術(shù)開發(fā)過程中也是一個極其普遍而又非
常重要的參數(shù)。因此,在這些領(lǐng)域中,對于這個參數(shù)的測量與控制就顯得尤為重要,特別是在紡織工業(yè)、冶金、化工、食品、溫室種植,汽車制造以及氣象預(yù)報和科研實驗室等許多地方,都具有舉足輕重的作用。
以往這些工作大多是由人工完成,不但工作量大,記錄的數(shù)據(jù)少,對溫度的調(diào)節(jié)缺乏實時性,而且電路復(fù)雜,標(biāo)定和校準(zhǔn)也比較麻煩,難以滿足現(xiàn)代溫度測量的要求[1]。自從傳感器技術(shù)、微控制器技術(shù)和計算機(jī)技術(shù)日漸成熟之后,現(xiàn)代的溫度測量與控制系統(tǒng)克服了以往系統(tǒng)中存在的一些問題,比如對環(huán)境溫度的控制與調(diào)節(jié)以及數(shù)據(jù)的記錄都由微控制器或計算機(jī)自動完成,人們的工作量大大地降低,而且測得的數(shù)據(jù)也更加的精確,對環(huán)境溫度的調(diào)節(jié)更具有實時性[2]。
1.2 設(shè)計的主要內(nèi)容
此次主要采用嵌入式Linux作為操作系統(tǒng),針對以S5PV210為處理器的開發(fā)板設(shè)計的一個嵌入式溫度監(jiān)測系統(tǒng)。在Linux設(shè)備驅(qū)動程序的基本工作原理基礎(chǔ)上,討論了開發(fā)中經(jīng)常會碰到的中斷處理、擁塞處理、I/O端口,并在此基礎(chǔ)上實現(xiàn)了基于S5PV210嵌入式處理器的開、讀、寫、關(guān)外部RAM的字符設(shè)備驅(qū)動和網(wǎng)絡(luò)驅(qū)動。結(jié)合高精度溫度傳感器DS18B20,實現(xiàn)溫度的正確采集,并通過以太網(wǎng)絡(luò)將數(shù)據(jù)上傳給上位機(jī)客戶端。
溫度監(jiān)測系統(tǒng)根據(jù)Linux中的網(wǎng)絡(luò)通信技術(shù)和串口通信技術(shù)來傳輸數(shù)據(jù)。用ubantu完成溫度監(jiān)測系統(tǒng)的軟件設(shè)計與實現(xiàn),為用戶提供一個友好的人機(jī)界面,對監(jiān)測系統(tǒng)進(jìn)行控制并顯示采集后的數(shù)據(jù)。本系統(tǒng)還通過多線程實現(xiàn)了多個客戶端與服務(wù)器的通信。
第二章 相關(guān)技術(shù)
2.1 嵌入式Linux Linux是UNIX系統(tǒng)的一套免費(fèi)使用和自由傳播的類Unix操作系統(tǒng),是一個基于POSIX和UNIX的多用戶、多任務(wù)、支持多線程和多CPU的操作系統(tǒng)。它能運(yùn)行主要的UNIX工具軟件、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。支持32位和64位硬件。Linux繼承了Unix以網(wǎng)絡(luò)為核心的設(shè)計思想,是一個性能穩(wěn)定的多用戶網(wǎng)絡(luò)操作系統(tǒng)。它誕生與1991年的10月5日。以后借助與Internet
網(wǎng),并進(jìn)過全世界各地計算機(jī)愛好者的共同努力下,現(xiàn)已成為世界上使用最多的一種UNIX類操作系統(tǒng),并且使用人數(shù)還在迅猛增漲。
本次設(shè)計采用Linux作為嵌入式操作系統(tǒng)的原因有以下幾點(diǎn):[3] 1)低成本開發(fā)系統(tǒng): 2)可應(yīng)用于多種硬件平臺 3)可定制的內(nèi)核 4)性能優(yōu)異 5)良好的網(wǎng)絡(luò)支持
2.2 S5PV210
S5PV210又名“蜂鳥”(Hummingbird),是三星推出的一款適用于智能手機(jī)和平板電腦等多媒體設(shè)備的應(yīng)用處理器。
S5PV210采用了ARM CortexTM-A8內(nèi)核,ARM V7指令集,主頻可達(dá)1GHZ,64/32位內(nèi)部總線結(jié)構(gòu),32/32KB的數(shù)據(jù)/指令一級緩存,512KB的二級緩存,可以實現(xiàn)2000DMIPS(每秒運(yùn)算20億條指令集)的高性能運(yùn)算能力。
包含很多強(qiáng)大的硬件編解碼功能,內(nèi)建MFC(Multi Format Codec),支持MPEG-1/2/4,H.263,H.264等格式視頻的編解碼,支持模擬/數(shù)字TV輸出。JPEG硬件編解碼,最大支持8000x8000分辨率
內(nèi)建高性能PowerVR SGX540 3D圖形引擎和2D圖形引擎,支持2D/3D圖形加速,是第五代PowerVR產(chǎn)品,其多邊形生成率為2800萬多邊形/秒,像素填充率可達(dá)2.5億/秒,在3D和多媒體方面比以往大幅提升,能夠支持DX9,SM3.0,OpenGL2.0等PC級別顯示技術(shù)。
具備IVA3硬件加速器,具備出色的圖形解碼性能,可以支持全高清、多標(biāo)準(zhǔn)的視頻編碼,流暢播放和錄制30幀/秒的1920×1080像素(1080p)的視頻文件,可以更快解碼更高質(zhì)量的圖像和視頻,同時,內(nèi)建的HDMIv1.3,可以將高清視頻輸出到外部顯示器上。
2.3 socket網(wǎng)絡(luò)編程
Socket是進(jìn)程通訊的一種方式,即調(diào)用這個網(wǎng)絡(luò)庫的一些API函數(shù)實現(xiàn)分布在不同主機(jī)的相關(guān)進(jìn)程之間的數(shù)據(jù)交換。[4] 幾個定義:
(1)IP地址:即依照TCP/IP協(xié)議分配給本地主機(jī)的網(wǎng)絡(luò)地址,兩個進(jìn)程要通訊,任一進(jìn)程首先要知道通訊對方的位置,即對方的IP。
(2)端口號:用來辨別本地通訊進(jìn)程,一個本地的進(jìn)程在通訊時均會占用一個端口號,不同的進(jìn)程端口號不同,因此在通訊前必須要分配一個沒有被訪問的端口號。
(3)連接:指兩個進(jìn)程間的通訊鏈路。
(4)半相關(guān):網(wǎng)絡(luò)中用一個三元組可以在全局唯一標(biāo)志一個進(jìn)程:(協(xié)議,本地地址,本地端口號)
這樣一個三元組,叫做一個半相關(guān),它指定連接的每半部分。(4)全相關(guān):一個完整的網(wǎng)間進(jìn)程通信需要由兩個進(jìn)程組成,并且只能使用同一種高層協(xié)議。也就是說,不可能通信的一端用TCP協(xié)議,而另一端用UDP協(xié)議。因此一個完整的網(wǎng)間通信需要一個五元組來標(biāo)識:(協(xié)議,本地地址,本地端口號,遠(yuǎn)地地址,遠(yuǎn)地端口號)
這樣一個五元組,叫做一個相關(guān)(association),即兩個協(xié)議相同的半相關(guān)才能組合成一個合適的相關(guān),或完全指定組成一連接。
第三章 具體實現(xiàn)功能
3.1總體框架圖
圖1 項目總體框架圖
3.2客戶端功能
1)顯示簡單的用戶界面 2)發(fā)送命令給服務(wù)器 3)接收服務(wù)器傳輸?shù)臄?shù)據(jù) 4)顯示溫度數(shù)據(jù)
3.3 服務(wù)器功能
1)接收客戶端發(fā)送的命令 2)處理命令
3)把命令轉(zhuǎn)發(fā)給硬件 4)獲取硬件處理所得的數(shù)據(jù) 5)把該數(shù)據(jù)傳給客戶端
3.4 實驗板輸出信息
1)LED燈按照客戶端的指令亮滅 2)蜂鳴器唱歌
3)核心板控制輸出溫度傳感器的數(shù)據(jù)到服務(wù)器
第四章 具體實現(xiàn)過程
個應(yīng)用系統(tǒng)要完成各項功能,首先必須有較完善的硬件作保證。同時還必須得到相應(yīng)設(shè)計合理的軟件的支持,尤其是微機(jī)應(yīng)用高速發(fā)展的今天,許多由硬件完成的工作,都可通過軟件編程而代替。甚至有些必須采用很復(fù)雜的硬件電路才能完成的工作,用軟件編和有時會變得很簡單。因此充分利用其內(nèi)部豐富的硬件資源和軟件資源。
程序設(shè)計語言有三種:機(jī)器語言、匯編語言、高級語言。本系統(tǒng)運(yùn)用的是高級語言所編寫,也就是C語言。所用到的開發(fā)平臺為ubuntu系統(tǒng)。
4.1 交叉編譯工具的安裝
(1)考慮到現(xiàn)今Linux平臺發(fā)展,交叉編譯平臺編統(tǒng)一為arm-linux-gcc-4.4.3(2)在windows系統(tǒng)下,建立一個共享目錄,如:e:/linux_file(3)將光盤目錄linux中的arm-linux-gcc-4.4.3.tar.gz 復(fù)制到e:/linux_file(4)注意在進(jìn)行虛擬機(jī)設(shè)置時使共享目錄的有效,并添加共享目錄e:/linux_file(5)進(jìn)入linux操作系統(tǒng),root目錄下建立一個Armcode的子目錄,將共享目錄下的文件arm-linux-gcc-4.4.3.tar.gz復(fù)制到該目錄(6)然后進(jìn)入到該目錄,執(zhí)行解壓命令:#cd /root/Armcode;#tar xvzf arm-linux-gcc-4.4.3.tgz –C /;注意:C 后面有個空格,并且C 是大寫的,它是英文單詞“Change”的第一個字母,在此是改變目錄的意思。(7)執(zhí)行
該
命
令,將
把
arm-linux-gcc
安
裝
到/opt/FriendlyARM/toolschain /4.4.3/bin 目錄。
(8)把編譯器路徑加入系統(tǒng)環(huán)境變量,運(yùn)行命令:#gedit /root/.bashrc 編輯/root/.bashrc 文件,在最后一行添加:export PATH=$PATH: /opt/FriendlyARM/toolschain/4.4.3/bin(9)重新登錄系統(tǒng)(不必重啟機(jī)器,開始->logout 即可),使以上設(shè)置生效,在命令行輸入:arm-linux-gcc –v,會出現(xiàn)如下信息,這說明交叉編譯環(huán)境已經(jīng)成功安裝。
4.2 客戶端模塊的設(shè)計
用戶界面的顯示:
void interface_print(char *temp){ system(“clear”);printf(“e[31m*******************2016梧*********************e[0mn”);printf(“e[31m*
*e[0mn”);printf(“e[31m*e[0m e[32m點(diǎn)亮LED1: on1
on2e[0me[31m
*e[0mn”);printf(“e[31m*e[0m e[33m關(guān)閉LED1: off1
off2e[0me[31m
*e[0mn”);printf(“e[31m*e[0m e[34m開蜂鳴器: onb
songe[0me[31m
*e[0mn”);printf(“e[31m*e[0m e[35m獲取溫度: get
e[31m *e[0mn”,temp);printf(“e[31m*e[0m e[36m退
出: e[0me[31m
*e[0mn”);printf(“e[31m*
*e[0mn”);printf(“e[31m******************未
來**********************e[0mn”);}
發(fā)送命令給服務(wù)器:
/*5.調(diào)用I/O函數(shù)(read/write)與客戶端通訊。*/ int i = 5;int pos;while(1){
ret = poll(pfd,2,-1);
if(ret > 0){
if(pfd[0].revents == POLLIN){
interface_print(temp);
/*從終端讀取數(shù)據(jù)*/
memset(buf,0,sizeof(buf));
ret = read(pfd[0].fd,buf,sizeof(buf)-1);7
州學(xué)院
|
點(diǎn)亮LED2:
|
關(guān)閉LED2:
|
播放音樂:
|
溫度:[%s]e[0m quit
|
的大
神
們
} if(ret > 0){
}
/*發(fā)送數(shù)據(jù)給服務(wù)器*/ write(sockfd,buf,ret);
接受服務(wù)器傳輸?shù)臄?shù)據(jù):
if(pfd[1].revents == POLLIN){
if(!strncmp(buf,“get”,3)){
/*接收服務(wù)器發(fā)送的信息*/
memset(temp,0,sizeof(temp));
ret = read(pfd[1].fd,temp,sizeof(temp)-1);
if(ret > 0){
temp[ret-1] = '