首页 > 代码库 > led driver 1--ioremap

led driver 1--ioremap

#define GPIO_OFT(x) ((x) - 0x56000000)
#define GPFCON (*(volatile unsigned long *)(gpio_va + GPIO_OFT(0x56000050)))

static int s3c24xx_leds_open(struct inode *inode, struct file *file){    int minor = MINOR(inode->i_rdev); //MINOR(inode->i_cdev);    switch(minor)    {        case 0: /* /dev/leds */        {            // 配置3引脚为输出            GPFCON &= ~(0x3<<(4*2));
//oo00:这里GPFCON是虚拟地址,在驱动模块开始(见下面s3c24xx_leds_init)的时候,这个虚拟地址已经通过宏定义 #define GPFCON (*(volatile unsigned long *)(gpio_va + GPIO_OFT(0x56000050)))被映射到物理地址
            GPFCON |= (1<<(4*2));
    .......}static struct file_operations s3c24xx_leds_fops = {    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */    .open   =   s3c24xx_leds_open,    .read    =    s3c24xx_leds_read,    .write    =    s3c24xx_leds_write,};static int __init s3c24xx_leds_init(void)//模块入口{    gpio_va = ioremap(0x56000000, 0x100000); // 物理地址0x56000000, 映射区分配的大小0x100000字节

printk(DEVICE_NAME "gpio_va = %x\n",gpio_va);//oo00 debug
    register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c24xx_leds_fops);    ...    leds_class = class_create(THIS_MODULE, "leds");    ...    for (minor = 1; minor < 4; minor++)    {        leds_class_devs[minor] = class_device_create(leds_class, NULL, MKDEV(LED_MAJOR, minor), NULL, "led%d", minor);        ..    }    }

 

gpio_va = ioremap(0x56000000, 0x100000);//变为虚拟地址

 

#define GPIO_OFT(x) ((x) - 0x56000000)
#define GPFCON (*(volatile unsigned long *)(gpio_va + GPIO_OFT(0x56000050)))

 GPFCON |= (1<<(4*2));//在ioremap成功的前提下,对虚拟地址的操作作用于对应的物理地址

 

————————————————————————————————————

test:

 

insmod myleds_ou.ko
ledsgpio_va = c5400000

 

—————————————————————————————————————————————————————————————————————

ioremap (unsigned long offset, unsigned long size);

参考: S3C2440开发板LED驱动——ioremap 映射  http://www.linuxidc.com/Linux/2012-12/76084.htm

 

led driver 1--ioremap