×
单片机 > 单片机程序设计 > 详情

ARM-Linux自动创建设备结点

发布时间:2020-08-26 发布时间:
|
硬件平台: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、配置内核

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

#!/bin/sh
/bin/mount -a
/sbin/ifconfig eth0 192.168.0.3 up
#exec /usr/etc/rc.mouse
 

4、修改文件系统中/linuxrc文件

#!/bin/sh
#echo "mount /etc as ramfs"
#/bin/mount -n -t ramfs ramfs /etc
#/bin/cp -a /mnt/etc/* /etc

#/bin/mount -n -t ramfs ramfs /var/state/dhcp
#/bin/mount -n -t ramfs ramfs /var/log/boa
#/bin/mount -n -t ramfs ramfs /usr/Setting
#/bin/cp -a /mnt/Setting/* /usr/Setting

#/bin/mount -n -t ramfs ramfs /tmp
#/bin/cp -a /mnt/etc/* /etc

/bin/mount -t proc proc /proc
/bin/mount -t sysfs sysfs /sys
/bin/mount -t tmpfs tmpfs /dev
mkdir /dev/pts
mkdir /dev/shm

/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s

exec /sbin/init

4、修改/etcfstab

vi ./etc/fstab
#device mount-point type     options     dump     fsck order
none            /dev/pts        devpts  mode=0622       0 0
tmpfs           /dev/shm        tmpfs   defaults        0 0

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

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

 

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

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈msp430f5529入门(2)----时钟配置.例程分析