[技术] 【Rico Board试用体验】跟着小狂玩RicoBoard之三种方法玩转GPIO第二篇

[复制链接]

实习版主

发表于 2016-11-30 19:41:35   10237 查看 12 回复 显示全部楼层 倒序浏览
分享

上一篇帖子已经把官方提供的历程解释了一遍,这一篇帖子我们直接调用公用的GPIO接口库gpiolib.c,实现我们的控制功能。米尔科技提供的内核已经吧RicoBoardGPIO操作和gpiolib连接起来啦,具体怎么连接,在这篇帖子里小狂就不做详细的描述了,这是一个非常复杂的过程,看的我也是头晕脑胀各种赋值操作,各种跳转。有兴趣的童鞋可以参考一下这篇帖子,

http://weimenlove.blog.163.com/blog/static/1777547320139251031924/

讲的非常之详细,能让你更加清晰内核的调用过程。我们要做的就是在我们的驱动程序中,调用gpiolib.c库中的内容,然后实现IO的拉高和拉低操作。其实米尔提供的内核文件也是基于TI的,我们从TI的官网上,可以直接找到他们GPIO的调用过程。

1.png

上一篇帖子我们直接用到的就是User Layer层来控制我们的GPIO ,这一节小狂主要就是带大家在GPIO 的字符驱动层调用gpiolib.c中的函数来实现IO的控制。

先介绍几个相关的函数,

static inline int gpio_request(unsignedgpio, const char *label);

其中gpio为请求的io号在内核中的表达形式,跟上一节的计算方式一致GPIO5_9=5*32+9=169GPIO1_25=1*32+25=57Lable是你为申请的GPIO起一个名字。

static inline void gpio_free(unsigned gpio)

有申请就要有释放,这个在驱动编程中应该要养成的一个好习惯,这个函数的作用就是释放你刚才申请的IO号。

int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio,int value);

这两个函数是设置GPIO为输入还是输出状态,当设置为输出的时候,可以指定初始时为高电平还是低电平

static inline void gpio_set_value(unsignedint gpio, int value);

设置当前GPIO的输出状态,这次驱动中对GPIO的控制主要为输出控制,小狂在这里只介绍输出。如果还想了解更多的gpiolib中函数的使用方法,可以查看documentat文件夹里gpio.txt文档。

我们在注册模块的时候应该注册IO,看下图

2.png

然后在移除模块的时候应该释放IO

3.png

这里我们事先在控制台的输出控制,不需要ioctl,先不实现,当我们往设备节点中写字符1的时候,io设置为0,开灯,同时打印信息,写0的时候关灯,同时打印信息,只需要事先写函数就行。

4.png

驱动程序,实现后,我们应该在内核中编译,makefile文件如下图所示,这个make文件只适合一个.c文档的编译,不适合多个.c,下一篇帖子会说多个.cmakefile,其中KERNELDIR指定你的内核主Makefile所在的目录。

12.png

在虚拟机中进入到你的make所在目录,然后执行make,编译完成如下图所示

5.png

然后我们把程序下载到开发板中,导入模块

6.png

查看我们的驱动有没有导入到内核

7.png

可以看到我们的主设备号为233,然后在驱动文件中建立设备节点

8.png

查看一下设备节点有没有成功建立

9.png

然后我们点亮LED

10.png

在这里就不上实物图啦,结果跟上一篇帖子一样

然后,我们让灯关了

11.png
总结

到这里,我们在驱动层控制LED的想法已经实现,其实吧,这种控制方式,是我们自己调用内核中GPIO驱动,就是上边说的那些函数,上一节是在系统中往文件中写内容,其实也是调用的那些函数,什么export啊,direction啊,分别对应就行了。下一篇我们讲怎么在驱动中使用物理地址映射。

