??? 摘 要:針對EPA設(shè)備需要滿足工業(yè)上實(shí)時(shí)性要求及與其他設(shè)備協(xié)調(diào)地工作等問題,,研究了ARM微處理器和Linux操作系統(tǒng)的關(guān)鍵技術(shù),,設(shè)計(jì)以ARM微處理器為核心,、Linux操作系統(tǒng)為軟件平臺的嵌入式系統(tǒng)。以ARM微處理器為核心的嵌入式系統(tǒng)應(yīng)用于EPA設(shè)備能夠滿足工業(yè)實(shí)時(shí)性要求,,并提供豐富的外圍接口,,為EPA設(shè)備的進(jìn)一步開發(fā)奠定了基礎(chǔ)。
??? 關(guān)鍵詞:EPA,;嵌入式系統(tǒng),;Linux;文件系統(tǒng),;設(shè)備驅(qū)動(dòng)
?
??? 嵌入式系統(tǒng)與Intenret技術(shù)的結(jié)合己經(jīng)成為未來嵌入式系統(tǒng)的發(fā)展趨勢,,而基于ARM的嵌入式系統(tǒng)由于其低功耗、低成本,、高性能等優(yōu)勢己經(jīng)廣泛地應(yīng)用于工業(yè)控制領(lǐng)域,。而與此同時(shí),Linux由于性能優(yōu)越,、支持硬件平臺廣泛,、源代碼公開、具有極強(qiáng)的網(wǎng)絡(luò)功能等優(yōu)點(diǎn)成為設(shè)計(jì)嵌入式系統(tǒng)一種很好的選擇,。
??? 本文從嵌入式系統(tǒng)的硬件電路和軟件開發(fā)兩個(gè)方面進(jìn)行設(shè)計(jì),。在硬件設(shè)計(jì)上采用Atmel公司生產(chǎn)的AT91RM 9200微處理器為CPU,選用8 MB的Flash和32 MB的SDRAM作為系統(tǒng)存儲器,,擴(kuò)展了以太網(wǎng)接口,、串行接口等外圍通信設(shè)備以及輸入輸出接口,根據(jù)處理器和其他接口芯片的要求設(shè)計(jì)了電源電路,、晶振電路,、Flash及SDRAM存儲器接口電路、以太網(wǎng)接口電路,、串行接口電路和擴(kuò)展I/O接口電路,。使用4層貼片工藝設(shè)計(jì)了系統(tǒng)PCB印刷電路板,焊接和安裝了貼片元件,,并進(jìn)行了電路調(diào)試等過程,。在軟件設(shè)計(jì)上基于Linux操作系統(tǒng),分析了Linux操作系統(tǒng)的引導(dǎo)程序(Bootloader)的結(jié)構(gòu),、工作流程及內(nèi)核的啟動(dòng)過程,; Bootloader移植和內(nèi)核裁剪技術(shù),移植了嵌入式Linux的引導(dǎo)過程,;Linux文件系統(tǒng)的結(jié)構(gòu),、根文件系統(tǒng)的層次和文件的管理方法;Linux設(shè)備管理方法和設(shè)備驅(qū)動(dòng)程序的中斷實(shí)現(xiàn)方法;Linux字符設(shè)備各驅(qū)動(dòng)程序設(shè)計(jì)技術(shù),;編寫了A/D轉(zhuǎn)換的驅(qū)動(dòng)程序和外擴(kuò)I/O接口的驅(qū)動(dòng)程序,。
1 嵌入式EPA設(shè)備硬件設(shè)計(jì)
1.1 EPA設(shè)備結(jié)構(gòu)框架
??? EPA(Ethenret for plant Au tomation)設(shè)備是基于工業(yè)以太網(wǎng)技術(shù)的分布式控制系統(tǒng)的底層設(shè)備,該設(shè)備具有模擬量輸入輸出,、開關(guān)量輸入輸出和1個(gè)l0Mb/s的以太網(wǎng)接口,、1個(gè)RS485的通信接口。通過以太網(wǎng)及RS485通信方式,,EPA設(shè)備在現(xiàn)場中既可作為主設(shè)備也可作為從設(shè)備,可方便地與其他設(shè)備進(jìn)行通信,。EPA設(shè)備的硬件結(jié)構(gòu)圖如圖1所示,。
?
??? 原有的EPA設(shè)備以Z-World公司的RCM2210處理器為核心,完成電流,、電壓,、溫度傳感器信號的輸入,標(biāo)準(zhǔn)電流信號的輸出和開關(guān)量電流輸出的功能,。由于RCM2210是以8位微處理器為基礎(chǔ)并且可以使用的V0口資源有限,,因此,對模塊的速度以及功能擴(kuò)展有很大的限制,。
??? 本文的主要目的就是設(shè)計(jì)以32位微處理器AT91RM 9200為CPU外擴(kuò)Flash,、SDRAM存儲器和以太網(wǎng)接口的嵌入式系統(tǒng)來代替RCM22100處理器。AT91RM 9200的主頻達(dá)到180MHz時(shí),,其性能可以高達(dá)200MIP,,這樣的處理速度可以更好地滿足工業(yè)上對實(shí)時(shí)性的要求。同時(shí)AT91RM9200有豐富的外圍接口,,為模塊的功能擴(kuò)展提供了更大的空間,。
1.2 基于ARM的嵌入式系統(tǒng)硬件結(jié)構(gòu)
??? 嵌入式系統(tǒng)的硬件結(jié)構(gòu)如圖2所示,主要由以下各部分組成:
?
??? (1) 電源電路:輸入5V,,經(jīng)過DC-DC變換轉(zhuǎn)換為1.8V和3.3V,,給系統(tǒng)內(nèi)各器件提供工作電壓。
??? (2) 晶振電路:18.432 MHz有源晶振經(jīng)過倍頻分別為ARM940T核/系統(tǒng)提供180 MHz的時(shí)鐘頻率,。
??? (3) 微處理器: AT91RM9200是系統(tǒng)的工作和控制中心,。
??? (4) Flash:可存放引導(dǎo)程序、嵌入式操作系統(tǒng),、用戶應(yīng)用程序或其他在系統(tǒng)掉電后需要保存的數(shù)據(jù),。
??? (5) SDRAM: 是系統(tǒng)代碼的運(yùn)行場所。
??? (6) 網(wǎng)絡(luò)端口: 10/100(Mb/s)速率的RJ45接口,,為系統(tǒng)提供以太網(wǎng)接入的物理通道,。
??? (7) 串行接口:用于AT91RM9200系統(tǒng)短距離雙向串行通信。
1.3 以太網(wǎng)接口電路
??? 作為一款優(yōu)秀的網(wǎng)絡(luò)控制器,基于AT91RM9200的系統(tǒng)若沒有以太網(wǎng)接口,,就會大大降低其應(yīng)用價(jià)值,,因此就整個(gè)系統(tǒng)而言,以太網(wǎng)接口電路應(yīng)是必不可少的,,但同時(shí)相對較復(fù)雜,。從硬件的角度看,以太網(wǎng)接口電路主要由MAC控制器和物理層接口兩大部分構(gòu)成,。
??? AT91RM9200微處理器內(nèi)嵌一個(gè)以太網(wǎng)控制器,,支持媒體獨(dú)立接口MII(Media Independent Interface),可在半雙工或全雙工模式下提供l0/100(Mb/s)的以太網(wǎng)接入,。在本設(shè)計(jì)中,,使用DAVICOM公司的DM9161作為以太網(wǎng)的物理層接口;DM9161是一款低功耗,、高性能的CMOS芯片,,支持10M 和100M的以太網(wǎng)傳輸,它起編碼,、譯碼輸入和輸出數(shù)據(jù)的作用[1],。提供了IEEE802.3標(biāo)準(zhǔn)定義的MII,它包括接收數(shù)據(jù)總線和發(fā)送數(shù)據(jù)總線,,來控制物理層和MAC的數(shù)據(jù)傳輸,;使用一個(gè)簡單的兩線制串行接口來通過MII控制物理層并接收來自物理層的信息,其串行控制接口包括數(shù)據(jù)時(shí)鐘(MDC)和數(shù)據(jù)輸入輸出(MDIO),;Mil串行管理包括1個(gè)數(shù)據(jù)接口,、基本寄存器設(shè)置和1個(gè)針對寄存器設(shè)置的串行接口。通過這個(gè)接口可以控制和配置很多物理層設(shè)備,,得到狀態(tài)和錯(cuò)誤信息,,并且確定PHY設(shè)備的工作方式和功能。
2 基于嵌入式Linux的EPA設(shè)備軟件設(shè)計(jì)
??? 由于Linuxr遵循GPL,所以任何對Linux定制于嵌入式設(shè)備感興趣的人都可以從Internet免費(fèi)下載其內(nèi)核和應(yīng)用程序,,并開始移植或開發(fā),,按照實(shí)際需要增減系統(tǒng)內(nèi)核。
??? 一個(gè)小型的嵌入式Linux系統(tǒng)需要下面3個(gè)基本元素:引導(dǎo)實(shí)用程序,;Linux微內(nèi)核(由內(nèi)存管理,、進(jìn)程管理和定時(shí)服務(wù)構(gòu)成);初始化過程,。要實(shí)現(xiàn)最低限度的工作能力,,還需添加:硬件驅(qū)動(dòng)程序、1個(gè)或多個(gè)應(yīng)用進(jìn)程,,以提供所需功能,。隨著要求的增加,,可能還需要:1個(gè)文件系統(tǒng)(可以是在ROM或者是RAM里);1個(gè)圖形用戶接口(GUI),;TCP/IP網(wǎng)絡(luò)棧,。由此可以歸納構(gòu)建嵌入式Linux的步驟為[2]:
??? (1) 編寫B(tài)ootloader用于加載嵌入式Linux內(nèi)核到內(nèi)存中。
??? (2) 重新編譯Linux內(nèi)核,,去掉內(nèi)核中不需要的模塊,。
??? (3) 構(gòu)建文件系統(tǒng)。
??? (4) 運(yùn)行應(yīng)用程序,。
??? 可從以上4方面構(gòu)建符合自已要求的嵌入式Linux的方法,。嵌入式執(zhí)行流程如圖3所示。
?
?
2.1 引導(dǎo)加載程序
??? 嵌入式Linux系統(tǒng)的引導(dǎo)過程如下:
??? (1) 處理器重新啟動(dòng)后,首先執(zhí)行啟動(dòng)代碼以初始化內(nèi)存控制器以及片上設(shè)備,然后配置存儲映射,。
??? (2) 引導(dǎo)加載程序(Bootloader)把內(nèi)核從Flash等固態(tài)存儲設(shè)備加載到RAM,,然后跳轉(zhuǎn)到內(nèi)核的第一條指令處執(zhí)行。
??? (3) 內(nèi)核首先配置微處理器的寄存器,,然后調(diào)用start-kernel(它是與微處理器體系結(jié)構(gòu)無關(guān)的開始點(diǎn))。
??? (4) 內(nèi)核初始化高速緩存和各種硬件設(shè)備,。
??? (5) 內(nèi)核掛裝根文件系統(tǒng),。
??? (6) 內(nèi)核執(zhí)行init進(jìn)程。
??? (7) init進(jìn)程加載運(yùn)行時(shí)共享庫,,讀取其配置文件,。
??? (8) init最后進(jìn)入用戶會話階段。
??? 在此過程中引導(dǎo)加載程序的作用是非常重要的,。
2.2 嵌入式Linux內(nèi)核配置
??? 內(nèi)核是一個(gè)操作系統(tǒng)的核心,,它負(fù)責(zé)管理系統(tǒng)的進(jìn)程、內(nèi)存,、設(shè)備驅(qū)動(dòng)程序,、文件和網(wǎng)絡(luò)系統(tǒng),決定著系統(tǒng)的性能和穩(wěn)定性,。Linux的核心是vmlinuz文件,,該文件控制著整套系統(tǒng),通常在根目錄下,。
??? 為了正確合理地設(shè)置內(nèi)核編譯配置選項(xiàng),,使制定編譯的內(nèi)核運(yùn)行更快并且系統(tǒng)能夠擁有更多的內(nèi)存,因此需對內(nèi)核進(jìn)行剪裁,,只編譯系統(tǒng)需要的功能代碼,。配置完成后保存配置退出,執(zhí)行內(nèi)核編譯:
??? make dep
??? make zImage
其中,,make dep命令用作建立內(nèi)核源碼的依存關(guān)系,,make zImage用于建立內(nèi)存內(nèi)核映像,。編譯成功后會在linux/arch/arm/boot/下獲得編譯好的Linux內(nèi)核映像zImage。
??? 在編譯內(nèi)核文件之前首先要修改根目錄下的Makefile文件,在該文件中制定系統(tǒng)構(gòu)架和交叉編譯器:ARCH=arm,、CROSS_COMPILE=/usr/local/arm/2.95.3/bin/arm-linux-(交叉編譯器所在路徑)[3-4],。Linux內(nèi)核提供多種配置工具,其中,,make menuconfig是以curses為基礎(chǔ)的,、終端式的配置菜單。在該配置菜單中可以選擇目標(biāo)系統(tǒng)的類型等,,內(nèi)核配置結(jié)束后會生成.config文件,,它保存了配置信息。
2.3 嵌入式Linux文件系統(tǒng)
??? Linux文件系統(tǒng)的層次結(jié)構(gòu)如圖4所示[5],。其中,,虛擬文件系統(tǒng)VFS(Virtual Filesystem Switch)為用戶程序提供一個(gè)統(tǒng)一的、抽象的,、虛擬的文件系統(tǒng)界面,,使用戶程序可以通過同一個(gè)文件系統(tǒng)操作界面及對各種不同的文件系統(tǒng)進(jìn)行操作,這樣Linux可支持多種不同的文件系統(tǒng),。不同的文件系統(tǒng)通過不同的程序來實(shí)現(xiàn)其各種功能,,但是與VFS之間的界面則是有明確定義的。這個(gè)界面就是file_operation數(shù)據(jù)結(jié)構(gòu),。每種文件系統(tǒng)都有自已的file_operation[6-7],。
?
??? 本文件系統(tǒng)使用的根文件系統(tǒng)是Ext2。Ext2是Linux中使用最多的文件系統(tǒng),,因?yàn)樗菍iT為Linux設(shè)計(jì)的,,擁有最快的速度和最小的CPU占有率。
2.4 系統(tǒng)運(yùn)行
2.4.1 minicom的建立
??? 本系統(tǒng)的PC機(jī)通過Linux下的minicom與嵌入式系統(tǒng)通信,,它為兩者間通信提供操作的界面,。minicom相當(dāng)于Windows下的超級終端,可通過串口與目標(biāo)板通信,。minicom的設(shè)置為:波特率為115 200 b/s,,數(shù)據(jù)位為8位,無奇偶校驗(yàn),,停止位為1,,無數(shù)據(jù)流控制。
2.4.2 啟動(dòng)U-Boot
??? U-Boot燒寫進(jìn)Flash后,,當(dāng)系統(tǒng)啟動(dòng)時(shí),,系統(tǒng)會自動(dòng)從Flash啟動(dòng),運(yùn)行U-Boot,。
2.4.3 下載Linux操作系統(tǒng)
??? 在下載操作系統(tǒng)之前,,首先用網(wǎng)線(交叉)直接把目標(biāo)板和PC機(jī)相連,,設(shè)置PC機(jī)的IP地址為192.168.0.2,并調(diào)試好tftp功能,。然后在U-Boot的命令行鍵入如下命令[8]:
??? Uboot>protect off all ????????????????????? ;把Flash寫保護(hù)去掉
??? Uboot>setenv ethaddr 12:34:56:78:9a:bc?????????????? ;設(shè)置目標(biāo)板的MAC地址
??? Uboot>saveenv???????????????????????????????????????????????? ,;保存參數(shù)
??? 環(huán)境變量設(shè)置好后就可以使用tftp下載內(nèi)核和文件系統(tǒng):
??? Uboot>tftp 0x20008000 zImage??????????????? ;下載Linux內(nèi)核
??? Uboot>tftp 0x21000000 ramdisk.gz??????????????????? ;下載Linux文件系統(tǒng)
??? Uboot
??? (1) 當(dāng)應(yīng)用程序在調(diào)試階段時(shí)可以通過tfp方式來運(yùn)行程序。目標(biāo)板上的Linux操作系統(tǒng)正常啟動(dòng)后首先要設(shè)置好目標(biāo)板的IP地址為192.168.0.2,,其命令如下:
??? $ ifconfig eth 192.168.0.2
然后在minicom的命令行下鍵入如下命令登錄tfp服務(wù)器(設(shè)tfp服務(wù)器的IP地址為192.168.0.1):
??? $ ftp 192.168.0.1
鍵入該命令后輸入Linux服務(wù)器的用戶名,,并在Password后面輸入密碼后回車,這時(shí)可以使用ls,、cd等命令顯示服務(wù)器上的文件并進(jìn)入相應(yīng)的目錄,。最后使用get命令就可以把所需要的程序下載到目標(biāo)板上。
??? (2) 如果應(yīng)用程序調(diào)試完畢,,就要把編輯好的程序放到目標(biāo)板的文件系統(tǒng)中,。重新創(chuàng)建文件系統(tǒng)的方法如下:
??? $ gunzip ramdisk.gz???????????? ;解壓縮原有的文件系統(tǒng)
??? $ mount –o loop ramdisk /mnt/newramdisk?????? ;解壓后的文件系統(tǒng)映像掛在到指定的目錄上
??? $ cd/mnt/newramdisk???????????????????????? ;進(jìn)入/newramdisk目錄進(jìn)行操作,隨意增減文件
??? 添加好自已的應(yīng)用程序后修改etcrc.d下的rc文件,,它是系統(tǒng)啟動(dòng)后自動(dòng)調(diào)用的應(yīng)用程序,。
??? 以上步驟完成后卸載文件系統(tǒng)映像,并重新壓縮:
??? $ umount /mnt/newramdisk
??? $ gzip –c –v9 ramdisk>./newramdisk
3 嵌入式Linux驅(qū)動(dòng)程序設(shè)計(jì)
??? 本文主要完成了EPA設(shè)備驅(qū)動(dòng)程序的模擬量輸入及開關(guān)量輸入輸出的驅(qū)動(dòng)程序,。
3.1 模擬量輸入驅(qū)動(dòng)程序設(shè)計(jì)
??? EPA設(shè)備具有多路模擬量輸入測量通道,,輸入信號經(jīng)過適當(dāng)?shù)奶幚恚M(jìn)入到24位A/D轉(zhuǎn)換器CS5522,,轉(zhuǎn)換后的數(shù)據(jù)會通過SPI接口輸出給處理器。該功能的驅(qū)動(dòng)程序的主要任務(wù)是合理地配置AT91RM 9200的SPI接口,,使其能夠正確地與A/D轉(zhuǎn)換器CS5522進(jìn)行數(shù)據(jù)通信,。
??? AT91RM 9200提供了很多寄存器用于控制SPI的操作,因此,,在編寫驅(qū)動(dòng)程序之前要先定義與SPI操作有關(guān)的變量,。定義指向SPI寄存器的結(jié)構(gòu)體的代碼如下:
??? AT91PS_SPI controller=(AT91PS_SPI)AT91C_VA-BASE_SPI
其中,AT91PS_SPI在linuxincludeasm-armarch-at91rm9200A T91RM9200_SPI.h中定義,,用于指向SPI操作的所有寄存器,,如配置寄存器、模式寄存器等:
??? Typedef struct_AT91S_SPI{
??? AT91_REG SPI_CR;? // SPI控制寄存器
??? AT91_REG SPI_MR;? // SPI模式寄存器
??? AT91_REG SPI_RDR;? //SPI接收數(shù)據(jù)寄存器
??? AT91_REG SPI_TDR;? //SPI發(fā)送數(shù)據(jù)寄存器
??? AT91_REG SPI_SR;? // SPI狀態(tài)寄存器
??? AT91_REG SPI_IER;? // SPI中斷使能寄存器
??? AT91_REG SPI_IDR;? //SPI中斷禁用寄存器
??? AT91_REG SPI_IMR;? //SPI屏蔽寄存器
??? AT91_REG Reserved0[9];
??? AT91_REG S PI_CSR0;? //SPI片選寄存器0
??? AT91_REG SPI_CSR1;? //SPI片選寄存器1
??? AT91_ REG SPI_CSR2;? //SP I片選寄存器2
??? AT91_ REG SP_CSR3;? //SPI片選寄存器3
??? AT91_REG Reservedl[10];
??? }AT91S_SP I,*AT91PS_SPI
??? AT91C_VA_BASE_SPI是在linuxincludeasm-armarch-at91rm9200hardware.h中定義的SPI寄存器的地址:
??? #define AT91C_VA_BASE_SPI AT91_IO_P2V(AT91C_BASE_SPI)
??? 本驅(qū)動(dòng)程序需要SPI接口的操作是打開/關(guān)閉SPI設(shè)備,,接收/發(fā)送數(shù)據(jù),,因此定義file operations結(jié)構(gòu)體如下:
??? int spi_open(struct inode* inode,struct file*filp);
??? int spi_release(struct inode*inode,struct file*filp);
??? ssize_t spi_read(struct file*filp,ch ar*buf,size_t count,lofft *1);
??? ssize_t spi_write(struct file*filp,const char* buf,size_t count,loff_t * 1) ;
??? struct file_operations spi_fops={
??? open : spi_open,
??? release: spi_release,
??? read: spi_read,
??? write: spi_write,
??? };
??? spi_open用于打開SPI設(shè)備,這個(gè)函數(shù)主要完成了SPI設(shè)備的初始化,。AT91RM9200的每條I/O線都可以復(fù)用2個(gè)外設(shè)功能,,可用于SPI接口的口線是PAO~PA3,因此要把這3個(gè)口線設(shè)置為SPI控制,,實(shí)現(xiàn)的函數(shù)是AT91_Cf9PIO_SPI( ),,該函數(shù)定義在linux/include/asm-ann/arch-at91rm 920io.h,,其原形如下:
??? staitc inline void AT91_CfgPIO_SPI(void){
??? AT91_SYS->PIOA_PDR=AT91C_PAO_MISO| AT91C_PAl_MOSI | AT91C_P A2_SPCK;
??? }
??? SPI口線設(shè)置好后就要設(shè)置SPI的工作方式,主要設(shè)置控制寄存器(SPI_CR),、模式寄存器(SPI_MR)和片選寄存器(SPI_CSR0):
??? controller->SPI_CR=AT91C_SPI_SWRST; // 軟件復(fù)位SPI
??? controller->SPI_MR=AT91C_SPI_MSTR| AT91C_SPI_ MODFDIS | AT91C_SPI_PCS;//設(shè)置SPI模式寄存器為主機(jī)模式,,固定片選
??? controller->SPI_CSR0=(AT91C_SPI_NCPHA | (AT91C_SPI_DLYBS&0x100000) | (SPI_CLOCK <<8) | CSR0_BITS_AD);//設(shè)置SPI片選寄存器包括時(shí)鐘極性、相位,、時(shí)鐘波特率,、傳輸數(shù)據(jù)位數(shù)
??? Controller->SPI_CR= AT91C_SPI_SPIEN;//設(shè)置SPI控制寄存器,使能SPI/發(fā)送與接收數(shù)據(jù)
??? 當(dāng)用戶程序想用SPI接收或發(fā)送數(shù)據(jù)時(shí),,系統(tǒng)會調(diào)用spi_write和spi_read函數(shù)完成讀寫操作,。AT91RM 9200提供了接收數(shù)據(jù)寄存器(SPI_RDR)、發(fā)送數(shù)據(jù)寄存器(SPI_TDR)和狀態(tài)寄存器(SPI_SR),。其中,,SPI_RDR和SPI_TDR分別存放接收到的數(shù)據(jù)和發(fā)送數(shù)據(jù)。SPI_SR用于表示SPI當(dāng)前操作的狀態(tài),,其中RDRF標(biāo)識接收數(shù)據(jù)寄存器滿,。當(dāng)RDRF=0時(shí),表示上次讀SPI_RDR后未收到數(shù)據(jù),;RDRF=1時(shí),,表示上次讀SPI_RDR后已收到數(shù)據(jù)并由串行器發(fā)送到SPI_RDR:TDRE標(biāo)識發(fā)送數(shù)據(jù)寄存器空。當(dāng)TDRE=0時(shí),,表示數(shù)據(jù)已寫入SPI_TDR但仍未傳輸?shù)酱衅?;?dāng)TDRE=1時(shí),表示最后寫入發(fā)送數(shù)據(jù)寄存器的數(shù)據(jù)已傳輸?shù)酱衅?。?qū)動(dòng)程序通過檢測RDRF和TDRE的值來完成接收和發(fā)送數(shù)據(jù)的操作,。讀寫操作主要的實(shí)現(xiàn)代碼如下:
??? while( !(controller->SPI_SR&AT91C_SPI_RDRF));
??? ret_ad = ( controller -> SPI_RDR); //存儲接收到的數(shù)據(jù)
??? adp =( char *)& ret_ad;
??? copy_ to_user( buf,adp, count);????????????? //把接收到的數(shù)據(jù)傳給用戶程序
??? copy _from_user(bf,buf,count);????????????? //接收用戶需要發(fā)送的數(shù)據(jù)
??? while(!(controller->SPI_SR&AT91C_SPI_TDRE));
??? contro ller -> SPI_TDR = (ad_cmd&0xFFFF); //向SPI設(shè)備發(fā)送數(shù)據(jù)
3.2 開關(guān)量輸出驅(qū)動(dòng)程序設(shè)計(jì)
??? EPA 設(shè)備具有8路開關(guān)量輸出,使用的8個(gè)引腳為PA24,、P A26,、P A27、PB0,、PB1,、 PB2、 PB3,、 PC15,。在本驅(qū)動(dòng)程序中用到的輸入輸出(PIO)控制器的用戶接口有:PIO使能寄存器(PIO_PER)、輸出使能寄存器(PIO_OER),、 PIO置位輸出數(shù)據(jù)寄存器(PIO_SODR),、 清零輸出數(shù)據(jù)寄存器(PIO_CODR)。以下為控制PA24引腳的輸出的部分代碼:
??? AT9I_ SYS->PIOA_PER=(unsignedint)(1<<24); //使能PTO來控制PA24
??? AT91_ SYS->PIOA_OER=(unsignedin t)(1<<24); //定義PA24為輸出引腳
??? if(ad_cmd&0x80)
??? AT91_ SYS-> PI OA _SODR=(unsignedin t)(1<<24); //使PA24輸出為高電平
??? else
??? AT 91_ SY S->PIOA CODR=(unsignedin t)(1<<24); //使PA24輸出為低電平
3.3 開關(guān)量輸入驅(qū)動(dòng)程序設(shè)計(jì)
??? EPA 設(shè)備具有8路數(shù)字量輸入,,其中有2路輸入要求可以產(chǎn)生中斷,,外設(shè)通過這2路向CPU提出數(shù)據(jù)輸入請求,。本系統(tǒng)所使用作為輸入的引腳有PA23、 PA25,、 PC0,、PC10、 PC11,、 PA19,、 PA20、 PA22,,其中PA23,、PA25作為外部中斷輸入。當(dāng)引腳被設(shè)為輸入時(shí),,每個(gè)I/O線的電平都可以通過外設(shè)數(shù)據(jù)狀態(tài)寄存器PIO_PDSR讀出,,而此時(shí)必須將PIO控制器的時(shí)鐘使能。AT91RM9200的電源控制器(PMC)獨(dú)立提供和控制多達(dá)30個(gè)外設(shè)時(shí)鐘,,其用戶接口為外設(shè)時(shí)鐘使能寄存器PMC_PCER,。AT91RM9200的每個(gè)外設(shè)都有自己的外設(shè)標(biāo)識,PMC_CER就是通過外設(shè)標(biāo)識來使能其時(shí)鐘的,。在includeasm-armarch-at91rm9200AT91RM9200.h文件中定義了各個(gè)外設(shè)的標(biāo)識,,部分定義如下:
??? #define AT91C_ID_PIOA???? (2) //Parallel IO Controller A
??? #define AT91C_ID_P IOB???? (3) // P arallelIO C ontroller B
??? #define AT91C_ID_PIOC????? (4 ) // P arallelIO C ontroller C
??? #define AT91C_ID_IRQ0????? (25) // A dvanced Interrupt Controller(IRQ0)
??? #define AT91C_ID_IRQ1????? (26) // A dvanced Interrupt Controller(IRQ1)
??? #define AT91C_ID_IRQ2????? (27) // A dvanced Interrupt Controller(IRQ2)
??? #define AT91C_ID_IRQ3????? (28) // A dvanced Interrupt Controller(IRQ3)
??? 以下為P A19作為輸入引腳的主要代碼:
????AT91_SYS->PIOA _PER=(unsignedin t)(1<<19); //使能PIO控制PA19
??? AT91_SYS->PMC_PCER=((unsignedin t)1<
??? PA 23 、PA25除了作為輸入引腳外還要產(chǎn)生中斷,,AT91RM9200使用高級中斷控制器(AIC)來對中斷進(jìn)行管理,。本驅(qū)動(dòng)程序用到的AIC寄存器有:AIC源模式寄存器(AIC SMR0-AIC_SMR31),用來設(shè)置各個(gè)中斷源的優(yōu)先級和中斷源類型;中斷使能命令寄存器(AIC_IECR),,根據(jù)每個(gè)設(shè)備的標(biāo)識號控制其使能,。
??? AT91_ SYS->AIC_SMR[27]=(unsigned int)(1<<5); //設(shè)置IRQ2為邊沿觸發(fā)
??? AT91_ SYS->AIC_IECR=((unsigned int)1<
??? //注冊中斷并激活中斷處理程序,返回值為0時(shí)表示注冊成功
??? if( result==-1)
??? {
??? printk ('Can 't get assigned irq %dn',EXTERNAL_IRQl);
??? return result ;
??? }
??? void test irq_interruptl(void)? //中斷處理程序
??? {
??? printk ('INTERRUPT1 n');
??? AT91_SYS ->A IC_IECR=((unsignedin t)1 <
??? 以上研究了Linux操作系統(tǒng)設(shè)備管理方法和Linux設(shè)備中斷機(jī)制,,通過分析Linux設(shè)備驅(qū)動(dòng)程序中斷機(jī)制實(shí)現(xiàn)的方法及字符設(shè)備驅(qū)動(dòng)程序的開發(fā)過程,編寫了EPA設(shè)備的驅(qū)動(dòng)程序,。
??? 本文基于ARM嵌入式開發(fā)技術(shù)研制了EPA設(shè)備的核心控制部分,,完成了從硬件平臺的設(shè)計(jì)、調(diào)試到Linux操作系統(tǒng)的BootLoader與內(nèi)核的移植,,文件系統(tǒng)和設(shè)備驅(qū)動(dòng)程序分析以及針對EPA設(shè)備驅(qū)動(dòng)程序的編寫,。
參考文獻(xiàn)
[1] 馬學(xué)文,朱名日,,程小輝.基于mclinux和53C4510B的網(wǎng)絡(luò)通信設(shè)計(jì).單片機(jī)與嵌入式系統(tǒng)應(yīng)用,,2004,4(6):30.
[2]?王亞軍,劉金剛.Linux運(yùn)用于嵌入式系統(tǒng)的技術(shù)分析.計(jì)算機(jī)應(yīng)用研究,,2005,20(5):102-105.
[3]?SCHACH S R ,JIN B ,WRIGHT D R. Maintainability of the Linux kernel.Software Engineering,2002,149(1):18-23.
[4]?魏平,,夏良正,,王巖.Linux體系結(jié)構(gòu)及嵌入式Linux的移植方法.東南大學(xué)學(xué)報(bào),2004,34(1):126-131.
[5]?毛德操,,胡希明.Linux內(nèi)核源代碼情景分析.杭州:浙江大學(xué)出版社,,2003.
[6]?胡寧,張德運(yùn),,王福豹.基于Linux的流媒體文件系統(tǒng).計(jì)算機(jī)工程,,2005,31(14):196-198.
[7]?史芳麗,周亞莉.Li nux系統(tǒng)中虛擬文件系統(tǒng)內(nèi)核機(jī)制研究.陜西師范大學(xué)學(xué)報(bào)(自然科學(xué)版),,2005,33(1):29.
[8]?劉斐,,王文君,楊建民.U-Boot在ARM系統(tǒng)中的啟動(dòng)及應(yīng)用.陜西師范大學(xué)學(xué)報(bào)(自然科學(xué)版),,2005,33(6):213-215.
[9]?蘭曉紅. 嵌入式Linux中斷設(shè)備驅(qū)動(dòng)程序設(shè)計(jì).計(jì)算機(jī)應(yīng)用研究,,2003,23(5):96-98.
[10]?ALESSANDRO R,JONATHAN C.Linux device driver(2nd edition).USA: O'Reilly, 2001.