Chinaunix首页 | 论坛 | 博客
  • 博客访问: 503709
  • 博文数量: 68
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 806
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-30 22:06
文章分类
文章存档

2011年(1)

2009年(8)

2008年(59)

我的朋友

分类: C/C++

2009-09-22 11:34:53

先看看简单的内核模块:                                                   

/**

 * @:通过对GPIO寄存器操作,蜂鸣器beep

 * @:volatile防止优化带来数据不一致,直接到内存读数据

 */
#include<linux/init.h>
#include<linux/module.h>
#include<linux/delay.h>

#include<mach/hardware.h>
#include<asm/io.h>

//#define P3_SET io_p2v(0x40028004)
//#define P3_CLR io_p2v(0x40028008)

#define P3_SET io_p2v((volatile unsigned int)0x40028004)
#define P3_CLR io_p2v((volatile unsigned int)0x40028008)


//#define P3_SET ((volatile unsigned int)0xf4028004)
//#define P3_CLR ((volatile unsigned int)0xf4028008)

static int __init hello_mod_init(void)
{    
    int tmp = 6;
    int i;
    printk(KERN_INFO"\n Hello Module\n");
    while(tmp)
    {
        __raw_writel(1<<7, P3_CLR);
        for(i = 50; i > 0; i--)
            udelay(1000);

        __raw_writel(1<<7, P3_SET);
        for(i = 50; i > 0; i--)
            udelay(1000);
        tmp--;
    }
    return 0;
}

static void __exit hello_mod_exit(void)
{
    printk(KERN_INFO"\n Bye Module\n");
}

module_init(hello_mod_init);
module_exit(hello_mod_exit);

MODULE_LICENSE("GPL");


1>通过GPIO寄存器地址0x40028004和0x40028008,io_p2v()转换得到虚拟地址操作
2>直接用转换后的地址0xf4028004和0xf4028008操作

   你觉得那种方法能是蜂鸣器beep。当然都可以,都是对虚拟地址操作,只是一个包装而已。

     RISC指令系统的CPU(如ARM、PowerPC等)通常只实现一个物理地址空间,外设I/O端口成为内存的一部分。此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令。

     一般来说,在系统运行时,外设的I/O内存资源的物理地址是已知的,由硬件的设计决定。但是CPU通常并没有为这些已知的外设I/O内存资源的物理地址预定义虚拟地址范围,驱动程序并不能直接通过物理地址访问I/O内存资源,而必须将它们映射到核心虚地址空间内,然后才能根据映射所得到的核心虚地址范围,通过访内指令访问这些I/O内存资源。

阅读(2108) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~