linux内核gpio操作函数解析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
•详解内核驱动操作GPIO引脚API函数
函数原型:
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
unsigned int s3c2410_gpio_getcfg(unsigned int pin);
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
unsigned int s3c2410_gpio_getpin(unsigned int pin);
unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change);
int s3c2410_gpio_getirq(unsigned int pin);
关于函数中用到的虚拟地址到物理地址转换的变量及算法可以参考
/hefeng330467115@126/blog/static/78205842201 0620511659/
或/u3/102836/showart_2065945.html
看简单led驱动程序是用到的文件及头文件可能有:
linux/include/asm-arm/arch-s3c2410/map.h
linux/include/asm-arm/arch-s3c2410/regs-gpio.h
linux/arch/arm/plat-s3c24xx/gpio.c
linux/include/asm-arm/io.h
用Source Insight 打开这些文件,然后再看驱动程序,可以随意跳转到定义处,很是方便
pin参数:
gpio引脚及特殊功能寄存器助记符都在
linux/include/asm-arm/arch-s3c2410/regs-gpio.h中定义:
eg:
S3C2410_GPACON
S3C2410_GPADAT
S3C2410_GPA0 - S3C2410_GPA22 //引脚
S3C2410_GPA0_OUT - S3C2410_GPA22_OUT //设置引脚为输出
用到哪个不清楚的可以直接到这个文件去查找
还有中断和GSTATUS:
S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23
……
function参数:
指定引脚功能:输出、输入还是特殊功能,也在
linux/include/asm-arm/arch-s3c2410/regs-gpio.h中定义。
函数功能:
1原型:void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
作用:配置GPIO引脚功能,即是配置相应的CON位
eg:
s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);//设置B5脚为输出功能
函数原代码及注释:
(这个函数注释的比较详细,后面类似的不再重复注释)
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) {
void __iomem *base = S3C24XX_GPIO_BASE(pin);
//取引脚基地址即是:GPA0、GPB0 …… 的虚拟基地址
unsigned long mask;
unsigned long con;
unsigned long flags;
if (pin < S3C2410_GPIO_BANKB) {
mask = 1 << S3C2410_GPIO_OFFSET(pin);
//用于查找对应的引脚位(端口A一位控制一个引脚)
} else {
mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
//除端口A外其他端口都是两位控制一个引脚
}
//根据function值具体确定怎么来调整function
switch (function) {
case S3C2410_GPIO_LEAVE:
mask = 0;
function = 0;
break;
case S3C2410_GPIO_INPUT:
case S3C2410_GPIO_OUTPUT:
case S3C2410_GPIO_SFN2:
case S3C2410_GPIO_SFN3:
if (pin < S3C2410_GPIO_BANKB)
{ // 当某位被设为0时,相应引脚为输出,此时可
function -= 1; //以在GPADAT中相应位写入1或0;当某位被
function &= 1; //设为1时,相应引脚为地址线或用于地址控制。
function <<= S3C2410_GPIO_OFFSET(pin); //偏移量即是相应的引脚位} else {
function &= 3;
function <<= S3C2410_GPIO_OFFSET(pin)*2; //除A端口以外的其他端口都是
} //两位控制一个引脚
}
/* modify the specified register wwith IRQs off */ local_irq_save(flags); //调用该宏
函数来保存IRQ 中断使能状态,并禁止IRQ 中断
con = __raw_readl(base + 0x00);
// 基地址加偏移量得到相应端口的控制寄存器(GPxCON)地址,然后读取该寄存器的值
con &= ~mask; // 找到需要修改的引脚的控制位
con |= function; // 使对应的引脚的功能为function
__raw_writel(con, base + 0x00); // 重写控制寄存器的值,实现引脚功能修改
local_irq_restore(flags); //恢复IRQ 和FIQ 的中断使能状态
}
2原型:unsigned int s3c2410_gpio_getcfg(unsigned int pin);
作用:该函数根据引脚获得指定引脚配置的功能值
eg:
s3c2410_gpio_getcfg (S3C2410_GPB5);//读取B5脚为的配置功能输入00、输出01、特殊功能02 ……
函数原代码及注释:
unsigned int s3c2410_gpio_getcfg(unsigned int pin)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long val = __raw_readl(base);
if (pin < S3C2410_GPIO_BANKB) { //此判断操作主要是针对A端口,原因前面已解释
val >>= S3C2410_GPIO_OFFSET(pin);
val &= 1;
val += 1;
} else {
val >>= S3C2410_GPIO_OFFSET(pin)*2;
val &= 3;
}
return val | S3C2410_GPIO_INPUT;
}
3 原型:void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
作用:设置相应GPIO口的上拉电阻
eg
s3c2410_gpio_pullup(S3C2410_GPB5,0)//设置S3C2410_GPB5不要上拉电阻
s3c2410_gpio_pullup(S3C2410_GPB5,1)//设置S3C2410_GPB5要上拉电阻
函数原代码及注释:
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C24XX_
GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long up;
if (pin < S3C2410_GPIO_BANKB)
return;
local_irq_save(flags);
up = __raw_readl(base + 0x08); // //0x08是GPxUP寄存器的物理偏移量
up &= ~(1L << offs);
up |= to << offs;
__raw_writel(up, base + 0x08);
local_irq_restore(flags);
}
4原型:void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
作用:该函数给指定的引脚位写入0或1,即是配置相应的DAT位。
eg
s3c2410_gpio_setpin (S3C2410_GPB5 ,0);//设置S3C2410_GPB5的输出值为0
s3c2410_gpio_setpin (S3C2410_GPB5 ,1);//设置S3C2410_GPB5的输出值为1
函数原代码及注释:
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) {
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long dat;
local_irq_save(flags);
dat = __raw_readl(base + 0x04); //0x04是GPxDAT寄存器的物理偏移量
dat &= ~(1 << offs);
dat |= to << offs;
__raw_writel(dat, base + 0x04);
local_irq_restore(flags);
}
5原型:void s3c2410_gpio_getpin(unsigned int pin);
作用:该函数读取指定引脚的状态返回0或 1,即是读取相应的DAT位。
eg
s3c2410_gpio_setpin (S3C2410_GPB5 );// 读取S3C2410_GPB5位的状态。
函数原代码及注释:
unsigned int s3c2410_
gpio_getpin(unsigned int pin)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
return __raw_readl(base + 0x04) & (1<< offs);
}
6原型:unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change);
作用:主要是设置混杂控制寄存器(Miscellaneous control :物理地址0x56000080),此寄存器控制数据口上拉寄存器,hi-z 状态,USB
块和CLKOUT选择
7原型:int s3c2410_gpio_getirq(unsigned int pin);
作用:读取中断引脚的状态 GPF0-GPF7、GPG0-GPG7
eg
s3c2410_gpio_ getirq (S3C2410_GPF0 );// 读取S3C2410_GPF0位的状态,看是否产生EINT8中断。
友情提示:范文可能无法思考和涵盖全面,供参考!最好找专业人士起草或审核后使用,感谢您的下载!。