ARM Linux自动创建设备结点

硬件平台:FL2440

内核版本:2.6.28

主机平台:Ubuntu 11.04

内核版本:2.6.39

1、首先配置busybox

busybox
Linux System Utilities --->
    [*] mdev
    [*] Support /etc/mdev.conf
    [*] Support command execution at device addition/removal

 

2、配置内核

ARM Linux自动创建设备结点

3、修改文件系统里的/etc/init.d/rcS

vi ./etc/init.d/rcS
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

4、修改/etcfstab

vi ./etc/fstab
#device mount-point type     options     dump     fsck order
proc      /proc         proc     defaults     0         0
tmpfs     /tmp         tmpfs     defaults     0         0
sysfs     /sys         sysfs     defaults     0         0
tmpfs     /dev         tmpfs     defaults     0         0

这样编写驱动时不用手动创建设备结点文件了

下面是改写的使用混杂设备的ADC驱动程序,这样可以自动创建和删除设备结点了

  1. #include <linux/kernel.h>   
  2. #include <linux/module.h>   
  3. #include <linux/fs.h>   
  4. #include <linux/miscdevice.h> /*创建设备节点*/   
  5. #include <linux/clk.h>   
  6. #include <linux/wait.h> /*定义DECLARE_WAIT_QUEUE_HEAD*/   
  7. #include <linux/irqreturn.h> /*定义了irqreturn_t等*/   
  8. #include <linux/interrupt.h> /*request_irq disable_irq enable_irq*/   
  9. #include <asm/io.h>   
  10. #include <asm/uaccess.h>   
  11. #include <asm/irq.h>  /*其中包含了#include "mach/irqs.h" */   
  12. #include <plat/regs-adc.h>   
  13. #include <mach/regs-clock.h>   
  14. #define ADC_MAJOR 102   
  15. #define ADC_NAME "my_adc"   
  16. #define SUCCESS 0   
  17. static int adc_open(struct inode *,struct file *);   
  18. static int adc_release(struct inode *,struct file *);   
  19. static int __init adc_init(void);   
  20. static int __exit adc_exit(void);   
  21. static ssize_t adc_read(struct file *,char *,size_t,loff_t *);   
  22. volatile unsigned long adc_con;   
  23. unsigned long adc_dat0;   
  24. int flag;//等待任务完成标志   
  25. unsigned long buf;//存放转换完成的数据   
  26. //声明等待队列   
  27. DECLARE_WAIT_QUEUE_HEAD(adc_wait);   
  28. struct clk *adc_clk;    
  29. static irqreturn_t adc_interrupt(int irq,void * dev_id)//中断处理程序   
  30. {   
  31.     if(flag==0)   
  32.     {   
  33.         buf=(readw(adc_dat0) & 0x3ff );//读取转换完成的数据   
  34.         flag=1;   
  35.         wake_up_interruptible(&adc_wait);//唤醒等待其上的进程   
  36.         printk("Read value is %ld\n",buf);   
  37.     }   
  38.     return IRQ_HANDLED;   
  39. }   
  40. static struct file_operations  adc_ops =   
  41. {   
  42.     .owner  =   THIS_MODULE,   
  43.     .read       =   adc_read,   
  44.     .open   =   adc_open,   
  45.     .release    =   adc_release,   
  46. };   
  47. static struct miscdevice adc_misc =    
  48. {   
  49.     .name = ADC_NAME,   
  50.     .minor = ADC_MAJOR,   
  51.     .fops = &adc_ops,   
  52. };   
  53. static int __init adc_init(void)   
  54. {   
  55.     int ret;   
  56.     adc_clk = clk_get(NULL,"adc");//获取时钟   
  57.     clk_enable(adc_clk);//使能时钟   
  58.        
  59.     ret=misc_register(&adc_misc); //注册设备   
  60.     if(ret<0)   
  61.     {   
  62.         printk("register device fail\n");   
  63.         return ret;   
  64.     }   
  65.     adc_con=(unsigned long)ioremap(0x58000000,4);   
  66.     adc_dat0=(volatile unsigned long)ioremap(0x58000000+S3C2410_ADCDAT0,4);   
  67.     if( !(adc_con & adc_dat0) )   
  68.     {   
  69.         printk("Failed to ioremap\n");   
  70.         goto handle;   
  71.     }   
  72.     printk("Initialized...\n");   
  73.     return SUCCESS;   
  74. handle:   
  75.     misc_deregister(&adc_misc);   
  76.     return -1;   
  77. }   
  78. static int adc_open(struct inode * inode,struct file * file) //打开设备函数   
  79. {   
  80.     //注册中断   
  81.     int ret;   
  82.     //disable_irq(IRQ_ADC);   
  83.     //enable_irq(IRQ_ADC);   
  84.     ret=request_irq(IRQ_ADC,adc_interrupt,IRQF_SHARED,ADC_NAME,1);//注册中断 IRQ_ADC在 mach/irqs.h中定义   
  85.     if(ret<0)   
  86.     {   
  87.         printk("IRQ %d can not request\n",IRQ_ADC);   
  88.         return ret;   
  89.     }   
  90.     return SUCCESS;   
  91. }   
  92. static int adc_release(struct inode * inode,struct file * file) //关闭设备函数   
  93. {   
  94.     free_irq(IRQ_ADC,1);//释放中断   
  95.     return SUCCESS;   
  96. }   
  97. static ssize_t adc_read(struct file *file,   
  98.                             char * buffer,   
  99.                             size_t length,   
  100.                             loff_t * offset)//设备读取函数   
  101. {   
  102.        
  103.     writew((1<<14)|(0x31<<6),adc_con);       //设置ADCCON   
  104.     writew((readw(adc_con) | 0x1),adc_con);  //启动AD转换   
  105.     wait_event_interruptible(adc_wait,flag);   
  106.     flag=0;   
  107. }   
  108. static int __exit adc_exit(void//驱动卸载函数   
  109. {   
  110.     iounmap(adc_con);   
  111.     iounmap(adc_dat0);   
  112.     misc_deregister(&adc_misc);   
  113.     clk_disable(adc_clk);   
  114.     clk_put(adc_clk);   
  115.     printk("The adc is unintialized\n");   
  116.     return SUCCESS;   
  117. }   
  118. module_init(adc_init);            
  119. module_exit(adc_exit);   
  120. MODULE_LICENSE("GPL");  

相关推荐