附代码如下
  1. #include <linux/module.h>
  2. #include <linux/fs.h>
  3. #include <linux/init.h>
  4. #include <linux/cdev.h>
  5. #include <linux/types.h>
  6. #include <linux/string.h>
  7. #include <linux/slab.h>
  8. #include <linux/uaccess.h>
  9. #include <linux/gpio.h>
  10. #define GPIO_SIZE 0X1000
  11. #define GPIO_MAJOR 233

  12. static int gpio_major=GPIO_MAJOR;
  13. struct gpio_dev{
  14.         struct cdev cdev;
  15.         uint8_t value;
  16. };
  17. struct gpio_dev *gpio_devp;
  18. MODULE_AUTHOR("Xiaokuang <guoyangyang37@163.com> ");
  19. MODULE_LICENSE("GPL v2");
  20. static int gpio_open(struct inode *inode,struct file *filp)
  21. {
  22.         struct gpio_dev *dev;
  23.         dev=container_of(inode->i_cdev,struct gpio_dev,cdev);
  24.         filp->private_data=dev;
  25. //        filp->private_data=gpio_devp;
  26.         printk(KERN_NOTICE "open ok\n");        
  27.         return 0;
  28. }
  29. int gpio_release(struct inode *inode , struct file *filp)
  30. {
  31.         return 0;
  32. }
  33. ssize_t gpio_write(struct file *filp,const char __user *buf ,size_t count,loff_t *f_pos)
  34. {
  35.         struct gpio_dev *dev=filp->private_data;
  36. //        printk(KERN_NOTICE "write ok\n");
  37.         if(copy_from_user(&(dev->value),buf,1))
  38.                 return -EFAULT;
  39.         if(dev->value=='0'){
  40.                 gpio_set_value(57,1);
  41.                 printk(KERN_NOTICE "gpio off %c\n",*buf);
  42.         } else if(dev->value == '1') {
  43.                 gpio_set_value(57,0);
  44.                 printk(KERN_NOTICE "gpio on %c\n",*buf);
  45.         }
  46.         return 1;
  47. }
  48. ssize_t gpio_read(struct file *filp,char __user *buf ,size_t count,loff_t *f_pos)
  49. {
  50.         struct gpio_dev *dev=filp->private_data;
  51.         if(copy_to_user(buf,&(dev->cdev),1))
  52.                 return -EFAULT;
  53.         return 1;
  54. }
  55. //int gpio_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
  56. //{
  57. //        struct gpio_dev *dev=filp->private_data;
  58. //        return 0;
  59. //}
  60. //
  61. struct file_operations gpio_fops = {
  62.         .owner=THIS_MODULE,
  63.         .open=gpio_open,
  64.         .release=gpio_release,
  65.         .write=gpio_write,
  66.         .read=gpio_read,
  67. };
  68. void gpio_setup_cdev(struct gpio_dev *dev ,int index)
  69. {
  70.         int err;
  71.         dev_t devno=MKDEV(gpio_major,index);
  72.         cdev_init(&dev->cdev,&gpio_fops);
  73.         dev->cdev.owner=THIS_MODULE;
  74.         dev->cdev.ops=&gpio_fops;
  75.         err=cdev_add(&dev->cdev,devno,1);
  76.         if(err)
  77.               printk(KERN_NOTICE "Error %d adding GPIO %d",err,index);
  78. }
  79. static int __init gpio_init(void)
  80. {
  81.         int result;
  82.         int a=0;
  83.         dev_t dev=MKDEV(gpio_major,0);
  84.         if(gpio_major)
  85.                result=register_chrdev_region(dev,1,"led");
  86.         else {
  87.                 result=alloc_chrdev_region(&dev,0,1,"led");
  88.                 gpio_major=MAJOR(dev);
  89.         }
  90.         if(result<0)
  91.                 return result;
  92.         gpio_devp=kmalloc(sizeof(struct gpio_dev),GFP_KERNEL);
  93.         if(!gpio_devp){
  94.                 result= -ENOMEM;
  95.                 goto failmalloc;
  96.         }
  97.         memset(gpio_devp,0,sizeof(struct gpio_dev));
  98.         gpio_setup_cdev(gpio_devp,0);
  99.         printk(KERN_NOTICE "init ok\n");
  100.         //gpio ini
  101.         a=gpio_request(57,"test_led");
  102.         if(a)
  103.                 printk(KERN_NOTICE "gpio request failed %d\n",a);
  104.         else {
  105.                 gpio_direction_output(57,1);
  106.         }
  107.         return 0;
  108.         failmalloc:
  109.                 unregister_chrdev_region(MKDEV(gpio_major,0),1);
  110.                 return result;
  111. }
  112. static void __exit gpio_clean_up(void)
  113. {
  114.         cdev_del(&gpio_devp->cdev);
  115.         kfree(gpio_devp);
  116.         unregister_chrdev_region(MKDEV(gpio_major,0),1);
  117.         gpio_free(57);
  118.         printk(KERN_NOTICE "exit ok\n");
  119. }
  120. module_init(gpio_init);
  121. module_exit(gpio_clean_up);
