Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5671
  • 博文数量: 2
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 32
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-01 01:23
文章分类
文章存档

2014年(2)

我的朋友
最近访客

分类: 嵌入式

2014-06-11 23:25:40

点击(此处)折叠或打开

/*************************LED驱动*************************/
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/fs.h>
  4. #include <linux/device.h>
  5. #include <linux/cdev.h>
  6. #include <linux/slab.h>
  7. #include <linux/gpio.h>
  8. #include <plat/gpio-cfg.h>
  9. #include <asm/uaccess.h>
  10. #include <asm/io.h>


  11. #define PA_GPC0CON 0xE0200060//LED 寄存器的基地址

  12. volatile unsigned int *GPC0CON;
  13. volatile unsigned int *GPC0DAT;

  14. //设计设备对象
  15. struct s5p210_led{
  16.     struct cdev *c_dev;//cdev结构体描述一个字符设备
  17.     struct class *cls;//设备结点类结构体
  18.     struct device *dev;//设备属性结构体
  19.     dev_t devno;//设备节点
  20. };

  21. static struct s5p210_led *led_dev;
  22. static int ret = -1;

  23. int led_open(struct inode *inode, struct file *filp)
  24. {//实现硬件的初始化

  25. #if 0
  26.     //GPIO配置为输出
  27.     *GPC0CON &= ~(0xFF<<12);
  28.     *GPC0CON |= (0x11<<12);
  29.     //LED输出为低
  30.     *GPC0DAT &= ~0x18;
  31.     printk(KERN_INFO"----%s--------\n", __FUNCTION__);
  32. #else
  33.     /*申请某个GPIO管脚*/
  34.     gpio_request(S5PV210_GPC0(3),"led0");
  35.     gpio_request(S5PV210_GPC0(4),"led1");
  36.     /*配置某个管脚为输入功能*/
  37.     s3c_gpio_cfgpin(S5PV210_GPC0(3),S3C_GPIO_OUTPUT);
  38.     s3c_gpio_cfgpin(S5PV210_GPC0(4),S3C_GPIO_OUTPUT);

  39. #endif

  40.     return 0;
  41. }

  42. ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *ofs)
  43. {
  44.     int get_ret = 0;
  45.     int led_signal=0;
  46.     
  47.     get_ret = copy_from_user(&led_signal,buf,1);
  48.     if(get_ret == 0)
  49.     {
  50.         if(!led_signal)
  51.         {//
  52.             //*GPC0DAT &= ~0x18;
  53.             gpio_direction_output(S5PV210_GPC0(3),1);
  54.             gpio_direction_output(S5PV210_GPC0(4),1);
  55.         }
  56.         else
  57.         {//
  58.             //*GPC0DAT |= 0x18;
  59.             gpio_direction_output(S5PV210_GPC0(3),0);
  60.             gpio_direction_output(S5PV210_GPC0(4),0);
  61.         }
  62.     }
  63.     return get_ret?-EFAULT:size;

  64.     printk(KERN_INFO"----%s--------\n", __FUNCTION__);
  65. }
  66. ssize_t led_read (struct file *filp, char __user *buf, size_t size, loff_t *ofs)
  67. {
  68.     printk(KERN_INFO"----%s--------\n", __FUNCTION__);
  69.     return 0;
  70. }
  71. int led_close(struct inode *inode, struct file *filp)
  72. {
  73.     printk(KERN_INFO"----%s--------\n", __FUNCTION__);
  74.     return 0;
  75. }
  76. long ioctl(struct file *filp, unsigned int argc, unsigned long argv)
  77. {
  78.     if(argc ==19870322)
  79.     {
  80.     
  81.          //*GPC0DAT &= ~0x10;
  82.          //*GPC0DAT |= 0x08;
  83.          gpio_direction_output(S5PV210_GPC0(3),1);
  84.          gpio_direction_output(S5PV210_GPC0(4),0);
  85.     }
  86.     if(argv==610428)
  87.     {
  88.          //*GPC0DAT &= ~0x08;
  89.          //*GPC0DAT |= 0x10;
  90.          gpio_direction_output(S5PV210_GPC0(3),0);
  91.          gpio_direction_output(S5PV210_GPC0(4),1);
  92.     }
  93.     printk(KERN_INFO"----%s--------\n", __FUNCTION__);
  94.     return 0;
  95. }


  96. //驱动文件为用户空间提供的操作函数(函数)
  97. struct file_operations led_file={
  98.         .owner = THIS_MODULE,
  99.         .open = led_open,
  100.         .write = led_write,
  101.         .read = led_read,
  102.         .release= led_close,
  103.         .unlocked_ioctl = ioctl,
  104. };

  105. static int __init led_init(void)
  106. {
  107.   //加载驱动过程
  108.   //1.为设备分配一个空间
  109.   led_dev = kmalloc(sizeof(struct s5p210_led),GFP_KERNEL);
  110.   
  111.   if(NULL == led_dev)
  112.   {
  113.       printk(KERN_ERR"kmalloc error!\n");
  114.      return -ENOMEM;
  115.   }
  116.   //2.申请设备号(自动申请设备号)
  117.   ret = register_chrdev(0,"s5pv210_led_drv",&led_file);
  118.   if(ret <=0)
  119.   {
  120.         printk(KERN_ERR"register_chrdev!\n");
  121.         ret = -EINVAL;
  122.         goto err_1;
  123.   }
  124.   //返回的主设备号ret
  125.   led_dev->devno = MKDEV(ret,0);
  126.   //3.创建与用户空间关联的文件
  127.   led_dev->cls = class_create(THIS_MODULE,"s5pv_led_class");
  128.   if(!led_dev->cls)
  129.   {
  130.         ret = PTR_ERR(led_dev->cls);
  131.         goto err_2;
  132.   }
  133.   led_dev->dev = device_create(led_dev->cls,NULL,led_dev->devno,NULL,"s5pv210_led_drv");
  134.   if(!led_dev->dev)
  135.   {
  136.         ret = PTR_ERR(led_dev->dev);
  137.         goto err_3;
  138.   }
  139.   //4.为硬件申请内存资源虚拟地址
  140.   /*GPC0CON = ioremap(PA_GPC0CON,24);
  141.   if(NULL == GPC0CON)
  142.   {
  143.         ret = -ENOMEM;
  144.         goto err_4;
  145.   }
  146.   GPC0DAT = GPC0CON +1;
  147.   */
  148.   printk(KERN_INFO"----%s--------\n", __FUNCTION__);
  149.   return 0;
  150. //err_4:
  151. // device_destroy(led_dev->cls,led_dev->devno);
  152. err_3:
  153.   class_destroy(led_dev->cls);
  154. err_2:
  155.   unregister_chrdev(MAJOR(led_dev->devno),"led_drv");
  156. err_1:
  157.   kfree(led_dev);
  158.   return ret;

  159. }
  160. static void __exit led_exit(void)
  161. {
  162.   //释放申请的资源
  163.   //iounmap(GPC0CON);
  164.   kfree(led_dev);
  165.   unregister_chrdev(MAJOR(led_dev->devno),"led_drv");
  166.   device_destroy(led_dev->cls,led_dev->devno);
  167.   class_destroy(led_dev->cls);
  168.   printk(KERN_INFO"----%s--------\n", __FUNCTION__);
  169. }



  170. //模块加载卸载函数
  171. module_init(led_init);
  172. module_exit(led_exit);
  173. MODULE_LICENSE("GPL");
  174. /*************************LED驱动*************************/
    /*************************LED驱动*************************/

/*********************LED驱动测试程序*********************************/

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<errno.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stropts.h>

  6. int main(int argc ,char *argv[])
  7. {
  8.     int fd = -1;
  9.     int on =1;
  10.     int off = 0;
  11.     fd = open("/dev/s5pv210_led_drv",O_RDWR);
  12.     if(fd ==-1)
  13.     {
  14.         perror("open");
  15.         return -1;
  16.     }
  17.     while(1)
  18.     {
  19.         //write(fd,&on,1);
  20.         //sleep(1);
  21.        //write(fd,&off,1);
  22.         //sleep(1);
  23.         ioctl(fd,19870322,1);
  24.         sleep(1);
  25.         ioctl(fd,1,610428);
  26.         sleep(1);
  27.         
  28.     }
  29.     return 0;
  30. }

阅读(1746) | 评论(0) | 转发(0) |
0

上一篇:linux驱动框架

下一篇:没有了

给主人留下些什么吧!~~