Board logo

标题: gpio映射 [打印本页]

作者: yuyang911220    时间: 2014-10-30 10:22     标题: gpio映射

一个函数分析(s3c2410_gpio_setpin),浅析ARM IO 内存映射
(这是我转载的一篇博客,不过我自己感觉其中有一点错误,不过按照这个上面的解释,还是有一点理解映射的机制的,呵呵)

   

目录:
1 S3c2410_gpio_setpin作用以及源码
2 在内核中队部分代码进行深入跟踪
3 ARM的IO内存映射计算及分析
4 一些琐碎的话

1  S3c2410_gpio_setpin作用以及源码

该函数根据传入的参数设这GPIO的数据输出。源码如下
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);
       dat &= ~(1<< offs);
       dat |= to << offs;
       __raw_writel(dat, base + 0x04);

       local_irq_restore(flags);
}

EXPORT_SYMBOL(s3c2410_gpio_setpin);


2  在内核中队部分代码进行深入跟踪

S3C24XX_GPIO_BASE的定义如下
#define S3C24XX_GPIO_BASE(x)  S3C2400_GPIO_BASE(x) //这一句我感觉有问题,源码中是这样写的:#ifdef CONFIG_CPU_S3C2400
#define S3C24XX_GPIO_BASE(x)  S3C2400_GPIO_BASE(x)
#define S3C24XX_MISCCR        S3C2400_MISCCR
#else
#define S3C24XX_GPIO_BASE(x)  S3C2410_GPIO_BASE(x)
#define S3C24XX_MISCCR       S3C24XX_GPIOREG2(0x80)
#endif /* CONFIG_CPU_S3C2400 */


由于CONFIG_CPU_S3C2400,对于2410和2440,应该是执行#else后面的宏定义的不是么?
我很疑惑,可是再网上都没有关于这方面的解释,所以说我还是按照他上面说的做的。。


#define S3C2400_GPIO_BASE(pin)   (pin < S3C2410_GPIO_BANKC ? \
                                 S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
                                 S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)

#define S3C2410_GPIO_BANKC   (32*2)
#define S3C2400_BASEA2B(pin)     ((((pin) & ~31) >> 2))
#define S3C2400_BASEC2H(pin)     ((S3C2400_BANKNUM(pin) * 10) + \
                                 (2 * (S3C2400_BANKNUM(pin)-2)))

#define S3C2400_BANKNUM(pin)     (((pin) & ~31) / 32)

#define S3C24XX_VA_GPIO         ((S3C24XX_PA_GPIO-S3C24XX_PA_UART)+S3C24XX_VA_UART)

#define S3C24XX_PA_GPIO     S3C2410_PA_GPIO

#define S3C2410_PA_GPIO     (0x56000000)

#define S3C2410_PA_UART    (0x50000000)

#define S3C24XX_VA_UART         S3C_VA_UART

#define S3C_VA_UART  S3C_ADDR(0x01000000)      /* UART */


#ifndef __ASSEMBLY__
#define S3C_ADDR(x)    ((void __iomem __force *)S3C_ADDR_BASE + (x))
#else
#define S3C_ADDR(x)    (S3C_ADDR_BASE + (x))
#endif

#define S3C_ADDR_BASE   (0xF4000000)
以上就是用cscope跟踪内核代码的结果。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0