打印
[嵌入式linux]

【Arm Linux】如何在kernel中加入测试pin

[复制链接]
844|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
JackWellem|  楼主 | 2016-1-20 10:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

环境说明:CPU(imx6)
问题:  在uboot中可以添加如下代码,来控制测试pin拉高。
               *(volatile unsigned long*) 0x020A4000 |= (0x200000);    (数据输出值)
               *(volatile unsigned long*) 0x020A4004 |= 0x200000;       (端口方向选择)
         但在kernel中则不行,大概是因为kernel的分页机制而不能访问对应的寄存器,请问有谁知道在内核中如何添加对测试pin的控制?

相关帖子

沙发
JackWellem|  楼主 | 2016-1-20 12:31 | 只看该作者
一、动态映射(ioremap)方式

动态映射方式是大家使用了比较多的,也比较简单。即直接通过内核提供的ioremap函数动态创建一段外设I/O内存资源到内核虚拟地址的映射表,从而可以在内核空间中访问这段I/O资源。
Ioremap宏定义在asm/io.h内:
#define ioremap(cookie,size)           __ioremap(cookie,size,0)


__ioremap函数原型为(arm/mm/ioremap.c):
void __iomem * __ioremap(unsigned long phys_addr, size_t size, unsigned long flags);
phys_addr:要映射的起始的IO地址
size:要映射的空间的大小
flags:要映射的IO空间和权限有关的标志
该函数返回映射后的内核虚拟地址(3G-4G). 接着便可以通过读写该返回的内核虚拟地址去访问之这段I/O内存资源。


举一个简单的例子: (取自s3c2410的iis音频驱动)
比如我们要访问s3c2410平台上的I2S寄存器, 查看datasheet 知道IIS物理地址为0x55000000,我们把它定义为宏S3C2410_PA_IIS,如下:
#define S3C2410_PA_IIS    (0x55000000)
若要在内核空间(iis驱动)中访问这段I/O寄存器(IIS)资源需要先建立到内核地址空间的映射:
our_card->regs = ioremap(S3C2410_PA_IIS, 0x100);
if (our_card->regs == NULL) {
         err = -ENXIO;
         goto exit_err;
}
创建好了之后,我们就可以通过readl(our_card->regs )或writel(value, our_card->regs)等IO接口函数去访问它。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

11

帖子

1

粉丝