BeagleBonewilliam hill官网
直播中

杨永胜

12年用户 2379经验值
擅长:嵌入式技术
私信 关注
[经验]

ioremap完成GPIO的输出控制。

为BBB写了一个小驱动,用ioremap完成的,可以用宏定义GPIOX1_X2,,程序如下:
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11. #include

  12. #define GPIOGROUP_NUM 4
  13. //#define GPIO1_BASE 0x4804c000
  14. #define GPIO_OE_OFFSET 0x134
  15. #define GPIO_DATAOUT_OFFET 0X13c
  16. /*修改GPIO_MA(对应GPIO0~GPIO3) GPIO_MI(对应0~31)) GPIO_NUM=GPIO_MA*32+GPIO_MI*/
  17. #define GPIO_MA 1
  18. #define GPIO_MI 28
  19. #define GPIO_NUM 0

  20. #define GPIOLED_NUM 1

  21. #define NAME_LEN 16
  22. #define GPIOLED_MAJOR 0

  23. #define MKGPIONUM(ma,mi) (ma * 32 + mi)
  24. #define MAGPIO(num) (num / 32)
  25. #define MIGPIO(num) (num % 32)

  26. static unsigned int gpiobase[GPIOGROUP_NUM] = {0x44E07000, 0x4804C000, 0x481AC000, 0x481AE000};

  27. static unsigned int gpio_oe,gpio_dataout;
  28. static char gpio_ma, gpio_mi;
  29. static int major = GPIOLED_MAJOR;
  30. static dev_t devnum;
  31. static struct class *gpioled_class;


  32.        
  33. struct gpioled_dev{
  34.         struct cdev cdev;
  35.         char name[NAME_LEN];
  36.         //unsigned int gpio_num;
  37.         char gpio_ma;
  38.         char gpio_mi;
  39.         struct device *gpioled_device;
  40. };

  41. static struct gpioled_dev *gpioled_devp;


  42. static int gpioled_open(struct inode *inode, struct file *filp)
  43. {
  44.         int ret = 0;
  45.         unsigned int value_tmp;
  46.         filp->private_data = container_of(inode->i_cdev, struct gpioled_dev, cdev);
  47.         struct gpioled_dev *devp = filp->private_data;
  48.         value_tmp = readl(gpio_dataout);
  49.         printk("gpioled open and gpio%d_outdata:0x%lx.n",MKGPIONUM(devp->gpio_ma, devp->gpio_mi),(unsigned long)value_tmp);
  50.         return ret;       
  51. }

  52. static ssize_t gpioled_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos)
  53. {
  54.         unsigned int value_tmp;
  55.         struct gpioled_dev *devp = filp->private_data;
  56.         value_tmp = readl(gpio_dataout);
  57.         if(copy_to_user(buf,&value_tmp,sizeof(value_tmp)))
  58.                 printk(KERN_INFO "read failed!n");
  59.         else
  60.         {
  61.                 *ppos+=sizeof(value_tmp);
  62.                 printk(KERN_INFO "%s open and outdata:0x%lx.n",devp->name, (unsigned long)value_tmp);
  63.         }
  64.         return 0;
  65. }

  66. static ssize_t gpioled_write (struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
  67. {
  68.         char value;
  69.         struct gpioled_dev *devp = filp->private_data;
  70.         copy_from_user(&value, buf, sizeof(value));
  71.         if(value == '1')
  72.                 writel((1<gpio_mi),gpio_dataout);
  73.         else if(value == '0')
  74.                 writel((0<gpio_mi),gpio_dataout);
  75.         else
  76.                 printk("no valid value value:%d.n",value);
  77.        
  78.         return sizeof(value);
  79. }

  80. static int gpioled_release(struct inode *inode, struct file *filp)
  81. {
  82.         int ret = 0;
  83.        
  84.         return ret;
  85. }

  86. static struct file_operations gpioled_fops = {
  87.         .owner = THIS_MODULE,
  88.         .open = gpioled_open,
  89.         .read = gpioled_read,
  90.         .write = gpioled_write,
  91.         .release =  gpioled_release,
  92. };

  93. static void gpioled_setup(struct gpioled_dev * devp, int index)
  94. {
  95.         int ret = 0;
  96.         devnum = MKDEV(major,index);
  97.         cdev_init(&devp->cdev,&gpioled_fops);
  98.         devp->cdev.owner = THIS_MODULE;
  99.         ret = cdev_add(&devp->cdev,devnum,1);
  100.         if(ret)
  101.         {
  102.                 printk(KERN_INFO "Error %d adding gpioled%d.n",ret, index);
  103.         }
  104.         else
  105.         {               
  106.                 devp->gpio_ma = gpio_ma;
  107.                 devp->gpio_mi = gpio_mi;
  108.                 sprintf(devp->name,"gpio%d_%d",devp->gpio_ma, devp->gpio_mi);
  109.                 devp->gpioled_device = device_create(gpioled_class, NULL, devnum,NULL,devp->name);
  110.                 printk(KERN_INFO "%s init.n",devp->name);
  111.         }       
  112. }
  113. static int __init gpioled_init(void)
  114. {
  115.         int i, ret = 0;
  116.         unsigned int value_tmp;
  117.         if(GPIO_NUM != 0)
  118.         {
  119.                 gpio_ma = MAGPIO(GPIO_NUM);
  120.                 gpio_mi = MIGPIO(GPIO_NUM);
  121.         }
  122.         else
  123.         {
  124.                 gpio_ma = GPIO_MA;
  125.                 gpio_mi = GPIO_MI;
  126.         }
  127.         if(request_mem_region(gpiobase[gpio_ma] | GPIO_OE_OFFSET,sizeof(int),"GPIO_OE"))
  128.         {
  129.                 ret = -EBUSY;
  130.                 goto fail;
  131.         }
  132.         if(request_mem_region(gpiobase[gpio_ma] | GPIO_DATAOUT_OFFET,sizeof(int),"GPIO_DATAOUT"))
  133.         {
  134.                 ret = -EBUSY;
  135.                 goto fail;
  136.         }
  137.         gpio_oe = ioremap(gpiobase[gpio_ma] | GPIO_OE_OFFSET,sizeof(int));
  138.         if(gpio_oe == NULL)
  139.         {
  140.                 release_mem_region(gpiobase[gpio_ma] | GPIO_OE_OFFSET,sizeof(int));
  141.                 ret = -ENOMEM;
  142.                 goto fail;
  143.         }
  144.         gpio_dataout = ioremap(gpiobase[gpio_ma] | GPIO_DATAOUT_OFFET,sizeof(int));
  145.         if(gpio_dataout == NULL)
  146.         {
  147.                 release_mem_region(gpiobase[gpio_ma] | GPIO_DATAOUT_OFFET,sizeof(int));
  148.                 ret = -ENOMEM;
  149.                 goto fail;
  150.         }
  151.         if(major)
  152.         {
  153.                 devnum = MKDEV(major,0);
  154.                 ret = register_chrdev_region(devnum,GPIOLED_NUM,"gpioled");
  155.         }
  156.         else
  157.         {
  158.                 ret = alloc_chrdev_region(&devnum,0,GPIOLED_NUM,"gpioled");
  159.                 major = MAJOR(devnum);
  160.         }
  161.         if(ret < 0)
  162.         {
  163.                 goto fail;
  164.         }
  165.         gpioled_devp = kzalloc(sizeof(struct gpioled_dev) * GPIOLED_NUM,GFP_KERNEL);
  166.         if(IS_ERR(gpioled_devp))
  167.         {
  168.                 ret = -ENOMEM;
  169.                 goto fail;
  170.         }
  171.         gpioled_class = class_create(THIS_MODULE,"gpioled");
  172.         for(i=0; i
  173.         {
  174.                 gpioled_setup(gpioled_devp + i, i);
  175.         }
  176.         writel(~(1<
  177. fail:
  178.         return ret;
  179. }

  180. static void __exit gpioled_exit(void)
  181. {
  182.         int i;
  183.         for(i=0; i
  184.         {
  185.                 devnum = MKDEV(major,i);
  186.                 device_destroy(gpioled_class,devnum);
  187.                 printk("%s exit.n",(gpioled_devp+ i)->name);
  188.                 cdev_del(&(gpioled_devp+i)->cdev);
  189.                 unregister_chrdev_region(devnum,1);               
  190.         }
  191.         class_destroy(gpioled_class);
  192.         kfree(gpioled_devp);
  193. }

  194. module_init(gpioled_init);
  195. module_exit(gpioled_exit);

  196. MODULE_AUTHOR("yang yongsheng");
  197. MODULE_LICENSE("GPL v2");
功能还有待完善,先贴上来吧。
有关的寄存器图如下:
gpioled00.PNG
gpiole1.PNG
看下效果图:
gpio.PNG
  • gpioled01.1.PNG

回帖(5)

michael_llh

2016-11-6 16:31:24
不错,感谢分享!
举报

杨永胜

2016-11-6 18:54:21
引用: michael_llh 发表于 2016-11-6 16:31
不错,感谢分享!

谢谢支持,
举报

柠檬守护

2016-11-15 12:19:09
这个叫做学以致用~
举报

柠檬守护

2016-11-15 12:19:42
棒棒哒~~~
举报

更多回帖

发帖
×
20
完善资料,
赚取积分