Linux下GPIO驱动详解文章 -
更新时间:2023-10-17 22:36:01 阅读量: 综合文库 文档下载
http://www.linuxidc.com/Linux/2011-09/43084.htm
打算跟着友善之臂的《mini2440 Linux移植开发指南》 见 http://www.linuxidc.com/Linux/2011-06/37904.htm 来做个LED驱动,虽然LED的原理简单得不能再简单了,但是要把kernel中针对于s3c24**的GPIO的一些数据结构,还有函数搞清楚也不是那么轻松的事,所以本文主要简单地说明下LED驱动中的相关数据结构以及函数/宏的定义,并对驱动加以验证
***************************************************************************
注意:在/arch/arm/mach-s3c2410/include/mach/gpio-fns.h源代码中有如下说明:
16/* These functions are in the to-be-removed category and it is strongly 17 * encouraged not to use these in new code. They will be marked deprecated 18 * very soon. 19 *
20 * Most of the functionality can be either replaced by the gpiocfg calls 21 * for the s3c platform or by the generic GPIOlib API. 22 *
23 * As of 2.6.35-rc, these will be removed, with the few drivers using them 24 * either replaced or given a wrapper until the calls can be removed. 25*/
该头文件包括:
static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
该函数直接使用
linux/arch/arm/plat-s3c/gpio-config.c中的
int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
即可
***************************************************************************
首先看一下设备初始化程序:
85 /*
86 * 设备初始化 87 */
88 static int __init dev_init(void) 89 {
90 int ret; 91 int i;
92 for (i = 0; i < 4; i++) {
93 //设置 LED 对应的端口寄存器为输出(OUTPUT)
94 if (s3c_gpio_cfgpin(led_table[i], led_cfg_table[i])<0)
printk(KERN_INFO \
95 printk(KERN_INFO \
95 //设置 LED 对应的端口寄存器为低电平输出,在模块加载> 结束后,四个 LED 应该是全部都是发光 96 状态
97 s3c2410_gpio_setpin(led_table[i], 0); 98 }
99 ret = misc_register(&misc); //注册设备
100 printk (DEVICE_NAME\打印初始化信息 101 return ret; 102 }
可以看到,这里涉及到两个函数,分别是s3c2410_gpio_cfgpin,s3c2410_gpio_setpin,这两个函数分别对四个LED进行配置,从函数名来看,cfgpin对引脚寄存器状态进行配置,而setpin应该是对寄存器数据值进行配置,我们在分析函数之前先弄清楚传入的参数到底是什么。
led_table[i]
28 //LED 对应的 GPIO 端口列表 29 static unsigned long led_table [] = {
30 S3C2410_GPB(5), 31 S3C2410_GPB(6), 32 S3C2410_GPB(7), 33 S3C2410_GPB(8), 34 };
这里S3C2410_GPB宏定义在mach/gpio-nrs.h中 /* GPIO bank sizes */
#define S3C2410_GPIO_A_NR (32) #define S3C2410_GPIO_B_NR (32) #define S3C2410_GPIO_C_NR (32) #define S3C2410_GPIO_D_NR (32) #define S3C2410_GPIO_E_NR (32) #define S3C2410_GPIO_F_NR (32) #define S3C2410_GPIO_G_NR (32) #define S3C2410_GPIO_H_NR (32)
#define S3C2410_GPIO_J_NR (32) /* technically 16. */ #define S3C2410_GPIO_K_NR (32) /* technically 16. */ #define S3C2410_GPIO_L_NR (32) /* technically 15. */ #define S3C2410_GPIO_M_NR (32) /* technically 2. */
#if CONFIG_S3C_GPIO_SPACE != 0
#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment #endif
#define S3C2410_GPIO_NEXT(__gpio) /
((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 0)
//这里的CONFIG_S3C_GPIO_SPAC是内核配置选项,在.config中可以找到,我的配置为:
CONFIG_S3C_GPIO_SPACE = 0
enum s3c_gpio_number {
S3C2410_GPIO_A_START = 0,
S3C2410_GPIO_B_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_A), S3C2410_GPIO_C_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_B),
S3C2410_GPIO_D_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_C), S3C2410_GPIO_E_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_D), S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E), S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F), S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G), S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H), S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J), S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K), S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L), };
#define S3C2410_GPB(_nr) (S3C2410_GPIO_B_START + (_nr))
因此,以S3C2410_GPB(5)为例,其宏展开为:
S3C2410_GPIO_NEXT(S3C2410_GPIO_A) +5 =>
(S3C2410_GPIO_A_START + S3C2410_GPIO_A_NR + CONFIG_S3C_GPIO_SPACE + 0) + 5 =>
很显然, S3C2410_GPB(5)就是从GPA的首地址+GPA个数+GPB的offset就是当前GPB的IO偏移量,即
0+32+5=37, 同理
S3C2410_GPB(0) 相当于 32
30 S3C2410_GPB(5) 相当于 37 31 S3C2410_GPB(6) 相当于 38 32 S3C2410_GPB(7) 相当于 39 33 S3C2410_GPB(8) 相当于 40
***************************************************************************
led_cfg_table[i]
36 //LED 对应端口将要输出的状态列表 37 static unsigned int led_cfg_table [] = { 38 S3C2410_GPIO_OUTPUT, 39 S3C2410_GPIO_OUTPUT, 40 S3C2410_GPIO_OUTPUT, 41 S3C2410_GPIO_OUTPUT, 42 };
S3C2410_GPIO_OUTPUT定义在mach/regs-gpio.h
#define S3C2410_GPIO_LEAVE (0xFFFFFFFF) // 最后两位是设置,11表示RESERVE
#define S3C2410_GPIO_INPUT (0xFFFFFFF0) /* not available on A */ // 最后两位是设置,00表示INPUT
#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1) // 最后两位是设置,01表示OUTPUT
#define S3C2410_GPIO_IRQ (0xFFFFFFF2) /* not available for all */
#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* bank A => addr/cs/nand */ #define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */
***************************************************************************
根据前面的分析,s3c2410传入了当前GPIO的偏移地址,以及OUTPUT状态
现在我们深入前面的两个函数:
定义在linux/arch/arm/plat-s3c/gpio-config.c
int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) {
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); //得到对应GPIO结构体首指针,里面包含了该GPIO的各种参数 unsigned long flags; int offset; int ret;
if (!chip)
return -EINVAL; // 没找到的话,返回invalid
offset = pin - chip->chip.base; // 否则offset等于该GPIO引脚相对于GPX(0)的偏移量,每个偏移1
s3c_gpio_lock(chip, flags); // 自旋锁锁住该GPIO,通过chip指针指向lock,看下面的define和图
ret = s3c_gpio_do_setcfg(chip, offset, config); //设置该GPIO状态寄存器的数值为config s3c_gpio_unlock(chip, flags); // 解锁
// 自旋锁操作
/* locking wrappers to deal with multiple access to the same gpio bank */ //#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
//#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
正在阅读:
Linux下GPIO驱动详解文章 -10-17
大学暑期保险公司实习报告范本02-22
电线电缆买卖合同03-06
山东省建筑市场企业诚信档案和评价系统 说明 - 图文12-30
马克思主义与社会科学方法论心得12-26
步步高 学案导学设计2014-2015学年高中人教B版数学必修三课时作业:第3章 概率 3.2.210-24
VRV中央空调和普通中央空调参数性能对比04-24
电工中级题库及答案10-21
高一数学必修1函数的基本性质08-12
窗口单位专项整治工作总结05-07
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 详解
- 驱动
- 文章
- Linux
- GPIO
- 生物统计学习总结
- 化学与传统文化1
- 施工现场重大危险源的控制措施
- 实验室内部审核报告 - 图文
- P3EC项目进度软件应用总结
- 神湾大桥防洪施工方案 - 图文
- 四年级学业水平测试语文练习卷1
- 金融专业毕业生经典个人求职简历模板封面+内页模板-word版15 - 图文
- 蓝莓栽培200问 -
- 重庆市物业管理条例
- (no.1)八年级思想品德下学期期中测试题(2)
- 国有企业人才队伍建设调研提纲
- 预应力钢筋 工程习题
- VPN使用指南
- 广数980T具体操作说明书
- 宁夏回族自治区挂靠证书前要知道的事项每日一讲(2月18日)
- 电气、给排水工程施工小结(范例)
- 初中化学湘教版《九年级下册》《专题7 初识酸碱盐》精品专题课后练习(含答案考点及解析)
- 预防农民工工资拖欠对策与建议
- ktv酒水知识培训