复制代码


技术员

发表于 2016-12-1 10:19:42  
小狂出品,必须精品
回复

举报

助理工程师

发表于 2016-12-1 14:10:16  
楼主真会玩
回复

举报

实习版主

发表于 2016-12-1 17:06:48    楼主|
新疆切糕 发表于 2016-12-1 10:19
小狂出品,必须精品

哈哈,小狂的口号啊,必须的,哈哈,谢谢支持
回复

点赞 举报

实习版主

发表于 2016-12-1 17:07:11    楼主|

玩就玩点不一样的吗,这才对得起玩啊
回复

点赞 举报

技术员

发表于 2016-12-7 12:53:19  
高手!
谢谢分享!



兜纳K1
回复

举报

实习版主

发表于 2016-12-7 15:57:22    楼主|
兜纳K1 发表于 2016-12-7 12:53
高手!
谢谢分享!

谢谢支持
回复

点赞 举报

发表于 2016-12-10 10:38:28  
论坛的原创担当啊~
回复

举报

实习版主

发表于 2016-12-12 21:50:51    楼主|
柠檬守护 发表于 2016-12-10 10:38
论坛的原创担当啊~

谢谢版主大人夸奖,哈哈
回复

点赞 举报

等待验证会员

发表于 2017-9-2 19:21:12  
楼主我问个问题 我照着你的Makefile写的 我把pwm-ehrpwm.c 复制过去了  然后make报了好几篇的错误 是怎么内核目录的Makefile不一样吗 我的也是自带的 不应该啊
回复

点赞 举报

实习版主

发表于 2017-9-2 22:35:34    楼主|
n5631228 发表于 2017-9-2 19:21
楼主我问个问题 我照着你的Makefile写的 我把pwm-ehrpwm.c 复制过去了  然后make报了好几篇的错误 是怎么内核目录的Makefile不一样吗 我的也是自带的 不应该啊

对,要指向你的内核的目录,另外,你的内核要编译一下
回复

点赞 举报

等待验证会员

发表于 2017-9-6 10:55:06  
3guoyangyang7 发表于 2017-9-2 22:35
对,要指向你的内核的目录,另外,你的内核要编译一下

谢谢楼主 我的Makefile写的不对 改了就好了
再问一下 我是3.12内核 PWM用不了 该设备树没效果 用.ko文件insmod不了 你的能用吗
回复

点赞 举报

实习版主

发表于 2017-9-6 22:18:40    楼主|
我的板子被收回了,嘿嘿,就没有玩,嘻嘻,应该只是支持的,insmod肯定可以的
回复

点赞 举报

只有小组成员才能发言,加入小组>>

17个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表
-

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

FPGA|CPLD|ASIC论坛

DSP论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

厂商专区

TI论坛

TI Deyisupport社区

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区