您的位置:首页 > 其它

驱动:9.2 ioremap

2020-06-19 14:56 85 查看

将特殊功能寄存器物理地址进行映射
通过映射之后的虚拟地址访问特殊功能寄存器

统一编址:将内存和外设(特殊功能寄存器)
使用同一套地址编号去编址,称作统一编址
ARM处理器
访问内存 ldr/str
访问外设 ldr/str
独立编址:将内存和外设(特殊功能寄存器)
各自使用一套独立的编号去编址,称作独立编址
X86处理器
访问内存 mov
访问外设 in / out
linux内核中将使用统一编址的外设称为I/O内存
独立编址的外设称为I/O端口
Linux内核中访问特殊功能寄存器(外设)的步骤:
1)申请I/O内存
request_mem_region(start,n,name)
start,要申请的I/O内存起始地址
n,     要连续申请的字节数
name,名称
2)映射I/O内存
void __iomem *ioremap(phys_addr_t start, unsigned long n)
start,要映射的起始物理地址
n,     要连续映射的字节数
返回值,映射后的起始虚拟地址
例如:start=0xc001c00   n=0x100  返回值=0xf0000000
意味着:   虚拟地址       物理地址
0xf0000000    0xc001c000
3)访问I/O内存
方法一:
*((volatile unsigned int *)0xf0000000) = var;
var = *(volatile unsigned int *)0xf0000000;
方法二:
#define readl(addr) __le32_to_cpu(__raw_readl(addr))
readl(addr); //   l,long
#define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr)
writel(val,addr);
4)取消映射
void iounmap(void __iomem *addr)
addr,ioremap时返回的起始虚拟地址
5)释放I/O内存
#define release_mem_region(start,n)	__release_region(&iomem_resource, (start), (n))
release_mem_region(start,n)
start,要释放的起始物理地址
n,要连续释放的字节数
注意:步骤1)、5)是可选的
练习:希望安装内核模块时LED1亮
卸载内核模块时LED1灭
通过直接访问特殊功能寄存器实现,而不用GPIO库函数
cpu  datasheet:
GPIOCALTFN0     0xc001c020
[25:24]          01
GPIOCOUTENB   0xc001c004
[12]                 1,输出模式
GPIOCOUT          0xc001c000
[12]                  0/1    输出低/高电平
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: