热门关键字:  ubuntu  分区  函数  Fedora  linux系统进程

led驱动

来源: 作者: 时间:2008-03-03 Tag: 点击:

说明:
1。0×378为LED地址位,已知
2。未使用ioctl方式,用write代替,因为可以使用bash直接调用测试,较方便。
3。init函数进行模块初始化,先通过misc_register 注册设备,然后申请端口,防止有冲突发生。
4。write方式调用时,需要从用户空间获取数据到内核空间,通过get_user实现,用outb写数据到对应端口上
5。删除模块时记得删除注册的设备和释放端口,否则会出错。


源码:
led.c

  1. #include <linux/delay.h>
  2. #include <linux/config.h>
  3. #include <linux/module.h>
  4. #include <linux/kernel.h> /* printk() */
  5. #include <linux/errno.h>  /* error codes */
  6. #include <linux/init.h>
  7. #include <linux/ioport.h>
  8. #include <asm/io.h>
  9. #include <linux/miscdevice.h>
  10. #include <asm/uaccess.h>
  11. #define GPIO_ADD 0x378
  12. static ssize_t led_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
  13. {
  14.         /*  Can't seek (pwrite) on this device  */
  15.         if (ppos != &file->f_pos)
  16.                 return -ESPIPE;
  17.         printk(KERN_DEBUG "write %p %p %d\n", buf, ppos, count);
  18.         if (count) {
  19.                 size_t i;
  20.                 for (i = 0; i != count; i++) {
  21.                         char c;
  22.                         if (get_user(c, buf+i))
  23.                                return -EFAULT;
  24.                         printk(KERN_DEBUG "outb %x\n", c);
  25.                         outb(GPIO_ADD, c);
  26.                 }
  27.         }
  28.         return count;
  29. }
  30. static int led_open(struct inode *inode, struct file *filp)
  31. {
  32.         return 0;
  33. }
  34. static int led_release(struct inode *inode, struct file *filp)
  35. {
  36.         return 0;
  37. }
  38. static struct file_operations led_fops = {
  39.         open:     led_open,
  40.         releaseled_release,
  41.         write:    led_write,
  42. };
  43. static struct miscdevice led_dev =
  44. {
  45.         minor:       MISC_DYNAMIC_MINOR,
  46.         name:        "led",
  47.         fops:        &led_fops,
  48. };
  49. static __init int __myinit(void)
  50. {
  51.         printk(KERN_INFO "led init\n");
  52.         /*initialize GPIO pin*/
  53.         misc_register(&led_dev);
  54.         request_region(GPIO_ADD, 2, "led region");
  55.         return 0;
  56. }
  57. static __exit void __myexit(void)
  58. {
  59.         misc_deregister(&led_dev);
  60.         printk(KERN_INFO "led unload\n");
  61.         release_region(GPIO_ADD,2);
  62. }
  63. module_init(__myinit);
  64. module_exit(__myexit);
  65. MODULE_LICENSE("GPL");
  66. MODULE_AUTHOR("YuYii <fin1983@hotmail.com>");
  67. MODULE_DESCRIPTION("LED driver");

编译:

  1. ARCH=i386 CROSS_COMPILE=/usr/local/i686-linux/bin/i686-linux- LINUX_SRC=/home/yuyii/linux24/kernel-stuff/install/linux-2.4.31 make

需要Makefile文件

测试:
insmod 安装后,通过bash命令测试LED:
echo -n -e “\x01″ > /dev/misc/led

另外附上一段应用程序来控制led

  1. //Includes
  2. #include<stdio.h>                    //stand input and output libs
  3. #include<stdlib.h>                    //stand sys libs
  4. #include<string.h>                    //string libs
  5. #include<unistd.h>                    //posix libs
  6. #include<sys/io.h>                    //io driver libs
  7. #include<pthread.h>                    //thead libs for multiple thread application
  8. unsigned int STOP=0;                 //sharded variable for terminate triggering the watch dog
  9. void delay(int i)                    //delay function for io ports operation taking effect
  10. {
  11.     int j=0;
  12.     for(j=0;j<i;j++)
  13.     {
  14.         usleep(100000);            //here, 100 ms is enough
  15.     }
  16. }
  17. int main()            //the major function
  18. {
  19.     int port = 0x378;
  20.   fprintf(stdout,"========================================================================\n");
  21.   fprintf(stdout,"==                                                                    ==\n");
  22.   fprintf(stdout,"==        LNSP4 STATUS LED  TEST PROGRAM                              ==\n");
  23.   fprintf(stdout,"==                                                                    ==\n");
  24.   fprintf(stdout,"========================================================================\n");
  25. //call the io ports driver for io ports access
  26.     if(ioperm(port,1,1))
  27.     {
  28.         fprintf(stdout,"Error for port \n");
  29.         exit(1);
  30.     }
  31.    outb(0x01,port);
  32.    delay(2);
  33.    printf(" status led1 off for 5s \n");
  34.    delay(50);
  35.    outb(0x02,port);
  36.    delay(2);
  37.    printf(" status led2 off for 5s \n");
  38.    delay(50);
  39.    outb(0x03,port);
  40.    delay(2);
  41.    printf(" status led1 and led2 off for 5s \n");
  42.    delay(50);
  43.  
  44.    outb(0x00,port);
  45.    delay(2);
  46.    printf(" status led1 and led2 on \n");
  47.   
  48. }

(注:来源于itlives.cn,本人即将被关闭的空间...)


最新评论共有 4 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册