ioremap()的理解

来源:互联网 发布:c语言求n的阶乘 编辑:程序博客网 时间:2024/05/16 10:21

刚开始学字符设备驱动,感觉最难的是驱动和底层硬件的连接。linux上的驱动程序,是基于操作系统之上的,他并不直接和底层的硬件打交道,但是我们写的驱动必须能使硬件“跑”起来,即与硬件紧密相连。

就拿最简单的LED驱动来说,我们的驱动程序是在虚拟的内存上面跑的,但是最终,LED的点亮还是必须靠GPIO管脚的高低电平来控制。那么,我们的虚拟的内存怎么才能和实际的硬件上面的寄存器对应起来呢?

这篇要写的就是ioremap这个映射函数,他可以将我们硬件上面的寄存器,映射为虚拟的内存,从而使驱动程序在我们的虚拟的内存中运行。

void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)

入口: phys_addr:要映射的起始的IO地址,即:物理地址

size:要映射的空间的大小;

flags:要映射的IO空间的和权限有关的标志;

下面是我用ioremap函数写的第一个LED 的驱动:(硬件是S3C2440的开发板)

/***************************************************************/
//file name: ioremap_driver.c
#include <linux/module.h>
#include <linux/init.h>
#include <asm/io.h>
volatile unsigned long virt, phys;//用于存放虚拟地址和物理地址
volatile unsigned long *GPBCON, *GPBDAT, *GPBUP;//用与存放三个寄存器的地址
void led_device_init(void)
{
// 0x56000010 + 0x10 包揽全所有的IO引脚寄存器地址
phys = 0x56000010; // 0x56000010=GPBCON
//在虚拟地址空间中申请一块长度为0x10的连续空间
//这样,物理地址phys到phys+0x10对应虚拟地址virt到virt+0x10
virt =(unsigned long)ioremap(phys, 0x10);
GPBCON = (unsigned long *)(virt + 0x00);//指定需要操作的三个寄存器的地址
GPBDAT = (unsigned long *)(virt + 0x04);
GPBUP  = (unsigned long *)(virt + 0x08);
}
//led配置函数,配置开发板的GPIO的寄存器
void led_configure(void)
{
*GPBCON &= ~(3 << 10)&~(3<<12)&~(3 << 16)&~(3<<20);//GPB12 defaule 清零
*GPBCON |= (1 << 10)|(1<<12)|(1<<16)|(1<<20); //output  输出模式
*GPBUP |= (1 << 5)|(1 <<6)|(1 <<8)|(1 <<10);  //禁止上拉电阻
}
void led_on(void) //点亮led
{
*GPBDAT &= ~(1 << 5)&~(1 << 6)&~(1 << 8)&~(1 << 10);
}
void led_off(void) //灭掉led
{
*GPBDAT |= (1 << 5)|(1 << 6)|(1 << 8)|(1 << 10);
}
static int __init led_init(void) //模块初始化函数
{
led_device_init(); //实现IO内存的映射
led_configure();  //配置GPB5 6 8 10为输出
led_on();
printk("hello ON!\n");
return 0;
}
static void __exit led_exit(void) //模块卸载函数
{
led_off();
iounmap((void *)virt); //撤销映射关系
printk("led OFF!\n");
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("hurryliu<>");
MODULE_VERSION("2012-8-5.1.0");
/*************************************************************************/

实验现象:

启动开发板,在命令行模式下将编译好的ioremap_driver.ko模块加载到内核中

# insmod ioremap_driver.ko

这时,我们可以看到,开发板上面的LED4个灯全亮了。

# rmmod ioremap_driver  卸载模块

这时,我们的LED灯就灭了。

另一篇参考文章:

http://www.linuxidc.com/Linux/2011-04/34295.htm

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝号码注册过怎么办 农行k宝怎么办信用卡 电脑页面无法显示怎么办 对方银行停止收款怎么办 淘宝东西买太多怎么办 淘宝号黑号了怎么办… 中通包裹异常怎么办 包裹退回去了怎么办 qq支付密码错误怎么办 ie8出现闪退怎么办 平板输不了密码怎么办 华硕笔记本键盘打不开怎么办 电脑打不开rar文件怎么办 苹果手机淘宝卡怎么办 淘宝联盟网址打不开怎么办 淘宝买东西卖家不退货怎么办 手机清理后微信打不开视频怎么办 搜索历史已关闭怎么办 微博重新激活怎么办 淘宝直播反应慢怎么办 微信新设备无法登录怎么办 dnf自动连接失败怎么办 APP注册没有成功怎么办 忘记绑定微信号怎么办 淘宝钻石绣被骗怎么办 safari出现闪退怎么办 12123手机号被占用怎么办 12306换手机了怎么办 51串口打开失败怎么办 打开com串口失败怎么办 xp串口打开失败怎么办 台式电脑没光驱怎么办 相机功能用不了怎么办 支付宝登录失败怎么办 淘宝号限制登陆怎么办 海信电视看不了怎么办 淘宝不记得密码怎么办 淘宝号忘记了怎么办 号码注销支付宝怎么办 旺旺号限制登录怎么办 淘宝单被监控了怎么办