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

3guoyangyang7 ( 楼主 ) 2016-11-30 19:41:35  显示全部楼层

上一篇帖子已经把官方提供的历程解释了一遍,这一篇帖子我们直接调用公用的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啊,分别对应就行了。下一篇我们讲怎么在驱动中使用物理地址映射。

附代码如下: W7 o/ z3 @6 ^! q
  1. #include <linux/module.h>
    ' C. z1 y3 F5 G2 g
  2. #include <linux/fs.h>
    , F/ i4 Q( b8 G( J0 l3 u( L
  3. #include <linux/init.h>" Z1 O9 j# M( P* ~9 k4 M' k
  4. #include <linux/cdev.h>
    + c7 Z2 V5 i6 {6 Q! H* u' i/ N7 T
  5. #include <linux/types.h>) Z! P5 c( W# I6 I
  6. #include <linux/string.h>+ z: o$ Y3 ]' i
  7. #include <linux/slab.h>) L2 K. }0 e9 K, Z2 Z# b! }
  8. #include <linux/uaccess.h>
    , D8 K& T  L3 O6 k. m
  9. #include <linux/gpio.h>
    3 n# T1 B! M. |
  10. #define GPIO_SIZE 0X1000
    4 T! r" x( T% T7 r5 X! [/ w
  11. #define GPIO_MAJOR 233
    2 c3 V; k9 a- {0 [- O* U

  12. 7 L! I. w. ~2 ^9 Z
  13. static int gpio_major=GPIO_MAJOR;
    0 _$ @- A( y' ~! y; C1 P8 B
  14. struct gpio_dev{
    8 |$ h3 f1 c8 b; Y9 z
  15.         struct cdev cdev;3 q1 [* D. x0 d" D* U0 `( T9 G
  16.         uint8_t value;
    , K. U: X2 G* V+ c/ `+ W! p
  17. };, `4 ]# o3 s% z) q
  18. struct gpio_dev *gpio_devp;3 ?* x; q( C0 H+ V- I
  19. MODULE_AUTHOR("Xiaokuang <guoyangyang37@163.com> ");
    ' D( R8 Y9 s5 n: ~. q
  20. MODULE_LICENSE("GPL v2");
    : j0 h1 w0 ^# F
  21. static int gpio_open(struct inode *inode,struct file *filp)# D7 C6 z5 @% i7 p& U- Q* s, c
  22. {
    . [$ T" O6 ]5 O. I( `* n( w
  23.         struct gpio_dev *dev;
    . m# r% F) K# a* i
  24.         dev=container_of(inode->i_cdev,struct gpio_dev,cdev);
    2 J% n) j! o# P/ d( d
  25.         filp->private_data=dev;
    4 b  ^# o2 f8 K( b& [4 J
  26. //        filp->private_data=gpio_devp;
    " k; n& ?& K" B- y: ?) h, g
  27.         printk(KERN_NOTICE "open ok\n");        7 P# T  Y2 v% w' [! Y8 a/ R) V
  28.         return 0;
    & b# o- T- t7 k! @" E, P- S- s
  29. }
    3 u, @7 X! F( b
  30. int gpio_release(struct inode *inode , struct file *filp)' I5 Z8 K. s( K+ e$ d1 H* H/ @7 X
  31. {% b9 G/ E* Q4 P1 A8 L
  32.         return 0;, l; m. B; u" ^# |! b# H% L5 g  [
  33. }
      \. D1 S- Q" n6 J5 N
  34. ssize_t gpio_write(struct file *filp,const char __user *buf ,size_t count,loff_t *f_pos)- T3 S. v& C8 ?4 n
  35. {% R% X3 W: x! q$ B6 I! \, P
  36.         struct gpio_dev *dev=filp->private_data;
    , ~$ s5 \7 k# u, G! k3 y
  37. //        printk(KERN_NOTICE "write ok\n");/ U" H1 R4 s5 _! H* t  \% {
  38.         if(copy_from_user(&(dev->value),buf,1))$ M; R% R. U! z: {' Z+ }; Q. Y8 s: [
  39.                 return -EFAULT;' |( s' Y: c" f' n2 {6 w+ B% @
  40.         if(dev->value=='0'){
    , P3 l5 [7 q2 ]6 Y
  41.                 gpio_set_value(57,1);
    ' a- @# E6 `$ b- w5 }
  42.                 printk(KERN_NOTICE "gpio off %c\n",*buf);  y  W: R2 `) ^4 h2 t, {) L3 z
  43.         } else if(dev->value == '1') {! ^7 v; j  n8 _/ `5 c' H
  44.                 gpio_set_value(57,0);
    7 \% J8 B! v6 W0 c5 z/ z4 A% r
  45.                 printk(KERN_NOTICE "gpio on %c\n",*buf);. S- k& o4 U6 p# ]1 S
  46.         }3 Z" o7 h9 T! ?
  47.         return 1;  ]4 P/ }1 a2 t  N  Z
  48. }
    4 }$ Z5 `( y9 @5 U3 C/ N/ ~* H+ Q- X
  49. ssize_t gpio_read(struct file *filp,char __user *buf ,size_t count,loff_t *f_pos)
    9 M; `; w5 I- y
  50. {
    0 b1 f  p; V3 f9 }9 b2 N
  51.         struct gpio_dev *dev=filp->private_data;* P  ]) ~& G! O! d% f) b
  52.         if(copy_to_user(buf,&(dev->cdev),1))$ u) X5 W3 ^0 }$ ^7 w8 j
  53.                 return -EFAULT;
    8 H5 v( \9 z! b7 D7 T8 H
  54.         return 1;
    ) ]$ y2 Q2 Z0 n8 {
  55. }
    # Y- a' S- B$ w5 E  L5 Q  j, v/ j
  56. //int gpio_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
    : p( O# J6 ~# ~
  57. //{6 \5 n; U( |0 s5 G
  58. //        struct gpio_dev *dev=filp->private_data;1 ]- N. h, g3 ^. c5 M
  59. //        return 0;
    % A( h7 f' \4 _
  60. //}$ ]! ^  Q5 k8 E- b5 ^. {
  61. //
    8 I6 n# v, q" l0 i: K, J
  62. struct file_operations gpio_fops = {
    + g/ z4 V  T' n5 [, i* O; a$ D
  63.         .owner=THIS_MODULE,
    / S4 a9 y$ Q+ r: o* k# o
  64.         .open=gpio_open,
    1 f! R0 n$ i, u# y4 U7 l
  65.         .release=gpio_release,. a( O* ~% o) R% y6 X& h  h7 j
  66.         .write=gpio_write,
    / o5 T' l4 A# [& |; k
  67.         .read=gpio_read,
    0 s3 z; B! U! C
  68. };
    3 ~9 ~" Q5 g# q
  69. void gpio_setup_cdev(struct gpio_dev *dev ,int index)
    7 e5 H3 X, F% D9 S+ T
  70. {
    * ]3 ^, ?& h& f, ^. W; ^( y
  71.         int err;
    9 z' U: V7 ?  s) B5 k' A- Y
  72.         dev_t devno=MKDEV(gpio_major,index);. i8 P. }  E4 X' d  Y
  73.         cdev_init(&dev->cdev,&gpio_fops);& M6 O; |% `, F- J& P+ p- M2 g
  74.         dev->cdev.owner=THIS_MODULE;
    1 h( Z+ u6 O/ E% F; O0 o
  75.         dev->cdev.ops=&gpio_fops;3 f8 U# H0 J- S& m+ T2 Y
  76.         err=cdev_add(&dev->cdev,devno,1);$ O7 d# X! G! x' m5 Q% }
  77.         if(err)
    ! M. s. `8 T) w
  78.               printk(KERN_NOTICE "Error %d adding GPIO %d",err,index);
    ) l; A: t  r3 H: \
  79. }
    $ s) j/ E& H6 X5 i- C4 ^* B" u
  80. static int __init gpio_init(void)5 D5 d7 ]; m# [7 H
  81. {' o3 o0 y' r/ \7 \1 n& f9 `+ z0 k
  82.         int result;4 s3 p* G- A! b7 }+ U1 C/ _
  83.         int a=0;
    ; N8 J6 X9 E  {6 p) Z( d
  84.         dev_t dev=MKDEV(gpio_major,0);5 b9 R6 r# _- D2 A: S9 [3 I
  85.         if(gpio_major)
    ) `6 H2 p% P8 B$ F
  86.                result=register_chrdev_region(dev,1,"led");+ G$ ?& i, X5 V9 X1 G' m
  87.         else {
    . Q; C' q+ Z# [$ b( B% t
  88.                 result=alloc_chrdev_region(&dev,0,1,"led");' h2 N. ]  U& J! _/ z
  89.                 gpio_major=MAJOR(dev);
    - {$ L4 N+ p& Y9 z0 L/ R. k
  90.         }
    4 [3 k% M$ j5 C" F; D( ?
  91.         if(result<0)& q- [4 K- O3 ?+ k+ i
  92.                 return result;5 u) y3 H; |( p
  93.         gpio_devp=kmalloc(sizeof(struct gpio_dev),GFP_KERNEL);$ W  w# v, k  j( G& A$ P; A4 C
  94.         if(!gpio_devp){
    : k2 p2 U+ G9 N
  95.                 result= -ENOMEM;/ E  Q; Z" \; g9 o
  96.                 goto failmalloc;
    6 ?3 J8 E+ Z/ H) t/ b
  97.         }
    * \9 [! \% G* ^/ k0 F- V& t! a% ~& J
  98.         memset(gpio_devp,0,sizeof(struct gpio_dev));! h7 a6 i( o; h0 H3 c: w
  99.         gpio_setup_cdev(gpio_devp,0);% ]3 k! u- u+ X
  100.         printk(KERN_NOTICE "init ok\n");0 |* K& a* e3 m+ |: C. p
  101.         //gpio ini' K9 {6 ~! r7 {0 g. F% x
  102.         a=gpio_request(57,"test_led");
    $ B' x* a$ b( ]  B' [
  103.         if(a)* O- @, Z. G1 H6 J' E
  104.                 printk(KERN_NOTICE "gpio request failed %d\n",a);" C$ Q2 f5 c7 Y$ o
  105.         else {
    . f5 E2 }6 Z( e5 o% w
  106.                 gpio_direction_output(57,1);
    / q6 ~- A$ I) J
  107.         }
    # y8 ?- _" d2 c) q( T+ a1 q
  108.         return 0;4 P# @, U. ]# J) `/ \
  109.         failmalloc:
    ! M3 K+ r8 \8 r3 L; A
  110.                 unregister_chrdev_region(MKDEV(gpio_major,0),1);7 W* p2 c2 C8 Z2 G$ a
  111.                 return result;4 n( B9 \& J4 U- j5 f1 ?
  112. }
    7 U3 S0 Y$ f+ z. @- e, K( P% n
  113. static void __exit gpio_clean_up(void)
    , b* o; [% w9 Z9 V/ o
  114. {
    6 j2 C4 O0 \& u9 d; [' K0 ^
  115.         cdev_del(&gpio_devp->cdev);
    0 i# H& }# I, |  I- d, i" ]  V  w
  116.         kfree(gpio_devp);
    - C/ H3 n+ ?$ }  y% U! v( }0 |% A
  117.         unregister_chrdev_region(MKDEV(gpio_major,0),1);3 I8 V) g5 e8 P1 w1 A! g  V
  118.         gpio_free(57);& B' i2 ?4 R# V  ~" y
  119.         printk(KERN_NOTICE "exit ok\n");+ }* ?1 T9 F) x; l7 X
  120. }
    4 |& l9 r% t( O0 J
  121. module_init(gpio_init);
    2 h9 T# s5 o' Q/ P5 c0 g3 U8 D& \
  122. module_exit(gpio_clean_up);
复制代码

8 z& _/ \; m) ~5 |/ ^4 a7 E. P" z$ ?* B% U$ [) A

12个回复

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

举报 使用道具

那些年儿ing 发表于 2016-12-1 14:10:16

PCB在线计价下单

板子大小:

cm
X
cm

层数:

2

板子数量:

10

厚度:

1.6
楼主真会玩
回复 3

举报 使用道具

3guoyangyang7 发表于 2016-12-1 17:06:48
新疆切糕 发表于 2016-12-1 10:19
. Y& m, L$ o+ o, ^小狂出品,必须精品
2 z' |% z$ `9 Z$ Q5 z
哈哈,小狂的口号啊,必须的,哈哈,谢谢支持
3guoyangyang7 发表于 2016-12-1 17:07:11
那些年儿ing 发表于 2016-12-1 14:10
4 @$ h3 K9 T, F# \/ Y  P% e楼主真会玩

/ Z9 G7 [& a9 R/ {) k" |( I玩就玩点不一样的吗,这才对得起玩啊
兜纳K1 发表于 2016-12-7 12:53:19
高手!
2 \4 B+ B3 X5 l谢谢分享!# I* r7 L9 c5 Q1 j, @* h* k4 p

/ u$ }3 K" H  V- V, a% a7 d" O) B! o2 j. l1 ?! `( r; }' O1 E
& r; h. B; `( i
兜纳K1
回复 3

举报 使用道具

3guoyangyang7 发表于 2016-12-7 15:57:22
兜纳K1 发表于 2016-12-7 12:53" b5 A# F5 {9 e. K* M% N/ D
高手!
! W4 W  I: H, r/ I谢谢分享!

8 C5 T$ p0 k8 G/ c* Q谢谢支持
柠檬守护 发表于 2016-12-10 10:38:28
论坛的原创担当啊~
回复 3

举报 使用道具

3guoyangyang7 发表于 2016-12-12 21:50:51
柠檬守护 发表于 2016-12-10 10:38
: z. @- _$ l% z4 l# v- a5 _论坛的原创担当啊~

% C* A& U! P! O谢谢版主大人夸奖,哈哈
n5631228 发表于 2017-9-2 19:21:12
楼主我问个问题 我照着你的Makefile写的 我把pwm-ehrpwm.c 复制过去了  然后make报了好几篇的错误 是怎么内核目录的Makefile不一样吗 我的也是自带的 不应该啊
3guoyangyang7 发表于 2017-9-2 22:35:34
n5631228 发表于 2017-9-2 19:21
2 z% j5 o7 k1 Z8 _9 j/ q楼主我问个问题 我照着你的Makefile写的 我把pwm-ehrpwm.c 复制过去了  然后make报了好几篇的错误 是怎么内核目录的Makefile不一样吗 我的也是自带的 不应该啊
) p5 C/ y* R1 t8 h, z2 A
对,要指向你的内核的目录,另外,你的内核要编译一下
n5631228 发表于 2017-9-6 10:55:06
3guoyangyang7 发表于 2017-9-2 22:35
! Y# U' ]7 o9 L6 ]对,要指向你的内核的目录,另外,你的内核要编译一下
& E8 l- P$ O+ S6 _% ?
谢谢楼主 我的Makefile写的不对 改了就好了
' z1 V% W8 B! v/ p再问一下 我是3.12内核 PWM用不了 该设备树没效果 用.ko文件insmod不了 你的能用吗
3guoyangyang7 发表于 2017-9-6 22:18:40
我的板子被收回了,嘿嘿,就没有玩,嘻嘻,应该只是支持的,insmod肯定可以的
您需要登录后才可以回帖 登录 | 注册

本版积分规则


关闭

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

小黑屋|手机版|Archiver|电子发烧友 ( 粤ICP备14022951号-2

GMT+8, 2017-9-25 16:10 , Processed in 0.141779 second(s), 18 queries , Memcache On.

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表