新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM-Linux自動創建設備結點

        ARM-Linux自動創建設備結點

        作者: 時間:2016-11-20 來源:網絡 收藏
        硬件平臺:FL2440

        內核版本:2.6.28

        本文引用地址:http://www.104case.com/article/201611/318863.htm

        主機平臺: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 plaincopy
        1. #include
        2. #include
        3. #include
        4. #include/*創建設備節點*/
        5. #include
        6. #include/*定義DECLARE_WAIT_QUEUE_HEAD*/
        7. #include/*定義了irqreturn_t等*/
        8. #includeinterrupt.h>/*request_irqdisable_irqenable_irq*/
        9. #include
        10. #include
        11. #include/*其中包含了#include"mach/irqs.h"*/
        12. #includeadc.h>
        13. #include
        14. #defineADC_MAJOR102
        15. #defineADC_NAME"my_adc"
        16. #defineSUCCESS0
        17. staticintadc_open(structinode*,structfile*);
        18. staticintadc_release(structinode*,structfile*);
        19. staticint__initadc_init(void);
        20. staticint__exitadc_exit(void);
        21. staticssize_tadc_read(structfile*,char*,size_t,loff_t*);
        22. volatileunsignedlongadc_con;
        23. unsignedlongadc_dat0;
        24. intflag;//等待任務完成標志
        25. unsignedlongbuf;//存放轉換完成的數據
        26. //聲明等待隊列
        27. DECLARE_WAIT_QUEUE_HEAD(adc_wait);
        28. structclk*adc_clk;
        29. staticirqreturn_tadc_interrupt(intirq,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("Readvalueis%ldn",buf);
        37. }
        38. returnIRQ_HANDLED;
        39. }
        40. staticstructfile_operationsadc_ops=
        41. {
        42. .owner=THIS_MODULE,
        43. .read=adc_read,
        44. .open=adc_open,
        45. .release=adc_release,
        46. };
        47. staticstructmiscdeviceadc_misc=
        48. {
        49. .name=ADC_NAME,
        50. .minor=ADC_MAJOR,
        51. .fops=&adc_ops,
        52. };
        53. staticint__initadc_init(void)
        54. {
        55. intret;
        56. adc_clk=clk_get(NULL,"adc");//獲取時鐘
        57. clk_enable(adc_clk);//使能時鐘
        58. ret=misc_register(&adc_misc);//注冊設備
        59. if(ret<0)
        60. {
        61. printk("registerdevicefailn");
        62. returnret;
        63. }
        64. adc_con=(unsignedlong)ioremap(0x58000000,4);
        65. adc_dat0=(volatileunsignedlong)ioremap(0x58000000+S3C2410_ADCDAT0,4);
        66. if(!(adc_con&adc_dat0))
        67. {
        68. printk("Failedtoioremapn");
        69. gotohandle;
        70. }
        71. printk("Initialized...n");
        72. returnSUCCESS;
        73. handle:
        74. misc_deregister(&adc_misc);
        75. return-1;
        76. }
        77. staticintadc_open(structinode*inode,structfile*file)//打開設備函數
        78. {
        79. //注冊中斷
        80. intret;
        81. //disable_irq(IRQ_ADC);
        82. //enable_irq(IRQ_ADC);
        83. ret=request_irq(IRQ_ADC,adc_interrupt,IRQF_SHARED,ADC_NAME,1);//注冊中斷IRQ_ADC在mach/irqs.h中定義
        84. if(ret<0)
        85. {
        86. printk("IRQ%dcannotrequestn",IRQ_ADC);
        87. returnret;
        88. }
        89. returnSUCCESS;
        90. }
        91. staticintadc_release(structinode*inode,structfile*file)//關閉設備函數
        92. {
        93. free_irq(IRQ_ADC,1);//釋放中斷
        94. returnSUCCESS;
        95. }
        96. staticssize_tadc_read(structfile*file,
        97. char*buffer,
        98. size_tlength,
        99. loff_t*offset)//設備讀取函數
        100. {
        101. writew((1<<14)|(0x31<<6),adc_con);//設置ADCCON
        102. writew((readw(adc_con)|0x1),adc_con);//啟動AD轉換
        103. wait_event_interruptible(adc_wait,flag);
        104. flag=0;
        105. }
        106. staticint__exitadc_exit(void)//驅動卸載函數
        107. {
        108. iounmap(adc_con);
        109. iounmap(adc_dat0);
        110. misc_deregister(&adc_misc);
        111. clk_disable(adc_clk);
        112. clk_put(adc_clk);
        113. printk("Theadcisunintializedn");
        114. returnSUCCESS;
        115. }
        116. module_init(adc_init);
        117. module_exit(adc_exit);
        118. MODULE_LICENSE("GPL");



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 饶平县| 三原县| 甘南县| 太仓市| 肃宁县| 大理市| 九龙城区| 慈利县| 榕江县| 容城县| 大丰市| 永胜县| 湄潭县| 水富县| 崇左市| 高陵县| 遵义县| 屯昌县| 寿宁县| 富阳市| 贺兰县| 靖边县| 吉水县| 洮南市| 昌吉市| 广宁县| 汉沽区| 盐源县| 金门县| 深水埗区| 将乐县| 依兰县| 永寿县| 新沂市| 黄梅县| 拉孜县| 石家庄市| 海阳市| 湘潭市| 临沭县| 都昌县|