生活随笔
收集整理的這篇文章主要介紹了
Exynos4412 ADC 设备驱动开发
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
具體ADC硬件知識及裸機驅動請看:?Exynos4412裸機開發 —— A/D轉換器
1、原理圖如下:
2、相關寄存器信息
ADC_BASE ? ? ?0x126C0000
ADCCON ? ? ? ?0x0000 ? ? ? ? ? ? ? 1<<0 | 1<<14 | 0X1<<16 | 0XFF<<6
ADCDLY ? ? ? ? ?0x0008 ? ? ? ? ? ? ??
ADCDAT ? ? ? ? 0x000C ? ? ? ? ? ? ?&0XFFF
CLRINTADC ? ?0x0018
ADCMUX ? ? ? ?0x001C
3、大體驅動編寫流程如下
read() { 1、向adc設備發送要讀取的命令 ? ? ? ? ? ADCCON? ??1<<0 | 1<<14 | 0X1<<16 | 0XFF<<6 ? ? ? ?2、讀取不到數據就休眠 ? ? ? ? ? ? wait_event_interruptible(); ? ? ? ?3、等待被喚醒讀數據 ? ? ? ? ? havedata = 0; } adc_handler() { 1、清中斷 ADC使用中斷來通知轉換數據完畢的 ? ? ? ?2、狀態位置位; ? ? ? ? ? ? havedata=1; ? ? ? ?3、喚醒阻塞進程 wake_up() } probe() { 1、 讀取中斷號,注冊中斷處理函數 2、讀取寄存器的地址,ioremap 3、字符設備的操作 } |
4、設備樹中的節點編寫
[java]?view plaincopy
fs4412-adc{?? ????compatible?=?"fs4412,adc";?? ????reg?=?<0x126C0000?0x20>;?? ????interrupt-parent?=?<&combiner>;?? ????interrupts?=?<10?3>;?? };??
5、驅動編寫
driver.c
[cpp]?view plaincopy
#include?<linux/module.h>?? #include?<linux/device.h>?? #include?<linux/platform_device.h>?? #include?<linux/interrupt.h>?? #include?<linux/fs.h>?? #include?<linux/wait.h>?? #include?<linux/sched.h>?? #include?<asm/uaccess.h>?? #include?<asm/io.h>?? static?int?major?=?250;?? ?? ?? static?wait_queue_head_t?wq;?? static?int?have_data?=?0;?? static?int?adc;?? static?struct?resource?*res1;?? static?struct?resource?*res2;?? static?void?*adc_base;?? ?? #define?ADCCON?0x0000????? #define?ADCDLY?0x0008????????????????? #define?ADCDAT?0x000C???????????????? #define?CLRINTADC?0x0018?? #define?ADCMUX?0x001C?? ?? ?? static??irqreturn_t?adc_handler(int?irqno,?void?*dev)?? {?? ????have_data?=?1;?? ?? ????printk("11111\n");?? ?????? ????writel(0x12,adc_base?+?CLRINTADC);?? ????wake_up_interruptible(&wq);?? ????return?IRQ_HANDLED;?? }?? static?int?adc_open?(struct?inode?*inod,?struct?file?*filep)?? {?? ?? ????return?0;?? }?? static?ssize_t?adc_read(struct?file?*filep,?char?__user?*buf,?size_t?len,?loff_t?*pos)?? {?? ????writel(0x3,adc_base?+?ADCMUX);?? ????writel(1<<0?|?1<<14?|?0X1<<16?|?0XFF<<6?,adc_base?+ADCCON?);?? ?? ????wait_event_interruptible(wq,?have_data==1);?? ?? ?????? ????adc?=?readl(adc_base+ADCDAT)&0xfff;?? ?????? ????if(copy_to_user(buf,&adc,sizeof(int)))?? ????{?? ????????return?-EFAULT;?? ????}?? ????have_data?=?0;?? ????return?len;?? }?? static??int?adc_release(struct?inode?*inode,?struct?file?*filep)?? {?? ????return?0;?? }?? static?struct?file_operations??adc_ops?=?? {?? ????.open?=?adc_open,?? ????.release?=?adc_release,?? ????.read?=?adc_read,?? };?? ?? ?? static?int?hello_probe(struct?platform_device?*pdev)?? {?? ????int?ret;?? ????printk("match?0k?\n");?? ?? ????res1?=?platform_get_resource(pdev,IORESOURCE_IRQ,?0);?? ????res2?=?platform_get_resource(pdev,IORESOURCE_MEM,?0);??? ????????? ????ret?=?request_irq(res1->start,adc_handler,IRQF_DISABLED,"adc1",NULL);?? ??????adc_base?=?ioremap(res2->start,res2->end-res2->start);?? ?? ????register_chrdev(?major,?"adc",?&adc_ops);?? ????init_waitqueue_head(&wq);?? ?????? ????return?0;?? }?? static?int?hello_remove(struct?platform_device?*pdev)?? {?? ????free_irq(res1->start,NULL);?? ????free_irq(res2->start,NULL);???? ????unregister_chrdev(?major,?"adc");?? ????return?0;?? }?? ?? static?struct?of_device_id?adc_id[]=?? {?? ????{.compatible?=?"fs4412,adc"?},?? };?? ?? static?struct?platform_driver?hello_driver=?? {?? ?????? ????.probe?=?hello_probe,?? ????.remove?=?hello_remove,?? ????.driver?={?? ????????.name?=?"bigbang",?? ????????.of_match_table?=?adc_id,?? ????},?? };?? ?? static?int?hello_init(void)?? {?? ????printk("hello_init");?? ????return?platform_driver_register(&hello_driver);?? }?? static?void?hello_exit(void)?? {?? ????platform_driver_unregister(&hello_driver);?? ????printk("hello_exit?\n");?? ????return;?? }?? MODULE_LICENSE("GPL");?? module_init(hello_init);?? module_exit(hello_exit);??
test.c
[cpp]?view plaincopy
#include?<sys/types.h>?? #include?<sys/stat.h>?? #include?<fcntl.h>?? #include?<stdio.h>?? ?? ?? main()?? {?? ????int?fd,len;?? ????int?adc;?? ????fd?=?open("/dev/hello",O_RDWR);?? ????if(fd<0)?? ????{?? ????????perror("open?fail?\n");?? ????????return?;?? ????}?? ?? ????while(1)?? ????{?? ????????read(fd,&adc,4);?? ????????printf("adc%0.2f?V?\n",(1.8*adc)/4096);?? ????}?? ?? ????close(fd);?? } ?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的Exynos4412 ADC 设备驱动开发的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。