EDA365电子论坛网

标题: 迅为4412开发板-实验LEDS驱动一 [打印本页]

作者: 阳阳天    时间: 2021-1-5 11:19
标题: 迅为4412开发板-实验LEDS驱动一
14.1 本章导读
+ p8 q7 Z$ ?, q5 x/ v% b) u) |& \/ `本节实验介绍一个完整的 GPIO 驱动,以后在 Linux 中需要处理 GPIO 驱动都可以仿照或
. i' W8 y" j0 v: N0 h6 v) B7 s者移植这个驱动。
* |# ~5 v. i, e- o8 p14.1.1 工具' ~" J/ j5 P, r0 A1 ^$ x
14.1.1.1 硬件工具/ {7 C$ m/ d2 S4 L
1)iTOP4412 开发板
- m: G7 L( ~2 ^; E$ d2)U 盘或者 TF 卡- B; f2 }6 ]  S8 w0 x
3)PC 机
2 g( P% U1 I% B1 R$ b# L" z" S4)串口
9 ^; N' a. j0 ]+ }: y14.1.1.2 软件工具0 ?. V( ~6 X- M: s: N$ j
1)虚拟机 Vmware
: G8 D' p. e" U2)Ubuntu12.04.2
/ C6 `4 q% M0 i& h. _5 c) V6 y3)超级终端(串口助手)6 Q1 c: ^8 t  N4 U( N* A5 ]
4)源码文件夹“leds”% c1 n& {8 H) q& l
14.1.2 预备课程1 P& Q) N( ~, U! z4 a3 J) e
实验 12_物理地址虚拟地址
& R6 [( u- n! i* c/ W1 d2 c实验 13_GPIO 初始化
! n9 o: u" H$ J" ^/ D. R14.1.3 视频资源/ }- v- i/ y  J& \+ b) |. Z9 D1 c
本节配套视频为“视频 14 LEDS 驱动一”6 B  J: }% y6 @$ k3 M5 a; A- o
14.2 学习目标' s" X0 h* T# D, c/ }
本章需要学习以下内容:
. P$ m1 M) ?* R8 [  \) YLed 硬件原理简单介绍. g7 L( R# T% Q
Led 管脚的调用、赋值以及配置; D2 q! _! H+ O2 r2 `/ b) t0 T: y
编写简单应用调用 LED 管脚,并测试
1 F  w) N; ?0 f; j14.3 Led 硬件原理简单介绍( |- y2 |* `3 z3 J
Led 的电路比较简单,一般是使用三极管搭建一个控制电路。" \) z/ F* `! W1 X) H* z# b
如下图所示,是原理图中两个 Led 的控制电路。KP_COL0 和 VDD50_EN 网络控制 Led的通断。
5 c4 K9 ?. y7 @* a% ]: X
; H; b6 P5 p$ Q  N8 t. w如上图所示。, F  ~% ~- w. k1 r# S
当 KP_COL0 和 VDD50_EN 网络时高电平的时候,三极管 L9014 的 BE 导通,CE 导通,相当于 5V 的 VSYS 电压加到 1K 和 Led 小灯上,小灯就会亮。4 q' @! t2 v. ]* J7 a) Q
当 KP_COL0 和 VDD50_EN 网络时低电平的时候,三极管 L9014 的 BE 会截止,CE 截止,相当于 5V 的 VSYS 电压加到 1K、Led 小灯和一个无限大的电阻上,电流为零,小灯就会灭。: Q+ @) I$ n. k) S; h; T% ?% t! L4 n
14.4 Led 管脚的调用、赋值以及配置& j! G. Z( K$ b7 N- b8 w8 L
本节给大家介绍一部分涉及 GPIO 调用、赋值以及配置的函数。6 I5 F; e' b0 _$ a, f2 }* Z! O
14.4.1 GPIO 申请和释放函数
: W" L3 J6 p) C5 D$ l! ?想用使用任何一个 GPIO 都必须先申请。+ G' I: s# {" ^
在头文件“include/linux/gpio.h”中有 Linux 默认的 GPIO 申请函数,这个头文件是属于嵌入式 Linux 平台,任何一个嵌入式 Linux 内核都可以这么使用。
# C5 B( E  G$ l8 h9 p, i* z如下图所示,在源码目录中使用命令“vim include/linux/gpio.h”打开该文件。
- k+ |9 a, F( g8 P- z9 D1 k4 W6 ]. w4 s2 T; X0 l
如下图所示,就是本节实验中需要用到的函数 gpio_request。2 H2 ~# P# d& v& G

  Z0 v6 A& n* y7 \* Y6 b7 c如上图所示,简单介绍一下 gpio_request 函数。/ ^3 S3 v8 y6 K& Q" F& }
首先这个函数有一个重要的“检测”功能,就是如果其它地方申请了这个 IO,那么这里就会返回错误,提示已经被占用了,这是 Linux 中的一个标准用法。
( u( M' ]7 T9 n( wgpio_request 函数有两个参数
; W4 m  ^, N! s" hunsigned gpio,申请的那个 GPIO,一般是 GPIO 对应的宏定义
* n' i! r0 e- e+ T8 e0 `3 |) oconst char *label,为 GPIO 取个名字,便于阅读
7 c& P8 [! H. i& d7 b如下图所示,和 gpio_request 函数对应的是 gpio_free 函数。( C$ m4 Z* O! m( m
; D. m$ P" w! o8 W" j3 a
在调用 gpio_request 函数之后,向系统表明这个 IO 已经被占用了,在卸载驱动的时候一般需要调用 gpio_free 函数将其释放。) E2 }6 \& f) t% D/ K1 _! j
gpio_free 函数的参数比较简单,只有一个 GPIO 参数,使用 GPIO 对应的宏定义即可。
0 i% D$ J+ e* b) U如下图所示,还有一个赋值函数 gpio_set_value。
5 I- @5 C" O. b) p1 S; z  C* {5 \; q, f
在将 GPIO 配置为输出模式之后,还需要给 GPIO 赋值,一般就是高电平和低电平两种。
9 S0 G$ d1 a* P3 m# ^两个参数分别为
6 p4 g) \6 n8 m, t1 C( qunsigned gpio,GPIO+ Q5 n: |; A( k$ [. z: {) ?; Q
int value,高电平 1 和低电平 0。
2 d0 N# G) r# P7 s( _) R. m# O14.4.2 GPIO 配置参数宏定义
! ^- B# f# l$ rGPIO 在 Linux 初始化,进行映射之后调用 GPIO 操作函数对 GPIO 宏定义进行操作就是对 GPIO 的操作。/ w. L$ P7 E3 Z: Q
这个 GPIO 宏定义文件都是由原厂提供,肯定是已经做好的,属于 BSP 板级开发包。5 R3 Y1 a, G, H: ], i
如下图所示,在源码目录中使用命令( g0 `3 t$ e2 P. M$ U) O) K  ?3 A
“vim arch/arm/mach-exynos/include/mach/gpio-exynos4.h”打开该文件。
* X1 r$ @% E! y, ~
" G( Y* n8 s' |% l6 w0 _如下图所示,可以看到所有的 GPIO 都已经定义了。
& E9 K9 r$ z- l0 V/ ]; s3 n7 F# v7 _0 R* p
在原理图中查找 KP_COL0、VDD50_EN 网络,最终连接到 4412 上的部分如下图所示。
; l5 n: S+ e4 G! h# D- v& R6 O9 D. K* n* G; X
如上图所示,则两个 Led 的宏定义为 EXYNOS4_GPL2(0),EXYNOS4_GPK1(1)。; z- V7 T; t7 y
14.4.3 GPIO 配置函数和参数
9 d7 J8 d$ j8 i$ H! Z在 Linux 中,对 GPIO 的配置函数以及参数都已经集成到三星板级开发包中。0 ^, v# |2 V3 b8 h3 h
先来看一下配置函数,如下图所示,在源码目录中使用命令+ i- v5 ^" K; h, I5 B
“vim arch/arm/plat-samsung/include/plat/gpio-cfg.h”打开该文件。
  c& @2 U( ]) s5 q+ c
: E' p  A6 G, P6 H: n) I- v如下图所示,s3c_gpio_cfgpin 函数就是本节实验需要的。
" q8 p) Y" F- O  u' D! [9 J) a$ \3 P1 H& Z0 H1 m2 u4 B/ \
如上图所示,函数 extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);9 S' Y' U% g  N/ k
一般来说带有 s3cxxx 的函数就是三星平台能够通用的函数。& d* Y$ c4 d( u
s3c_gpio_cfgpin 管脚配置函数有两个参数  \4 F* F& o" T8 [0 P, ^/ t( f
参数 unsigned int pin,管脚
; E1 l( T3 M6 ~6 i( H参数 unsigned int to,配置参数。) m) O% i3 O3 `. B- A8 K2 C/ j  `
再来看一下配置参数,如下图所示,在源码目录中使用命令: k( o+ I2 ]& X& c- o" T
“vim arch/arm/plat-samsung/include/plat/gpio-cfg.h”打开该文件,配置参数和函数是在同一个函数中。0 T% v9 ]" p' ]8 E  o3 h; h4 @( X  Q
# r- Y2 j' V: x8 B6 c/ T
如下图所示,对于 GPIO 需要将其配置为输出模式,对应 S3C_GPIO_OUTPUT 宏定义。$ o- }' F  Z" f! F0 V- p

* v3 D  E) y  Z  B# p; A  f  v# V14.5 编写简单应用调用 LED 管脚,并测试
& @) S! l  h" `4 E8 h# k在前面的 devicenode_linux_module.c 文件上添加代码,首先将文件名devicenode_linux_module.c 改为 leds.c。+ ]5 M. R7 y2 k2 v4 Z
先处理一下编译文件 Makefile,如下图所示,将 devicenode_linux_module 改为leds。5 |% G* Z& e7 i

0 V' v  Y7 N% F* z7 Y) L接着修改 leds.c 文件。( a3 M' {3 T1 C; S; U
首先添加需要的头文件,如下图所示,分别是申请 GPIO、配置函数、配置参数、GPIO宏定义等的头文件。然后将设备节点名称由 hello_ctl123 修改为 hello_ctl
+ c& B  X8 x( H" T9 E' R# z/ O+ p% {' U8 E! I( I
然后需要修改的就是 probe 函数,一般说来 GPIO 的初始化都是在 probe 中。如下图所示,调用配置函数以及配置函数。$ B; O" C7 l0 a
: X" m! M+ |0 o6 C2 O: z
然后就是修改一下 ioctl 函数,在 Linux 中对 GPIO 的控制一般是使用 ioctl,虽然 write函数也可以实现类似的功能,但是 ioctl 函数的效率高一些。如下图所示,根据应用传入的参数给 GPIO 赋值。% t, k% M' n) b6 Z+ O2 v

8 h. d7 t* H- ]; e5 c# c$ W如上图所示,先对于参数做一个简单的判断,然后给 led 赋值。: _  R" x0 t  N# ~- X
接着再来看一下应用,如下图所示,应用比较简单,调用延时函数,首先将 Led 点亮三秒,然后再灭掉三秒,再点亮。
8 H5 J7 A' M. P8 @: K
) _% y( j, I- A; P/ d在 Ubuntu 系统下新建 leds 文件夹,将写好的 leds 和编译脚本拷贝到 leds 文件夹下,使用 Makefile 命令编译驱动,使用0 P! o$ l' a$ i
“arm-none-linux-gnueabi-gcc -o invoke_leds invoke_leds.c -static”命令编译应用。如下图所示% f1 v; T* l* j
# `- A" ^# B9 v+ X  b0 R# T
将上图中的文件 invoke_leds 和 leds.ko 拷贝到 U 盘。, T2 @; w& }* t+ y. |) B% h
启动开发板,将 U 盘插入开发板,使用命令“ mount /dev/sda1 /mnt/udisk/”加载 U盘符,) k2 t2 B2 Q0 C# U! s
使用命令“ insmod /mnt/udisk/leds.ko ”加载驱动 leds.ko,2 ?5 i6 Y, S- R
使用命令“./mnt/udisk/invoke_leds”运行小应用 invoke_leds,如下图所示。
4 M+ ]- l+ o1 w8 ^3 a8 x% O' {# m3 u* R; `1 B3 z* c, c
经过上面的操作可观察到 led 小灯会一亮一灭一亮,中间大概间隔三秒钟。
: a7 A% S- _; a% [8 ~3 s) G0 t  s$ [" q6 L: p8 Q9 ^/ D
. z: v4 z* S! m1 E! K+ ?' [. c0 Q

作者: modengxian111    时间: 2021-1-5 13:09
看着还不错




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2