




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、嵌入式Linux之我行,主要講述和總結(jié)了本人在學(xué)習(xí)嵌入式linux中的每個(gè)步驟。一為總結(jié)經(jīng)驗(yàn),二希望能給想入門嵌入式Linux的朋友提 供方便。如有錯(cuò)誤之處,謝請(qǐng)指正。一、開(kāi)發(fā)環(huán)境主 機(jī):VMWare-Fedora 9二、硬件原理分析S3C2440內(nèi)部ADC結(jié)構(gòu)圖我們從上面的結(jié)構(gòu)圖和數(shù)據(jù)手冊(cè)可以知道,該ADC模塊總共有8個(gè)通道可以進(jìn)行模擬信號(hào)的輸入,分別是AIN0、AIN1、AIN2、AIN3、 YM、YP、XM、XP。那么ADC是怎么實(shí)現(xiàn)模擬信號(hào)到數(shù)字信號(hào)的轉(zhuǎn)換呢?首先模擬信號(hào)從任一通道輸入,然后設(shè)定寄存器中預(yù)分頻器的值來(lái)確定AD轉(zhuǎn)換器 頻率,最后ADC將模擬信號(hào)轉(zhuǎn)換為數(shù)字信號(hào)保存到ADC數(shù)
2、據(jù)寄存器0中(ADCDAT0),然后ADCDAT0中的數(shù)據(jù)可以通過(guò)中斷或查詢的方式來(lái)訪問(wèn)。 對(duì)于ADC的各寄存器的操作和注意事項(xiàng)請(qǐng)參閱數(shù)據(jù)手冊(cè)。上圖是mini2440上的ADC應(yīng)用實(shí)例,開(kāi)發(fā)板通過(guò)一個(gè)10K的電位器(可變電阻)來(lái)產(chǎn)生電壓模擬信號(hào),然后通過(guò)第一個(gè)通道(即:AIN0)將 模擬信號(hào)輸入ADC。三、實(shí)現(xiàn)步驟ADC設(shè)備在Linux中可以看做是簡(jiǎn)單的字符設(shè)備,也可以當(dāng)做是一混雜設(shè)備(misc設(shè)備),這里我們就看做是misc設(shè)備來(lái)實(shí)現(xiàn)ADC的驅(qū)動(dòng)。 注意:這里我們獲取AD轉(zhuǎn)換后的數(shù)據(jù)將采用中斷的方式,即當(dāng)AD轉(zhuǎn)換完成后產(chǎn)生AD中斷,在中斷服務(wù)程序中來(lái)讀取ADCDAT0的第0-9位的值(即AD
3、 轉(zhuǎn)換后的值)。1、建立驅(qū)動(dòng)程序文件my2440_adc.c,實(shí)現(xiàn)驅(qū)動(dòng)的初始化和退出,代碼如下:1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 13 /*定義了一個(gè)用來(lái)保存經(jīng)過(guò)虛擬映射后的內(nèi)存地址*/ 14 static void _iomem *adc_base; 15 16 /*保存從平臺(tái)時(shí)鐘隊(duì)列中獲取ADC的時(shí)鐘*/ 17 static struct clk *adc_clk; 18 1
4、9 /*申明并初始化一個(gè)信號(hào)量ADC_LOCK,對(duì)ADC資源進(jìn)行互斥訪問(wèn)*/ 20 DECLARE_MUTEX(ADC_LOCK); 21 22 static int _init adc_init(void) 23 24 int ret; 25 26 /*從平臺(tái)時(shí)鐘隊(duì)列中獲取ADC的時(shí)鐘,這里為什么要取得這個(gè)時(shí)鐘,因?yàn)锳DC的轉(zhuǎn)換頻率跟時(shí)鐘有關(guān)。 27 系統(tǒng)的一些時(shí)鐘定義在arch/arm/plat-s3c24xx /s3c2410-clock.c中*/ 28 adc_clk = clk_get(NULL, adc); 29 if (!adc_clk) 30 31 /*錯(cuò)誤處理*/ 32 pr
5、intk(KERN_ERR failed to find adc clock sourcen); 33 return -ENOENT; 34 35 36 /*時(shí)鐘獲取后要使能后才可以使用,clk_enable定義在arch/arm/plat-s3c/clock.c中*/ 37 clk_enable(adc_clk); 38 39 /*將ADC的IO端口占用的這段 IO空間映射到內(nèi)存的虛擬地址,ioremap定義在io.h中。 40 注意:IO空間要映射后才能使用,以后對(duì)虛擬地址的操作就是對(duì)IO空間的操作, S3C2410_PA_ADC41 是ADC控制器的基地址,定義在mach-s3c2410
6、/include/mach/map.h中,0x20是虛擬地址長(zhǎng)度大小*/ 42 adc_base = ioremap(S3C2410_PA_ADC, 0x20); 43 if (adc_base = NULL) 44 45 /*錯(cuò)誤處理*/ 46 printk(KERN_ERR Failed to remap register blockn); 47 ret = -EINVAL; 48 goto err_noclk; 49 50 51 /*把看ADC注冊(cè)成為misc設(shè)備,misc_register定義在miscdevice.h中adc_miscdev結(jié)構(gòu)體定義 52 及內(nèi)部接口函數(shù)在第步中講,
7、MISC_DYNAMIC_MINOR是次設(shè)備號(hào),定義在miscdevice.h中*/ 53 ret = misc_register(&adc_miscdev); 54 if (ret) 55 56 /*錯(cuò)誤處理*/ 57 printk(KERN_ERR cannot register miscdev on minor=%d (%d)n,58 MISC_DYNAMIC_MINOR, ret); 59 goto err_nomap; 60 61 62 printk(DEVICE_NAME initialized!n); 63 64 return 0; 65 66 /以下是上面錯(cuò)誤處理的跳轉(zhuǎn)點(diǎn) 67
8、 err_noclk: 68 clk_disable(adc_clk); 69 clk_put(adc_clk); 70 71 err_nomap: 72 iounmap(adc_base); 73 74 return ret; 75 76 77 static void _exit adc_exit(void) 78 79 free_irq(IRQ_ADC, 1);/*釋放中斷*/ 80 iounmap(adc_base);/*釋放虛擬地址映射空間*/ 81 82 if (adc_clk)/*屏蔽和銷毀時(shí)鐘*/ 83 84 clk_disable(adc_clk); 85 clk_put(ad
9、c_clk); 86 adc_clk = NULL; 87 88 89 misc_deregister(&adc_miscdev);/*注銷misc設(shè)備*/ 90 91 92 /*導(dǎo)出信號(hào)量ADC_LOCK在觸摸屏驅(qū)動(dòng)中使用,因?yàn)橛|摸屏驅(qū)動(dòng)和ADC驅(qū)動(dòng)公用 93 相關(guān)的寄存器,為了不產(chǎn)生資源競(jìng)態(tài),就用信號(hào)量來(lái)保證資源的互斥訪問(wèn)*/ 94 EXPORT_SYMBOL(ADC_LOCK); 95 96 module_init(adc_init); 97 module_exit(adc_exit); 98 99 MODULE_LICENSE(GPL); 100 MODULE_AUTHOR(Huang
10、 Gang); 101 MODULE_DESCRIPTION(My2440 ADC Driver); 2、adc_miscdev結(jié)構(gòu)體定義及內(nèi)部各接口函數(shù)的實(shí)現(xiàn),代碼如下:102 #include 103 104 /*設(shè)備名稱*/ 105 #define DEVICE_NAME my2440_adc 106 107 /*定義并初始化一個(gè)等待隊(duì)列adc_waitq,對(duì)ADC資源進(jìn)行阻塞訪問(wèn)*/ 108 static DECLARE_WAIT_QUEUE_HEAD(adc_waitq); 109 110 /*用于標(biāo)識(shí)AD轉(zhuǎn)換后的數(shù)據(jù)是否可以讀取,0表示不可讀取*/ 111 static volat
11、ile int ev_adc = 0; 112 113 /*用于保存讀取的AD轉(zhuǎn)換后的值,該值在ADC中斷中讀取*/ 114 static int adc_data; 115 116 /*misc設(shè)備結(jié)構(gòu)體實(shí)現(xiàn)*/ 117 static struct miscdevice adc_miscdev = 118 119 .minor = MISC_DYNAMIC_MINOR, /*次設(shè)備號(hào),定義在 miscdevice.h中,為255*/ 120 .name = DEVICE_NAME, /* 設(shè)備名稱*/ 121 .fops = &adc_fops, /*對(duì)ADC設(shè)備文件操作*/ 122 ; 1
12、23 124 /*字符設(shè)備的相關(guān)操作實(shí)現(xiàn)*/ 125 static struct file_operations adc_fops = 126 127 .owner = THIS_MODULE, 128 .open = adc_open, 129 .read = adc_read, 130 .release = adc_release, 131 ; 132 133 /*ADC設(shè)備驅(qū)動(dòng)的打開(kāi)接口函數(shù)*/ 134 static int adc_open(struct inode *inode, struct file *file) 135 136 int ret; 137 138 /*申請(qǐng)ADC中
13、斷服務(wù),這里使用的是共享中斷:IRQF_SHARED,為什么要使用共享中斷,因?yàn)樵谟|摸屏驅(qū)動(dòng)中 139 也使用了這個(gè)中斷號(hào)。中斷服務(wù)程序?yàn)?adc_irq在下面實(shí)現(xiàn),IRQ_ADC是ADC的中斷號(hào),這里注意: 140 申請(qǐng)中斷函數(shù)的最后一個(gè)參數(shù)一定不能為NULL,否則中斷申請(qǐng)會(huì)失敗,如果中斷服務(wù)程序中用不到這個(gè) 141 參數(shù),就隨便給個(gè)值就好了,我這里就給個(gè)1*/ 142 ret = request_irq(IRQ_ADC, adc_irq, IRQF_SHARED, DEVICE_NAME, 1); 143 if (ret) 144 145 /*錯(cuò)誤處理*/ 146 printk(KERN_
14、ERR IRQ%d error %dn, IRQ_ADC, ret); 147 return -EINVAL; 148 149 150 return 0; 151 152 153 /*ADC中斷服務(wù)程序,該服務(wù)程序主要是從ADC數(shù)據(jù)寄存器中讀取AD轉(zhuǎn)換后的值*/ 154 static irqreturn_t adc_irq(int irq, void *dev_id) 155 156 /*保證了應(yīng)用程序讀取一次這里就讀取 AD轉(zhuǎn)換的值一次, 157 避免應(yīng)用程序讀取一次后發(fā)生多次中斷多次讀取AD轉(zhuǎn)換值*/ 158 if(!ev_adc) 159 160 /*讀取AD轉(zhuǎn)換后的值保存到全局變量ad
15、c_data 中,S3C2410_ADCDAT0定義在regs-adc.h中, 161 這里為什么要與上一個(gè)0x3ff,很簡(jiǎn)單,因?yàn)锳D轉(zhuǎn)換后的數(shù)據(jù)是保存在ADCDAT0的第0-9位, 162 所以與上0x3ff(即:1111111111)后就得到第0-9位的數(shù)據(jù),多余的位就都為0*/ 163 adc_data = readl(adc_base + S3C2410_ADCDAT0) & 0x3ff; 164 165 /*將可讀標(biāo)識(shí)為1,并喚醒等待隊(duì)列*/ 166 ev_adc = 1; 167 wake_up_interruptible(&adc_waitq); 168 169 170 ret
16、urn IRQ_HANDLED; 171 172 173 /*ADC設(shè)備驅(qū)動(dòng)的讀接口函數(shù)*/ 174 static ssize_t adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos) 175 176 /*試著獲取信號(hào)量(即:加鎖)*/ 177 if (down_trylock(&ADC_LOCK) 178 179 return -EBUSY; 180 181 182 if(!ev_adc)/*表示還沒(méi)有AD轉(zhuǎn)換后的數(shù)據(jù),不可讀取*/ 183 184 if(filp-f_flags & O_NONBLOCK)
17、 185 186 /*應(yīng)用程序若采用非阻塞方式讀取則返回錯(cuò)誤*/ 187 return -EAGAIN; 188 189 else/*以阻塞方式進(jìn)行讀取*/ 190 191 /*設(shè)置ADC控制寄存器,開(kāi)啟AD轉(zhuǎn)換*/ 192 start_adc(); 193 194 /*使等待隊(duì)列進(jìn)入睡眠*/ 195 wait_event_interruptible(adc_waitq, ev_adc); 196 197 198 199 /*能到這里就表示已有AD轉(zhuǎn)換后的數(shù)據(jù),則標(biāo)識(shí)清0,給下一次讀做判斷用*/ 200 ev_adc = 0; 201 202 /*將讀取到的AD轉(zhuǎn)換后的值發(fā)往到上層應(yīng)用程序*/
18、 203 copy_to_user(buffer, (char *)&adc_data, sizeof(adc_data); 204 205 /*釋放獲取的信號(hào)量(即:解鎖)*/ 206 up(&ADC_LOCK); 207 208 return sizeof(adc_data); 209 210 211 /*設(shè)置ADC控制寄存器,開(kāi)啟AD轉(zhuǎn)換*/ 212 static void start_adc(void) 213 214 unsigned int tmp; 215 216 tmp = (1 14) | (255 6) | (0 3);/* 0 1 00000011 000 0 0 0 *
19、/ 217 writel(tmp, adc_base + S3C2410_ADCCON); /*AD預(yù)分頻器使能、模擬輸入通道設(shè)為AIN0*/ 218 219 tmp = readl(adc_base + S3C2410_ADCCON); 220 tmp = tmp | (1 0); /* 0 1 00000011 000 0 0 1 */ 221 writel(tmp, adc_base + S3C2410_ADCCON); /*AD轉(zhuǎn)換開(kāi)始*/ 222 223 224 /*ADC設(shè)備驅(qū)動(dòng)的關(guān)閉接口函數(shù)*/ 225 static int adc_release(struct inode *inode, struct file *filp) 226 227 return 0; 228 注意:在上面實(shí)現(xiàn)的每步中,為了讓代碼邏輯更加有條理和容易理解,就沒(méi)有考慮代碼的順序,比如函數(shù)要先定義后調(diào)用。如果要編譯此代碼,請(qǐng)嚴(yán)格按照C 語(yǔ)言的規(guī)范來(lái)調(diào)整代碼的順序。3、編寫(xiě)用戶應(yīng)用程序測(cè)試my2440_adc驅(qū)動(dòng)。建立應(yīng)用程序adc_test.c,代碼如下:229 #include
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 文化創(chuàng)意產(chǎn)品研發(fā)資金申請(qǐng)2025年政策扶持與產(chǎn)業(yè)升級(jí)策略報(bào)告
- 2025年新能源汽車廢舊電池回收處理技術(shù)及案例分析報(bào)告
- 2025年生物科技行業(yè)可持續(xù)發(fā)展目標(biāo)(SDGs)實(shí)踐與產(chǎn)業(yè)融合報(bào)告
- 煤炭清潔高效燃燒技術(shù)在煤炭洗選加工中的應(yīng)用與發(fā)展報(bào)告
- 醫(yī)療器械臨床試驗(yàn)質(zhì)量管理與規(guī)范化2025年發(fā)展趨勢(shì)研究報(bào)告
- 2025年建筑信息模型(BIM)在施工全過(guò)程精細(xì)化管理中的應(yīng)用策略報(bào)告
- 工業(yè)互聯(lián)網(wǎng)平臺(tái)量子密鑰分發(fā)技術(shù)在智慧醫(yī)療領(lǐng)域的應(yīng)用與挑戰(zhàn)報(bào)告
- 2025年電商平臺(tái)內(nèi)容營(yíng)銷與種草經(jīng)濟(jì)產(chǎn)業(yè)鏈研究報(bào)告
- 深度解析:2025年工業(yè)互聯(lián)網(wǎng)平臺(tái)AR交互技術(shù)在制造領(lǐng)域的應(yīng)用創(chuàng)新報(bào)告
- 綠色環(huán)保產(chǎn)業(yè)資金申請(qǐng)政策變化與應(yīng)對(duì)策略報(bào)告2025
- 語(yǔ)文課堂精彩兩分鐘PPT課件
- 三生事業(yè)六大價(jià)值
- 鋯石基本特征及地質(zhì)應(yīng)用
- 絲網(wǎng)除沫器小計(jì)算
- 制缽機(jī)的設(shè)計(jì)(機(jī)械CAD圖紙)
- 學(xué)校財(cái)務(wù)管理制度
- 三年級(jí)下冊(cè)美術(shù)課件-第15課色彩拼貼畫(huà)|湘美版(共11張PPT)
- 水稻病蟲(chóng)統(tǒng)防統(tǒng)治工作總結(jié)
- 水在不同溫度下的折射率、粘度和介電常數(shù)
- howdoyoucometoschoolPPT課件
- 四柱特高弟子班絕密資料——席學(xué)易
評(píng)論
0/150
提交評(píng)論